v1.7.4 — Nested-route id-or-slug + RBAC permission gating
v1.7.4 — Nested-route id-or-slug + RBAC permission gating
Patch release closing the last two API contract drift bugs surfaced by
the #433 test suite. Same model as v1.7.3 (small focused fixes + version
bump). Bundled here:
Fixes
#574 — Nested authorization_boundaries routes accept id OR slug
Same class as #566 (catalogs / mappings, fixed in v1.7.3). The
parent authorization_boundaries controller AND every nested
controller under it accepted only slug in the URL — callers that
built nested URLs from the id returned by the parent create got
404s. Now any of those URL segments accepts either form.
Controllers updated:
- authorization_boundaries_controller#set_boundary
- ksi_validations_controller#set_boundary
- baseline_parameters_controller#set_profile
Pattern: numeric /\A\d+\z/ → find_by id; else find_by slug.
#575 Path D — Permission-based gating on profile + tightened
ordering on catalog + mapping
profile_documentswas open to any authenticated user — no gate
at all. Now requires admin ORprofiles.write.control_catalogs+control_mappingsalready had
authorize_admin!but ran it AFTERset_xxx, so a non-admin
probing a non-existent id got 404 (existence leak) instead of
403. Now runs auth first.
All three controllers share the Path D pattern:
- run authorize_<resource>_write! BEFORE set_xxx
- admin always passes (instance-admin shortcut)
- a user with the resource's *.write permission via any role
(e.g. policy_manager) passes — uses the existing
has_permission? RBAC infrastructure
- otherwise 403 with no record-existence leak
CDEF stays open by design. Its controller comment explicitly
documents "All CRUD operations are available to any authenticated
user" — the AWS Labs bulk-ingest flow and catalog-refresh button
depend on this. tests/api/test_cdef_documents renames the
negative-auth test to test_non_admin_can_create to match, with
a comment pointing to Path D if CDEF ever needs gating.
Test infrastructure cleanup
- tests/api/test_federation_peers switches from the workaround
FederationPeerListEnvelope back to the standard
PaginatedEnvelope[FederationPeerIndex] (#562 was fixed in
v1.7.3, the workaround is no longer needed) - schemas/_federation drops the workaround envelope + reduced-meta
types - spec/requests/api/v1/profile_documents_spec adds a positive
"non-admin WITH profiles.write" example proving the role-permission
path works (the third state #575 called out — admin / unauthenticated
/ role-permissioned)
Container image
risksentinel/sparc:1.7.4
Compatibility
No env-var changes. No schema migrations. API contract:
- Profile create/update/destroy now returns 403 to any non-admin user
without theprofiles.writepermission (was 201 — this is a
SECURITY-TIGHTENING change). Any operator that needs non-admin
write access can grantprofiles.writeto a role via the existing
Role configuration. - Catalog + Mapping create/update/destroy: an existing non-admin
user withoutcatalogs.write/mappings.writenow also passes
the gate (was already 403 from authorize_admin!, but now via the
permission gate); admins are unchanged. - Boundary nested routes (
/api/v1/authorization_boundaries/...)
that previously returned 404 to id-based URLs now return 200/422
as expected.
Drop-in upgrade from v1.7.3 for any consumer using slug-based URLs
and admin-or-permissioned writes. The only breaking case is "non-admin
caller that previously could write profiles" — grant them
profiles.write via a role and they're unblocked.