API Client - evansims/openfga-php GitHub Wiki

OpenFGA Client implementation for relationship-based access control operations. This client provides a complete implementation of the OpenFGA API, supporting all core operations including store management, authorization model configuration, relationship tuple operations, and authorization checks. The client uses PSR-7, PSR-17 and PSR-18 HTTP standards and implements the Result pattern for error handling. The client supports multiple authentication methods including OAuth 2.0 Client Credentials flow and pre-shared key authentication, with automatic token management and retry capabilities for reliable operation.

Table of Contents


Namespace

OpenFGA


Source

View source code


Implements


Related Classes


Constants

Name Value Description
VERSION 1.4.0 The version of the OpenFGA PHP SDK.


Methods

batchCheck

public function batchCheck(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\AuthorizationModelInterface|string $model,
    OpenFGA\Models\Collections\BatchCheckItemsInterface $checks,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Performs multiple authorization checks in a single batch request. This method allows checking multiple user-object relationships simultaneously for better performance when multiple authorization decisions are needed. Each check in the batch has a correlation ID to map results back to the original requests. The batch check operation supports the same features as individual checks: contextual tuples, custom contexts, and detailed error information for each check.

Batch checking multiple permissions efficiently:

$checks = new BatchCheckItems([
    new BatchCheckItem(
        tupleKey: new TupleKey('user:anne', 'viewer', 'document:budget'),
        correlationId: 'check-anne-viewer'
    ),
    new BatchCheckItem(
        tupleKey: new TupleKey('user:bob', 'editor', 'document:budget'),
        correlationId: 'check-bob-editor'
    ),
    new BatchCheckItem(
        tupleKey: new TupleKey('user:charlie', 'owner', 'document:roadmap'),
        correlationId: 'check-charlie-owner'
    ),
]);

$result = $client->batchCheck(
    store: 'store-id',
    model: 'model-id',
    checks: $checks
);

if ($result->success()) {
    $responses = $result->value()->getResults();
    foreach ($responses as $response) {
        echo $response->getCorrelationId() . ': ' .
             ($response->getAllowed() ? 'ALLOWED' : 'DENIED') . "\n";
    }
}

View source


Parameters

Name Type Description
$store StoreInterface | string The store to check against
$model AuthorizationModelInterface | string The authorization model to use
$checks BatchCheckItemsInterface The batch check items

Returns

FailureInterface | SuccessInterface — The batch check results


check

public function check(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\AuthorizationModelInterface|string $model,
    OpenFGA\Models\TupleKeyInterface $tupleKey,
    ?bool $trace = NULL,
    ?object $context = NULL,
    ?OpenFGA\Models\Collections\TupleKeysInterface $contextualTuples = NULL,
    ?OpenFGA\Models\Enums\Consistency $consistency = NULL,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Checks if a user has a specific relationship with an object. Performs an authorization check to determine if a user has a particular relationship with an object based on the configured authorization model. This is the core operation for making authorization decisions in OpenFGA.

Basic permission check:

$result = $client->check(
    store: 'store-id',
    model: 'model-id',
    tupleKey: new TupleKey('user:anne', 'reader', 'document:budget')
);

if ($result->success()) {
    $allowed = $result->value()->getAllowed();
    if ($allowed) {
        // User has permission
    }
}

Check with contextual tuples:

$contextualTuples = new TupleKeys([
    new TupleKey('user:anne', 'member', 'team:finance')
]);

$result = $client->check(
    store: 'store-id',
    model: 'model-id',
    tupleKey: new TupleKey('user:anne', 'reader', 'document:budget'),
    contextualTuples: $contextualTuples
);

View source


Parameters

Name Type Description
$store StoreInterface | string The store to check against
$model AuthorizationModelInterface | string The authorization model to use
$tupleKey TupleKeyInterface The relationship to check
$trace bool | null Whether to include a trace in the response
$context object | null Additional context for the check
$contextualTuples TupleKeysInterface | null Additional tuples for contextual evaluation
$consistency Consistency | null Override the default consistency level

Returns

FailureInterface | SuccessInterface — Success contains CheckResponseInterface, Failure contains Throwable


createAuthorizationModel

public function createAuthorizationModel(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\Collections\TypeDefinitionsInterface $typeDefinitions,
    ?OpenFGA\Models\Collections\ConditionsInterface $conditions = NULL,
    OpenFGA\Models\Enums\SchemaVersion $schemaVersion = OpenFGA\Models\Enums\SchemaVersion::V1_1,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Creates a new authorization model with the given type definitions and conditions. Authorization models define the permission structure for your application, including object types, relationships, and how permissions are computed. Models are immutable once created and identified by a unique ID.

Creating a document authorization model with DSL (recommended):

// Using DSL is usually easier than manually building type definitions
$dsl = '
    model
      schema 1.1

    type user

    type document
      relations
        define owner: [user]
        define editor: [user] or owner
        define viewer: [user] or editor
';

$authModel = $client->dsl($dsl)->unwrap();
$result = $client->createAuthorizationModel(
    store: 'store-id',
    typeDefinitions: $authModel->getTypeDefinitions()
);

if ($result->success()) {
    $modelId = $result->value()->getAuthorizationModelId();
    echo "Created model: {$modelId}";
}

View source


Parameters

Name Type Description
$store StoreInterface | string The store to create the model in
$typeDefinitions TypeDefinitionsInterface The type definitions for the model
$conditions ConditionsInterface | null The conditions for the model
$schemaVersion SchemaVersion The schema version to use (default: 1.1)

Returns

FailureInterface | SuccessInterface — Success contains CreateAuthorizationModelResponseInterface, Failure contains Throwable


createStore

public function createStore(string $name): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Creates a new store with the given name. Stores provide data isolation for different applications or environments. Each store maintains its own authorization models, relationship tuples, and provides complete separation from other stores.

View source


Parameters

Name Type Description
$name string The name for the new store

Returns

FailureInterface | SuccessInterface — Success contains CreateStoreResponseInterface, Failure contains Throwable


deleteStore

public function deleteStore(
    OpenFGA\Models\StoreInterface|string $store,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Deletes a store.

View source


Parameters

Name Type Description
$store StoreInterface | string The store to delete

Returns

FailureInterface | SuccessInterface — Success contains DeleteStoreResponseInterface, Failure contains Throwable


dsl

public function dsl(string $dsl): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Parses a DSL string and returns an AuthorizationModel. The Domain Specific Language (DSL) provides a human-readable way to define authorization models using intuitive syntax for relationships and permissions. This method converts DSL text into a structured authorization model object.

Parse a complete authorization model from DSL:

$dsl = '
    model
      schema 1.1

    type user

    type organization
      relations
        define member: [user]

    type document
      relations
        define owner: [user]
        define editor: [user, organization#member] or owner
        define viewer: [user, organization#member] or editor
';

$result = $client->dsl($dsl);

if ($result->success()) {
    $authModel = $result->value();
    echo "Parsed model with " . count($authModel->getTypeDefinitions()) . " types";
}

View source


Parameters

Name Type Description
$dsl string The DSL string to parse

Returns

FailureInterface | SuccessInterface — Success contains AuthorizationModelInterface, Failure contains Throwable


expand

public function expand(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\TupleKeyInterface $tupleKey,
    ?OpenFGA\Models\AuthorizationModelInterface|string|null $model = NULL,
    ?OpenFGA\Models\Collections\TupleKeysInterface $contextualTuples = NULL,
    ?OpenFGA\Models\Enums\Consistency $consistency = NULL,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Expands a relationship tuple to show all users that have the relationship.

View source


Parameters

Name Type Description
$store StoreInterface | string The store containing the tuple
$tupleKey TupleKeyInterface The tuple to expand
$model AuthorizationModelInterface | null | string | null The authorization model to use
$contextualTuples TupleKeysInterface | null Additional tuples for contextual evaluation
$consistency Consistency | null Override the default consistency level

Returns

FailureInterface | SuccessInterface — Success contains ExpandResponseInterface, Failure contains Throwable


getAuthorizationModel

public function getAuthorizationModel(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\AuthorizationModelInterface|string $model,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Retrieves an authorization model by ID.

View source


Parameters

Name Type Description
$store StoreInterface | string The store containing the model
$model AuthorizationModelInterface | string The model to retrieve

Returns

FailureInterface | SuccessInterface — Success contains GetAuthorizationModelResponseInterface, Failure contains Throwable


getLanguage

public function getLanguage(): string

Get the configured language for i18n translations.

View source


Returns

string — The configured language code


getLanguageEnum

public function getLanguageEnum(): Language

Get the configured language enum for type-safe access. Returns the Language enum representing the currently configured language, providing access to language metadata and type-safe operations.

View source


Returns

Language — The configured language enum


getLastRequest

public function getLastRequest(): ?Psr\Http\Message\RequestInterface

Retrieves the last HTTP request made by the client.

View source


Returns

Psr\Http\Message\RequestInterface | null


getLastResponse

public function getLastResponse(): ?Psr\Http\Message\ResponseInterface

Retrieves the last HTTP response received by the client.

View source


Returns

Psr\Http\Message\ResponseInterface | null


getStore

public function getStore(
    OpenFGA\Models\StoreInterface|string $store,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Retrieves store details by ID.

View source


Parameters

Name Type Description
$store StoreInterface | string The store to retrieve

Returns

FailureInterface | SuccessInterface — Success contains GetStoreResponseInterface, Failure contains Throwable


listAuthorizationModels

public function listAuthorizationModels(
    OpenFGA\Models\StoreInterface|string $store,
    ?string $continuationToken = NULL,
    ?int $pageSize = NULL,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Lists authorization models in a store with pagination.

View source


Parameters

Name Type Description
$store StoreInterface | string The store to list models from
$continuationToken string | null Token for pagination
$pageSize int | null Maximum number of models to return (must be positive)

Returns

FailureInterface | SuccessInterface — Success contains ListAuthorizationModelsResponseInterface, Failure contains Throwable


listObjects

public function listObjects(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\AuthorizationModelInterface|string $model,
    string $type,
    string $relation,
    string $user,
    ?object $context = NULL,
    ?OpenFGA\Models\Collections\TupleKeysInterface $contextualTuples = NULL,
    ?OpenFGA\Models\Enums\Consistency $consistency = NULL,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Lists objects that have a specific relationship with a user.

List all documents a user can view:

$result = $client->listObjects(
    store: 'store-id',
    model: 'model-id',
    type: 'document',
    relation: 'viewer',
    user: 'user:anne'
);

if ($result->success()) {
    $objects = $result->value()->getObjects();
    echo "Anne can view " . count($objects) . " documents:\n";
    foreach ($objects as $object) {
        echo "- {$object}\n";
    }
}

List objects with contextual evaluation:

// Check what documents anne can edit, considering her team membership
$contextualTuples = new TupleKeys([
    new TupleKey('user:anne', 'member', 'team:engineering')
]);

$result = $client->listObjects(
    store: 'store-id',
    model: 'model-id',
    type: 'document',
    relation: 'editor',
    user: 'user:anne',
    contextualTuples: $contextualTuples
);
/

View source


Parameters

Name Type Description
$store StoreInterface | string The store to query
$model AuthorizationModelInterface | string The authorization model to use
$type string The type of objects to list
$relation string The relationship to check
$user string The user to check relationships for
$context object | null Additional context for evaluation
$contextualTuples TupleKeysInterface | null Additional tuples for contextual evaluation
$consistency Consistency | null Override the default consistency level

Returns

FailureInterface | SuccessInterface — Success contains ListObjectsResponseInterface, Failure contains Throwable


listStores

public function listStores(
    ?string $continuationToken = NULL,
    ?int $pageSize = NULL,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Lists all stores with pagination.

View source


Parameters

Name Type Description
$continuationToken string | null Token for pagination
$pageSize int | null Maximum number of stores to return

Returns

FailureInterface | SuccessInterface — Success contains ListStoresResponseInterface, Failure contains Throwable


listTupleChanges

public function listTupleChanges(
    OpenFGA\Models\StoreInterface|string $store,
    ?string $continuationToken = NULL,
    ?int $pageSize = NULL,
    ?string $type = NULL,
    ?DateTimeImmutable $startTime = NULL,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Lists changes to relationship tuples in a store.

View source


Parameters

Name Type Description
$store StoreInterface | string The store to list changes for
$continuationToken string | null Token for pagination
$pageSize int | null Maximum number of changes to return
$type string | null Filter changes by type
$startTime DateTimeImmutable | null Only include changes at or after this time (inclusive)

Returns

FailureInterface | SuccessInterface — Success contains ListTupleChangesResponseInterface, Failure contains Throwable


listUsers

public function listUsers(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\AuthorizationModelInterface|string $model,
    string $object,
    string $relation,
    OpenFGA\Models\Collections\UserTypeFiltersInterface $userFilters,
    ?object $context = NULL,
    ?OpenFGA\Models\Collections\TupleKeysInterface $contextualTuples = NULL,
    ?OpenFGA\Models\Enums\Consistency $consistency = NULL,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Lists users that have a specific relationship with an object.

List all users who can view a document:

$userFilters = new UserTypeFilters([
    new UserTypeFilter('user') // Only include direct users, not groups
]);

$result = $client->listUsers(
    store: 'store-id',
    model: 'model-id',
    object: 'document:budget',
    relation: 'viewer',
    userFilters: $userFilters
);

if ($result->success()) {
    $users = $result->value()->getUsers();
    echo "Users who can view the budget document:\n";
    foreach ($users as $user) {
        echo "- {$user}\n";
    }
}

Find both users and groups with access:

$userFilters = new UserTypeFilters([
    new UserTypeFilter('user'),
    new UserTypeFilter('group')
]);

$result = $client->listUsers(
    store: 'store-id',
    model: 'model-id',
    object: 'document:sensitive',
    relation: 'editor',
    userFilters: $userFilters
);
/

View source


Parameters

Name Type Description
$store StoreInterface | string The store to query
$model AuthorizationModelInterface | string The authorization model to use
$object string The object to check relationships for
$relation string The relationship to check
$userFilters UserTypeFiltersInterface Filters for user types to include
$context object | null Additional context for evaluation
$contextualTuples TupleKeysInterface | null Additional tuples for contextual evaluation
$consistency Consistency | null Override the default consistency level

Returns

FailureInterface | SuccessInterface — Success contains ListUsersResponseInterface, Failure contains Throwable


readAssertions

public function readAssertions(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\AuthorizationModelInterface|string $model,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Retrieves assertions for an authorization model.

View source


Parameters

Name Type Description
$store StoreInterface | string The store containing the model
$model AuthorizationModelInterface | string The model to get assertions for

Returns

FailureInterface | SuccessInterface — Success contains ReadAssertionsResponseInterface, Failure contains Throwable


readTuples

public function readTuples(
    OpenFGA\Models\StoreInterface|string $store,
    ?OpenFGA\Models\TupleKeyInterface $tupleKey = NULL,
    ?string $continuationToken = NULL,
    ?int $pageSize = NULL,
    ?OpenFGA\Models\Enums\Consistency $consistency = NULL,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Reads relationship tuples from a store with optional filtering and pagination.

View source


Parameters

Name Type Description
$store StoreInterface | string The store to read from
$tupleKey TupleKeyInterface | null Filter tuples by this key (return all if null)
$continuationToken string | null Token for pagination
$pageSize int | null Maximum number of tuples to return
$consistency Consistency | null Override the default consistency level

Returns

FailureInterface | SuccessInterface — Success contains ReadTuplesResponseInterface, Failure contains Throwable


streamedListObjects

public function streamedListObjects(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\AuthorizationModelInterface|string $model,
    string $type,
    string $relation,
    string $user,
    ?object $context = NULL,
    ?OpenFGA\Models\Collections\TupleKeysInterface $contextualTuples = NULL,
    ?OpenFGA\Models\Enums\Consistency $consistency = NULL,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Streams objects that a user has a specific relationship with. Returns all objects of a given type that the specified user has a relationship with, using a streaming response for memory-efficient processing of large result sets. This is ideal for handling thousands of objects without loading them all into memory.

View source


Parameters

Name Type Description
$store StoreInterface | string The store to query
$model AuthorizationModelInterface | string The authorization model to use
$type string The object type to find
$relation string The relationship to check
$user string The user to check relationships for
$context object | null Additional context for evaluation
$contextualTuples TupleKeysInterface | null Additional tuples for contextual evaluation
$consistency Consistency | null Override the default consistency level

Returns

FailureInterface | SuccessInterface — Success contains Generator<StreamedListObjectsResponseInterface>, Failure contains Throwable


writeAssertions

public function writeAssertions(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\AuthorizationModelInterface|string $model,
    OpenFGA\Models\Collections\AssertionsInterface $assertions,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Creates or updates assertions for an authorization model.

View source


Parameters

Name Type Description
$store StoreInterface | string The store containing the model
$model AuthorizationModelInterface | string The model to update assertions for
$assertions AssertionsInterface The assertions to upsert

Returns

FailureInterface | SuccessInterface — Success contains WriteAssertionsResponseInterface, Failure contains Throwable


writeTuples

public function writeTuples(
    OpenFGA\Models\StoreInterface|string $store,
    OpenFGA\Models\AuthorizationModelInterface|string $model,
    ?OpenFGA\Models\Collections\TupleKeysInterface $writes = NULL,
    ?OpenFGA\Models\Collections\TupleKeysInterface $deletes = NULL,
    bool $transactional = true,
    int $maxParallelRequests = 1,
    int $maxTuplesPerChunk = 100,
    int $maxRetries = 0,
    float $retryDelaySeconds = 1.0,
    bool $stopOnFirstError = false,
): OpenFGA\Results\FailureInterface|OpenFGA\Results\SuccessInterface

Writes or deletes relationship tuples in a store. This method supports both transactional (all-or-nothing) and non-transactional (independent operations) modes. In transactional mode, all operations must succeed or the entire request fails. In non-transactional mode, operations are processed independently with detailed success/failure tracking.

Transactional write (all-or-nothing):

// Create relationships - all succeed or all fail together
$writes = new TupleKeys([
    new TupleKey('user:anne', 'owner', 'document:budget'),
    new TupleKey('user:bob', 'viewer', 'document:budget'),
    new TupleKey('user:charlie', 'editor', 'document:roadmap'),
]);

$result = $client->writeTuples(
    store: 'store-id',
    model: 'model-id',
    writes: $writes
);

if ($result->success()) {
    echo "Successfully wrote " . count($writes) . " relationships";
}

Non-transactional batch processing:

// Process large datasets with parallel execution and partial success handling
$writes = new TupleKeys([
    // ... hundreds or thousands of tuples
]);

$result = $client->writeTuples(
    store: 'store-id',
    model: 'model-id',
    writes: $writes,
    transactional: false,
    maxParallelRequests: 5,
    maxTuplesPerChunk: 50,
    maxRetries: 2
);

$result->success(function($response) {
    if ($response->isCompleteSuccess()) {
        echo "All operations succeeded\n";
    } elseif ($response->isPartialSuccess()) {
        echo "Partial success: {$response->getSuccessfulChunks()}/{$response->getTotalChunks()} chunks\n";
        foreach ($response->getErrors() as $error) {
            echo "Error: " . $error->getMessage() . "\n";
        }
    }
});

Updating permissions by adding and removing tuples:

$writes = new TupleKeys([
    new TupleKey('user:anne', 'editor', 'document:budget'), // Promote anne to editor
]);

$deletes = new TupleKeys([
    new TupleKey('user:bob', 'viewer', 'document:budget'), // Remove bob's access
]);

$client->writeTuples(
    store: 'store-id',
    model: 'model-id',
    writes: $writes,
    deletes: $deletes
);
/

View source


Parameters

Name Type Description
$store StoreInterface | string The store to modify
$model AuthorizationModelInterface | string The authorization model to use
$writes TupleKeysInterface | null Tuples to write (create or update)
$deletes TupleKeysInterface | null Tuples to delete
$transactional bool Whether to use transactional mode (default: true)
$maxParallelRequests int Maximum concurrent requests (non-transactional only, default: 1)
$maxTuplesPerChunk int Maximum tuples per chunk (non-transactional only, default: 100)
$maxRetries int Maximum retry attempts (non-transactional only, default: 0)
$retryDelaySeconds float Retry delay in seconds (non-transactional only, default: 1.0)
$stopOnFirstError bool Stop on first error (non-transactional only, default: false)

Returns

FailureInterface | SuccessInterface — Success contains WriteTuplesResponseInterface, Failure contains Throwable

⚠️ **GitHub.com Fallback** ⚠️