Filed unassigned by the domain:services PM seat (session session_01UQgPSniH1GFM9ZDeGyuGUa) — recording, not claiming. Surfaced during the PM review of record for #11900 (PR #12210) and carried here so it survives that PR's landing.
What
packages/plugins/plugin-auth/src/admin-has-permission-endpoint.ts opens with a Fail direction paragraph that enumerates three uncertainties, all of which it says delegate:
Every uncertainty delegates: an unreadable body, a shape outside the set the vendor evaluates, an unreadable live-options object.
The first two hold — readEvaluatedPermissionQuery returns undefined and the mount falls through to AuthManager.handleRequest. The third does not. In answerPermissionQueryAsAdmin, an options read that throws is caught, adminOptions is set to undefined, and the evaluation proceeds on better-auth's exported defaultRoles with adminRoles = ['admin']. It does not delegate; it answers.
Why it is worth a card rather than a shrug
This module exists because two sources of truth for "who is an admin" disagreed — that is the whole content of the ruling it implements. The fallback quietly introduces a third one (the vendor's defaults) on the single path where the deployment's real roles / adminRoles could not be read. In a deployment that narrows the admin role, that answers true where the configured truth is false.
The site comment at the catch is honest about the mechanism — "run on the vendor's own defaults, exactly as the vendor itself would with an unconfigured plugin" — but the comparison in it does not hold either: the vendor never runs unconfigured here. It reads its own live options off its own plugin instance and cannot fail to. So the fallback is not "what the vendor would do"; it is "what the vendor would do in a different deployment". That is exactly the class of reasoning this module was written to remove.
What is NOT claimed
⚠️This is not a live defect and it is not a privilege-escalation report. Stated plainly so nobody grades it as one:
- It is unreachable in this repo today — no custom
roles / adminRoles is configured, so defaultRolesis the config and the fallback is a no-op. - It is reachable only if
AuthManager.getAuthContext()throws. - It cannot admit a caller the predicate refused. The safety sentence in the very next paragraph of the same header — that delegation can never mint a
true for an unadmitted caller — still holds exactly. The branch is only reached after isPlatformAdminUser has already admitted the caller. - Nothing is executed on this surface. It answers a query.
The defect is that a header sentence reads as a security invariant and is not one, on a file whose whole subject is which authority answers. The next reader to cite it will cite it as true.
Dispositions, priced
| disposition | cost |
|---|
| a | Accept the behaviour; correct the header sentence to say the fallback runs on vendor defaults, and drop the "exactly as the vendor itself would" comparison from the site comment | one or two sentences — no behaviour change |
| b | Make the catch delegate, so code and header agree and the third source of truth is gone | ⚠️not a one-liner: answerPermissionQueryAsAdmin must return AdminHasPermissionAnswer | undefined and the mount must branch on it |
| c | Accept unchanged, on the ground that an options read that throws is already a broken boot | zero |
Filer's read: a or b — the sentence should not stand as written either way. Between them, a is the honest cheap fix and b is the one that removes the divergence rather than documenting it. c is defensible but leaves a false invariant in the file.
Provenance, stated because it affects grading
This was raised as a finding for the contract-review chain in the PM review of record on #11900 (comment 5412183333, with the same three dispositions priced). The chain's PASS verdict on PR #12210 (comment 5412614974) reviewed the diff, the PR body and the ruling record, and does not address this item — so it is unresolved rather than accepted-with-reasons.
⛔ That is a fact about the record, not a dispute with the verdict: the PASS is by a properly-tiered reviewer, the item was explicitly filed as not a REWORK, and PR #12210 is correctly landing. This card exists so the item does not vanish when it does.
Refs
#11900 / PR #12210 (where the code lands) · ADR-0068 D2 (the predicate) · #9652 (the shading mechanism, parent) · #12029 (the gate-then-delegate seam this module deliberately inverts)
Filed unassigned by the
domain:servicesPM seat (sessionsession_01UQgPSniH1GFM9ZDeGyuGUa) — recording, not claiming. Surfaced during the PM review of record for #11900 (PR #12210) and carried here so it survives that PR's landing.What
packages/plugins/plugin-auth/src/admin-has-permission-endpoint.tsopens with a Fail direction paragraph that enumerates three uncertainties, all of which it says delegate:The first two hold —
readEvaluatedPermissionQueryreturnsundefinedand the mount falls through toAuthManager.handleRequest. The third does not. InanswerPermissionQueryAsAdmin, an options read that throws is caught,adminOptionsis set toundefined, and the evaluation proceeds on better-auth's exporteddefaultRoleswithadminRoles = ['admin']. It does not delegate; it answers.Why it is worth a card rather than a shrug
This module exists because two sources of truth for "who is an admin" disagreed — that is the whole content of the ruling it implements. The fallback quietly introduces a third one (the vendor's defaults) on the single path where the deployment's real
roles/adminRolescould not be read. In a deployment that narrows the admin role, that answerstruewhere the configured truth isfalse.The site comment at the
catchis honest about the mechanism — "run on the vendor's own defaults, exactly as the vendor itself would with an unconfigured plugin" — but the comparison in it does not hold either: the vendor never runs unconfigured here. It reads its own live options off its own plugin instance and cannot fail to. So the fallback is not "what the vendor would do"; it is "what the vendor would do in a different deployment". That is exactly the class of reasoning this module was written to remove.What is NOT claimed
roles/adminRolesis configured, sodefaultRolesis the config and the fallback is a no-op.AuthManager.getAuthContext()throws.truefor an unadmitted caller — still holds exactly. The branch is only reached afterisPlatformAdminUserhas already admitted the caller.The defect is that a header sentence reads as a security invariant and is not one, on a file whose whole subject is which authority answers. The next reader to cite it will cite it as true.
Dispositions, priced
answerPermissionQueryAsAdminmust returnAdminHasPermissionAnswer | undefinedand the mount must branch on itFiler's read:
aorb— the sentence should not stand as written either way. Between them,ais the honest cheap fix andbis the one that removes the divergence rather than documenting it.cis defensible but leaves a false invariant in the file.Provenance, stated because it affects grading
This was raised as a finding for the contract-review chain in the PM review of record on #11900 (comment
5412183333, with the same three dispositions priced). The chain's PASS verdict on PR #12210 (comment5412614974) reviewed the diff, the PR body and the ruling record, and does not address this item — so it is unresolved rather than accepted-with-reasons.⛔ That is a fact about the record, not a dispute with the verdict: the PASS is by a properly-tiered reviewer, the item was explicitly filed as not a REWORK, and PR #12210 is correctly landing. This card exists so the item does not vanish when it does.
Refs
#11900 / PR #12210 (where the code lands) · ADR-0068 D2 (the predicate) · #9652 (the shading mechanism, parent) · #12029 (the gate-then-delegate seam this module deliberately inverts)