Operator

RBAC

Org roles and scoped role bindings — Wardn's access model

RBAC

Wardn's access model is organizations + scoped role bindings. Org membership assigns a baseline role; role bindings elevate specific users or teams on specific clusters or deployments.

Two Layers

Org roles — the baseline

Assigned by Better Auth at org membership:

Org roleCapabilities
OwnerEverything — full org administration
AdminFull operational access — can't edit org settings
ContributorRead + sync + most creates — can't delete clusters or manage stores
ViewerRead-only — deployments, clusters, logs

Scoped bindings — the elevation

Rows in role_bindings grant a higher ceiling on a narrower scope:

SubjectRoleScopeExample scope_id
user:<id> or team:<id>admin | sync | readorg""
cluster"prod-cluster"
deployment"prod-cluster/default"

A deployment is the cluster/namespace destination pairing — not a stored resource, but every App targeting it falls under the binding. Give a Viewer sync on deployment:prod-cluster/default and they can sync every app deploying into that namespace on that cluster — that's the intended granularity (a namespace is the deployment unit). cluster scope covers all deployments on that cluster.

A binding is additive — it can grant sync on one deployment to a Viewer, never remove an Owner's rights.

Permission Matrix

The full permission set checked by rbacService.Require:

PermissionOwnerAdminContributorViewer
org:read / org:manage✅ / ✅✅ / ❌✅ / ❌✅ / ❌
cluster:read / register / update / remove / shellall ✅all ✅read ✅ / rest ❌read ✅ / rest ❌
deployment:read / create / update / delete / sync / restart / scale / rollbackall ✅all ✅read+sync+restart+scale+rollback ✅, create/update/delete ❌read ✅, rest ❌
team:read / team:manage✅ / ✅✅ / ✅✅ / ❌✅ / ❌
audit:read✅✅✅❌
secretstore:read / manage✅ / ✅✅ / ✅✅ / ❌✅ / ❌
registry:read / manage✅ / ✅✅ / ✅✅ / ❌✅ / ❌
webhook:read / manage✅ / ✅✅ / ✅✅ / ❌✅ / ❌
remediation:approve✅✅❌❌
mcp:read✅✅✅✅

deployment:manage is the umbrella perm for create/update/delete; deployment:sync covers sync/deploy/rollback/restart/approve. A scoped binding can grant any of these on a narrower scope.

How It Works

Request ──▶ auth middleware ──▶ Caller{user_id, org_id, org_role, api_key?}
                                        │
                                        ▼
                        rbacService.Require(perm, ctx)
                                        │
              ┌─────────────────────────┼─────────────────────────┐
              ▼                         ▼                         ▼
        org role grants           scoped binding             api key ceiling
        it directly?            grants it on scope?         clamps the user?
              │                         │                         │
              └──────────── any true → allow ─── else → 403 ──────┘
  1. Baseline — the caller's org role grants the perm
  2. Scoped — a role_bindings row where subject matches the caller (or one of their teams), role covers the perm, and scope_id matches the cluster/deployment
  3. Key ceiling — API-key callers can never exceed the key's role + scope, even when the owning user could

can-i — the frontend contract

POST /api/v1/auth/can-i lets the UI hide actions the caller can't take:

curl -X POST http://localhost:8080/api/v1/auth/can-i -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{"permission":"deployment:sync","scope":"deployment","scope_id":"prod-cluster/default"}'
# {"allowed": true}

Same rules as the can_i MCP tool.

Sessions vs API Keys

CallerScope
Session cookieFull user capability — org role + bindings
wrd_ API keyUser capability ∩ key's role/scope ceiling
Session-only endpoints/auth/sessions, secret-store/registry writes — unreachable with a key

Kubernetes RBAC vs Wardn RBAC

Separate systems:

SystemControlsCeiling
Kubernetes RBACWhat the operator/registered kubeconfig can apply on clustersCluster-level
Wardn RBACWhat users/keys can trigger through the APIOperator's kubeconfig is the ceiling

A Wardn Owner can't deploy anything the operator's SA can't apply.

Best Practices

  • Most users Viewer — grant sync scoped bindings per deployment or cluster instead of broad Contributor
  • CI = wrd_ key with sync deployment-scope — the key can't create clusters or stores even if leaked
  • Contributor for day-to-day — can sync and restart but not delete clusters or manage secret stores
  • Audit team.create/apikey.* — role elevation events are in the audit log

On this page