43 lines
2.0 KiB
Markdown
43 lines
2.0 KiB
Markdown
# US08-01 — Make the Trust Boundary Configurable and Authenticated
|
|
|
|
Epic: [E08](../E08-container-deployment.md)
|
|
|
|
As an operator, I want to reach the application through my own hostname without
|
|
weakening it, so a container behind a reverse proxy is as safe as the loopback
|
|
deployment it replaces.
|
|
|
|
## Context
|
|
|
|
`photo_pipeline/api/security.py` refuses any request whose `Host` or `Origin` is not
|
|
loopback. That check is the current stand-in for authentication: whoever can reach
|
|
`127.0.0.1:8000` is the owner. Behind a proxy the hostname is no longer loopback, so
|
|
relaxing the check without adding an authentication gate would publish the library.
|
|
|
|
## Acceptance criteria
|
|
|
|
- Allowed hosts and origins come from configuration (`PHOTO_PIPELINE_*`), default to
|
|
the current loopback set, and an unset configuration behaves exactly as today.
|
|
- Whenever a non-loopback host is configured, startup requires an access secret and
|
|
refuses to serve without one; loopback-only deployments keep working with no secret.
|
|
- The secret is exchanged for the existing session cookie and CSRF token through the
|
|
bootstrap endpoint; every protected route keeps its current session and CSRF
|
|
requirements unchanged.
|
|
- Forwarded headers (`X-Forwarded-Proto`, `X-Forwarded-Host`) are honored only from a
|
|
configured trusted proxy and ignored otherwise, so a client cannot forge its origin.
|
|
- Cookies are marked `Secure` when the effective external scheme is HTTPS.
|
|
- Failed authentication is rate-limited and logged without the secret, the session id,
|
|
or any request body.
|
|
- Health endpoints stay reachable without the secret; nothing else does.
|
|
|
|
## Automated tests
|
|
|
|
- Unit tests for host/origin evaluation across loopback default, configured host,
|
|
unconfigured host, forged forwarded headers, and trusted-proxy forwarded headers.
|
|
- Integration tests: startup refusal without a secret, successful exchange, wrong
|
|
secret, replay of an old session, cross-site request, and unauthenticated access to
|
|
every route class.
|
|
|
|
## Dependencies
|
|
|
|
- US07-02
|