Son of Anton Docs
Architecture

Key Broker

Separating the App private key from native review containers, without overstating the broker's authorization controls.

This page describes the broker in the deployed-engine lineage, son-of-anton-review on feat/cloudflare-native. It is not an endpoint in the unmerged feat/greptile-operator-parity operator API.

The native configuration keeps GITHUB_APP_PRIVATE_KEY in a separate Worker. The review container receives scoped installation tokens instead of the App private key. This removes the key from the container environment; it does not make a compromised container incapable of requesting broader tokens.

Deployment boundary

cloudflare-native/wrangler.key-broker.jsonc selects src/key-broker.js, sets workers_dev: false, and defines no public route. Its default fetch handler returns 404. The main Worker binds service son-of-anton-key-broker, entrypoint KeyBroker, as KEY_BROKER.

The broker reads GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY from its own environment. The main container environment allowlist does not forward the private key. Keep that separation when provisioning; it is a property of this configuration, not a claim about every self-host deployment.

Sources: engine cloudflare-native/wrangler.key-broker.jsonc:5-26; cloudflare-native/wrangler.jsonc:102-105; cloudflare-native/src/key-broker.js:13-33; cloudflare-native/src/container-env.js:15-85.

RPC contract

The service method is mintToken({ installationId, repositories, permissions }). Its successful result contains token and scope.

InputActual broker behavior
installationIdRequired to be non-null by shapeTokenRequest
permissions omitted or nullDefaults to contents: read, pull_requests: write, checks: write, metadata: read
permissions suppliedPassed through, not checked against a purpose allowlist
Nonempty repositories arrayPassed through to scope the GitHub token request
Empty or omitted repositoriesOmitted from the GitHub request, so the broker does not enforce repository restriction

GitHub remains responsible for accepting or refusing the requested installation, repositories and permissions. The broker does not implement the design document's publish, clone, reconcile, or audit purpose authorization, nor an explicit denial of contents:write or administration.

Source: engine cloudflare-native/src/key-broker-core.js:15-55.

Container transport and normal callers

The container sends POST http://broker.internal/mint. Outbound interception invokes handleBrokerRequest, which forwards the caller's installation, repositories and permissions directly to KEY_BROKER.mintToken. This handler does not bind the requested scope to the active review lease.

The normal container client is stricter than the broker:

  • mintPublishToken requires a broker, installation ID, repository scope and nonempty returned token.
  • Clone setup requests contents:read and metadata:read for the target repository, including in shadow publish mode.
  • Check publication requests checks:write; review/comment publication requests pull_requests:write, scoped to the repository.
  • The broker-backed GitHub client mints for each request. Reads use up to three fetch attempts; writes use one attempt because a lost response is ambiguous.

These are caller conventions, not a security boundary against a caller that bypasses the helper. A compromised container with outbound broker access is not limited to the read token already present in its environment. The model-provider key is also present in the orchestration container.

Sources: engine cloudflare-native/src/state-transport.js:583-599; cloudflare-native/src/broker-github-client.js:26-99; cloudflare-native/container/entrypoint.mjs:97-123; src/github-publisher.js:13-78; cloudflare-native/src/container-env.js:49-69.

Lifetime, caching and revocation

The broker does not set a custom token expiry. GitHubAppClient uses the expiry returned by GitHub. Its instance cache reuses a scope-matched token until 60 seconds before expiry.

However, each broker RPC constructs a new GitHubAppClient. The cache therefore does not persist across broker RPC calls. Do not use the client's cache implementation as evidence of broker-wide reuse.

Neither key-broker.js nor the internal broker HTTP handler exposes a revoke operation. There is no automatic post-use revocation in this path. Clearing the clone credential environment in the container's finally block restores local environment state; it does not invalidate the GitHub token.

Sources: engine cloudflare-native/src/key-broker-core.js:41-55; src/github-app.js:75-111; cloudflare-native/src/key-broker.js:13-33; cloudflare-native/src/state-transport.js:583-599; cloudflare-native/container/entrypoint.mjs:178-183.

Node self-host differs

server.mjs and worker.mjs can load GITHUB_APP_PRIVATE_KEY or read GITHUB_APP_PRIVATE_KEY_PATH, then construct GitHubAppClient in-process. The native broker isolation does not apply to those branches of the Node runtime.

GILF_BROKER_URL, GILF_BROKER_TOKEN and GILF_BROKER_ALLOW_LOCAL_KEY are design-only names, not configuration read by these entrypoints or the audited engine/broker modules. Do not set them expecting a broker cutover. The earlier unverified claims about these flags, purpose enforcement and revocation are replaced here with their implemented status.

Sources: engine server.mjs:52-59; worker.mjs:35-40; cloudflare-native/src/key-broker-core.js:26-55. A source search of engine src/, native src/, server.mjs and worker.mjs found no reads of those three variables or /token/revoke.

See Security model and Publish modes. Token isolation is one control, not a certification or a complete hostile-code containment guarantee.

On this page