RBAC Model¶
This document describes the role-based access control model used by ClusterPulse to authorize access to cluster resources.
Overview¶
ClusterPulse implements a policy-based RBAC system that evaluates access requests against compiled policies stored in Redis. The model supports:
- Multiple subject types (users, groups, service accounts)
- Fine-grained resource filtering (clusters, nodes, namespaces, operators, pods)
- Custom resource types defined via MetricSource CRDs
- Priority-based policy resolution
- Time-based policy validity
Core Components¶
flowchart TB
subgraph Request
P[Principal]
A[Action]
R[Resource]
end
subgraph Evaluation
PE[Policy Engine]
PC[Policy Cache]
Redis[(Redis)]
end
subgraph Decision
D{Decision}
Allow[Allow]
Deny[Deny]
Partial[Partial + Filters]
end
P --> PE
A --> PE
R --> PE
PE <--> PC
PC <--> Redis
PE --> D
D --> Allow
D --> Deny
D --> Partial
Principal¶
The entity making a request. Contains:
| Field | Type | Description |
|---|---|---|
username |
string | Unique identifier |
email |
string | Optional email address |
groups |
list | Group memberships |
is_service_account |
bool | Whether this is a service account |
attributes |
dict | Additional metadata |
Principals are extracted from OAuth proxy headers or Kubernetes authentication.
Resource¶
The object being accessed:
| Field | Type | Description |
|---|---|---|
type |
enum | Resource type (see below) |
name |
string | Resource name |
namespace |
string | Kubernetes namespace (if applicable) |
cluster |
string | Cluster name |
labels |
dict | Resource labels |
Resource Types¶
| Type | Description |
|---|---|
CLUSTER |
A monitored Kubernetes cluster |
NODE |
A cluster node |
NAMESPACE |
A Kubernetes namespace |
OPERATOR |
An OLM-managed operator |
POD |
A pod (used for namespace-scoped filtering) |
ALERT |
A cluster alert |
EVENT |
A cluster event |
CUSTOM |
A custom resource defined by MetricSource |
Action¶
Operations that can be performed:
| Action | Description |
|---|---|
VIEW |
Basic read access |
VIEW_METRICS |
Access to performance metrics |
Policy Structure¶
Policies are defined as MonitorAccessPolicy custom resources:
apiVersion: clusterpulse.io/v1alpha1
kind: MonitorAccessPolicy
metadata:
name: policy-name
namespace: clusterpulse
spec:
identity:
priority: 100
subjects:
users: []
groups: []
serviceAccounts: []
access:
effect: Allow | Deny
enabled: true
scope:
clusters:
default: all | none | filtered
rules:
- selector: {}
permissions: {}
resources: {}
lifecycle:
validity:
notBefore: "2024-01-01T00:00:00Z"
notAfter: "2024-12-31T23:59:59Z"
Identity Section¶
Defines who the policy applies to and its evaluation priority.
Priority: Integer from 0-999. Lower values are evaluated first. When multiple policies match, the first Allow or Deny decision wins.
Subjects: Policies can target:
- Individual users by username or email
- Groups (resolved at request time from OpenShift)
- Service accounts by name and namespace
Access Section¶
Effect: Determines the authorization outcome when the policy matches.
| Effect | Behavior |
|---|---|
Allow |
Grant access with specified permissions and filters |
Deny |
Block access regardless of other policies |
Enabled: Boolean flag to enable/disable the policy without deleting it.
Scope Section¶
Defines which clusters and resources the policy covers.
Default Cluster Access:
| Value | Behavior |
|---|---|
all |
Access all clusters unless restricted by rules |
none |
Deny by default; only rules grant access |
filtered |
Apply rule-based filtering |
Rules: Array of cluster access rules, each containing:
selector: Label-based cluster matchingpermissions: Actions allowed on matching clustersresources: Resource-level filters
Resource Filters¶
Resources are defined as a list under each cluster rule. Both built-in types (nodes, namespaces, operators, pods, alerts, events) and custom types (any MetricSource resourceTypeName) use the same structure:
resources:
- type: nodes
visibility: all | none | filtered
filters:
labels:
env: production
- type: namespaces
visibility: filtered
filters:
names:
allowed:
- "app-*"
denied:
- "kube-system"
- type: operators
visibility: filtered
filters:
namespaces:
allowed:
- "operator-*"
names:
denied:
- "*-test"
- type: pods
visibility: filtered
filters:
namespaces:
allowed:
- "app-*"
Custom Resource Filters¶
Custom resources defined by MetricSource CRDs use the same resources list. The type field must match the MetricSource's rbac.resourceTypeName:
resources:
- type: pvc # resourceTypeName from MetricSource
visibility: filtered
filters:
namespaces:
allowed:
- "app-*"
denied:
- "kube-system"
names:
allowed:
- "data-*"
denied:
- "*-test"
fields:
storageClass:
allowed:
- "gp3"
- "io2"
phase:
denied:
- "Failed"
aggregations:
include:
- "totalStorage"
- "countByStorageClass"
exclude:
- "costEstimate"
Resource Filter Properties:
| Property | Description |
|---|---|
type |
Resource type name (nodes, pods, or a custom type like pvc) |
visibility |
all, none, or filtered |
filters.namespaces |
Filter by resource namespace |
filters.names |
Filter by resource name |
filters.labels |
Filter by Kubernetes labels |
filters.fields |
Filter by extracted field values (custom types only) |
aggregations.include |
Whitelist of visible aggregations (custom types only) |
aggregations.exclude |
Blacklist of hidden aggregations (custom types only) |
Decision Types¶
The RBAC engine returns one of three decisions:
| Decision | Description |
|---|---|
ALLOW |
Full access granted |
DENY |
Access blocked |
PARTIAL |
Access granted with filters applied |
A PARTIAL decision includes filters that restrict which resources are visible.
Filter Model¶
Filters control resource visibility when visibility: filtered is set:
flowchart TD
R[Resource] --> V{Visibility}
V -->|all| A[Show All]
V -->|none| N[Show None]
V -->|filtered| F{Apply Filters}
F --> E{In Exclude List?}
E -->|yes| N
E -->|no| I{In Include List?}
I -->|yes| A
I -->|no| P{Matches Pattern?}
P -->|yes| A
P -->|no| N
Filter Properties¶
| Property | Type | Description |
|---|---|---|
visibility |
enum | all, none, or filtered |
include |
set | Literal values to include |
exclude |
set | Literal values to exclude (takes precedence) |
patterns |
list | Wildcard patterns to match |
labels |
dict | Label selectors |
Pattern Syntax¶
| Pattern | Matches |
|---|---|
* |
Any characters |
? |
Single character |
app-* |
app-frontend, app-backend, etc. |
team-?-prod |
team-a-prod, team-b-prod, etc. |
Custom Resource Authorization¶
Custom resources follow a specialized authorization flow that integrates with the MetricSource-defined schema.
ResourceMatcher¶
Both built-in and custom resources use a unified ResourceMatcher for filtering:
| Dimension | Description |
|---|---|
| Namespaces | Filter by namespace (include/exclude with patterns) |
| Names | Filter by resource name (include/exclude with patterns) |
| Labels | Filter by Kubernetes labels |
| Fields | Filter by extracted field values (custom types only) |
CustomResourceDecision¶
The authorization decision for custom resources includes:
| Field | Type | Description |
|---|---|---|
decision |
enum | ALLOW, DENY, or PARTIAL |
resource_type_name |
string | The MetricSource resourceTypeName |
matcher |
ResourceMatcher | Applicable filters |
allowed_aggregations |
set | Aggregations user can see (null = all) |
denied_aggregations |
set | Aggregations hidden from user |
permissions |
set | Granted actions |
Aggregation Filtering¶
When filterAggregations: true in the MetricSource (default), aggregations are recomputed from the filtered resource set. Policies can additionally restrict which aggregation values are visible:
include: Only these aggregations are shownexclude: These aggregations are hidden- Include takes precedence over exclude
Storage Model¶
Policies are compiled and stored in Redis for fast evaluation:
flowchart LR
subgraph Kubernetes
CRD[MonitorAccessPolicy CRD]
end
subgraph Controller
PC[Policy Controller]
Compiler[Compiler]
end
subgraph Redis
Policy[policy:ns:name]
UserIdx[policy:user:username]
GroupIdx[policy:group:groupname]
SAIdx[policy:sa:account]
CustomIdx[policy:customtype:typename]
end
CRD --> PC
PC --> Compiler
Compiler --> Policy
Compiler --> UserIdx
Compiler --> GroupIdx
Compiler --> SAIdx
Compiler --> CustomIdx
Redis Key Patterns¶
| Pattern | Purpose |
|---|---|
policy:{namespace}:{name} |
Compiled policy data |
policy:user:{user} |
Policies indexed by user |
policy:group:{group} |
Policies indexed by group |
policy:sa:{serviceaccount} |
Policies indexed by service account |
policy:customtype:{typename} |
Policies indexed by custom resource type |
policies:all |
Set of all policy keys |
policies:enabled |
Set of enabled policy keys |
policies:by:priority |
Sorted set by priority |
Development Mode¶
Dev-mode auth bypass (dev-user principal) is only active when all of these are true:
ENVIRONMENT=developmentOAUTH_PROXY_ENABLED=falseENABLE_DEV_AUTH=true(explicit opt-in)
Caching¶
The RBAC engine supports optional decision caching:
- Decision cache key:
rbac:decision:{principal}:{action}:{resource} - Custom resource cache key:
rbac:custom:{principal}:{typename}:{cluster}:{action} - Configurable TTL (default: disabled for real-time evaluation)
- Automatically invalidated when policies change
Cache invalidation occurs when:
- A policy is created, updated, or deleted — clears
policy:eval:*,rbac:decision:*, andrbac:custom:*for affected users/groups - Manual cache clear via
POST /api/v1/auth/cache/clear— clears bothrbac:decision:*andrbac:custom:*
Related Documentation¶
- Policy Evaluation - Detailed evaluation algorithm
- RBAC Basics Tutorial - Hands-on introduction
- Create Read-Only Policy - Practical example
- Grant Custom Resource Access - Custom resource RBAC guide