Authorization Model¶
OpenFGA uses authorization models to define what types of objects exist and what relations are possible between them. In Platform-Mesh, the Security Operator manages these models, combining a core module with dynamically generated modules for each API resource.
Overview¶
An OpenFGA authorization model consists of:
- Types - Categories of objects (e.g.,
account,namespace,deployment) - Relations - How users or objects relate to each other (e.g.,
owner,member,parent) - Rules - How relations derive from other relations (e.g.,
ownerimpliesmember)
graph TB
subgraph "Authorization Model"
Core[Core Module]
API1[API Module: deployments]
API2[API Module: cowboys]
API3[API Module: ...]
end
Core --> |base types| Model[(Combined Model)]
API1 --> Model
API2 --> Model
API3 --> Model
Model --> Store[(OpenFGA Store)]
Model Structure¶
Core Module¶
The core module defines the foundational types used across all Platform-Mesh workspaces:
| Type | Purpose |
|---|---|
user |
End users (identity) |
role |
Named roles with assignees |
core_platform-mesh_io_account |
Account/workspace container |
core_namespace |
Kubernetes namespace |
These types include base relations like owner, member, and parent that API modules extend.
API Modules¶
Each API resource (from APIResourceSchemas) gets its own module that:
- Defines a resource type with standard relations
- Extends the parent type with collection-level relations
Type Hierarchy¶
Platform-Mesh uses a hierarchical model where permissions flow from parent to child:
graph TD
Account[core_platform-mesh_io_account] -->|parent| Namespace[core_namespace]
Account -->|parent| ClusterResource[Cluster-scoped Resource]
Namespace -->|parent| NamespacedResource[Namespaced Resource]
User[user] -->|assignee| Role[role]
Role -->|owner/member| Account
The parent relation enables permission inheritance - if you're an owner of an account, you inherit owner on its namespaces and resources.
Relations¶
Base Relations¶
Every type in the model supports these core relations:
| Relation | Definition | Purpose |
|---|---|---|
parent |
Direct link to parent object | Hierarchy structure |
owner |
[role#assignee] or owner from parent |
Full control, inherited |
member |
[role#assignee] or owner or member from parent |
Read access, inherited |
Verb Relations¶
Resource types include relations for Kubernetes verbs:
| Relation | Grants To | Purpose |
|---|---|---|
get |
member |
Read single |
list |
member |
Read collection |
watch |
member |
Watch changes |
create |
owner |
Create new |
update |
member |
Modify existing |
delete |
member |
Remove |
patch |
member |
Partial update |
Collection Relations¶
Parent types (account or namespace) define relations for collection-level operations:
| Relation | Definition | Purpose |
|---|---|---|
create_<group>_<plural> |
owner |
Create new resources |
list_<group>_<plural> |
member |
List resources |
watch_<group>_<plural> |
member |
Watch resources |
IAM Relations¶
Resources include relations for managing access:
| Relation | Grants To | Purpose |
|---|---|---|
manage_iam_roles |
owner |
Manage roles on the resource |
get_iam_roles |
member |
View roles |
get_iam_users |
member |
View users |
Naming Conventions¶
When generating type and relation names from Kubernetes resources:
| Element | Format | Example |
|---|---|---|
| Module name | <plural> |
cowboys |
| Resource type | <group>_<singular> |
wildwest_dev_cowboy |
| Group normalization | Dots replaced with underscores | foo.bar.com → foo_bar_com |
| Max length | Group truncated if exceeds 50 chars | - |
API Versions
The model generator ignores API versions. It only uses group, scope, and names. Publishing v1alpha1 and v1alpha2 produces identical model definitions.
Dynamic Model Generation¶
The Security Operator dynamically generates model modules when APIs are bound to workspaces via APIBindings.
Trigger: APIBinding¶
graph LR
APIBinding -->|triggers| Generator
Generator -->|reads| APIResourceSchema
Generator -->|produces| DSLModule[DSL Module]
DSLModule -->|written to| OrgStore[(Org Store)]
The controller watches APIBindings across clusters via the APIExport virtual workspace. It does not globally watch APIExports or APIResourceSchemas.
Discovery Process¶
sequenceDiagram
participant Controller
participant APIExportEndpointSlice
participant VirtualWorkspace
participant Clusters
Controller->>APIExportEndpointSlice: Fetch core.platform-mesh.io
APIExportEndpointSlice-->>Controller: status.apiExportEndpoints[0].url
Controller->>VirtualWorkspace: Append /clusters/*
Controller->>Clusters: Watch APIBindings (multicluster-runtime)
- Fetch
APIExportEndpointSlicenamedcore.platform-mesh.io - Read
status.apiExportEndpoints[0].url(virtual workspace URL) - Append
/clusters/*to build a wildcard client - Use multicluster-runtime to reconcile APIBindings in all clusters
Model Update Process¶
When an APIBinding is reconciled:
flowchart TD
A[APIBinding reconciled] --> B[Read AccountInfo]
B --> C[Get org store reference]
C --> D[Resolve APIExport cluster]
D --> E[Fetch APIResourceSchemas]
E --> F[Generate DSL modules]
F --> G[Create/Update AuthorizationModel CR]
G --> H[Set storeRef to org store]
| Step | Data Source | Output |
|---|---|---|
| 1 | AccountInfo in binding workspace |
organization.name, organization.originClusterId |
| 2 | binding.status.apiExportClusterName |
APIExport cluster |
| 3 | apiExport.spec.latestResourceSchemas |
List of schemas |
| 4 | DSL template | Generated module |
| 5 | AuthorizationModel CR | spec.storeRef → org store |
Result¶
- New DSL modules are added for the bound APIResourceSchemas
- The org's Store receives a new authorization model ID
- The Authorization Webhook can now check relations for the newly bound resources
Example: Generated Module¶
An APIExport wildwest.dev publishes an APIResourceSchema:
| Field | Value |
|---|---|
| Group | wildwest.dev |
| Kind | Cowboy |
| Plural | cowboys |
| Singular | cowboy |
Namespaced Resource¶
module cowboys
extend type core_namespace
relations
define create_wildwest_dev_cowboys: owner
define list_wildwest_dev_cowboys: member
define watch_wildwest_dev_cowboys: member
type wildwest_dev_cowboy
relations
define parent: [core_namespace]
define member: [role#assignee] or owner or member from parent
define owner: [role#assignee] or owner from parent
define get: member
define update: member
define delete: member
define patch: member
define watch: member
define manage_iam_roles: owner
define get_iam_roles: member
define get_iam_users: member
Cluster-Scoped Resource¶
module cowboys
extend type core_platform-mesh_io_account
relations
define create_wildwest_dev_cowboys: owner
define list_wildwest_dev_cowboys: member
define watch_wildwest_dev_cowboys: member
type wildwest_dev_cowboy
relations
define parent: [core_platform-mesh_io_account]
define member: [role#assignee] or owner or member from parent
define owner: [role#assignee] or owner from parent
define get: member
define update: member
define delete: member
define patch: member
define watch: member
define manage_iam_roles: owner
define get_iam_roles: member
define get_iam_users: member