Skip to content

ReBAC with OpenFGA

Relationship-Based Access Control (ReBAC) is the authorization model used in Platform-Mesh to determine whether a user can perform an action on a resource. Unlike traditional Role-Based Access Control (RBAC), ReBAC evaluates permissions based on the relationships between entities.

What is ReBAC?

ReBAC answers the question: "Does user X have relation Y to object Z?"

Instead of assigning permissions directly to users or roles, ReBAC models access through relationships:

  • A user can be an owner of an account
  • An account can be a parent of another account
  • A resource can belong to a namespace

These relationships form a graph that can be traversed to determine access. For example, if a user is an owner of account A, and account A is the parent of account B, the user may inherit certain permissions on account B.

OpenFGA

OpenFGA is an open-source authorization engine that implements ReBAC. Platform-Mesh uses OpenFGA to:

  • Store authorization models - Define what types of objects exist and what relations are possible
  • Store tuples - Record the actual relationships between users and objects
  • Evaluate checks - Answer "can user X do Y on object Z?" queries
graph LR
    subgraph "OpenFGA"
        Model[Authorization Model]
        Tuples[(Tuples)]
        Check{Check API}
    end

    Model --> Check
    Tuples --> Check
    Request[Can user X do Y on Z?] --> Check
    Check --> Response[allowed: true/false]
Hold "Alt" / "Option" to enable pan & zoom

Components

The ReBAC implementation in Platform-Mesh involves three components:

Security Operator

The Security Operator is responsible for managing the authorization infrastructure in OpenFGA. While the Security Operator has broader responsibilities in the platform, its ReBAC-related duties include:

  • Creating and managing OpenFGA stores
  • Writing authorization models that define object types and relations
  • Optionally writing baseline tuples (e.g., authenticated user membership)

Learn more about Security Operator's FGA integration →

Account Operator

The Account Operator manages account lifecycle in the platform. As part of this responsibility, it maintains the authorization relationships for accounts in OpenFGA:

  • Assigning account creators to owner roles
  • Establishing parent-child relationships between accounts
  • Cleaning up tuples when accounts are deleted

Learn more about Account Operator's FGA integration →

Authorization Webhook

The Authorization Webhook is the component that actually enforces ReBAC. It intercepts every authorization request (SubjectAccessReview) from kcp and queries OpenFGA to determine if the request should be allowed.

Learn more about the Authorization Webhook →

IAM Service

The IAM Service manages user role assignments and writes the corresponding OpenFGA tuples. It also creates Invite resources when a user does not exist in the IDM system.

Learn more about IAM Service role assignment →

How It All Fits Together

sequenceDiagram
    participant User
    participant kcp
    participant Webhook
    participant OpenFGA

    Note over Security Operator: Creates stores & models
    Security Operator->>OpenFGA: WriteAuthorizationModel

    Note over Account Operator: Account created
    Account Operator->>OpenFGA: WriteTuples (owner, parent)

    User->>kcp: kubectl get apibindings
    kcp->>Webhook: SubjectAccessReview
    Webhook->>OpenFGA: Check(user, list_apibindings, account)
    OpenFGA-->>Webhook: allowed: true
    Webhook-->>kcp: allowed: true
    kcp-->>User: apibindings list
Hold "Alt" / "Option" to enable pan & zoom
  1. Security Operator sets up the authorization model defining what relations exist
  2. Account Operator writes tuples when accounts are created, establishing ownership
  3. Authorization Webhook queries OpenFGA for every access request
  4. OpenFGA evaluates the request against the model and tuples, returning allow/deny

Component Diagram

graph TB
  %% Users / Clients
  Kubectl[kubectl / CLI]
  User[Portal User]

  %% UI & API
  Portal[Portal UI]
  GraphQLGW[Kubernetes GraphQL Gateway]
  IAMService[IAM Service GraphQL]
  KCP[kcp Control Planes]

  %% AuthZ / ReBAC
  Webhook[ReBAC Authorization Webhook]
  OpenFGA[OpenFGA]
  Keycloak[Keycloak IDM]

  %% Operators / Controllers
  AccountOp[Account Operator]
  SecurityOp[Security Operator]
  ExtensionCtl[Extension Controller]

  %% Stores / Models / Tuples
  Store[(OpenFGA Store)]
  Model[(Authorization Model)]
  Tuples[(Tuples)]

  %% Auth / Identity
  User --> Kubectl
  User --> Portal

  Portal --> GraphQLGW
  GraphQLGW -->|CRUD/query| KCP
  GraphQLGW --> IAMService
  Kubectl --> KCP

  %% GraphQL authz path
  IAMService -->|creates Invite CR| KCP
  IAMService -->|authorized directive| OpenFGA
  IAMService -->|invite user| Keycloak

  %% kcp authz path
  KCP -->|SubjectAccessReview| Webhook
  Webhook -->|Check| OpenFGA
  Webhook -->|Allow/Deny| KCP

  %% Operators writing FGA data
  AccountOp -->|account tuples| OpenFGA
  SecurityOp -->|store + model + tuples| OpenFGA
  IAMService -->|role assignment tuples| OpenFGA

  %% Operators watching kcp
  AccountOp --> KCP
  SecurityOp --> KCP
  ExtensionCtl --> KCP

  %% OpenFGA internal structure
  OpenFGA --> Store
  OpenFGA --> Model
  OpenFGA --> Tuples

  %% classDef user fill:#c4e0ff,stroke:#2b6cb0,stroke-width:2px,color:#1a365d
  %% class User user
Hold "Alt" / "Option" to enable pan & zoom