Skip to content

Environment

The server always starts, even when configuration is missing. Each RPC that needs the missing piece answers with a precise FailedPrecondition naming it. The pod does not crash-loop over a missing secret. Secrets are read through the platform secret backend: the environment locally, a mounted file in production.

Identity and access

VariablePurposeWhen unset
CORE_FORGE_IDENTITY_KEYRequired. Base64 of at least 32 random bytes, shared only with CORE’s console proxy. Verifies every request’s X-Core-Identity. forge dev proxy reads the same variable.Every RPC answers FailedPrecondition naming it (fail closed). This also applies if the value is not base64 or is shorter than 32 bytes.
FORGE_OWNER_EMAILOptional extra allowlist: comma, semicolon or space separated, and case-insensitive. Read on every RPC.CORE’s sign-in is the only gate.

GitHub

VariablePurposeWhen unset
CORE_GH_APP_ID, CORE_GH_APP_PRIVATE_KEY or CORE_GH_APP_PRIVATE_KEY_FILEThe platform’s GitHub App. FORGE mints an installation token from it. The token stays in memory and is never persisted.The server runs, and GitHub-backed RPCs answer “not connected to GitHub”.
FORGE_GITHUB_ORGThe organisation that holds forged reposorg-runink
FORGE_GITHUB_TOKENDev only, never a deployment. A personal token used instead of the App. The server logs DEV: acting as a personal GitHub token, not the platform App.The App is used.
FORGE_TEMPLATE_REPOowner/name template for new single-kind web apps (CreateApp)Seeded from the embedded web skeleton
FORGE_TEMPLATE_REPO_PIPELINEThe same for pipelines. It deliberately does not fall back to FORGE_TEMPLATE_REPO.Seeded from the embedded pipeline skeleton

Storage

VariablePurposeWhen unset
CORE_ENVELOPE_KEKRequired for chats and every write. FORGE derives its appfs key from it with HKDF (label runink/appfs/forge).appfs does not mount. Chats and approvals answer FailedPrecondition. WhoAmI and the ForgeService reads still work.
FORGE_APPFS_DIRThe local encrypted appfs root, used when no object store is configured. A pod must mount a persistent volume here, or every restart loses the audit and the chats.~/.local/state/forge/appfs
OBJECTSTORE_ENDPOINT, OBJECTSTORE_ACCESS_KEY, OBJECTSTORE_SECRET_KEYPut the appfs root on objectd (bucket forge)The local fallback is used. If these are set but broken, appfs does not mount; it never falls back to local disk silently.

Planner

VariablePurposeWhen unset
INFERENCE_URLThe in-cluster OpenAI-compatible plane. Point it at the general tier.ProposePlan answers FailedPrecondition. Typed commands are unaffected.
INFERENCE_MODELRequired for the planner. The model name sent in the request. There is deliberately no default.The same FailedPrecondition, naming it
FORGE_JUDGEMENTThe planner’s judging gateOn. Only off, false, 0, no or disabled turn it off.

Serving

VariablePurposeDefault
PORTThe port for gRPC, gRPC-web and the bundle (flag --port)0 (auto-assign)
FORGE_LISTEN_HOSTThe listen address (flag --host)127.0.0.1 by hand. The image sets ::, because the platform’s pod network is IPv6 single-stack and 0.0.0.0 would be unreachable.
FORGE_WEB_DIRThe Flutter web bundle directory, served from the same origin. The bundle must be built with --base-href /forge/.—
CORS_ALLOWED_ORIGINSComma-separated origins allowed for gRPC-web*

Sources

CLAUDE.md (“Environment”); grpc/cmd/serve.go; grpc/internal/auth/identity.go; grpc/internal/ghforge/ghforge.go (FromEnv); grpc/internal/appstate/appstate.go; grpc/internal/planner/planner.go (ConfigFromEnv).