Skip to content

v1.7.4 — Nested-route id-or-slug + RBAC permission gating

Choose a tag to compare

@clem-field clem-field released this 26 May 16:23

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_documents was open to any authenticated user — no gate
    at all. Now requires admin OR profiles.write.
  • control_catalogs + control_mappings already had
    authorize_admin! but ran it AFTER set_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 the profiles.write permission (was 201 — this is a
    SECURITY-TIGHTENING change). Any operator that needs non-admin
    write access can grant profiles.write to a role via the existing
    Role configuration.
  • Catalog + Mapping create/update/destroy: an existing non-admin
    user without catalogs.write / mappings.write now 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.