Skip to content

Commit c54c260

Browse files
baozhoutaoclaude
andauthored
docs(lint): security-anchor-high-privilege states its scope (#16429)
security-anchor-high-privilege judged declared isDefault:true (everyone) suggestions only, but nothing in the module header or the rule-site comment said so — the rule id read as coverage for any anchor-bound set, including one an operator binds to guest at install time. That binding is outside what a package-time linter can see and is held by the bind-time gate (describeAnchorForbiddenBits(set, 'guest')) instead. Docblock-only: catalogue table row, header paragraph, and the rule-site comment now state the scope explicitly. No message/hint string moved, no behaviour changed, no new finding branch. Claude-Session: https://claude.ai/code/session_01Vbw3RPgdtqesx4azk9SbW8 Co-authored-by: Claude <noreply@anthropic.com>
1 parent a7e78f7 commit c54c260

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

packages/lint/src/validate-security-posture.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* | security-owd-alias (error) | ADR-0090 D4 canonical enum |
1313
* | security-external-wider (error) | ADR-0090 D11 external ≤ internal|
1414
* | security-wildcard-vama (error) | ADR-0066 superuser wildcard |
15-
* | security-anchor-high-privilege(error) | ADR-0090 D5/D9 anchors |
15+
* | security-anchor-high-privilege(error) | ADR-0090 D5/D9 anchors — declared `everyone` suggestions (`isDefault: true`) only; a `guest`-bound set is outside a package-time linter's sight and is the bind-time gate's alone (#16110) |
1616
* | security-role-word (error) | ADR-0090 D3 vocabulary freeze — own function/registry entry since #8310 |
1717
* | security-book-audience-unknown-set(warn)| ADR-0046 §6.7 { permissionSet } |
1818
* | security-private-no-readscope (info) | admin-intent mismatch class |
@@ -26,6 +26,14 @@
2626
* BUT ONE mirrors a runtime enforcement point (D1 fail-closed OWD default, D4
2727
* zod enum + fail-closed evaluator, D5/D9 anchor binding gate, D3 rename wave)
2828
* — the lint moves the failure from runtime-deny to author-time fix-it.
29+
* `security-anchor-high-privilege` mirrors that gate for the one suggestion a
30+
* package can actually declare (`isDefault: true` → the `everyone` anchor,
31+
* `suggested-audience-bindings.ts`'s "the only declarable suggestion"); a set
32+
* an operator binds to `guest` at install time is a decision ADR-0090 D9
33+
* ("a package may suggest bindings … the admin confirms each individually")
34+
* puts past authoring, so this rule is not — and cannot be — coverage for an
35+
* app-authored anchor set bound to `guest` (#16110). That binding is held by
36+
* the runtime's own `describeAnchorForbiddenBits(set, 'guest')` gate instead.
2937
*
3038
* The exception INVERTS that argument rather than weakening it.
3139
* `security-cbp-ambiguous-relation` has no runtime refusal to mirror precisely
@@ -531,6 +539,10 @@ export function validateSecurityPosture(stack: AnyRec, opts?: { nowMs?: number }
531539
// D5: an isDefault set is a SUGGESTED binding to the `everyone` anchor —
532540
// hold it to the anchor tier at author time (the runtime gate enforces the
533541
// same predicate at bind time; this moves the failure to the author).
542+
// Scope: `isDefault: true` is the only declarable suggestion today — a set
543+
// an operator binds to `guest` at install carries no author-time flag for
544+
// this rule to key off, so that binding is outside what a package-time
545+
// linter can see and is judged by the bind-time gate alone (#16110).
534546
if (ps.isDefault === true) {
535547
const offending = describeAnchorForbiddenBits(ps, 'everyone');
536548
if (offending) {

0 commit comments

Comments
 (0)