Gate the VPS instance behind Traefik basic auth until Phase 16
Petal authenticates nobody yet -- StaticResolver hands every request the same local user -- so on a public host the whole API is open: anyone who finds the hostname can read and write documents and fill the disk with image uploads. Traefik holds the door until the OIDC flow exists. /api/health keeps its own higher-priority router with no middleware, so the acceptance criterion (public health endpoint, reachable by the monitoring on this box) still holds. Both the middleware and that router are deleted when Phase 16 lands.
This commit is contained in:
@@ -20,6 +20,14 @@ TZ=Europe/Lisbon
|
|||||||
PETAL_UID=1001
|
PETAL_UID=1001
|
||||||
PETAL_GID=1001
|
PETAL_GID=1001
|
||||||
|
|
||||||
|
# --- Interim edge gate (delete when Phase 16 auth lands) ---------------------
|
||||||
|
# Petal has no authentication of its own yet — StaticResolver hands every
|
||||||
|
# request the same local user — so Traefik holds the door with basic auth until
|
||||||
|
# the OIDC flow exists. user:bcrypt-hash, as produced by:
|
||||||
|
# htpasswd -nbB petal 'your-password'
|
||||||
|
# /api/health is deliberately exempt (its own router) so monitoring still works.
|
||||||
|
PETAL_BASIC_AUTH=
|
||||||
|
|
||||||
# --- LLM (millenia, over headscale) ------------------------------------------
|
# --- LLM (millenia, over headscale) ------------------------------------------
|
||||||
# The only cross-VPN dependency. Petal degrades warmly when it's unreachable:
|
# The only cross-VPN dependency. Petal degrades warmly when it's unreachable:
|
||||||
# spell check, gloss, garden, search, export and read-aloud all keep working and
|
# spell check, gloss, garden, search, export and read-aloud all keep working and
|
||||||
|
|||||||
+16
-1
@@ -65,8 +65,23 @@ services:
|
|||||||
traefik.http.routers.petal.tls: "true"
|
traefik.http.routers.petal.tls: "true"
|
||||||
traefik.http.routers.petal.tls.certResolver: default
|
traefik.http.routers.petal.tls.certResolver: default
|
||||||
traefik.http.routers.petal.service: petal
|
traefik.http.routers.petal.service: petal
|
||||||
traefik.http.routers.petal.middlewares: compression@file,petal-headers
|
traefik.http.routers.petal.middlewares: compression@file,petal-headers,petal-auth
|
||||||
traefik.http.services.petal.loadbalancer.server.port: "8080"
|
traefik.http.services.petal.loadbalancer.server.port: "8080"
|
||||||
|
# INTERIM — delete this middleware and the petal-health router when Phase
|
||||||
|
# 16's OIDC login lands. Petal has no authentication of its own yet
|
||||||
|
# (StaticResolver hands every request the same local user), so without a
|
||||||
|
# gate at the edge anyone who finds the hostname can read and write
|
||||||
|
# documents and upload images. PETAL_BASIC_AUTH is a user:bcrypt-hash
|
||||||
|
# pair; see deploy/README.md for generating it.
|
||||||
|
traefik.http.middlewares.petal-auth.basicauth.users: ${PETAL_BASIC_AUTH:?set PETAL_BASIC_AUTH in .env}
|
||||||
|
# /api/health stays open on its own higher-priority router: a monitoring
|
||||||
|
# probe must not need a credential, and the endpoint carries no user data.
|
||||||
|
traefik.http.routers.petal-health.rule: Host(`${PETAL_HOST:-petal.parodia.dev}`) && Path(`/api/health`)
|
||||||
|
traefik.http.routers.petal-health.priority: "100"
|
||||||
|
traefik.http.routers.petal-health.entrypoints: web-secure
|
||||||
|
traefik.http.routers.petal-health.tls: "true"
|
||||||
|
traefik.http.routers.petal-health.tls.certResolver: default
|
||||||
|
traefik.http.routers.petal-health.service: petal
|
||||||
# Petal is a private writing space: no framing, no sniffing, HSTS on.
|
# Petal is a private writing space: no framing, no sniffing, HSTS on.
|
||||||
traefik.http.middlewares.petal-headers.headers.customresponseheaders.Content-Security-Policy: frame-ancestors 'self'
|
traefik.http.middlewares.petal-headers.headers.customresponseheaders.Content-Security-Policy: frame-ancestors 'self'
|
||||||
traefik.http.middlewares.petal-headers.headers.customresponseheaders.Strict-Transport-Security: max-age=31536000; includeSubDomains
|
traefik.http.middlewares.petal-headers.headers.customresponseheaders.Strict-Transport-Security: max-age=31536000; includeSubDomains
|
||||||
|
|||||||
Reference in New Issue
Block a user