v1.0.40 — ACL labels, country allowlists, and audit improvements
Implements the four non-SSO requests in issue #34:
- Add labels/comments to IP/CIDR ACL entries, with row and bulk editors and normalized previews. Labels are metadata and do not change enforcement.
- Add a global Allow only selected countries mode alongside the existing country blocklist. Enforcement uses a complete cached dataset; private/unknown clients are denied in allow mode. Explicit trusted-IP bypass precedence is preserved, and passing country checks continues through normal ACL, authentication, and WAF processing.
- Record event-time actor names/IDs and detailed ACL edits and site attachments in the audit log. Historical entries use an explicitly marked fallback where a snapshot is unavailable.
- Optionally return an empty HTTP 403 for ACL/geo denials. Detailed responses remain the default. This does not drop TCP connections or suppress unrelated authentication/WAF errors.
Management-UI SSO and management-UI access restrictions are not included.
Compatibility and recovery
Migration 0042_access_controls preserves existing enforcement defaults. Older ACL clients can omit label maps without erasing retained labels. Legacy geo endpoints work in block mode and explicitly reject operations in allow mode rather than misinterpreting it.
Country policies are revisioned and use a pinned MMDB snapshot. Failed or incomplete extraction rejects the candidate; cached enforcement survives a missing database. Cached removals and resetting to block mode do not require a working MMDB. Uncertain Caddy publication requires reconciliation before further writes.
Country MMDB is preferred, with City fallback only when Country is absent. Extraction permits one worker per API process, a 256 MiB source, one million retained spans and one million final CIDRs, and a 100-second extraction/summarization deadline. A private temporary snapshot needs writable temporary storage. Native MaxMind decoding is preferable for a full City database; the Python fallback can time out safely.
This release also includes the previously merged Caddy certificate persistence fix. Before recreating an existing deployment that lacks the /data and /config mounts, follow the certificate persistence migration to retain existing certificates and avoid unnecessary reissuance. Preserve existing Compose project names and volumes.
Images and upgrade
Production images target linux/amd64:
ghcr.io/socfortress/waf-caddy:1.0.40ghcr.io/socfortress/waf-admin-api:1.0.40ghcr.io/socfortress/waf-admin-ui:1.0.40
Back up the database, configuration, certificate storage, and deployment settings. Preserve local Compose overrides. Installations older than v1.0.37 must follow its CRS prerequisites; installations older than v1.0.39 must review its path ACL behavior changes. Existing experimental NTLM limitations still apply.
Update deployment files with git pull --ff-only, preserving customizations, and set both values in .env:
WAF_IMAGE_TAG=1.0.40
CRS_CADDY_DIGEST=sha256:64493f2d5299c84c8bb6cfa0ee14ce7c06ca39bf64f4d7e89c2a5689a2d5fd37The digest takes precedence over the tag. Production Caddy and the CRS validator must use the same release digest. Verify docker compose config, stop configuration edits, and upgrade the services together:
docker compose pull
docker compose stop admin-ui admin-api caddy-waf waf-sandbox
docker compose up -d --wait postgres redis http-echo caddy-waf waf-sandbox
docker compose up -d --wait admin-api admin-ui
docker compose psConfirm migration and startup synchronization, then test allowed/denied clients and certificate persistence before enabling new country policies.
Validation
Independent design and implementation reviews completed. All findings, including a full-City-dataset capacity issue, were fixed and independently re-reviewed with no remaining blockers.
- Final complete backend suite: 619 passed; targeted ACL/access-control suites: 98 passed.
- Final frontend changes: 19 targeted tests passed, plus the production build.
- Disposable PostgreSQL and real-Caddy integration covered migrations, concurrent writers, recovery failures, audit persistence, HTTP/TLS, trusted-proxy handling, and downstream security.
- The full 69,925,690-byte City MMDB produced 320,558 CIDRs for US/CA/GB/DE/AU in 42.1 seconds, with about 164 MiB extraction peak RSS, in the local Linux/arm64 test runtime.
- Four geo-only Caddy configurations loaded in 0.39–2.18 seconds; 132 sampled routing decisions passed. Maximum JSON size was 6.86 MiB, with about 250 MiB Caddy peak RSS.
Capacity results are representative observations, not production throughput guarantees. The capacity runtime was Linux/arm64; release images are independently built for Linux/amd64.
Images are built from merged source a39d9187fe3f1a326a1aa745178d86dc24fbfbdb. See publication verification for digests, revisions, platforms, and anonymous pull checks.
Rollback
Before reverting to an older API/UI, reset the country policy to block mode with the intended blocked selection, and restore detailed denial responses. An older binary would interpret cached allowed-country rows as blocked countries. Do not run mixed old/new API writers after enabling allow mode. Schema downgrade refuses active allow mode and discards labels and actor snapshots.
Restore a consistent pre-upgrade database/configuration backup and matching image versions when required. Preserve certificate volumes and matching Caddy/validator digest pins. Do not attempt rollback during unresolved configuration publication or CRS recovery.
This release does not deploy changes to the lab or production servers.