Commit graph

3 commits

Author SHA1 Message Date
522c5d7a54 fix(forgejo): generate + set SECRET_KEY (was empty under INSTALL_LOCK)
Follow-up to the crypto-secret mirror: Forgejo's [security] SECRET_KEY was
EMPTY because the bootstrap skips the web installer (INSTALL_LOCK), which is
what normally generates it. An empty SECRET_KEY weakens at-rest encryption of
2FA secrets, push-mirror/migration passwords, and OAuth app secrets.

Generate it with @pulumi/random (it is a plain high-entropy string, not a
format-constrained JWT — so unlike INTERNAL_TOKEN/JWT_SECRET it CAN be
random-generated, matching CONTRACT_002 §2.3) and inject via
FORGEJO__security__SECRET_KEY; env-to-ini overwrites it in the volume's
app.ini while leaving Forgejo's own INTERNAL_TOKEN + JWT secrets untouched.
The GATE-B mirror then captures the real value into Vault.

Done now while the egg is fresh (no encrypted data yet) → no re-encryption.

Validated live: app.ini + Vault forgejoSecretKey = 40 chars; forge healthz
pass + https 200; scp-form clone works; idempotent at 44 unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 23:30:35 +02:00
3a297d021e feat(bootstrap): forgejo admin + org + repo + operator key (T09)
bootstrapForgejo (idempotent, docker-exec — ADR-007) creates the headless admin
via `forgejo admin user create` (run as the git user; no web installer, no default
credentials — PLAN-002 §9.3), then via the image's own curl against the API: the
olsitec org, an auto-init'd olsitec/foundation repo, and the operator's SSH public
key. credentials.ts gains the forgejo admin slice (@pulumi/random) and
writeCredentialsToVault now also writes foundation/forgejo/service-credentials.

Live on cx33 Helsinki: admin + org + repo + key created. GOAL MET —
`git clone git@git.olsitec.net:olsitec/foundation.git` (scp-form, :22) and
`ssh://git@git.olsitec.net:2222/olsitec/foundation.git` both clone the repo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 22:31:13 +02:00
f1e1d6facd feat(bootstrap): forgejo forge — postgres + rustfs + ssh (T08)
foundation-forgejo (forgejo:11, digest-pinned) on foundation-net: git repos on the
foundation-forgejo-data volume (the irreducible state), metadata in external
Postgres, blobs in RustFS (default storage + LFS over the minio API). Config is
seeded via FORGEJO__section__KEY env -> app.ini; INSTALL_LOCK skips the web
installer and the crypto secrets (SECRET_KEY/INTERNAL_TOKEN/JWT) auto-generate and
persist in the volume. HTTP 3000 is internal (Caddy fronts forge.olsitec.net); the
image's openssh sshd owns container :22 (START_SSH_SERVER=false — explicitly, so a
stale app.ini value can't keep Forgejo's built-in Go SSH server colliding on :22),
published on host :22 (scp-form goal) and :2222 (CONTRACT_003). A healthz-gated
ready command is GATE B for T09/T10.

Live on cx33 Helsinki: container healthy, https://forge.olsitec.net = 200 over a
valid Let's Encrypt cert, API 11.0.15, sshd reachable on :22 and :2222.
Acceptance T08 met.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 22:23:39 +02:00