feat(gateway,hephaestus): forward proxied headers + trust Silent Mode CA

Two pieces from testing "login through hephaestus.x":

1. bns-gateway (public-gateway.mjs, ip: case) — forward the upstream's
   response headers, not just content-type. The old code stripped Location,
   Set-Cookie, and everything else, so redirects from a proxied hostname
   died silently in the browser ("Temporary Redirect" body with no Location
   header). Header set now respects RFC 7230 hop-by-hop exclusions and
   drops Content-Length (we may rewrite HTML for baseHref).

2. Hephaestus stack:
   - forgejo/Dockerfile: tiny extension of the official image that copies
     the Silent Mode Argonautica root CA into the OS trust store, so
     Forgejo's Go client can validate hephaestus.x's cert on OIDC discovery
     calls. Deliberately no `USER git` at the end — parent's s6-overlay
     needs to init as root.
   - docker-compose.yml: switch to `build: ./forgejo` and add
     `extra_hosts: - "hephaestus.x:host-gateway"` so Forgejo can resolve
     hephaestus.x back to the host's Caddy.

Both changes are inert at the moment because Forgejo's ROOT_URL is back at
code.silentmode.st (browsers-without-BCNR-resolvers couldn't complete
OAuth through hephaestus.x because session cookies don't cross origins —
the working UX has the "Sign in with wallet" button on hephaestus.x
delegate to code.silentmode.st). Keep the infrastructure in place for when
Theseus/Ariadne adoption makes it viable to flip ROOT_URL properly.
This commit is contained in:
Local Dev 2026-08-31 16:23:43 +02:00
parent 8d9b3a8a7a
commit fc43382d48
3 changed files with 41 additions and 1 deletions

View file

@ -50,7 +50,10 @@ services:
- auth-proxy-keys:/data
forgejo:
image: codeberg.org/forgejo/forgejo:10
# Small extension of the official image that adds the Silent Mode CA cert
# (Argonautica root) to the OS trust store, so Forgejo's Go client can
# validate hephaestus.x's cert on OIDC-discovery calls.
build: ./forgejo
restart: unless-stopped
environment:
USER_UID: "1000"
@ -107,6 +110,11 @@ services:
FORGEJO__oauth2_client__UPDATE_AVATAR: "false"
# Skip the web installer wizard — everything is already configured
FORGEJO__server__INSTALL_LOCK: "true"
# hephaestus.x isn't in ICANN DNS, so the Forgejo container can't resolve
# it via its default resolver. Map it to the host gateway so OIDC-discovery
# calls (Forgejo → https://hephaestus.x/auth/…) reach Caddy on the host.
extra_hosts:
- "hephaestus.x:host-gateway"
# Caddy proxies / → forgejo:3000 over the internal network. No public HTTP port.
# 22 stays on 2222 for git-over-SSH (no TLS involved).
expose:

10
forgejo/Dockerfile Normal file
View file

@ -0,0 +1,10 @@
# Forgejo + Silent Mode CA cert baked into the trust store, so Forgejo's Go
# client can validate hephaestus.x's cert (issued by Argonautica) when it
# fetches OIDC discovery from https://hephaestus.x/auth/.well-known/... .
#
# Do NOT switch to USER git at the end — parent image's s6-overlay init needs
# to start as root (it drops to `git` internally). USER git broke s6-svscan
# with "unable to open .s6-svscan/lock: Permission denied".
FROM codeberg.org/forgejo/forgejo:10
COPY silent-mode-ca.crt /usr/local/share/ca-certificates/silent-mode-ca.crt
RUN update-ca-certificates

View file

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDszCCApugAwIBAgIIQnTLcHP2GA4wDQYJKoZIhvcNAQELBQAwQTEaMBgGA1UE
AxMRQk5TIExvY2FsIFJvb3QgQ0ExIzAhBgNVBAoTGkJOUyAoLmJjaCBvbiBCaXRj
b2luIENhc2gpMB4XDTI2MDgyMTAwMDEwNVoXDTM2MDgyMTAwMDEwNVowQTEaMBgG
A1UEAxMRQk5TIExvY2FsIFJvb3QgQ0ExIzAhBgNVBAoTGkJOUyAoLmJjaCBvbiBC
aXRjb2luIENhc2gpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4igg
3dQZUNedViiuXNjlwtNBpsNnjTQYCmvFqwBuUH7r5VT1zPzdANMyDwE93NrYWEmO
LQY+SqnlKKOAiaZOKVegCdJ2xUwn8D62GVR3MT7/31+VAZHvh4GqRQkHzDR7/0Ch
EhGom+aZE/N/y30FpTQytUI/0FQJnHdRtIRkRR1fKg8uUI23PhHNMuT6EYjYhObb
LMIUzXnP3f48OmI2A8die/n2sfXwrNBqrtc/OzO2XuQm0uBP38R8CBnuy+W/NeSw
BRB2BgmdawZc3e4MxnqpsTR76QcCy6XLtJVBNRtFwK7/Jb00DV7zX4xRw8BQ1N24
yHXfSh15FvUXJMCplwIDAQABo4GuMIGrMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
AQH/BAQDAgEGMB0GA1UdDgQWBBTD3l5ztWFyW1di/HaXt2FUNFz1tzBpBgNVHR4B
Af8EXzBdoCkwBYIDYmNoMAWCA3AycDAFggNiaXQwBYIDbmF2MAaCBHRlc3QwA4IB
eKEwMAqHCAAAAAAAAAAAMCKHIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAMA0GCSqGSIb3DQEBCwUAA4IBAQAL5JTGXJ39nR9q8U8YH4Oaq13XINbZycRv
2yG+PQaNlPCwSOucMvatN1+DQqW5dSTulu2e873KrXraBYjXphFUSfTS8nMEi92U
B5+f0l+MSAJXDKc8RwNJ/7SDYblodUg3bN6x70RHFMlAq6FcIondpTEBbOPdaDDi
pw+mLnQj+55xMXV0yxkgsvc/SxdXyLLm7uTWRzKJQi0N3p4YYOEURIyZ491gprwF
QTt0WeBYmRc1MLXbs9D0Svh6D4d0ovKZawZ83rx+TfM7nSfxV6VubbOV/urXtgyh
84Bcq9+1cZZMNAT86uBW+EF7J70mJlctSmwHdIXdxXDaVtl+rZ4o
-----END CERTIFICATE-----