Skip to content

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., owner implies member)
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)]
Hold "Alt" / "Option" to enable pan & zoom

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:

  1. Defines a resource type with standard relations
  2. 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
Hold "Alt" / "Option" to enable pan & zoom

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.comfoo_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)]
Hold "Alt" / "Option" to enable pan & zoom

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)
Hold "Alt" / "Option" to enable pan & zoom
  1. Fetch APIExportEndpointSlice named core.platform-mesh.io
  2. Read status.apiExportEndpoints[0].url (virtual workspace URL)
  3. Append /clusters/* to build a wildcard client
  4. 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]
Hold "Alt" / "Option" to enable pan & zoom
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