Skip to main content
Version: Next

Conditions

A role binding answers who, what, and where. Conditions add a fourth constraint — under what circumstances. For example, you can grant a developer permission to manage release bindings in the crm project, but only when the target environment is dev or staging — keeping production off-limits.

Conditions are optional. Omit them and the role mapping behaves like any other RBAC grant — every action the role grants applies within the binding's scope.

Condition Structure

A condition has two parts: a list of actions it applies to, and an expression that decides whether those actions are permitted. You can attach conditions to a role mapping either in YAML (the conditions field on AuthzRoleBinding / ClusterAuthzRoleBinding) or through the Access Control UI in Backstage.

FieldTypeRequiredDescription
actionsstring[]YesAction patterns this condition applies to — the entry's expression is attached to each listed action. Supports exact matches and wildcards.
expressionstringYesA CEL expression that must evaluate to true for the action to be permitted by this role mapping.

Action patterns follow the same wildcard rules used elsewhere in OpenChoreo RBAC:

  • releasebinding:create — a single concrete action
  • releasebinding:* — every action on the releasebinding resource
  • * — every action in the system

Only entries whose actions match the request contribute to the decision. If a mapping has conditions but none target the requested action, the condition check is skipped for that action.

Available Attributes

CEL expressions reference a predefined set of attributes. Each attribute is registered against the specific actions where it is meaningful; a binding that references an attribute on an action that does not support it will be rejected at creation time.

Currently the following attributes are available — more will be added in future releases:

AttributeTypeAvailable onDescription
resource.environment
(dual-scoped)
stringreleasebinding:create, releasebinding:view, releasebinding:update, releasebinding:delete, logs:view, metrics:view, traces:viewEnvironment associated with the resource (e.g., acme/prod).

When a condition lists multiple actions — whether explicitly (["releasebinding:create", "logs:view"]) or via a wildcard pattern (releasebinding:*) — the expression may only reference attributes registered for every action the entry covers. An attribute supported by only some of those actions is not usable in the condition.

Resource Identifiers (Dual-Scoped)

Some resource kinds in OpenChoreo come in two variants — one namespace-scoped, one cluster-scoped. In conditions, both variants share a single logical name (such as environment). Conditions don't pick the variant by kind; they pick it by the shape of the identifier.

Attributes that identify such a resource (such as resource.environment) carry one of two forms:

  • For the namespace-scoped variant: {namespace}/{name} — for example, acme/prod.
  • For the cluster-scoped variant: just {name} — for example, prod.

Match the same form in your CEL expression: resource.environment == "acme/prod" targets a namespace-scoped environment named prod in acme, while resource.environment == "prod" targets the cluster-scoped one.

For resources that exist in only one scope, the resource identifiers simply carry the resource name.

How Conditions Affect the Authorization Decision

For a role mapping to permit a request, four things must all be true:

  1. The subject matches the binding's entitlement.
  2. The target resource is within the binding's scope.
  3. The role lists the requested action (exactly or via a wildcard).
  4. The condition (if any) evaluates to true.

A mapping with no conditions skips step four. A mapping with conditions that don't target the request action also skips step four — steps one through three still apply.

Aggregation across bindings is unchanged. A request is allowed only if at least one matching binding has effect: allow and no matching binding has effect: deny. See How OpenChoreo RBAC determines access for the full algorithm.

note

If a condition expression cannot be evaluated cleanly at runtime, OpenChoreo treats it as failing closed — see Fail-Closed Evaluation.

Multiple Entries on the Same Mapping

A single role mapping can carry multiple conditions entries. Among the entries whose actions match the request action, the expressions are combined with OR — at least one entry must evaluate to true for the role mapping to permit the action:

conditions:
- actions: ["releasebinding:view"]
expression: 'resource.environment == "dev"'
- actions: ["releasebinding:view"]
expression: 'resource.environment == "staging"'

This binding permits the releasebinding:view actions when the target environment is either dev or staging. Combining alternatives in one entry with CEL's in operator (resource.environment in ["dev", "staging"]) is equivalent and usually clearer.

Examples

A platform engineer needs to give the backend-team group developer access — but with two safety rails: release-binding mutations must stay out of production, and log access should be limited to dev and staging. A single role mapping can carry both rules, one condition per action group:

apiVersion: openchoreo.dev/v1alpha1
kind: AuthzRoleBinding
metadata:
name: backend-team-binding
namespace: acme
spec:
entitlement:
claim: groups
value: backend-team
roleMappings:
- roleRef:
kind: AuthzRole
name: developer
conditions:
- actions:
- releasebinding:create
- releasebinding:update
- releasebinding:delete
expression: 'resource.environment != "acme/prod"'
- actions:
- logs:view
expression: 'resource.environment in ["acme/dev", "acme/staging"]'
effect: allow

Read-only actions on releasebinding (e.g., releasebinding:view) and every other action in the developer role remain unrestricted — only the listed actions are gated.