OpenFGA Python SDK

0.10.0 · active · verified Mon Apr 13

The OpenFGA Python SDK provides a high-performance and flexible authorization/permission engine client, inspired by Google Zanzibar. It allows developers to integrate OpenFGA for fine-grained access control in their Python applications. The library is actively developed with frequent releases, typically every few weeks.

Warnings

Install

Imports

Quickstart

Initialize the OpenFGA client, write an authorization model tuple, and perform a check. This example demonstrates basic 'Write' and 'Check' operations. Ensure `FGA_API_URL` and `FGA_STORE_ID` (and authentication variables like `FGA_API_TOKEN`) are set in your environment. The provided `fga_store_id` is an example and must be replaced with a real one from your OpenFGA setup.

import os
from openfga_sdk import OpenFgaClient, Credentials
from openfga_sdk.models import WriteRequest, TupleKey, User, Relation, Object, CheckRequest

# Configure OpenFGA client using environment variables for sensitive data.
# Required: FGA_API_URL, FGA_STORE_ID
# Optional (for auth): FGA_API_TOKEN or FGA_CLIENT_ID/FGA_CLIENT_SECRET/FGA_TOKEN_URL/FGA_AUDIENCE

fga_api_url = os.environ.get("FGA_API_URL", "http://localhost:8080")
fga_store_id = os.environ.get("FGA_STORE_ID", "01H4F8G5K4S8K7J2G8R1T0V9M0") # Replace with your actual Store ID

credentials = None
api_token = os.environ.get("FGA_API_TOKEN")
if api_token:
    credentials = Credentials(api_token=api_token)
elif os.environ.get("FGA_CLIENT_ID") and os.environ.get("FGA_CLIENT_SECRET"):
    # Example for Client Credentials flow with OAuth2 (replace with your IdP details)
    credentials = Credentials(
        client_id=os.environ.get("FGA_CLIENT_ID", ""),
        client_secret=os.environ.get("FGA_CLIENT_SECRET", ""),
        token_url=os.environ.get("FGA_TOKEN_URL", "https://auth.fga.example.com/oauth/token"),
        audience=os.environ.get("FGA_AUDIENCE", fga_api_url) # Audience often matches API URL
    )

if not fga_store_id:
    raise ValueError("FGA_STORE_ID environment variable is required.")

client = OpenFgaClient(
    api_url=fga_api_url,
    store_id=fga_store_id,
    credentials=credentials,
)

try:
    # 1. Write a relationship: "user:anne can view document:roadmap"
    write_response = client.write(
        body=WriteRequest(
            writes=[
                TupleKey(
                    user=User(id="anne"),
                    relation="viewer",
                    object=Object(type="document", id="roadmap")
                )
            ]
        )
    )
    print(f"Wrote relationship: user:anne is viewer of document:roadmap")

    # 2. Check if "user:anne can view document:roadmap"
    check_response = client.check(
        body=CheckRequest(
            user=User(id="anne"),
            relation="viewer",
            object=Object(type="document", id="roadmap")
        )
    )
    print(f"Check result (anne can view roadmap): {check_response.allowed}") # Expected: True

    # 3. Check if "user:bob can view document:roadmap" (assuming bob has no relation)
    check_response_bob = client.check(
        body=CheckRequest(
            user=User(id="bob"),
            relation="viewer",
            object=Object(type="document", id="roadmap")
        )
    )
    print(f"Check result (bob can view roadmap): {check_response_bob.allowed}") # Expected: False

except Exception as e:
    print(f"An error occurred: {e}")

# The client uses an httpx.Client which is typically managed internally.
# No explicit close() is necessary for OpenFgaClient as of v0.10.0 in most cases.

view raw JSON →