mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 12:41:30 +00:00
docs(rbac): DOC-002 + COMP-005 — pin auditor role invariants in operator docs
Acquisition-audit DOC-002 + COMP-005 closure (Sprint 7 ACQ,
2026-05-16). Both findings were UNKNOWN because the auditor
couldn't independently verify the auditor-role permission set is
locked-down. The set IS locked down in three places (schema,
code, tests) — DOC-002 + COMP-005 close by surfacing that pin in
docs/operator/rbac.md so a future SOC 2 / FedRAMP / PCI auditor
can re-derive the proof without rebuilding the trail.
New "Auditor role invariants" subsection in docs/operator/rbac.md
under the existing two-person integrity section. Documents:
Layer 1 (schema) — migrations/000029_rbac.up.sql:261-262 +
migrations/000039_audit_crit1_perms.up.sql:111 (the inline
"r-auditor: NOTHING new" comment).
Layer 2 (code) — internal/domain/auth/DefaultRoles[RoleIDAuditor].
Layer 3 (the load-bearing one — tests):
- TestAuditorRoleHoldsExactlyAuditReadAndExport
set-equality on {audit.read, audit.export}
- TestAuditorRoleDoesNotHoldMutatingOrReadingNonAuditPerms
catches subtle widening even if set-equality is bypassed
- TestAuditorRoleSeparateFromViewer
pins auditor and viewer permission sets are disjoint
except audit.read (which viewer shares by design)
Explicitly notes the audit prompt's recommendation against a bash
CI guard — the property is already enforced at the Go test layer
with stronger semantics (struct-aware set equality) than `grep`
could provide.
No code changes; documentation-only closure (existing tests + schema
already pin the invariant). Verified locally: gofmt clean, go vet
clean across internal/domain/auth + internal/service.
This commit is contained in:
@@ -68,6 +68,45 @@ giving them the keys to the kingdom. The
|
|||||||
`internal/domain/auth/auditor_test.go` invariants pin this set going
|
`internal/domain/auth/auditor_test.go` invariants pin this set going
|
||||||
forward.
|
forward.
|
||||||
|
|
||||||
|
### Auditor role invariants (DOC-002 / COMP-005 closure)
|
||||||
|
|
||||||
|
Acquisition-audit DOC-002 + COMP-005 closure (Sprint 7 ACQ, 2026-05-16).
|
||||||
|
The auditor role's permission set is **pinned at exactly two
|
||||||
|
permissions** — `audit.read` and `audit.export` — and any drift breaks
|
||||||
|
the SOC 2 / FedRAMP / PCI separation. The pin is enforced at three
|
||||||
|
layers and the load-bearing layer is the unit-test set, not a bash CI
|
||||||
|
guard:
|
||||||
|
|
||||||
|
1. **Schema layer** — `migrations/000029_rbac.up.sql:261-262` seeds
|
||||||
|
exactly two `role_permissions` rows for `r-auditor`
|
||||||
|
(`r-auditor / p-audit-read / global / NULL` and
|
||||||
|
`r-auditor / p-audit-export / global / NULL`).
|
||||||
|
`migrations/000039_audit_crit1_perms.up.sql:111` adds an inline
|
||||||
|
comment confirming `r-auditor` was NOT widened by the migration that
|
||||||
|
shipped the five admin-only fine-grained perms.
|
||||||
|
2. **Code layer** — `internal/domain/auth/DefaultRoles[RoleIDAuditor]`
|
||||||
|
matches the schema. A future code change that adds a non-audit
|
||||||
|
permission to the slice is caught by:
|
||||||
|
3. **Test layer** (the load-bearing one) —
|
||||||
|
`internal/domain/auth/auditor_test.go` ships three pinning tests:
|
||||||
|
- `TestAuditorRoleHoldsExactlyAuditReadAndExport` — set-equality
|
||||||
|
comparison; fails on any add or remove
|
||||||
|
- `TestAuditorRoleDoesNotHoldMutatingOrReadingNonAuditPerms` —
|
||||||
|
enumerates the slice and rejects any permission outside the
|
||||||
|
`{audit.read, audit.export}` set; catches subtle widening even if
|
||||||
|
the set-equality test is bypassed
|
||||||
|
- `TestAuditorRoleSeparateFromViewer` — pins that the auditor and
|
||||||
|
viewer permission sets are disjoint except for `audit.read` (which
|
||||||
|
viewer shares by design); catches the "auditor inherits viewer
|
||||||
|
reads" leg
|
||||||
|
|
||||||
|
A bash CI guard was deliberately **not** added — the property is
|
||||||
|
already enforced at the Go test layer with stronger semantics
|
||||||
|
(struct-aware set equality) than `grep` could provide. If a future
|
||||||
|
contributor proposes widening `r-auditor`, the three tests above
|
||||||
|
fail at `go test ./internal/domain/auth/...` BEFORE the change can
|
||||||
|
land in a merge.
|
||||||
|
|
||||||
The five **admin-only fine-grained perms** seeded by migration
|
The five **admin-only fine-grained perms** seeded by migration
|
||||||
000030 gate the high-blast-radius endpoints:
|
000030 gate the high-blast-radius endpoints:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user