fix(rbac): enforce rank-ceiling on scoped-key mint (close escalation merged in #99)#114
Merged
Conversation
…n scoped-key mint P0 BLOCK (identity-surface): mintScopedKey lacked a minter-rank-ceiling check. A plain admin (rank 4) could mint another admin (rank 4) — lateral admin proliferation. Fix: minterRank is now required in MintParams; the preset's role rank must be STRICTLY LESS THAN minterRank or the call returns rank_ceiling (403 at the route layer). Owner (5) can mint admin (4); admin (4) can mint lead/member/observer but not admin. WARN (audit-label divergence): the INSERT OR IGNORE strategy allowed re-minting a higher preset over an existing lower grant to silently no-op — the stored grant stayed at the lower rank while the token label advertised a higher one. Fix: rank-max upsert — read existing grant first; INSERT OR REPLACE only when the preset rank > existing rank; skip the write and set grantUnchanged=true when the existing rank is already >=. The show-once page surfaces a notice when the grant was unchanged. Route (dashboard/index.ts): resolves minterRank via actorMaxRankOnScope before calling mintScopedKey; maps rank_ceiling → 403; passes grantUnchanged to keysMintedBody. Tests: 5 new cases (50 total in dashboard-keys.test.ts): admin minting admin preset → rank_ceiling owner minting admin preset → OK admin minting sales-rep/observer → OK rank-max upsert: sales-rep over observer → grant upgraded to member observer over existing lead → stays lead, grantUnchanged=true Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Incident fix-forward: PR #99 merged WITHOUT its rank-ceiling fix (isolated worktree didn't push). Main shipped the identity BLOCK: a plain admin could mint another org-admin. This cherry-picks the fix (65b3c2c): rank-ceiling enforced (403 rank_ceiling when preset.role rank >= minter rank; admin can't mint admin), rank-max upsert (no audit-label divergence). Verified: 10 rank-ceiling refs, typecheck clean, 50/50 scoped-key tests, 811 suite green. Closes the #99 BLOCK; #106 (granular requireCapability gates) remains the next follow-up.