Compare commits
1 changed files with 0 additions and 53 deletions
|
|
@ -466,56 +466,3 @@ follow-up.
|
||||||
display in the credential dialog. Defaults to `"hyperhive"`. Must not
|
display in the credential dialog. Defaults to `"hyperhive"`. Must not
|
||||||
contain `"` or `$`.
|
contain `"` or `$`.
|
||||||
|
|
||||||
**Custom 401 page:** when credentials are absent or wrong, nginx serves
|
|
||||||
a Catppuccin-styled `unauthorized.html` page (built into the same Nix
|
|
||||||
derivation as the agent error pages) that tells the operator which
|
|
||||||
`hivectl` command to run to create a user. The response status is still
|
|
||||||
`401` (`error_page 401 =401 /__hive_auth_unauthorized`) so browsers
|
|
||||||
present the login dialog on the first visit — users who dismiss the
|
|
||||||
dialog see the human-readable hint. The internal exact-match location
|
|
||||||
(`= /__hive_auth_unauthorized`) beats `location /` in nginx's prefix
|
|
||||||
ordering, preventing the subrequest from looping back through
|
|
||||||
`auth_basic`.
|
|
||||||
|
|
||||||
## Security headers
|
|
||||||
|
|
||||||
The following headers are emitted at server scope on every gateway
|
|
||||||
vhost (`_`, `forge.<domain>`, `matrix.<domain>`):
|
|
||||||
|
|
||||||
| Header | Value |
|
|
||||||
|--------|-------|
|
|
||||||
| `X-Frame-Options` | `SAMEORIGIN` |
|
|
||||||
| `X-Content-Type-Options` | `nosniff` |
|
|
||||||
| `Referrer-Policy` | `strict-origin-when-cross-origin` |
|
|
||||||
|
|
||||||
nginx's `add_header` inheritance rule: a `location` block that sets its
|
|
||||||
own `add_header` does **not** inherit server-scope headers. API locations
|
|
||||||
that carry their own CORS headers (e.g. `/.well-known/matrix/client`,
|
|
||||||
`/_matrix/`) are therefore unaffected. HTML-serving and proxy locations
|
|
||||||
with no `add_header` of their own pick the security headers up
|
|
||||||
automatically.
|
|
||||||
|
|
||||||
### HSTS (`gateway.hsts`)
|
|
||||||
|
|
||||||
HSTS is **opt-in** and disabled by default:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
services.hyperhive.gateway.hsts = {
|
|
||||||
enable = true; # default: false
|
|
||||||
maxAge = 31536000; # default: 1 year (required for preload list)
|
|
||||||
includeSubDomains = true; # default: true
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
When enabled, a `Strict-Transport-Security: max-age=...[; includeSubDomains]`
|
|
||||||
header is added alongside the other security headers.
|
|
||||||
|
|
||||||
**Opt-in rationale**: HSTS pins HTTPS in the browser's preload cache;
|
|
||||||
enabling it on a deployment that later loses TLS locks browsers out
|
|
||||||
until `max-age` expires. Only enable when TLS is permanent.
|
|
||||||
|
|
||||||
**Assertion**: `hsts.enable = true` without a TLS mode configured
|
|
||||||
(`selfSignedTls`, `tls.certDir`, or `tls.acme.enable`) is a NixOS
|
|
||||||
build-time assertion failure — HSTS over plain HTTP is harmless but
|
|
||||||
almost always a misconfiguration.
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue