control-plane-api: no-amplification and compatibility suite - #3434
Open
bbartman wants to merge 1 commit into
Open
control-plane-api: no-amplification and compatibility suite#3434bbartman wants to merge 1 commit into
bbartman wants to merge 1 commit into
Conversation
bbartman
force-pushed
the
bmb/3376-stack-9-no-amplification-suite
branch
2 times, most recently
from
August 28, 2026 16:59
ffa2828 to
caac98d
Compare
bbartman
force-pushed
the
bmb/3376-stack-9-no-amplification-suite
branch
from
August 31, 2026 12:45
caac98d to
85d2a4d
Compare
Task 7 of #3376: end-to-end assertions that a masked token's authority is always a subset of its user's live grants. Every test drives a token minted by the real capability_token grant through real routes over a DB-backed snapshot: an insta-gridded implication sweep over an 11-mask family, the lifecycle of one token across snapshot refreshes (via the new test_server::RefreshableSnapshot), the legacy-metadata null-attenuation probe, and the full refresh-token credential loop — whose SQL exchange runs under a new jwt_sign_polyfill fixture supplying the HS256 sign() and secret a sqlx::test database lacks. Assertions already pinned by tasks 3c/5/6 are deliberately not repeated; the module doc carries coverage pointers.
bbartman
force-pushed
the
bmb/3376-stack-9-no-amplification-suite
branch
from
September 1, 2026 13:08
85d2a4d to
99fdc4d
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.
Task 7 of #3376 (PR 9 on the stack, stacked on #3427): end-to-end assertions
that a capability-masked token's authority is always a subset of its user's
live grants. Tests only — no production code changes.
What the suite is
Every assertion drives a token minted by the real
capability_tokengrant through real routes, over a real snapshot of a real database — the
composed mint→use pipeline no single enforcement or mint test exercises.
Per-surface enforcement plumbing with hand-signed tokens is already pinned in
each surface's own module (3c/5/6) and is deliberately not re-proven here.
New module
src/server/masked_token_suite/(#[cfg(test)]):walk— the headline property as an implication sweep: fixturecollections × an 11-mask family, every masked row minted through the
endpoint, asserting masked-allowed ⟹ unmasked-allowed and
all-bundles ≡ unmasked, with the outcome grid insta-snapshotted so a
legitimate behavior change reads as a grid diff. Plus targeted tests:
empty mask is identity-only (structured
missing_capabilitiesbody),requested-but-unheld bits are inert, and the legacy-metadata GraphQL probe
(under a mask, an unreachable referent presents
userCapability: nullwith null gated fields — legacy attenuates to null rather than leaking,
and never authorizes; an accessible ref keeps its literal informational
label per decision 3).
lifecycle— one minted token observed across snapshot refreshes asits user's grants change: a grant addition activates already-approved
mask bits with no re-mint, and revocation takes effect at the next
refresh. Both stale windows (before the refresh) are pinned deliberately:
"immediately" means next-snapshot-refresh, no restart, no token
invalidation.
guards_and_compat— the full-authority credential loop(createRefreshToken → exchange → full authority, including the dot-less
bearer-credential form) closed by the empty-mask identity probe: an
identity-only minted token still revokes its user's refresh token
(revocation never widens), and the revoked credential is dead.
Task-7 assertions already pinned elsewhere are deliberately not repeated,
and the suite's module doc points at each: a minted token cannot re-mint
and the mint refuses service accounts (
token_exchange), maskedcreateRefreshTokenrefusal and masked-revocation openness(
graphql/refresh_tokens), and the/adminfail-closed guards(
create_data_plane/update_l2_reporting).Test infrastructure
test_server::RefreshableSnapshot— a manual snapshot watch the testrefreshes by hand (via
tokens::manual), so a single running serverobserves DB grant mutations the way production observes a periodic
snapshot refresh. Fetches via
try_fetchdirectly to skipPgSnapshotSource's MIN_REFRESH_INTERVAL cool-off.fixtures/masked_suite.sql— a purpose-built grant graph, one edge perwalk behavior under a mask (direct grant / Delegate hop / Assume hop /
no path), documented in-file.
alice.sqlis untouched.fixtures/jwt_sign_polyfill.sql— enables the SQLgenerate_access_tokenmint inside a sqlx::test database by overridinginternal.access_token_jwt_secret()to the harness key and supplying aminimal HS256
sign()over pgcrypto'shmac(). This unlocks thecredential loop's real exchange (previously impossible under sqlx::test —
see the coverage note in
graphql/refresh_tokens.rs); the polyfill'scorrectness is proven by SQL-signed tokens passing real Envelope
verification.
Decisions (grilled 2026-08-28)
genuinely minted token; unit-level duplication of 3c/5/6 coverage is out
of scope. The suite is the regression net for mint/enforcement drift.
live grants" and "expired-upgrade re-mint" items predate the removal of
upgrade_token(Gregor, 2026-08-27) and are not implemented. Theirsuccessor property — a minted token cannot re-mint itself — turned out
to be already pinned inside task 5's
test_capability_token_mint. Theplan comment's task-7 text is amended accordingly.
refresh) over the two-servers-over-one-DB alternative, pinning
"immediately = next snapshot refresh" as the documented semantics.
designed per-assertion, rather than growing
alice.sql(whose shape manyexisting snapshots pin) or inlining SQL per test.
#[cfg(test)]directory module grouped by harness need(minting / walk / lifecycle / guards+compat).
/authorize/user/collectionis the canonical walk surface(richest outcome shape; denial messages carry the caller's email, which
doubles as the identity-copy-through probe). Surface-specific assertions
keep their own endpoints. The full assertion×surface matrix was rejected
as re-proving 3c's per-surface plumbing.
over a mask family, catching any future mask-widens-something regression
nobody thought to enumerate, plus targeted example tests for the named
semantics (Delegate confinement, Assume containment, empty mask).
["Viewer"]-maskwritesTocontrast — accessible ref keeps its informational literal label,
mask-denied referent attenuates to null metadata and null fields
together.
still can" alongside the guards' "masked cannot"), with the
revokeRefreshTokenrider pinning that an identity-only token'sidentity operates. Discovered constraint: the SQL exchange needs
vault/pgjwt, absent under sqlx::test — resolved with the
jwt_sign_polyfillfixture rather than degrading the approved looptest.
test whose only delta from an existing pinned test was token
provenance — the standalone re-mint probe, the empty-mask standalone
(it was verbatim the sweep's
emptyrow), the/adminrefusal test,and the loop's masked-
createRefreshTokenstep. The module doc carriescoverage pointers instead.
Closes the task-7 item of #3376's implementation plan.