request-validation: 403 auth-deny for uniformly-secured APIs (Hub)#394
Draft
esraagamal6 wants to merge 1 commit into
Draft
request-validation: 403 auth-deny for uniformly-secured APIs (Hub)#394esraagamal6 wants to merge 1 commit into
esraagamal6 wants to merge 1 commit into
Conversation
Phase B of the Hub negative-suite auth coverage (camunda/camunda-hub#25264); 401 (Phase A) landed in #391. Adds an `all-secured` mode to the 403 auth-deny generator for APIs that authorize every op via a single scheme and short-circuit the authority check before any resource lookup (Camunda Hub: `hasAuthority(...) && hasAccessToOrganization(...)`). - New per-config `authDenyMode: 'slice' | 'all-secured'` (default 'slice', preserving OCA's read-side allowlist). Hub uses 'all-secured'. - `generateAuthDeny` all-secured branch: one 403 scenario per `secured` op (reusing the `secured` field the 401 generators target, so the 403 surface matches the 401 surface) with dummy path keys and no request body. No SLICE, no fixtures — the dummy key is never dereferenced because authority is denied first. - Bearer deny probe: `denyProbeHeaders()` returns a Bearer token when `RBAC_DENY_PROBE_BEARER_TOKEN` is set (Hub), else the Basic zero-grant probe user (OCA). The rbac global-setup skips all fixture/probe-user provisioning in Bearer-probe mode. - Keycloak: a reduced-permission `c8-client-deny` M2M client (no public-api authorities). start-hub.sh adds it a web-modeler-api audience mapper so its token authenticates (passes 401) and reaches the authorization (403) gate. - Hub config opts in (`authDenyMode: 'all-secured'`); README documents minting the probe token and running RV_PROFILE=rbac. OCA auth-deny unchanged. - Unit tests for the all-secured generator (targeting, dummy keys, filter) and the denyProbeHeaders Bearer/Basic switch. Generates 29 rbac deny-tests for Hub (one per secured op). Live validation against a secured local Hub is the remaining acceptance step. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Phase B of the Camunda Hub negative-suite auth coverage (camunda-hub#25264) — 403 unauthorized. Phase A (401) landed in #391; this closes #392.
Adds an
all-securedmode to the 403auth-denygenerator for APIs that authorize every op via a single scheme and short-circuit the authority check before any resource lookup — Camunda Hub's@PreAuthorize("hasAuthority(...) && hasAccessToOrganization(...)"). A reduced-permission Bearer probe is therefore denied 403 on every secured op with dummy keys (no fixtures).This is the zero-permission probe approach (option 1): full surface coverage, generic "this op is permission-gated" assertion — the same model OCA's auth-deny uses, but extended from a 7-op read slice to the whole secured surface (Hub's short-circuit removes OCA's need for real fixtures).
Changes
authDenyMode: 'slice' | 'all-secured'(default'slice', preserving OCA's read-side allowlist). Mirrors request-validation: 401 negatives for uniformly-secured APIs (Hub) — missing + invalid token #391'sauthAbsentMode.generateAuthDenyall-secured branch: one 403 scenario persecuredop (reusing thesecuredfield the 401 generators target, so the 403 surface matches the 401 surface), dummy path keys, no body. NoSLICE, no fixtures.denyProbeHeaders()returns a Bearer token whenRBAC_DENY_PROBE_BEARER_TOKENis set (Hub), else the Basic zero-grant probe user (OCA). The rbac global-setup skips fixture/probe-user provisioning in Bearer-probe mode.c8-client-denyM2M client (no public-api authorities);start-hub.shadds it aweb-modeler-apiaudience mapper so its token authenticates (passes 401) and reaches the 403 gate.RV_PROFILE=rbac. OCA auth-deny unchanged.denyProbeHeadersBearer/Basic switch.Generation
CONFIG=camunda-hub npm run generate:request-validationemits 29 rbac deny-tests (one per secured op, matching the 401 surface).Open / remaining (why this is a draft)
@PreAuthorize, which runs after@RequestBodydeserialization/validation. A bodylessPOSTcreate could return 400 before the 403. If the live run shows that, this PR will exclude required-body ops (bodyRequired === true) from the all-secured surface with a documented note, deferring create/update deny-tests (which need a valid body) to a follow-up.🤖 Generated with Claude Code