docs(product): forge scope enforcement — API writes + git operations (RIG-2679 B) - #601
Open
rigel-mintaka wants to merge 3 commits into
Open
docs(product): forge scope enforcement — API writes + git operations (RIG-2679 B)#601rigel-mintaka wants to merge 3 commits into
rigel-mintaka wants to merge 3 commits into
Conversation
|
Compass engineering docs preview: https://compass-server-rig-2679-forg.compass-eng-docs.pages.dev Deployed from Changed pages: |
rigel-mintaka
added a commit
that referenced
this pull request
Aug 25, 2026
…9 B) Review PR #601 (2 low, advisory on a design record): - L1: reword the Ledger-impact amend attribution — the A8 no-scope posture lives in DL-200's implementing comment (forge.go:16-18) tracing to the board 'Resolved decision 2' ruling, not in the DL-200 row text. - L2: name the exhaustiveness test's residual (a mis-classified write arm) and add the T2 signature cross-check (read/unimplemented sets hold only no-caller handlers) that closes it structurally, in §A3 and T2. Ledger-impact: deferred to freeze
…2679 B)
The deferred A8 forge-write scope control: a server-side per-account allowlist
(account_forge_scopes table) checked by requireForgeScope in every write arm of
ExecuteForgeCallAsAccount — after coordinate resolution, on create arms after
the F3 idempotency-memo check, before any provider call — rejecting out-of-scope
targets as the in-band ForgeCallError{code:"not_found"}, byte-identical to the
403/404 flatten (no probe oracle). Gated by ForgeConfig.EnforceScopes: off for
Dogfood, mandatory for Beta.
design-critic pass folded (6 findings). OQ-1 (fail-open vs fail-closed default)
deferred to Matt at freeze. Ledger row proposed (Ledger-impact declared; applied
at freeze), next free id DL-242.
Status: Draft.
Ledger-impact: deferred to freeze (adds one Comms & tools row; amends DL-200's
inherited no-scope-rejection A8 clause without superseding it).
…9 B) Review PR #601 (2 low, advisory on a design record): - L1: reword the Ledger-impact amend attribution — the A8 no-scope posture lives in DL-200's implementing comment (forge.go:16-18) tracing to the board 'Resolved decision 2' ruling, not in the DL-200 row text. - L2: name the exhaustiveness test's residual (a mis-classified write arm) and add the T2 signature cross-check (read/unimplemented sets hold only no-caller handlers) that closes it structurally, in §A3 and T2. Ledger-impact: deferred to freeze
rigel-mintaka
force-pushed
the
compass-server/rig-2679-forge-scope-enforcement
branch
from
August 26, 2026 06:16
20634fb to
f2900f5
Compare
rigel-mintaka
force-pushed
the
compass-server/rig-2679-forge-scope-enforcement
branch
2 times, most recently
from
August 26, 2026 06:42
84059e4 to
e6b2a3e
Compare
…ecord (RIG-2679 B) Folds Matt's 2026-08-26 scope expansion (scope the repos an agent can clone/push/pull, not just the forge-API write path) plus a design-critic red-team into the forge-scope-enforcement record. ### Git-operation scope (new A5 + Plan T4/T4.5/T5) Scope the credential, not the git call: mint a GitHub App installation token narrowed via the `repositories` field to the workstream repo + the account's `account_forge_scopes` set, so an out-of-scope `git push`/`clone` fails at GitHub itself — zero enforcement code inside the agent-controlled container. - **Self-clone invariant**: the agent's own workstream repo is always clonable/pullable (else provisioning succeeds but the agent is dead on arrival); push stays write-gated; extra repos need grants; zero/insufficient-grant provision fails LOUD. - **T4.5 (new, proto)**: the minted token must cross the Server→Runner process boundary — `ProvisionAgentWorkspaceRequest` carries no credential today; adds a server-authoritative `WorkspaceCredential` field + a server-driven refresh push on the hub control channel. - **T5 hardened refresh**: pre-expiry margin, retry-with-backoff, keep-old-token-on-failure, atomic tmp+mv rewrite (the `GHHostsScript` shape). ### Critic dispositions folded Loud PAT-fallback Warn (classic vs fine-grained PAT distinction corrected), half-landed cross-check Warn, x-access-token username, deploy-key + fine-grained-PAT Alternatives dismissals. ### New load-bearing forks for the freeze gate OQ-6 gains a fine-grained-PAT option (c) + a #634-sequencing sub-fork (iii, recommend contingent split); OQ-7 added (git-op allowlist = write set + implicit workstream read, vs a distinct read superset). Spec-impact: none (design record only; Ledger-impact declared in-record, applied at freeze). Refs RIG-2679 Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
force-pushed
the
compass-server/rig-2679-forge-scope-enforcement
branch
from
August 26, 2026 06:49
e6b2a3e to
40cd38d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The deferred A8 forge scope control, in two enforcement legs sharing one per-account allowlist (
account_forge_scopes).A1-A4 — forge-API write chokepoint
requireForgeScopein every write arm ofExecuteForgeCallAsAccount— after coordinate resolution, on create arms after the F3 idempotency-memo check, before any provider call — rejecting out-of-scope targets as the in-bandForgeCallError{code:"not_found"}, byte-identical to the 403/404 flatten (no probe oracle). Gated byForgeConfig.EnforceScopes: off for Dogfood, mandatory for Beta.A5 / T4-T5 — git clone/push/pull scope (Matt's 2026-08-26 expansion)
Scope the credential, not the git call: mint a GitHub App installation token narrowed via the
repositoriesfield to the workstream repo + the account's granted repo set, so an out-of-scopegit push/clonefails at GitHub itself — zero enforcement code inside the agent-controlled container. The self-clone invariant keeps the agent's own workstream repo always clonable (else provisioning succeeds but the agent is dead on arrival); zero/insufficient-grant provision fails loud. Both credential surfaces (.git-credentials+ gh-CLIhosts.yml) carry the narrowed token from provision (t=0), not only after first refresh. A new T4.5 (proto) task carries the minted token across the Server→Runner process boundary (ProvisionAgentWorkspaceRequestcarries no credential today) with a server-driven refresh push keyed by a per-live-container scheduler registry; T5 hardens refresh (margin, backoff, keep-old-token-on-failure, atomic rewrite, both surfaces).Review history
Prior design-critic + code-review passes on the forge-API core (A1-A4) folded. Git-op leg (A5/T4/T4.5/T5) added; a design-critic red-team folded (self-clone invariant, Server→Runner wire path, loud PAT-fallback); then a three-round code-review loop reached all-clear at the high+medium floor — round 1 (1 high / 3 med / 2 low: SEA-1527 miscitation → OQ-8, hosts.yml refresh surface, refresh-scheduler state, read/write asymmetry, 404/403, owner-alias), round 2 (provision-time hosts.yml gap + co-resident gh-host preservation + projection phrasing), round 3 all-clear. Sub-floor items (same-host token precedence, citation normalization) dispositioned inline.
Open questions deferred to the freeze gate (Matt)
agent_accountscolumn, or store-side spawn-target record); reverses a prior Matt ruling, so it is his call. Blocks T4/T4.5/T5.Status: at freeze gate pending the OQ rulings above.
Ledger-impact: deferred to freeze (adds one Comms & tools row; amends DL-200's inherited no-scope-rejection A8 clause without superseding it). Driver assigns the row id at freeze (≥ DL-264 on current main).
Refs RIG-2679
Spec-impact: none