G4: R2 buckets live, Gitea storage wired, checksum trap pinned
Three buckets created. S3 round-trip against R2 proven end to end (PUT/GET/DELETE) before any of it was wired in. Includes the R2 checksum trap: R2 rejects the algorithm S3 clients send by default, and the resulting error reads like a credential problem and is not one. Records a NAMED DEBT in SUBSTRATE.md: the R2 credential is currently the account-wide god token, because no available token can mint a scoped one. Gated — it must be replaced before G7 puts CI runners on this host, since I-5 exists precisely to keep untrusted job code away from broadly-scoped credentials. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
26
SUBSTRATE.md
26
SUBSTRATE.md
@@ -72,10 +72,28 @@ consulted, so a perfect service presents as "the app is broken."
|
||||
All in the fleet lockbox, injected by env, **never committed**. `make check`
|
||||
fails on any `cfat_` / `cfut_` / `gh[pousr]_` / `et_plt_` literal in the tree.
|
||||
|
||||
⚠️ The R2 credential should be **scoped to this cell**. The sites cell ended up
|
||||
holding the account-wide god token because v4 R2 object endpoints reject
|
||||
restricted tokens. Whichever we end up with, record it here — an account-wide
|
||||
token is an acceptable named debt and an unacceptable invisible one.
|
||||
### ⚠️ NAMED DEBT — the R2 credential is account-wide
|
||||
|
||||
**As of 2026-08-11 this cell holds the Cloudflare god token as its R2
|
||||
credential.** R2's S3 credentials are derived from an API token (access key id =
|
||||
the token's id, secret = SHA-256 of its value), and **no token available to this
|
||||
session has permission to mint a new one** — creating tokens is dashboard-only
|
||||
or needs a token-creating token. So the wiring was proven with the god token
|
||||
rather than blocked on it.
|
||||
|
||||
This is recorded, not hidden, because an account-wide token is an acceptable
|
||||
named debt and an unacceptable invisible one.
|
||||
|
||||
**GATE: this must be replaced with a scoped R2 token BEFORE strand G7 lands
|
||||
CI runners on this host.** I-5 says runners execute untrusted code and must not
|
||||
share a kernel with credentials scoped beyond their own job; a god token with
|
||||
R2 + Workers + Pages + WAF + SSL rights sitting on the same box as a runner is
|
||||
exactly the thing I-5 exists to prevent.
|
||||
|
||||
Minting one is a two-minute job in the Cloudflare dashboard: **R2 → Manage R2
|
||||
API Tokens → Create → Object Read & Write, scoped to the three `windy-git-*`
|
||||
buckets.** Then set `R2_ACCESS_KEY_ID` / `R2_SECRET_ACCESS_KEY` in
|
||||
`/srv/windygit/src/.env` and redeploy.
|
||||
|
||||
⚠️ The Cloudflare **god token has Zone:Read but no DNS:Edit.** Use the DNS:Edit
|
||||
token for record creation.
|
||||
|
||||
@@ -53,7 +53,22 @@ services:
|
||||
# G2.2 — OIDC only. No local password login, no self-registration.
|
||||
GITEA__service__DISABLE_REGISTRATION: "true"
|
||||
GITEA__service__ALLOW_ONLY_EXTERNAL_REGISTRATION: "true"
|
||||
GITEA__lfs__PATH: /data/lfs
|
||||
# G4.3 — heavy bytes to R2 at ZERO egress. Git object databases stay on
|
||||
# local NVMe (I-3); this covers LFS, attachments, packages, avatars and
|
||||
# Actions artifacts, which is where GitHub's painful bills actually come
|
||||
# from and where R2's free egress is a structural, permanent advantage.
|
||||
GITEA__storage__STORAGE_TYPE: minio
|
||||
GITEA__storage__MINIO_ENDPOINT: ${R2_ACCOUNT_ID}.r2.cloudflarestorage.com
|
||||
GITEA__storage__MINIO_ACCESS_KEY_ID: ${R2_ACCESS_KEY_ID}
|
||||
GITEA__storage__MINIO_SECRET_ACCESS_KEY: ${R2_SECRET_ACCESS_KEY}
|
||||
GITEA__storage__MINIO_BUCKET: ${R2_BUCKET_LFS:-windy-git-lfs}
|
||||
GITEA__storage__MINIO_LOCATION: auto
|
||||
GITEA__storage__MINIO_USE_SSL: "true"
|
||||
# ⚠️ THE R2 TRAP. R2 rejects the checksum algorithm S3 clients send by
|
||||
# default; without this, uploads fail with an opaque checksum error that
|
||||
# reads like a credential problem and is not one.
|
||||
GITEA__storage__MINIO_CHECKSUM_ALGORITHM: md5
|
||||
GITEA__lfs__STORAGE_TYPE: minio
|
||||
volumes:
|
||||
# I-3: git object databases on a POSIX filesystem. Never object storage.
|
||||
- ${GIT_DATA_ROOT:-./data/gitea}:/data
|
||||
|
||||
Reference in New Issue
Block a user