PR13 — Fix ACTION_PERMISSION_MAP gap for workflow.execute/model.use - #2
Merged
Merged
Conversation
The Gateway sends the literal permission string as `action` for workbench/tes/toolserver (workflow.execute) and model-registry (model.use), which matched neither this map nor the "tes." prefix rule -- 4 of 5 gateway-routed services had zero real permission enforcement regardless of caller permissions. Only rag (dataset.read) was enforced. Co-Authored-By: Claude Sonnet 5 <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.
Summary
Fixes a real, verified gap in permission enforcement for gateway-routed traffic:
ACTION_PERMISSION_MAPonly had an entry fordataset.read. The Gateway'sPolicyClientsendsactionas the literal permission string itself for its 5 mapped services —workflow.executefor workbench/tes/toolserver,model.usefor model-registry — never a"tes.*"-prefixed string. Neither literal matched this map norPREFIX_PERMISSION_MAP's"tes."prefix rule (which only ever matched this repo's own synthetic test fixtures, never real gateway traffic), sorequired_permission()silently returnedNoneand the PERMISSION gate allowed unconditionally. 4 of 5 gateway-routed services had zero real permission enforcement, regardless of what permissions a caller held — onlyragwas ever actually enforced.Both are identity mappings by design — the Gateway pre-resolves
actionto already be the permission name for its 5 mapped services, so the map's job is confirming "yes, required," not translating.No other functional change.
app/core/rbac.py's"tes."prefix rule is left inert (it's permanently unreachable for real gateway traffic for the same reason) rather than "fixed" to also matchworkflow.execute— doing so would reintroduce a hardcoded role check, contradicting PR13's own "no hardcoded role-name checks, rely on permissions" direction.Dependency
This PR is part of PR13 — Dynamic Enterprise RBAC Activation.
It must be reviewed and merged in dependency order with the other PR13 repositories.
Do not merge independently.
Dependency order: auth → policy-engine (this PR) → api-gateway → control-center → studio → docs. Depends on
omnibioai-auth's companion PR for real (non-empty) permissions to actually reach this engine in production traffic.Validation
Tests performed: 90 passed (full suite). New regression-lock tests:
test_required_permission_for_workflow_execute_action,test_required_permission_for_model_use_action(unit level), plus two additions totest_engine_permission_tenancy.pyusing the exact gateway-real action shape (action="workflow.execute"/"model.use", not the"tes.submit"-style shape every prior test used — which is exactly what let this gap ship unnoticed originally).Security checks: this fix closes an enforcement gap, not a new attack surface — the effect is 4 services moving from "always allowed regardless of permissions" to "correctly gated," strictly narrowing access, never widening it.
Compatibility notes: this repo compiles Cython
.sobinaries from.pysource for IP protection (setup.py build_ext --inplace) — the compiledpermissions.cpython-*.so/.c/.oartifacts in this PR were rebuilt from the updated source and are committed alongside it, per this repo's existing convention. No schema, no API surface change.Related PRs
Part of the PR13 review set, all on
feature/pr13-dynamic-rbac-activation:omnibioai-auth— PR #32 (draft, open) — the dynamic permission source this fix activatesomnibioai-api-gateway— tests confirming this repo receives the right permissions per role tieromnibioai-control-center— PR #20 (draft, open)omnibioai-studio— deployment runbook + smoke test exercising this fix end to endomnibioai-docs— documents this exact gap and fixReview only — do not merge. No migration applied, no deployment performed, live stack untouched.