Relationship tuples replace permission checks scattered through code
OpenFGA stores an authorization model plus tuples that connect users, groups, and objects. A client can ask whether a user may perform a relation such as viewer on a document, or list the objects available to that user. HTTP and gRPC APIs serve the same engine, with official SDKs for 5 named languages: Java, Node.js, Go, Python, and .NET. A Go application can also embed the server package.
This model suits permissions that grow through membership and inheritance. A user may reach a document through a team, folder, or organization instead of one row in a role table. The price is another source of state whose meaning comes from both tuples and model versions. Teams need reviews for authorization-model changes, migration rules, and application tests that express expected access before a new model reaches production.
The memory quick start loses every tuple at shutdown
The one-command Docker example exposes the API on port 8080 and the playground on port 3000. It uses the in-memory datastore, which the README labels for development only because all data disappears when the process stops. The playground is also restricted to local development and expects a local server. That is enough to learn the model, create a store, write tuples, and make checks without first provisioning a database.
Production storage choices are narrower. The README lists PostgreSQL 14+ and MySQL 8 as supported, with SQLite in beta. MySQL has stricter length limits on tuple properties than the other backends. A real deployment also needs migrations, backups, connection sizing, authentication, network policy, and observability. OpenFGA centralizes authorization decisions; it does not supply user login or make outside OAuth revocation alter tuples already stored in its database.
What happened when we ran it
Our sandbox installed 321 Go packages in 60 seconds. The source checkout at commit 450b68c contained 575 files, about 178,207 lines of source, and occupied 6.9 MB. Building the server succeeded in 150 seconds. Our measurement setup was a fresh unprivileged Debian container with 3 CPUs, 8 GB of RAM, no secrets, and a base image labeled Go 1.24.
The test command failed with exit code 1 after 165 seconds. Its summary reported 66 passed and 16 failed out of 82. The final log lines named TestListObjectsPostgres, TestListObjectsMySQL, TestListUsersPostgres, and TestListUsersMySQL, with their package runs ending in failure. The excerpt does not give the assertions or setup error, so it would be wrong to claim a database outage, missing credential, or product defect from that tail alone.
The repository has a Dockerfile, a tests directory, and 11 CI workflow files. Its module at the checked commit declares Go 1.25.7 and toolchain 1.26.5. The build succeeding from the supplied Go 1.24 image does not erase those declared requirements; use the module's toolchain declaration when building your own image. Our run provides no vulnerability-audit result for the Go dependency set, so this review makes no vulnerability-count claim.
Version 1.19.0 changes how malformed models fail
OpenFGA v1.19.0 was released on August 25, 2026. Its main model fix validates malformed relation references before graph construction. The release notes mark a behavior change: an affected model already in storage can now return ErrInvalidModel on a cache miss instead of continuing in a degraded state. The release also fixes a connection-pool deadlock path and adjusts diagnostic logging. Read those notes before upgrading an installation with old stored models.
GitHub recorded a push on September 4, 2026, and we separately fetched 146 open issues plus 61 open pull requests. Current work includes PostgreSQL secondary credentials, SQL iterator deadlines, JWT caching, and query-pipeline changes. That issue and release activity shows active maintenance after v1.19.0. It also reflects the size of the job: storage, graph evaluation, authentication, caching, and protocol behavior all meet inside an authorization server.
ListObjects can report success with an incomplete answer
Open issue 3276 describes a sharp client-side risk in the fallback ListObjects path. With a deliberately tiny deadline, the reporter received HTTP 200 and an empty or partial object array after evaluation stopped. The proposed warning header was absent. The report targets the latest version and uses the in-memory backend. Until the behavior is resolved and verified in your version, do not treat a successful status alone as proof that a list is exhaustive.
Authorization checks and object listings have different failure consequences. A denied point check may block one action, while an incomplete object list can hide accessible records or mislead downstream code about what exists. Test deadline behavior with realistic graph depth, record response metadata, and choose a safe product behavior for partial results. The 16 failures in our run make those database-specific regression checks more urgent, even though the log does not connect them to issue 3276.
OpenFGA fits shared graphs, while simple roles belong in the app
OpenFGA is worth the operating cost when several services ask the same relationship questions or permissions no longer fit a user-role table. Its Apache-2.0 server, 5 official SDKs, Docker image, CLI, playground, and Terraform provider give a team several integration paths. The documentation is direct about disposable storage and production databases, which matters more than a frictionless demo.
A simple application with a handful of static roles should stay simple. For a real permission graph, budget for a supported datastore, model tests, schema migrations, protected APIs, and client behavior under deadlines. Our 150-second build shows the source is buildable in the stated lab; the 16 failed test results stop us short of calling that checkout verified. Run the full suite with your chosen SQL backend before OpenFGA becomes the service deciding who sees what.

