Skip to content

Authorize node/namespace mutations in the deployment path#2361

Open
ruizhang0519 wants to merge 3 commits into
mainfrom
rbac-deployment-path-authorization
Open

Authorize node/namespace mutations in the deployment path#2361
ruizhang0519 wants to merge 3 commits into
mainfrom
rbac-deployment-path-authorization

Conversation

@ruizhang0519

Copy link
Copy Markdown
Contributor

Tracking: #2234 (step 0, internal mutation paths). This is the deployment slice; background propagation, the availability service-identity model, and remaining internal paths are separate follow-ups.

Deployments are declarative bulk syncs: the orchestrator creates/updates nodes and namespaces and deletes whatever the spec drops. It runs in a detached background task (asyncio.create_task) after the HTTP response, so the actual mutations happen outside the request scope where AccessChecker lives. The POST /deployments entrypoint only authorizes WRITE on the deployment's root namespace — and since WRITE does not imply DELETE, a WRITE-only caller could delete nodes via an empty re-deploy.

This re-authorizes inside the orchestrator (fail-closed) against the deploying user (context.current_user), after the plan is built and before it is applied:

  • WRITE on the deployment root and the namespace each deployed node lands in
  • DELETE on nodes and namespaces the deploy removes

Names are the rendered (fully-qualified) names — what the deploy actually mutates and what RBAC scopes match against. The check runs inside the deployment SAVEPOINT, so a denial rolls back any setup-phase writes. Git sync inherits this via the shared DeploymentOrchestrator.


Why this won't take effect now: DJ's default access policy is permissive, so the check allows requests unless an explicit restrictive grant/policy denies them.

When this will start taking effect: once a deployment enables restrictive RBAC. Until then this is a no-op.

Out of scope (internal-path follow-ups): _maybe_autolock_git_namespace (namespace git-fields mutated after the orchestrator returns), per-preagg-parent authorization within a deploy, background revalidation/propagation, and the availability service-identity model.


Verification:

  1. Denial test — a WRITE-but-not-DELETE caller passes the HTTP entrypoint (WRITE allowed), then an empty re-deploy that would delete a node is denied by the orchestrator; the deploy fails and the node survives. Fails before this change (node deleted), passes after.

@netlify

netlify Bot commented Jul 23, 2026

Copy link
Copy Markdown

Deploy Preview for thriving-cassata-78ae72 canceled.

Name Link
🔨 Latest commit 146c025
🔍 Latest deploy log https://app.netlify.com/projects/thriving-cassata-78ae72/deploys/6a638a87a221c60008a8ed6f

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant