Site Access Protection
Overview
Accent CMS can restrict access to your entire site using HTTP Basic Authentication and/or IP allowlisting. This is designed for preview and staging deployments where only authorized reviewers should see the content before it goes live.
The protection feature requires a Standard or Pro license under accent serve --production. On a server started without --production it works without a license, so you can test the configuration locally or put a password in front of a LAN preview. Only the --production flag decides this; the dev.* settings (such as dev.browser_reload) have no effect on whether protection is enforced.
Configuration
Add a protection section to your config.yaml:
protection: basic_auth: enabled: true realm: "Preview Access" users: - username: reviewer1 password: "s3cret-preview" - username: client-alice password: "alice-2026!" public_paths: - "/healthz" - "/readyz" - "/favicon.ico" - "/robots.txt"
Basic Authentication
When basic_auth.enabled is true, browsers display a native login dialog. Only users listed in the users array can access the site.
| Setting | Default | Description |
|---|---|---|
enabled | false | Enable HTTP Basic Authentication |
realm | "Restricted" | Text shown in the browser’s login dialog |
users | [] | List of username/password pairs |
IP Allowlist
Restrict access to specific IP addresses or CIDR ranges. Useful for office networks or VPN egress IPs.
protection: ip_allowlist: enabled: true addresses: - "192.168.1.0/24" # Office LAN - "10.0.0.0/8" # VPN range - "203.0.113.42" # Specific IP trust_forwarded_for: false
| Setting | Default | Description |
|---|---|---|
enabled | false | Enable IP allowlisting |
addresses | [] | IP addresses or CIDR ranges to allow |
trust_forwarded_for | false | Use X-Forwarded-For header for client IP (enable only behind a trusted reverse proxy) |
Combining Strategies
When both basic_auth and ip_allowlist are enabled, a request must satisfy at least one strategy (OR logic). This lets office users browse without credentials while remote reviewers use a password.
Public Paths
Paths listed in public_paths bypass all protection. Use this for health probes, robots.txt, and other endpoints that must remain accessible.
Patterns support a * wildcard suffix:
/healthz– exact match/_dev/*– matches/_dev/reload,/_dev/anything, etc.
Credentials from the environment
Every string in config.yaml supports ${VAR} placeholders, so you can keep the password out of the file and supply it through the environment:
protection: basic_auth: enabled: true users: - username: "${SITE_AUTH_USER:-preview}" password: "${SITE_AUTH_PASSWORD}"
If a referenced variable is unset when the server starts, the server refuses to start and names the variable and the user entry:
protection.basic_auth.users[0] (username "preview"): password references the unset environment variable SITE_AUTH_PASSWORD; set it, or the site would be protected by the literal placeholder
An empty password is rejected the same way. The ${VAR:-default} form is unaffected: it expands to the default when the variable is unset, and that default is the value the server authenticates against. Placeholders in a basic_auth block with enabled: false are not checked.
Runtime Reload
Protection settings reload on SIGHUP (or via the /_admin/reload endpoint) without restarting the server. You can add or remove users, change IP ranges, or toggle strategies on the fly.
Security Notes
- Passwords are stored as plaintext in
config.yaml. This is acceptable for short-lived preview credentials but not for production authentication. Use HTTPS to prevent credentials from being transmitted in the clear. To keep the password out of the file, use an environment placeholder as shown above. - The
trust_forwarded_foroption defaults tofalseto prevent IP spoofing. Only enable it when Accent CMS is behind a trusted reverse proxy (nginx, Caddy, etc.). - For production authentication needs (SSO, OAuth2), use a reverse proxy or identity-aware proxy in front of Accent CMS.