flametrench / authz
Authorization primitives for Flametrench: relational tuples and exact-match check(). Spec-conformant; no rewrite rules in v0.1.
Requires
- php: ^8.3
- flametrench/ids: ^0.2.0-rc
Requires (Dev)
- pestphp/pest: ^3.0
Suggests
- ext-pdo: Required by PostgresTupleStore for the durable backend.
- ext-pdo_pgsql: Postgres driver for PostgresTupleStore.
This package is auto-updated.
Last update: 2026-04-29 02:58:40 UTC
README
Authorization primitives for Flametrench: relational tuples and exact-match check(). Spec-conformant — exact-match remains the default, with no implicit rewriting at the API boundary (ADR 0001). v0.2 adds opt-in rewrite rules (ADR 0007) — computed_userset (role implication) and tuple_to_userset (parent-child inheritance) — for adopters who want hierarchies. Group expansion remains deferred.
The PHP counterpart of @flametrench/authz. Same shapes, same invariants, same test fixtures.
Status: v0.2.0-rc.5 (release candidate). PHP 8.3+ required. Includes ShareStore (ADR 0012) and Postgres-backed adapters (PostgresTupleStore, PostgresShareStore). Per ADR 0013 the Postgres adapters cooperate with adopter-side outer transactions via savepoints when nested.
Install
composer require flametrench/authz
Quick start
use Flametrench\Authz\InMemoryTupleStore; $store = new InMemoryTupleStore(); $store->createTuple( subjectType: 'usr', subjectId: 'usr_0190...alice', relation: 'editor', objectType: 'proj', objectId: '0190...project42', ); // Single-relation check. $result = $store->check( subjectType: 'usr', subjectId: 'usr_0190...alice', relation: 'editor', objectType: 'proj', objectId: '0190...project42', ); // $result->allowed === true // Set-form: true if any of the listed relations matches. $any = $store->checkAny( subjectType: 'usr', subjectId: 'usr_0190...alice', relations: ['owner', 'admin', 'editor'], objectType: 'proj', objectId: '0190...project42', );
Default check() semantics
check() is exact match by default. admin does NOT imply editor. editor does NOT imply viewer. Being a member of an org does NOT imply any object-level access. The test suite has dedicated fixtures for each invariant — they catch the most common way an SDK could accidentally violate ADR 0001.
If you want implication or inheritance, three options:
- Materialize at state-change time (Pattern A) — write the implied tuples explicitly when state changes. Works at every spec version.
- Pass a relation set to
checkAny(Pattern B) — let the caller list equivalent relations. - Opt into v0.2 rewrite rules (ADR 0007) — declare
computed_userset(role implication) andtuple_to_userset(parent-child inheritance) explicitly, with depth and fan-out caps. Currently in-memory only; Postgres-backed rule evaluation lands in a future release.
Format rules
- Relations match
/^[a-z_]{2,32}$/. Six built-ins (owner,admin,member,guest,viewer,editor); applications register custom relations matching the same pattern. - Object-type prefixes match
/^[a-z]{2,6}$/perdocs/ids.md. Use short prefixes —projnotproject,docnotdocument. - Subject types must be
'usr'. Group subjects (grp) remain deferred.
Errors
Every error is a Flametrench\Authz\Exceptions\AuthzException subclass with a flametrenchCode matching the OpenAPI Error envelope:
| Class | Code |
|---|---|
TupleNotFoundException |
not_found |
DuplicateTupleException |
conflict.duplicate_tuple (carries existingTupleId) |
InvalidFormatException |
invalid_format.<field> |
EmptyRelationSetException |
invalid_format.relations |
Development
composer install
composer test
License
Apache License 2.0. Copyright 2026 NDC Digital, LLC.