Spec v0.3.0 · stable

Backbone infrastructure
for every application.

Flametrench is an open specification and SDK family for the load-bearing parts of modern applications — identity, tenancy, and authorization — implemented the same way in every language.

UUIDv7 storagePostgres nativeNode · PHP · Python · Java · GoApache 2.0DCO, no CLA

What's covered

Three concerns, one contract.

Every application re-implements these. The specification pins the data model, the wire format, and the semantic edges — SDKs conform to it.

Identity

Users, sessions, credentials, MFA.

Password, passkey, and OIDC flows behind a single interface. Session rotation and credential revocation as first-class operations — not bolt-ons. v0.2 adds TOTP and WebAuthn (ES256 / RS256 / EdDSA) as first-class factors. v0.3 adds personal access tokens (PATs) for long-lived machine credentials.

usr_ses_cred_mfa_pat_

Tenancy

Organizations, memberships, invitations.

Multi-tenancy as a primitive, not a pattern. Memberships carry roles. Invitations carry scoped grants. Scale from one-org-per-user to enterprise-with-sub-orgs on the same model.

org_mem_inv_

Authorization

Relational tuples, evaluated at the edge.

Subject–relation–object tuples. No rule languages to learn. Check permissions with a predicate call that translates cleanly to a single SQL index seek. v0.2 adds optional rewrite rules and time-bounded share tokens.

tup_shr_

Who are you?

Flametrench, in your stack’s vocabulary.

Pick the closest match and we’ll explain what Flametrench replaces, what it leaves alone, and what you actually get — in the libraries and patterns you already use.

Laravel dev

Spatie · Fortify · Sanctum

If you've shipped a Laravel SaaS, you've written the org → membership → invitation flow once already. Flametrench is that code — conformance-tested across five languages, with sole-owner protection, atomic invitation acceptance, and revoke-and-re-add role lifecycle baked in.

spatie/laravel-permission gives you $user->hasRole('admin'). Flametrench gives you $store->check($subject, 'admin', 'org', $orgId) — same idea, per-resource grain. The flametrench/laravel package wires it into the service container; on an external IdP, skip flametrench/identity and bridge from your user table.

What Flametrench replaces

  • spatie/laravel-permission (replaced by flametrench/authz tuples — finer-grained than role-per-user, conformance-tested)
  • Your hand-rolled org/membership/invitation schema (replaced by flametrench/tenancy with sole-owner protection and atomic invitation acceptance built in)
  • Optionally Fortify (flametrench/identity offers password/passkey/OIDC + MFA if you want one less package)

What it doesn’t

  • Eloquent — Flametrench's stores are PDO-based; coexists with Eloquent in the same app
  • Your application's domain logic — Flametrench is the load-bearing layer underneath
  • Laravel's broadcasting / queues / scheduler

What it actually does

Multi-tenant identity, done right.

Four spec invariants in one example: bearer-token sessions, atomic invitation acceptance with pre-attached resource grants, sole-owner protection, and atomic ownership transfer. Byte-identical semantics in Node, PHP, Python, and Java.

01

Bearer-token sessions, not session IDs

verifyPassword + createSession returns an opaque token. Server stores only SHA-256(token); verifySessionToken is constant-time. Argon2id at the OWASP floor — same hash verifies in every language.

02

Atomic invitation with pre-attached grants

createInvitation accepts a list of pre-tuples. acceptInvitation materializes the membership AND every grant in one transition. Postgres: one BEGIN/COMMIT. In-memory: equivalent atomicity. No half-states.

03

Sole-owner protection at the API boundary

changeRole, suspendMembership, and selfLeave all refuse to leave an org without an active owner. The SDK rejects the call before it reaches storage — the multi-tenant bug nobody wants to debug at 2am.

04

Atomic ownership transfer

transferOwnership promotes the target before demoting the donor. The intermediate state with zero owners is never observable. Two role tuples swap in one transaction.

Try it · live authz check

What “no derivation” actually means.

Most authz libraries silently let admin imply editor and let org membership imply project access. Flametrench doesn’t — by default. Every check is exact-match on the 5-tuple natural key. v0.2 adds optional rewrite rules for adopters who want role hierarchies, but you opt in, not out. Click a preset query to see what passes — and what doesn’t.

Active tuples (5)
  • usr_alice, owner, org_acme
  • usr_alice, editor, proj_42
  • usr_bob, admin, org_acme
  • usr_bob, viewer, proj_42
  • usr_carol, member, org_acme

Each row is one (subject, relation, object) tuple in the store. No rules engine; no inference; no rewrite.

check()
ALLOWED

matched: (usr_alice, editor, proj_42)

store.check({
  subjectType: "usr",
  subjectId: "alice",
  relation: "editor",
  objectType: "proj",
  objectId: "42"
})
// → { allowed: true, matchedTupleId: "tup_..." }

Preset queries — click to load

All six queries run the same check() primitive against the same store. The outcome depends only on whether an exact-match tuple exists — not on roles you might assume are equivalent.

Want role hierarchies? v0.2 rewrite rules (ADR 0007) let adopters declare computed_userset (role implication) and tuple_to_userset (parent-child inheritance) explicitly, with depth and fan-out caps.

Roadmap

What ships, and when.

Versions track the specification, not the SDKs. Every SDK is conforming at every spec version.

v0.1Shipped

Contract-first foundations

  • Identity, tenancy, and authorization specification
  • Cross-SDK conformance suite (10 fixtures, 70+ tests)
  • Node, PHP, Python, and Java SDKs at full v0.1 parity
  • Cross-language Argon2id parity proven across all four SDKs
  • Postgres reference data model
v0.2Shipped

Operational surface

  • Authorization rewrite rules (computed_userset, tuple_to_userset)
  • Multi-factor authentication — TOTP + WebAuthn (ES256/RS256/EdDSA)
  • Share tokens (shr_) for time-bounded resource access
  • Postgres-backed reference adapters across all 4 SDKs, with caller-owned transaction cooperation (ADR 0013)
  • User display_name + listUsers; organization name + slug; invitation acceptance binding
  • Threat model and 27-fixture conformance corpus across all four SDK families
v0.3Shipped

Platform breadth

  • Personal access tokens (pat_) — long-lived machine credentials (ADR 0016)
  • Go SDK family — fifth language, full v0.3 parity (ADR 0018)
  • Postgres rewrite-rule evaluation — computed_userset and tuple_to_userset in SQL (ADR 0017)
v0.4Planned

Observability & extensibility

  • Audit events (aud_) — tamper-evident operation log (ADR 0019, in progress)
  • Notifications (not_) — delivery hooks for membership and authz events
  • File metadata primitive (file_)
  • Feature flags (flag_)

Status

Package × language × registry.

The specification is at v0.3.0 · stable. All five SDK families ship the v0.3 contract and are live on their registries — identity is at v0.3.1 on Node and PHP (CWE-208 timing-oracle patch); Java published to Maven Central at v0.3.0.

PackageNode· npmPHP· PackagistPython· PyPIJava· Maven CentralGo· pkg.go.dev
ids
Wire-format identifiers (UUIDv7, prefixed).
v0.3.0
Live
v0.3.0
Live
v0.3.0
Live
v0.3.0
Live
v0.3.2
Live
identity
Users, credentials, sessions, MFA, display name, listUsers.
v0.3.1
Live
v0.3.1
Live
v0.3.0
Live
v0.3.0
Live
v0.3.2
Live
tenancy
Organizations, memberships, invitations.
v0.3.0
Live
v0.3.0
Live
v0.3.0
Live
v0.3.0
Live
v0.3.2
Live
authz
Tuples, check(), rewrite rules, share tokens.
v0.3.0
Live
v0.3.0
Live
v0.3.0
Live
v0.3.0
Live
v0.3.2
Live
Protocol: v0.3.0 Live — installable today. RC — pre-release, installable via rc dist-tag. Pending — publishing soon.