Rbac background path authorization - #2392
Merged
Merged
Conversation
✅ Deploy Preview for thriving-cassata-78ae72 canceled.
|
ruizhang0519
marked this pull request as ready for review
August 4, 2026 20:18
shangyian
approved these changes
Aug 6, 2026
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.
Tracking: #2234 (step 0) — the background half of "carry authorization through deployment and background mutation paths". The deployment half landed in #2361.
derive_frozen_measuresandsave_column_level_lineagerun after the response returns, in their own session, and took only a revision id — so the mutation carried no authorization context and relied on whichever caller scheduled it having checked first.Both now take the acting user plus the resource their scheduling endpoint governed, and re-authorize
WRITEon it. That resource is not always the node: creation is governed on the target namespace, updates and revalidation on the node. Deriving a node request instead would deny the create path, because a namespace scope reaches a node request only through pattern matching —namespace:financedoes not matchfinance.total_events, andnamespace:*does not match a NODE request at all. Denials log and skip rather than raise, since these callers swallow exceptions.No legitimate flow changes behavior; what changes is that the internal path is now independently fail-closed, so a future caller that schedules these without authorizing cannot mutate through them.
Downstream revalidation (
propagate_update_downstream) is a deliberate exception, documented and pinned by a test: a node is only downstream because its own owner pointed it at the upstream, so gating it would either block owners whose nodes have dependents, or leave the graph assertingVALIDfor nodes that are now broken.Two operator scripts have no request user, so they move to the system-facing
derive_frozen_measures_bulkthat the deployment path already uses.migrate-measures.pyadditionally had a stale two-argument call that the new signature would have bound silently.No-op under the permissive default; relevant once a deployment enables restrictive RBAC.
Verification — same case, before and after. A caller is denied
WRITEon the resource governing metricbgwrite.total_events, then derivation runs for it.Before:
After:
With
WRITEgranted, both proceed and lineage is written. Confirmed by neutralizing the check and re-running: the mutations return, then stop once it is restored.Against the real RBAC matcher under a restrictive policy, an exact
namespace:bgwriteWRITEgrant — the grant that lets the create succeed — authorizes the namespace target and denies the node target, which is why the target is carried through rather than derived. Reverting creation to a node target makes that pin fail.Shown at the function level because this path runs after the response is sent; the scheduling endpoints already return
403before reaching it.