API ClientInterface - evansims/openfga-php GitHub Wiki
OpenFGA Client Interface for relationship-based access control operations. This interface defines the complete API for interacting with OpenFGA services, providing methods for managing stores, authorization models, relationship tuples, and performing authorization checks. The client implements the Result pattern, returning Success or Failure objects instead of throwing exceptions. All operations support OpenFGA's core concepts including stores for data isolation, authorization models for defining permission structures, and relationship tuples for expressing user-object relationships.
Table of Contents
-
check()
createAuthorizationModel()
createStore()
deleteStore()
dsl()
expand()
getAuthorizationModel()
getLastRequest()
getLastResponse()
getStore()
listAuthorizationModels()
listObjects()
listStores()
listTupleChanges()
listUsers()
readAssertions()
readTuples()
streamedListObjects()
writeAssertions()
writeTuples()
OpenFGA
- Client (implementation)
public function batchCheck(
StoreInterface|string $store,
AuthorizationModelInterface|string $model,
BatchCheckItemsInterface $checks,
): FailureInterface|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";
}
}
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 |
FailureInterface
| SuccessInterface
— The batch check results
public function check(
StoreInterface|string $store,
AuthorizationModelInterface|string $model,
TupleKeyInterface $tupleKey,
bool|null $trace = NULL,
object|null $context = NULL,
TupleKeysInterface|null $contextualTuples = NULL,
Consistency|null $consistency = NULL,
): FailureInterface|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
);
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 |
FailureInterface
| SuccessInterface
— Success contains CheckResponseInterface, Failure contains Throwable
public function createAuthorizationModel(
StoreInterface|string $store,
TypeDefinitionsInterface $typeDefinitions,
ConditionsInterface|null $conditions = NULL,
SchemaVersion $schemaVersion = OpenFGA\Models\Enums\SchemaVersion::V1_1,
): FailureInterface|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}";
}
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) |
FailureInterface
| SuccessInterface
— Success contains CreateAuthorizationModelResponseInterface, Failure contains Throwable
public function createStore(string $name): FailureInterface|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.
Name | Type | Description |
---|---|---|
$name |
string |
The name for the new store |
FailureInterface
| SuccessInterface
— Success contains CreateStoreResponseInterface, Failure contains Throwable
public function deleteStore(StoreInterface|string $store): FailureInterface|SuccessInterface
Deletes a store.
Name | Type | Description |
---|---|---|
$store |
StoreInterface | string
|
The store to delete |
FailureInterface
| SuccessInterface
— Success contains DeleteStoreResponseInterface, Failure contains Throwable
public function dsl(string $dsl): FailureInterface|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";
}
Name | Type | Description |
---|---|---|
$dsl |
string |
The DSL string to parse |
FailureInterface
| SuccessInterface
— Success contains AuthorizationModelInterface, Failure contains Throwable
public function expand(
StoreInterface|string $store,
TupleKeyInterface $tupleKey,
AuthorizationModelInterface|string|null $model = NULL,
TupleKeysInterface|null $contextualTuples = NULL,
Consistency|null $consistency = NULL,
): FailureInterface|SuccessInterface
Expands a relationship tuple to show all users that have the relationship.
Name | Type | Description |
---|---|---|
$store |
StoreInterface | string
|
The store containing the tuple |
$tupleKey |
TupleKeyInterface |
The tuple to expand |
$model |
AuthorizationModelInterface | string | null
|
The authorization model to use |
$contextualTuples |
TupleKeysInterface | null
|
Additional tuples for contextual evaluation |
$consistency |
Consistency | null
|
Override the default consistency level |
FailureInterface
| SuccessInterface
— Success contains ExpandResponseInterface, Failure contains Throwable
public function getAuthorizationModel(
StoreInterface|string $store,
AuthorizationModelInterface|string $model,
): FailureInterface|SuccessInterface
Retrieves an authorization model by ID.
Name | Type | Description |
---|---|---|
$store |
StoreInterface | string
|
The store containing the model |
$model |
AuthorizationModelInterface | string
|
The model to retrieve |
FailureInterface
| SuccessInterface
— Success contains GetAuthorizationModelResponseInterface, Failure contains Throwable
public function getLastRequest(): ?Psr\Http\Message\RequestInterface
Retrieves the last HTTP request made by the client.
Psr\Http\Message\RequestInterface
| null
public function getLastResponse(): ?Psr\Http\Message\ResponseInterface
Retrieves the last HTTP response received by the client.
Psr\Http\Message\ResponseInterface
| null
public function getStore(StoreInterface|string $store): FailureInterface|SuccessInterface
Retrieves store details by ID.
Name | Type | Description |
---|---|---|
$store |
StoreInterface | string
|
The store to retrieve |
FailureInterface
| SuccessInterface
— Success contains GetStoreResponseInterface, Failure contains Throwable
public function listAuthorizationModels(
StoreInterface|string $store,
string|null $continuationToken = NULL,
int|null $pageSize = NULL,
): FailureInterface|SuccessInterface
Lists authorization models in a store with pagination.
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) |
FailureInterface
| SuccessInterface
— Success contains ListAuthorizationModelsResponseInterface, Failure contains Throwable
public function listObjects(
StoreInterface|string $store,
AuthorizationModelInterface|string $model,
string $type,
string $relation,
string $user,
object|null $context = NULL,
TupleKeysInterface|null $contextualTuples = NULL,
Consistency|null $consistency = NULL,
): FailureInterface|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
);
/
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 |
FailureInterface
| SuccessInterface
— Success contains ListObjectsResponseInterface, Failure contains Throwable
public function listStores(
string|null $continuationToken = NULL,
?int $pageSize = NULL,
): FailureInterface|SuccessInterface
Lists all stores with pagination.
Name | Type | Description |
---|---|---|
$continuationToken |
string | null
|
Token for pagination |
$pageSize |
int | null
|
Maximum number of stores to return |
FailureInterface
| SuccessInterface
— Success contains ListStoresResponseInterface, Failure contains Throwable
public function listTupleChanges(
StoreInterface|string $store,
string|null $continuationToken = NULL,
?int $pageSize = NULL,
string|null $type = NULL,
DateTimeImmutable|null $startTime = NULL,
): FailureInterface|SuccessInterface
Lists changes to relationship tuples in a store.
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) |
FailureInterface
| SuccessInterface
— Success contains ListTupleChangesResponseInterface, Failure contains Throwable
public function listUsers(
StoreInterface|string $store,
AuthorizationModelInterface|string $model,
string $object,
string $relation,
UserTypeFiltersInterface $userFilters,
object|null $context = NULL,
TupleKeysInterface|null $contextualTuples = NULL,
Consistency|null $consistency = NULL,
): FailureInterface|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
);
/
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 |
FailureInterface
| SuccessInterface
— Success contains ListUsersResponseInterface, Failure contains Throwable
public function readAssertions(
StoreInterface|string $store,
AuthorizationModelInterface|string $model,
): FailureInterface|SuccessInterface
Retrieves assertions for an authorization model.
Name | Type | Description |
---|---|---|
$store |
StoreInterface | string
|
The store containing the model |
$model |
AuthorizationModelInterface | string
|
The model to get assertions for |
FailureInterface
| SuccessInterface
— Success contains ReadAssertionsResponseInterface, Failure contains Throwable
public function readTuples(
StoreInterface|string $store,
?OpenFGA\Models\TupleKeyInterface $tupleKey = NULL,
string|null $continuationToken = NULL,
?int $pageSize = NULL,
Consistency|null $consistency = NULL,
): FailureInterface|SuccessInterface
Reads relationship tuples from a store with optional filtering and pagination.
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 |
FailureInterface
| SuccessInterface
— Success contains ReadTuplesResponseInterface, Failure contains Throwable
public function streamedListObjects(
StoreInterface|string $store,
AuthorizationModelInterface|string $model,
string $type,
string $relation,
string $user,
object|null $context = NULL,
TupleKeysInterface|null $contextualTuples = NULL,
Consistency|null $consistency = NULL,
): FailureInterface|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.
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 |
FailureInterface
| SuccessInterface
— Success contains Generator<StreamedListObjectsResponseInterface>, Failure contains Throwable
public function writeAssertions(
StoreInterface|string $store,
AuthorizationModelInterface|string $model,
AssertionsInterface $assertions,
): FailureInterface|SuccessInterface
Creates or updates assertions for an authorization model.
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 |
FailureInterface
| SuccessInterface
— Success contains WriteAssertionsResponseInterface, Failure contains Throwable
public function writeTuples(
StoreInterface|string $store,
AuthorizationModelInterface|string $model,
TupleKeysInterface|null $writes = NULL,
TupleKeysInterface|null $deletes = NULL,
bool $transactional = true,
int $maxParallelRequests = 1,
int $maxTuplesPerChunk = 100,
int $maxRetries = 0,
float $retryDelaySeconds = 1.0,
bool $stopOnFirstError = false,
): FailureInterface|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
);
/
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) |
FailureInterface
| SuccessInterface
— Success contains WriteTuplesResponseInterface, Failure contains Throwable