Silent Mode Hephaestus — the docker-compose + Caddyfile + auth-proxy that runs code.silentmode.st and hephaestus.x. BCH wallet auth via OIDC, Sia cold storage, restic backups. Open source.
| auth-proxy | ||
| caddy | ||
| forgejo | ||
| scripts | ||
| .env.example | ||
| docker-compose.yml | ||
| PROTOCOL.md | ||
| README.md | ||
Hephaestus
Decentralized code forge. Forgejo web UI on a VPS, Sia network for durable storage, Bitcoin Cash wallet signatures for identity — no email required.
Architecture
User browser
│
├── OIDC login via wallet signature ──▶ auth-proxy ──▶ (issues id_token)
│ │
└── Forgejo web UI ◀─── OIDC handshake ────────────────────┘
│
├── live git repos, Postgres ──▶ local SSD on VPS (hot path)
└── LFS, attachments, packages,
archive downloads, backups ──▶ sia.storage S3 (cold path)
- Identity: users generate or import a BCH wallet client-side. Their
cashaddris their username. Login = signing a challenge. - Hot storage: live
.gitbare repos + Postgres live on the VPS's local disk. Git operations stay fast. - Cold storage: every large or immutable blob (LFS, attachments, release artifacts, package registries) lives on sia.storage via its S3-compatible endpoint. Forgejo speaks S3 natively.
- Backups: nightly
resticsnapshot of repos +pg_dumpto a second bucket. Dual-write to independent storage for the belt-and-suspenders story since sia.storage caps liability at ~$100.
Why sia.storage instead of self-hosted renterd for MVP
- Their free tier gives 50 GB pooled + 4 Gbps throughput with no monthly egress meter
- Standard S3 API — zero code changes to Forgejo
- No Sia wallet management, no SC volatility, no contract-formation ops
- Swap to self-hosted
renterdlater without touching Forgejo config (both speak S3)
Quota math
The 50 GB sia.storage free tier is one pooled resource we allocate to Forgejo users via Forgejo's built-in per-user quotas.
| Our tier | Per-user quota | Users on Free (50 GB) | Users on Plus (500 GB) | Users on Pro (5 TB) |
|---|---|---|---|---|
| Free | 500 MB | ~100 | ~1,000 | ~10,000 |
| Pro | 10 GB | ~5 | ~50 | ~500 |
| Team | 50 GB | ~1 | ~10 | ~100 |
Quickstart
cp .env.example .env
# fill in SIA_STORAGE_ACCESS_KEY, SIA_STORAGE_SECRET_KEY, SIA_STORAGE_BUCKET
docker compose up -d
open http://localhost:3000
First launch:
- Forgejo initialises Postgres and its schema
- Auth-proxy generates its OIDC signing keypair
- On first browser visit, the login page offers "Generate new BCH wallet" or "Import wallet"
- After signing the challenge you're logged into Forgejo — your cashaddr is your username
Directory layout
Hephaestus/
├── docker-compose.yml # forgejo + postgres + auth-proxy
├── .env.example
├── forgejo/
│ └── app.ini.template # config with sia.storage S3 + OIDC + quotas
├── auth-proxy/
│ ├── Dockerfile
│ ├── package.json
│ └── src/ # Fastify OIDC provider
│ ├── index.ts
│ ├── oidc.ts
│ ├── verify.ts # BCH signed-message verification
│ └── sessions.ts
├── auth-proxy/public/
│ ├── login.html # Wallet UI
│ └── wallet.js # Client-side keygen + signing (libauth)
├── scripts/
│ ├── smoke-test-s3.sh # Verify sia.storage handles multipart LFS
│ └── backup-restic.sh # Nightly backup
└── PROTOCOL.md # Wallet-auth flow spec
Status
- MVP scaffolding: complete
- Wallet auth: functional (challenge + signature verify, no persistence beyond cashaddr)
- sia.storage backend: config template ready; must run
scripts/smoke-test-s3.shbefore trusting LFS - Restic backup: template ready, needs cron wiring
- WalletConnect: deferred to Phase 2
- BCNR-name registration for
code.silentmode.st: separate task in Ariadne stack
Known unknowns
- sia.storage S3 multipart maturity. Their roadmap targets full S3 compatibility Q3 2026 — partial today. Smoke test verifies this before we depend on it for LFS.
- Account-recovery UX for wallet loss. No email = no password reset. Users must back up their mnemonic. Docs will hammer this. Phase 2: social recovery via BCH multisig.
- Content moderation workflow. sia.storage ToS bans certain content classes; we need our own AUP + takedown flow before public launch.