You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Phase B of the Camunda Hub negative-suite auth coverage (camunda/camunda-hub#25264). Phase A (401 auth-absent) landed in #391. This issue covers 403 unauthorized.
Hub authorization model (assessed from camunda-hub restapi)
The Public API v2 uses @PreAuthorize("hasAuthority(PERMISSION_X) && hasAccessToOrganization(...)") on each controller:
CRUD authority per op — read / create / update / delete (PublicApiToken.PERMISSION_*), mechanically derivable from the HTTP method (GET/search→read, POST-create→create, PATCH→update, DELETE→delete).
Org access — token organizationId must match the resource's (org-wide; no per-resource roles).
Returns 403, not 404, on authz failure.
Key simplification: the SpEL is hasAuthority(...) && hasAccessToOrganization(...) — authority is checked first and short-circuits, so a token lacking the op's permission yields 403 without any resource/org lookup. → Hub 403 tests can use dummy keys (no fixtures needed to make resources exist, unlike OCA's auth-deny which needed real resources to avoid 404).
Why the existing authDeny (OCA) doesn't fit
request-validation/src/analysis/authDeny.ts is OCA-specific: a hardcoded SLICE of get-by-key reads using a Basic-auth zero-grant probe (denyProbeHeaders()) + real fixtures. Hub is Bearer/JWT + CRUD-authority, dummy keys OK.
Proposed implementation
Per-op permission mapping from method (config-driven or convention): GET/*/search→read, POST(non-search create)→create, PATCH→update, DELETE→delete.
A reduced-permission Bearer probe token — analogous to denyProbeHeaders() but Bearer: a token missing the op's required permission (e.g. a Keycloak web-modeler/client scoped to fewer web-modeler-public-api permissions, or a read-only token used against create/update/delete). Mint via the Keycloak setup already in docker/docker-compose.hub.yml (the c8-client M2M client + audience mapper).
Emitter: denyProbeHeaders() currently renders a Basic header (OCA). Needs a Bearer-probe variant for Hub (or parameterize the probe-header fn per config).
Emit into the existing rbac profile (or a hub-appropriate profile); run against a secured Hub.
Open questions
Token minting: simplest is a second Keycloak client/scope with reduced permissions; confirm the SM Identity → permission mapping (create:*/read:*/… → PublicApiToken authorities).
Wrong-org 403 is largely a SaaS concern (SM is single-org) — scope local coverage to the missing-permission flavor.
Phase B of the Camunda Hub negative-suite auth coverage (camunda/camunda-hub#25264). Phase A (401 auth-absent) landed in #391. This issue covers 403 unauthorized.
Hub authorization model (assessed from camunda-hub
restapi)The Public API v2 uses
@PreAuthorize("hasAuthority(PERMISSION_X) && hasAccessToOrganization(...)")on each controller:read/create/update/delete(PublicApiToken.PERMISSION_*), mechanically derivable from the HTTP method (GET/search→read, POST-create→create, PATCH→update, DELETE→delete).organizationIdmust match the resource's (org-wide; no per-resource roles).Key simplification: the SpEL is
hasAuthority(...) && hasAccessToOrganization(...)— authority is checked first and short-circuits, so a token lacking the op's permission yields 403 without any resource/org lookup. → Hub 403 tests can use dummy keys (no fixtures needed to make resources exist, unlike OCA's auth-deny which needed real resources to avoid 404).Why the existing
authDeny(OCA) doesn't fitrequest-validation/src/analysis/authDeny.tsis OCA-specific: a hardcodedSLICEof get-by-key reads using a Basic-auth zero-grant probe (denyProbeHeaders()) + real fixtures. Hub is Bearer/JWT + CRUD-authority, dummy keys OK.Proposed implementation
*/search→read, POST(non-search create)→create, PATCH→update, DELETE→delete.denyProbeHeaders()but Bearer: a token missing the op's required permission (e.g. a Keycloakweb-modeler/client scoped to fewerweb-modeler-public-apipermissions, or a read-only token used against create/update/delete). Mint via the Keycloak setup already indocker/docker-compose.hub.yml(thec8-clientM2M client + audience mapper).authDenyto a config-driven Hub variant (method→permission, dummy params, Bearer probe) emitting one 403 scenario per op, distinct from OCA's Basic zero-grant slice. Likely gate via a per-configauthDenyModemirroring theauthAbsentModeadded in request-validation: 401 negatives for uniformly-secured APIs (Hub) — missing + invalid token #391.denyProbeHeaders()currently renders a Basic header (OCA). Needs a Bearer-probe variant for Hub (or parameterize the probe-header fn per config).rbacprofile (or a hub-appropriate profile); run against a secured Hub.Open questions
create:*/read:*/… → PublicApiToken authorities).Acceptance