Skip to main content
Version: v1.0.x

Authorization in OpenChoreo

OpenChoreo RBAC controls who can perform what actions on which OpenChoreo resources. It is managed declaratively through Kubernetes Custom Resource Definitions alongside your workloads.

note

Authorization can be disabled for testing purposes. When disabled, a passthrough implementation allows all requests without any policy evaluation.

What can I do with OpenChoreo RBAC?

Here are some examples of what you can do with OpenChoreo RBAC:

  • Allow one team to manage components in a single project, while another team has read-only access across the whole namespace.
  • Give a developer permission to create and update components in the crm project, but not delete them.
  • Grant a platform engineer cluster-wide permission to manage data planes, component types, and workflows.
  • Allow a service account to view logs and metrics for a specific component, and nothing else.
  • Restrict an auditor to read-only access across every namespace in the cluster.

How OpenChoreo RBAC works

You control access in OpenChoreo RBAC by defining roles and creating role bindings. A role is a named collection of allowed actions. A role binding attaches a role to a subject at a specific scope, answering the question "who can do what, and where?"

  • Subjectwho is being granted access.
  • Rolewhat actions are allowed.
  • Scopewhere in the resource hierarchy the permissions apply.

The rest of this page walks through each of these in detail, followed by how OpenChoreo evaluates a request against them.

Core Concepts

Subject

A subject represents the identity making a request. Subjects are identified by entitlements — claim-value pairs extracted from the caller's JWT/OIDC token. For example:

  • groups:platformEngineer — user belongs to the "platformEngineer" group
  • sub:user-abc-123 — user's unique identifier
  • email:alice@acme.com — user's email address

A single user can have multiple entitlements (e.g., belonging to several groups), and each entitlement is evaluated independently during authorization.

Action

An action represents an operation that can be performed on a resource. Actions follow the format resource:verb. For example:

  • component:create — create a new component
  • project:view — view a project
  • componenttype:create — create a new component type

Actions also support wildcards:

  • component:* — all operations on components
  • * — all operations on all resources

Resource Hierarchy

Resources in OpenChoreo form a four-level ownership hierarchy:

Cluster (everything)
└── Namespace
└── Project
└── Component

Every resource belongs to a specific point in this hierarchy. For example, a component belongs to a project, which belongs to a namespace. Cluster-scoped resources (like ClusterAuthzRole or ClusterDataPlane) sit at the top level and are not owned by any namespace.

Scope

Scope is the boundary that controls where in the resource hierarchy a role's permissions apply. When a role binding includes a scope, only resources at or below that point in the hierarchy are affected. Resources outside the scope are invisible to that binding, as if it doesn't exist.

Scope is set via the scope field on each role mapping in a binding:

Scope levelHow to setWhat it means
Cluster-wideOmit scope on a ClusterAuthzRoleBindingPermissions apply to all resources at every level of the hierarchy
Namespacescope.namespace: acmePermissions apply to the acme namespace and all resources within it — its projects, their components, and any other namespace-scoped resources
Projectscope.namespace: acme, scope.project: crmPermissions apply to the crm project and all resources within it
Componentscope.namespace: acme, scope.project: crm, scope.component: backendPermissions apply only to the backend component and its resources

Effective Permissions

A role defines what actions are permitted (e.g., component:view, project:create). Scope defines where those actions take effect. The effective permissions of a binding are the intersection of both — a user can only perform an action if the role grants that action and the target resource falls within the scope.

For example, a developer role that includes component:create and project:view:

  • Scoped to namespace: acme, project: crm — the user can create components and view the project, but only within the crm project. Other projects in acme are unaffected.
  • Scoped to namespace: acme — the user can create components and view projects across all projects in acme.
  • No scope (cluster-wide) — the user can create components and view projects across the entire cluster.

Two key properties:

  • Permissions cascade downward. Granting component:view at the namespace scope allows viewing components in every project within that namespace.
  • Permissions do not cascade upward. Even if a role includes actions for higher-level resources (e.g., environment:view), a binding scoped to a project will not grant access to namespace-level or cluster-level resources. If a user needs visibility into those, add supplementary role mappings at the appropriate scope — see Scoping Roles Below Cluster Level.

Each role binding also carries an effect field — either allow or deny (default: allow). A deny binding is an explicit exception: it revokes access that would otherwise be granted by an allow binding at the same or a higher scope. See How OpenChoreo RBAC determines access for exactly how allow and deny bindings are combined.

How OpenChoreo RBAC determines access

When a request arrives, OpenChoreo evaluates it against every role binding the subject matches. For each binding, all of the following must hold for the binding to apply:

  1. The subject matches. One of the caller's entitlement values (e.g., groups:platformEngineer) equals the binding's subject.
  2. The resource is within scope. The target resource lies at or below the binding's scope in the resource hierarchy. A binding at namespace: acme applies to everything inside acme; a ClusterAuthzRoleBinding with no scope applies cluster-wide.
  3. The role grants the action. The role referenced by the binding lists the requested action, either exactly (component:create) or via a wildcard (component:*, *).

A request is allowed only if:

  • at least one matching binding has effect: allow, and
  • no matching binding has effect: deny.

A single matching deny is enough to block the request, even when multiple allow bindings would otherwise grant it. Deny applies across role kinds — a namespace-scoped AuthzRoleBinding with effect: deny can block access that a ClusterAuthzRoleBinding would otherwise allow.

Bindings default to effect: allow. Set effect: deny explicitly only when you need to create a targeted exception to a broader allow — for example, granting developer access across the acme namespace but denying it on the secret project within it.

Authorization CRDs

OpenChoreo uses four CRDs to manage authorization. Roles define what actions are permitted, and role bindings connect subjects to those roles with a specific scope and effect.

CRDScopePurpose
ClusterAuthzRoleClusterDefine a set of allowed actions, available across all namespaces
AuthzRoleNamespaceDefine actions scoped to a single namespace
ClusterAuthzRoleBindingClusterBind an entitlement to one or more cluster roles, optionally scoped to a namespace, project, or component
AuthzRoleBindingNamespaceBind an entitlement to one or more roles within a specific namespace

For detailed field descriptions and YAML examples, see the Authorization API Reference.

Available Actions

The following actions are defined in the system:

ResourceActions
Namespacenamespace:view, namespace:create, namespace:update, namespace:delete
Projectproject:view, project:create, project:update, project:delete
Componentcomponent:view, component:create, component:update, component:delete
Component Releasecomponentrelease:view, componentrelease:create
Release Bindingreleasebinding:view, releasebinding:create, releasebinding:update, releasebinding:delete
Component Typecomponenttype:view, componenttype:create, componenttype:update, componenttype:delete
Cluster Component Typeclustercomponenttype:view, clustercomponenttype:create, clustercomponenttype:update, clustercomponenttype:delete
Workflowworkflow:view, workflow:create, workflow:update, workflow:delete
Workflow Runworkflowrun:view, workflowrun:create, workflowrun:update
Cluster Workflowclusterworkflow:view, clusterworkflow:create, clusterworkflow:update, clusterworkflow:delete
Traittrait:view, trait:create, trait:update, trait:delete
Cluster Traitclustertrait:view, clustertrait:create, clustertrait:update, clustertrait:delete
Environmentenvironment:view, environment:create, environment:update, environment:delete
Data Planedataplane:view, dataplane:create, dataplane:update, dataplane:delete
Cluster Data Planeclusterdataplane:view, clusterdataplane:create, clusterdataplane:update, clusterdataplane:delete
Workflow Planeworkflowplane:view, workflowplane:create, workflowplane:update, workflowplane:delete
Cluster Workflow Planeclusterworkflowplane:view, clusterworkflowplane:create, clusterworkflowplane:update, clusterworkflowplane:delete
Observability Planeobservabilityplane:view, observabilityplane:create, observabilityplane:update, observabilityplane:delete
Cluster Observability Planeclusterobservabilityplane:view, clusterobservabilityplane:create, clusterobservabilityplane:update, clusterobservabilityplane:delete
Deployment Pipelinedeploymentpipeline:view, deploymentpipeline:create, deploymentpipeline:update, deploymentpipeline:delete
Observability Alert Notification Channelobservabilityalertsnotificationchannel:view, observabilityalertsnotificationchannel:create, observabilityalertsnotificationchannel:update, observabilityalertsnotificationchannel:delete
Secretssecretreference:view, secretreference:create, secretreference:update, secretreference:delete
Workloadworkload:view, workload:create, workload:update, workload:delete
ClusterAuthzRoleclusterauthzrole:view, clusterauthzrole:create, clusterauthzrole:update, clusterauthzrole:delete
AuthzRoleauthzrole:view, authzrole:create, authzrole:update, authzrole:delete
ClusterAuthzRoleBindingclusterauthzrolebinding:view, clusterauthzrolebinding:create, clusterauthzrolebinding:update, clusterauthzrolebinding:delete
AuthzRoleBindingauthzrolebinding:view, authzrolebinding:create, authzrolebinding:update, authzrolebinding:delete
Observabilitylogs:view, metrics:view, traces:view, alerts:view
Incidentsincidents:view, incidents:update
RCA Reportrcareport:view, rcareport:update