RBAC Conditions: Attribute-Based Access Control
Vì Sao Quantum Trọng
Standard RBAC — verb + resource matching — không support fine-grained policies:
- Cannot restrict by resource labels — "grant get pods, nhưng chỉ pods có label tier=prod"
- Cannot restrict by request IP — "allow deploy từ CI system IP, deny từ personal laptop"
- Cannot restrict by time — "allow deployment only 9-5 business hours"
- Cannot restrict by custom attributes — "allow create secrets, nhưng chỉ nếu secret name match pattern"
RBAC Conditions extend RBAC với attribute-based access control (ABAC) capabilities via CEL (Common Expression Language) expressions.
Understanding conditions crucial để:
- Fine-grained authorization beyond binary verb+resource match
- Compliance policies (time-based restrictions, geolocation checks)
- Security policies (resource label restrictions, network source checks)
RBAC Conditions Mechanism
Conditions in ClusterRole Rules
ClusterRole rules có thể include conditions field:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: pod-reader-restricted
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
conditions:
resourceRules:
- apiGroups: [""]
resources: ["pods"]
resourceNames: []
evaluationRules:
- rule: "resource.labels['tier'] == 'prod'"
- rule: "request.time.getHours('UTC') >= 9 && request.time.getHours('UTC') <= 17"Semantics:
- Rule match permission — user có thể GET pods
- Conditions further restrict — nhưng chỉ nếu conditions all evaluate true
- Nếu condition false → authorization DENIED (even nếu rule matched)
CEL Expression Evaluation
CEL (Common Expression Language) là language để writing conditions:
# Simple comparisons
resource.labels['tier'] == 'prod'
# Arithmetic
resource.metadata.generation < 10
# String operations
resource.metadata.name.startsWith('test-')
# Logical operators
(resource.labels['tier'] == 'prod' && request.time.hour >= 9)Kubernetes API server evaluates expressions; nếu true → ALLOW, nếu false → DENY.
Available Request Attributes
Conditions có thể access request attributes:
| Attribute | Type | Example |
|---|---|---|
request.user.username | String | "alice@example.com" |
request.user.groups | String list | ["engineers", "system:authenticated"] |
request.time | Timestamp | có thể call .getHours(), .getDate(), etc. |
request.path | String | API path /api/v1/namespaces/default/pods |
request.verb | String | "get", "create", etc. |
request.sourceIP | String | "192.168.1.100" |
resource.name | String | Pod name |
resource.namespace | String | Namespace |
resource.labels['key'] | String hoặc null | Label value |
Resource Attributes for Conditions
For resource-level conditions:
| Attribute | Available For | Example |
|---|---|---|
resource.metadata.name | All resources | Pod name |
resource.metadata.labels | All resources | Labels map |
resource.metadata.ownerReferences | All resources | Owner info |
resource.spec.selector | Select resources | Label selector |
CEL Expression Examples
Example 1: Production Pods Only
Restrict access đến pods với label tier=prod:
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "delete"]
conditions:
evaluationRules:
- rule: "resource.labels['tier'] == 'prod'"User có thể delete pods, nhưng chỉ nếu pod labeled tier=prod.
Example 2: Time-Bounded Access
Allow deployments chỉ during business hours:
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["create", "update"]
conditions:
evaluationRules:
- rule: |
request.time.getHours('UTC') >= 9
&& request.time.getHours('UTC') <= 17
&& request.time.getDayOfWeek('UTC') >= 1
&& request.time.getDayOfWeek('UTC') <= 5Deployments có thể được tạo/updated chỉ Monday-Friday, 9am-5pm UTC.
Example 3: IP-Based Restrictions
Allow kubelet và CI system chỉ:
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["update"]
conditions:
evaluationRules:
- rule: |
request.sourceIP.startsWith('10.0.1.')
|| request.sourceIP == '192.168.100.5'Node updates từ request IP di range 10.0.1.0/24 hoặc CI IP.
Example 4: Resource Name Patterns
Restrict đến resources matching pattern:
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create", "update"]
conditions:
evaluationRules:
- rule: "resource.metadata.name.startsWith('team-specific-')"Can create/update ConfigMaps chỉ nếu name start với "team-specific-".
Example 5: Complex: Org-Wide Policy
Only SREs có thể scale deployments với memory > 2Gi:
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["update", "patch"]
conditions:
evaluationRules:
- rule: |
(request.user.groups.contains('sre-team')
|| request.user.groups.contains('platform-team'))
&& has(resource.spec.template.spec.containers[0].resources.requests.memory)Multiple conditions combined: role-based (group check) + resource-based (memory check).
Feature Status & Enablement
Alpha Status
RBAC Conditions masih Alpha di Kubernetes 1.30+. Enablement:
kube-apiserver --feature-gates=AuthorizeWithConditions=trueEnable để API server và authorization webhooks.
Limitations of Current Implementation
Performance — CEL evaluation adds latency đến mỗi authorization decision
- Estimated 1-5ms per condition evaluation
- Saat scale (10K requests/sec), significant overhead
Expression language — CEL punya limitations:
- Cannot call external services
- Cannot access etcd directly
- Cannot modify resources (only read)
Debugging — CEL error messages không selalu clear:
Error evaluating condition: undefined reference to 'foo'Debugging require careful inspection expression.
No condition on verb — Cannot write:
yamlrule: "request.verb == 'delete' && request.time.hour >= 22" # Won't work; conditions evaluate after verb match
Conditions vs. Webhooks
When to Use Conditions
| Requirement | Conditions | Webhook |
|---|---|---|
| Simple attribute checks | ✓ | ✓ |
| Performance critical | ✓ | ✗ |
| No external calls | ✓ | ✓ |
| Complex business logic | ✗ | ✓ |
| Offline availability | ✓ | ✗ |
Conditions ideal để:
- Label-based restrictions
- Time/IP-based policies
- Simple attribute checks
- Policies mà không thay đổi frequently
Webhooks ideal để:
- Complex business logic
- Integration với external systems (policy engine)
- Dynamic policies
- Policies maintained externally
Example: Conditions vs. Webhook
Scenario: Allow delete pods chỉ nếu pod trong grace-period bởi policy engine.
Conditions approach:
# Can't query external policy engine trong condition
# Not possibleWebhook approach:
Authorization → Webhook call → Policy engine → decisionPractical Patterns
Pattern 1: Environment-Specific Permissions
Different permissions để dev vs. prod:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: developer
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["create", "update", "delete"]
conditions:
evaluationRules:
- rule: "resource.metadata.namespace.startsWith('dev-')"
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list"]
conditions:
evaluationRules:
- rule: "resource.metadata.namespace.startsWith('prod-')"
# Get/list only, no create/update/deleteDevelopers full access dev namespaces, read-only prod.
Pattern 2: Scheduled Maintenance Windows
Allow cluster changes trong maintenance window:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: maintenance-operator
rules:
- apiGroups: ["apps", ""]
resources: ["deployments", "pods"]
verbs: ["update", "delete"]
conditions:
evaluationRules:
- rule: |
request.time.getDayOfWeek('UTC') == 6
&& request.time.getHours('UTC') >= 23Changes allowed chỉ Saturday nights (23:00 UTC).
Anti-Patterns & Gotchas
Anti-Pattern 1: Over-Complex Conditions
# Awful: CEL becomes hard to read
rule: |
(request.user.groups.contains('sre') || request.user.groups.contains('platform'))
&& (resource.labels['env'] == 'prod' || resource.labels['env'] == 'staging')
&& (request.time.getHours('UTC') >= 9 && request.time.getHours('UTC') <= 17)
&& (request.sourceIP.startsWith('10.0.') || request.sourceIP.startsWith('192.168.'))Better: split đến multiple rules hoặc use webhook.
Anti-Pattern 2: Time-Based Restrictions as Security
rule: "request.time.getHours('UTC') >= 22" # "After hours only"Problem: Attackers có thể set system clock forward. Time conditions không phải security boundary, chỉ audit/compliance tool.
Anti-Pattern 3: Assuming Conditions Cache
# Không true: conditions evaluated mỗi request
# Jangan expect caching hoặc optimizationCEL evaluates fresh per request. No assumptions về caching.
Troubleshooting Conditions
Issue 1: Condition Syntax Error
Error: invalid condition: undefined reference to 'xyz'Debug:
# Test condition expression với kubebuilder hoặc standalone CEL
# Check attribute names và types availableIssue 2: Condition Evaluates Wrong
# Enable audit logging để see actual attribute values
kubectl patch clusterrole some-role -p '{"metadata":{"labels":{"debug":"true"}}}'
# Check audit log với full resource objectIssue 3: Performance Degradation
Authorization latency increased after enabling conditionsCauses:
- Too many conditions per rule
- Conditions evaluating large resource objects
Mitigation:
- Limit conditions per rule
- Use resourceRules filter để reduce evaluations
- Consider webhook nếu conditions too complex
Summary
RBAC Conditions enable fine-grained authorization:
- Extend RBAC với attribute checks (labels, time, IP, request attributes)
- CEL expressions để writing conditions
- Per-rule scoping — conditions apply đến specific rule, not role
- Alpha feature — performance/stability implications
Use conditions để:
- Environmental (label-based) access control
- Time-based policies
- IP restrictions
- Simple attribute checks
Use webhooks để:
- Complex business logic
- External policy integration
- Dynamic policies