OpenFGA Documentation

June 22, 2026 · View on GitHub

This document provides comprehensive guidance on managing OpenFGA stores and authorization models in the LFX Platform, including how to create, update, and query stores and models using both the fga-operator and direct CLI commands.

Overview

OpenFGA (Open Fine-Grained Authorization) is a modern authorization system that provides flexible, high-performance authorization for applications. The LFX Platform uses OpenFGA for managing authorization models and stores through the fga-operator.

Architecture

The fga-operator automates the synchronization between your Kubernetes deployments and OpenFGA authorization models. It provides:

  • AuthorizationModelRequest: Defines authorization models and creates stores
  • Store: Kubernetes resource representing an OpenFGA store
  • AuthorizationModel: Kubernetes resource representing an authorization model
  • Automatic Deployment Updates: Updates deployments with latest model IDs

Quick Start

1. Verify the Model Deployed

The LFX Platform includes a pre-configured authorization model that's automatically deployed when you install the chart. The canonical model DSL lives in charts/lfx-platform/files/model.fga; the Helm template at charts/lfx-platform/templates/openfga/model.yaml injects it along with the versioning metadata. Check that it deployed successfully:

# Check AuthorizationModelRequest status
kubectl get AuthorizationModelRequest -n lfx

# Check Store resource
kubectl get Store -n lfx

# Check AuthorizationModel resource
kubectl get AuthorizationModel -n lfx

2. View the Authorization Model Details

Get detailed information about the deployed authorization model:

# Get the store name from values (default is 'lfx-core')
STORE_NAME=$(helm get values lfx-platform -n lfx -o json | jq -r '.["fga-operator"].store // "lfx-core"')

# View the authorization model details
kubectl get AuthorizationModel/$STORE_NAME -n lfx -o yaml

This will show you the model ID, version, and the complete authorization model definition.

Managing Stores and Models

Listing Stores

Use the fga-cli to list all stores:

kubectl run --rm -it fga-cli --namespace lfx --image=openfga/cli --env="FGA_API_URL=http://lfx-platform-openfga:8080" --restart=Never -- store list

Listing Models

List all authorization models for a specific store:

# First, get the store ID
STORE_ID="$(kubectl get Store lfx-core -n lfx -o jsonpath='{.spec.id}')"

# Then list models
kubectl run --rm -it fga-cli --namespace lfx --image=openfga/cli --env="FGA_STORE_ID=$STORE_ID" --env="FGA_API_URL=http://lfx-platform-openfga:8080" --restart=Never -- model list

Getting Model Details

Get detailed information about a specific model:

# Get model details (replace MODEL_ID with actual ID)
kubectl run --rm -it fga-cli --namespace lfx --image=openfga/cli --env="FGA_STORE_ID=$STORE_ID" --env="FGA_API_URL=http://lfx-platform-openfga:8080" --restart=Never -- model get --id MODEL_ID

Updating Authorization Models

To update the authorization model:

  1. Edit the model DSL in charts/lfx-platform/files/model.fga — this is the single source of truth.

  2. Increment the version in charts/lfx-platform/templates/openfga/model.yaml:

    instances:
      - version:
          major: X      # bump the appropriate component
          minor: Y
          patch: Z
        authorizationModel: |
    

{{ .Files.Get "files/model.fga" | indent 8 }}

Note: the `{{ .Files.Get ... }}` line starts at column 0 in the template
file — `indent 8` provides the required indentation for the YAML block scalar.

CI will fail if `files/model.fga` changes without any corresponding change to `model.yaml`. The version bump itself is a social contract — CI verifies the files were edited together, not that the numbers were incremented.

3. **Regenerate `PERMISSIONS.md`** by running the render-permissions agent skill to keep the human-readable permissions reference in sync.

4. **Redeploy the chart** to apply the changes:
```bash
helm upgrade lfx-platform ./charts/lfx-platform -n lfx

The fga-operator will automatically detect the version change and create a new authorization model in OpenFGA while keeping the existing model for backward compatibility.

Deployment Integration

Automatic Environment Variable Updates

The fga-operator automatically updates deployments with the openfga-store label. When you create or update an authorization model, the operator will:

  1. Update the OPENFGA_AUTH_MODEL_ID environment variable
  2. Update the OPENFGA_STORE_ID environment variable
  3. Add annotations with timestamps and version information

Example Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami
  namespace: lfx
  labels:
    openfga-store: lfx-core
    # Set a version to use a specific model
    # openfga-auth-model-version: 1.2.3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: whoami
  template:
    metadata:
      labels:
        app: whoami
    spec:
      containers:
      - name: api
        image: traefik/whoami:latest
        env:
        - name: OPENFGA_API_URL
          value: "http://lfx-platform-openfga:8080"
        # OPENFGA_AUTH_MODEL_ID and OPENFGA_STORE_ID will be automatically set

Checking Deployment Updates

Verify that your deployment updated with the latest model information:

# Check environment variables
kubectl get deployment whoami -n lfx -o jsonpath='{.spec.template.spec.containers[0].env}'

# Check annotations
kubectl get deployment whoami -n lfx -o jsonpath='{.metadata.annotations}'

Querying Authorization Data

Writing Tuples

Add authorization relationships:

# Add a user as owner of a project
kubectl run --rm -it fga-cli --namespace lfx --image=openfga/cli --env="FGA_STORE_ID=$STORE_ID" --env="FGA_API_URL=http://lfx-platform-openfga:8080" --restart=Never -- tuple write --tuple "user:john@example.com:owner:project:project1"

Reading Tuples

Query existing relationships:

# List all tuples
kubectl run --rm -it fga-cli --namespace lfx --image=openfga/cli --env="FGA_STORE_ID=$STORE_ID" --env="FGA_API_URL=http://lfx-platform-openfga:8080" --restart=Never -- tuple read

# Query specific relationships
kubectl run --rm -it fga-cli --namespace lfx --image=openfga/cli --env="FGA_STORE_ID=$STORE_ID" --env="FGA_API_URL=http://lfx-platform-openfga:8080" --restart=Never -- tuple read --tuple "user:john@example.com:owner:project:project1"

Checking Authorization

Test authorization decisions:

# Check if a user can write to a project (a tuple-dependent relation).
# Note: `project#viewer` is public in the model (`define viewer: [user:*] ...`),
# so a `viewer` check always returns allowed even with no tuples. Use a
# restrictive relation like `writer` or `auditor` for a meaningful check that
# actually validates the tuples you have written.
kubectl run --rm -it fga-cli --namespace lfx --image=openfga/cli --env="FGA_STORE_ID=$STORE_ID" --env="FGA_API_URL=http://lfx-platform-openfga:8080" --restart=Never -- check --tuple "user:john@example.com:writer:project:project1"

Advanced Topics

Events and Monitoring

Monitor operator events:

# Check events
kubectl get events -n lfx --sort-by='.lastTimestamp'

# Check specific resource events
kubectl describe AuthorizationModelRequest lfx-core -n lfx

References