DEV Community

Cover image for How to Protect Your API with OpenFGA: From ReBAC Concepts to Practical Usage
Edouard Maleix for This is Learning

Posted on

How to Protect Your API with OpenFGA: From ReBAC Concepts to Practical Usage

Another story, another article. A client asked me recently:

πŸ—£οΈ Can we add temporary permissions for a group of users assigned to a maintenance task, while it's ongoing?

It should be simple enough, right? Yes, until I examined the authorization code behind the API and found a 500-line function checking user roles and groups, time windows, resource ownership, and various business rules. πŸ˜Άβ€πŸŒ«οΈ

Unlike authentication (who is accessing the system), where we have OIDC, JWT, and other established standards and patterns, authorization (what they can do) often forces us into custom implementations.

🫷You might argue that OAuth 2.0 cover authorization, but they focus on third-party access, not complex and dynamic authorization patterns.

The OWASP Top 10 API Security Risks lists Broken Object Level Authorization as the #1 risk, showing us how common it is to expose sensitive data due to poor authorization checks.
Is it far-fetched to think that the complexity of authorization logic contributes to this risk?

Each new policy adds another conditional branch, another database join, another custom role, another edge case that breaks during the next feature request. The authorization flow becomes a spaghetti bowl and even experienced developers hesitate before touching it.

this is fine

Traditional approaches quickly hit walls:

  • RBAC works until you need "sometimes" permissions
  • ABAC offers flexibility but becomes a rule engine nightmare
  • Database queries slow to a crawl as your permission matrix grows

What if there is a better way? A way that lets you express complex relationships without messy code or performance hits? πŸ€”

My exploration for a better paradigm started with Ory Keto:

It introduced me to Google's Zanzibar paper and the concept of Relation-Based Access Control (ReBAC).

Zanzibar: A Global Authorization System - Presented by Auth0

Zanzibar handles authorization for all of Google’s products, allows teams to specify their unique authorization models, globally replicates authorization data, and responds to access checks blazing fast.

favicon zanzibar.academy

This time, I needed more flexibility to introduce contextual relationships. That "simple" feature request led me to OpenFGA β€” a richer implementation of Zanzibar's principles that extends ReBAC with powerful features like contextual-based conditions, attribute-based access, and a simple query language.

And since you might be familiar with this story, I'll share with you my learning journey, starting from the concepts and terminology, through practical examples and considerations, to real-world usage of OpenFGA.

  1. βœ… The Authorization Problem
  2. πŸ“ Why OpenFGA? ← You are here
  3. ⬜ ReBAC and OpenFGA concepts
  4. ⬜ OpenFGA in Action
  5. ⬜ Testing permissions with OpenFGA CLI
  6. ⬜ Adoption Challenges and Strategies

Why OpenFGA [β–“β–‘β–‘β–‘β–‘β–‘β–‘β–‘]

Before I grab your attention and your brain 🧠 with the ReBAC concepts and how OpenFGA implements them, let me explain why I chose OpenFGA over other solutions.

It Matches How You Think

Expressive Relationships

Cat owners own cats. Sitters sit cats. Admins administrate. The authorization model mirrors reality instead of forcing you into artificial role hierarchies. Demo

Cat owner relationship diagram


Direct relations

Cat sitting scenario diagram


Implied relations

Time Works Automatically

No more "grant permission at 9 AM, revoke at 5 PM" cron jobs. Time-based access happens naturally through conditions.
Grant permissions only when conditions are metβ€”like during scheduled hours.
Demo

🀝 Yes! My client is going to love this.

Time-based conditions

Status Drives Decisions

Your app's workflow probably includes some entities' states (e.g., pending, active, completed). OpenFGA uses these attributes directly for permissions instead of requiring separate access control flags. Demo

Status-based conditions

Queries, Not Just Checks

Traditional systems answer "Can Alice do X?" OpenFGA also answers "What can Alice do?" and "Who can do X?" This opens opportunities for features like smart dashboards and permission audits.
Demo

Is user Jenny related to system development as an admin?
Tuple Queries from OpenFGA playground
Who is Romeo's owner?
Who has the right to feed Romeo?

Scale Like Google

Google's Zanzibar (which inspired OpenFGA) handles billions of authorization checks daily. Your application(s) probably won't hit those numbers, but it's nice to know you won't hit a wall due to a poorly performing authorization system.

☝️ In my tests, OpenFGA performed slightly better than custom database lookups for complex relationships (both based on PostgreSQL).

Great Documentation and CLI Tools

I can't deny it, OpenFGA has a steep learning curve, but its documentation is complete and well-structured. It covers everything from basic concepts to advanced usage patterns until deployment strategies.

The CLI tools make it easy to manage your authorization model and test your policies.

Business Backing

OpenFGA is open-source and Okta is funding it, this ensures a long-term viability and support. On one side, you can always deploy it on your own infrastructure, and the community is growing rapidly. On the other side, Okta has strong competitors like OSO, Ory Keto or AWS Cedar, so they have a vested interest in making OpenFGA a successful product extending what Auth0 has to offer.

Deployment Flexibility

OpenFGA can be deployed in various ways, depending on your needs:

  • Self-hosted: Use Docker Compose to get started locally, Kubernetes for full control and Terraform to orchestrate your infrastructure.
  • Managed service: Use Auth0's FGA offering for a hassle-free experience.

Observability and Debugging

You can configure:

This makes it easier to monitor your authorization system with open standards and integrate with your existing observability stack.

Simpler Code To Maintain

To illustrate this, I'm using Typescript to check if a user can update a cat sitting arrangement with both approaches: a plain database lookup and an OpenFGA check.

Database Lookup

async function isSystemAdmin(userId: string): Promise<boolean> {
  const user = await userRepository.findById(userId);
  if (!user) return false;
  return user.role === 'admin';
}

async function checkCatSittingUpdatePermission(
  userId: string,
  sittingId: string
): Promise<boolean> {
  const sitting = await catSittingRepository.findById(sittingId);
  if (!sitting) return false;

  const cat = await catRepository.findById(sitting.catId);
  if (!cat) return false;

  const isOwner = cat.ownerId === userId;
  const isSitter = sitting.sitterId === userId;
  const isAdmin = () => await isSystemAdmin(userId);
  const isPending = () =>
    sitting.status === 'requested' && new Date(sitting.startTime) > new Date();

  return isOwner || (isSitter && isPending()) || isAdmin();
}
Enter fullscreen mode Exit fullscreen mode

OpenFGA Check

async function checkCatSittingUpdatePermission(
  userId: string,
  catSittingId: string
): Promise<boolean> {
  const openfgaClient = new OpenFgaApi({
    apiUrl: process.env.OPENFGA_API_URL,
  });

  const request: CheckRequest = {
    tuple_key: {
      user: `user:${userId}`,
      relation: 'can_update',
      object: `cat_sitting:${catSittingId}`,
    },
    context: {
      current_time: new Date().toISOString(),
    },
  };

  const { allowed } = await openfgaClient.check(
    process.env.FGA_STORE_ID,
    request
  );
  return !!allowed;
}
Enter fullscreen mode Exit fullscreen mode

Does it need a lot of explanation? The OpenFGA version is objectively cleaner, more maintainable, and scales better as your authorization logic grows.

ReBAC and OpenFGA concepts [β–“β–“β–“β–‘β–‘β–‘β–‘]

I'll walk you through ReBAC using PurrfectSitter Β©, a cat sitting app where owners find sitters. Real problems, real solutions.
As trivial as it sounds, this example shows:

  • Role-based access control (RBAC) for admins
  • Attribute-based access control (status-driven permissions)
  • Time-based access control
  • Resource ownership and management

Three Building Blocks

ReBAC builds authorization from three simple pieces:

Types: Entities in Your App

type user
type system
type cat
type cat_sitting
type review
Enter fullscreen mode Exit fullscreen mode

These map to your app's core entities:

  • user: πŸ‘€ People using your app
  • system: 🏒 Admin access controls
  • cat: 🐱 Furry clients needing care
  • cat_sitting: 🏠 A sitting arrangement
  • review: πŸ“ Post-sitting feedback

Each type will declare relationships with other types - in the type definition.

ℹ️ In Ory Keto, these are called namespaces.

Objects: Instances of Types

In OpenFGA, an object is an instance of a type. For example:

  • user:bob: A specific user named Bob
  • cat:romeo: A specific cat named Romeo
  • system:development: The development environment
  • cat_sitting:1: The first cat sitting arrangement
  • review:1: The first review

Objects are the concrete entities your users interact with.

Users: The Actors

A user is an entity that is related to objects in your system. In our app, users can be:

  • People (like Bob)
  • Systems (like the PurrfectSitter development environment)
  • Cats (like Romeo)

ℹ️ In Ory Keto, these are called subjects. I believe subject is less ambiguous than user, but OpenFGA uses user, so we will too.

Relations: How Things Connect

A relation defines how users interact with objects. For example:

  • user:bob owner cat:romeo: Bob is the owner of Romeo
  • user:anne sitter cat_sitting:1: Anne is the sitter for the first cat sitting arrangement

Each relation (e.g., admin) evaluation logic is defined in the relation definition (e.g., [user]).

type system
  relations
    define admin: [user]

type cat
  relations
    define owner: [user]
    define admin: admin from system
    define can_manage: owner or admin
    define system: [system]

type cat_sitting
  relations
    define active_sitter: [cat_sitting#sitter with is_active_timeslot]
    define can_post_updates: owner or active_sitter
    define can_review: [cat#owner with is_cat_sitting_completed]
    define cat: [cat]
    define owner: owner from cat
    define sitter: [user]
Enter fullscreen mode Exit fullscreen mode

‼️ For the sake of this example, we will assume that cats are owned by humans. We all know that, in reality, cats own us, not the other way around.

OpenFGA computes relationships in several ways:

  • Direct:
    • system.admin β€” A user can be an admin of the system
    • cat.owner β€” A user can be a cat owner
    • cat.system β€” A system can be assigned to a cat
    • cat_sitting.sitter β€” A user can be a sitter for a cat_sitting
  • Implied:
    • cat.admin: admin from system β€” An admin is a user from the system
    • cat_sitting.owner: owner from cat β€” The cat_sitting owner is the cat owner
  • Union:
    • cat.can_manage β€” either the cat owner or an admin from the system can manage the cat
    • cat_sitting.can_post_updates β€” either the cat_sitting owner or an active_sitter can post updates
  • Conditional:
    • cat_sitting.active_sitter β€” Conditional relation between user and cat_sitting based on the outcome of the is_active_timeslot condition
    • cat_sitting.can_review β€” Conditional relation between user and cat_sitting based on the outcome of the is_cat_sitting_completed condition

There are even more ways to express relationships, such as exclusion, intersection and nesting, you can find the complete configuration language reference in the OpenFGA documentation.

The Complete Authorization Model

The ensemble of types and relations definitions forms the authorization model.
Here, the PurrfectSitter's authorization model in OpenFGA's configuration language (Domain-Specific Language for the purist), defines how users interact with cats, cat sittings, and reviews.

model
  schema 1.1

type user

type system
  relations
    define admin: [user]

type cat
  relations
    define admin: admin from system
    define can_manage: owner or admin
    define owner: [user]
    define system: [system]

type cat_sitting
  relations
    define admin: admin from system
    define active_sitter: [cat_sitting#sitter with is_active_timeslot]
    define pending_sitter: [cat_sitting#sitter with is_pending_timeslot]
    define can_post_updates: owner or active_sitter
    define can_delete: admin or owner or pending_sitter
    define can_view: admin or owner or sitter
    define can_update: admin or owner or pending_sitter
    define can_review: [cat#owner with is_cat_sitting_completed]
    define cat: [cat]
    define owner: owner from cat
    define sitter: [user]
    define system: [system]

type review
  relations
    define admin: admin from system
    define author: owner from cat_sitting
    define can_delete: admin or author
    define can_edit: admin or author
    define can_view: [user, user:*]
    define cat: cat from cat_sitting
    define cat_sitting: [cat_sitting]
    define subject: sitter from cat_sitting
    define system: [system]

condition is_active_timeslot(current_time: timestamp, end_time: timestamp, start_time: timestamp) {
  current_time >= start_time && current_time <= end_time
}

condition is_pending_timeslot(current_time: timestamp, start_time: timestamp) {
  current_time < start_time
}

condition is_cat_sitting_completed(cat_sitting_attributes: map<string>, completed_statuses: list<string>) {
  cat_sitting_attributes["status"] in completed_statuses
}
Enter fullscreen mode Exit fullscreen mode

Notice how readable, yet compact, this is β€” no complex SQL joins or nested conditions. The model captures business logic naturally.

Nice one Johnny

βœ… Checkpoint: Can You Answer These?

Before moving on, make sure you can answer:

  1. What's the difference between a user and an object?
  2. How do relations differ from roles?
  3. When would you use indirect relationships?

Answers
  1. User vs Object: A user is an entity (like a person), while an object is an instance of a type (like a specific cat or cat sitting arrangement). Users interact with objects through relations.
  2. Relations vs Roles: Relations define how entities connect (like "owner of cat"), while roles are broader categories (like "admin" or "sitter") that can have multiple relations.
  3. Indirect Relationships: Use these when you want to derive permissions from other relationships, like "can a sitter post updates if they are also the owner?" This allows for more flexible and dynamic permission checks.

OpenFGA in Action [β–“β–“β–“β–‘β–‘β–‘β–‘]

Let's test our model with real scenarios. I use the OpenFGA CLI to initialize the authorization model, create relation tuples, check the permissions and run some querie but you can use any other client SDK.


Save some time, create a GitHub codespace

It will provide you a ready-to-use environment with all dependencies installed and external services running, so you can focus on running the examples in this article.


Setup OpenFGA

1. Creating a Store and a Model

First, create a store:

Then create the authorization model in the new store:

⚠️ If you are using Codespaces, specify the API path with

  • the flag --api-url http://openfga:8080
  • the environment variable FGA_API_URL=http://openfga:8080

2. Creating Basic Relationships

Bob owns Romeo, Anne sits for him. Simple.

3. Admin Powers

Jenny becomes a system admin who can manage any cat β€” traditional RBAC within ReBAC.

4. Time Magic

Anne's permissions activate and deactivate automatically based on time. No cron jobs, no cleanup code β€” the authorization system handles it.

5. Status-Driven Access

Reviews only make sense after sitting ends. OpenFGA enforces this business rule automatically, ABAC style.

6. Creating and Checking Review Permissions

Create a review and check who can edit or delete it. OpenFGA's query language shines here, allowing you to check permissions and also list objects a user can interact with.

7. Making the Review Public

Control visibility using wildcards.

Explore Relationships with OpenFGA Playground

You can visualize the relations graph and run queries in the OpenFGA's Playground.
I find it a great way to discover and understand relationships in your model and test queries interactively.

OpenFGA Playground generated from PurrfectSitter model

πŸ’‘ If you are using Codespaces, just open http://localhost:8082/playground in your browser.

Testing permissions with OpenFGA CLI [β–“β–“β–“β–“β–‘β–‘β–‘]

Another one of OpenFGA's strengths, is its built-in testing capabilities. The CLI provides a declarative way to test authorization models without writing application code.

Declarative Testing with YAML

Define tests in YAML and run with a single command:

fga model test --tests store.fga.yml
Enter fullscreen mode Exit fullscreen mode

...and forget about all the commands above πŸ™‚. The store.fga.yml file contains everything you need to create the model and tuples, and run the tests before writing application code!

Thank goodness

Let's look at the store.fga.yml file that tests our PurrfectSitter model:

The authorization model

This is the model we defined earlier, but in YAML format for the OpenFGA CLI:

model: |
  model
    schema 1.1

  # Our full model definition goes here...
Enter fullscreen mode Exit fullscreen mode

ℹ️ The model section is the same as the one we defined earlier, but in YAML format for the OpenFGA CLI.

The tuples

This section defines the relationships (tuples) in our model. Each tuple represents a relationship between a user and an object, along with the relation type.

model:
  # ...
tuples:
  - user: user:jenny
    relation: admin
    object: system:development

  - user: user:bob
    relation: owner
    object: cat:romeo

  - user: system:development
    relation: system
    object: cat:romeo

  - user: cat:romeo
    relation: cat
    object: cat_sitting:1

  - user: user:anne
    relation: sitter
    object: cat_sitting:1

  - user: cat_sitting:1#sitter
    relation: active_sitter
    object: cat_sitting:1
    condition:
      name: is_active_timeslot
      context:
        start_time: '2023-01-01T00:00:00Z'
        end_time: '2023-01-02T00:00:00Z'

  - user: cat:romeo#owner
    relation: can_review
    object: cat_sitting:1
    condition:
      name: is_cat_sitting_completed
      context:
        completed_statuses: ['completed']

  - user: system:development
    relation: system
    object: review:1

  - user: cat_sitting:1
    relation: cat_sitting
    object: review:1

  - user: user:*
    relation: can_view
    object: review:1
Enter fullscreen mode Exit fullscreen mode

The tests

This section defines the tests that will be run against the model and tuples. Each test checks specific permissions or relationships.

The example demonstrates several test types:

  1. Basic permission checks: Simple assertions about relationships
  2. Contextual checks: Testing time-based permissions
  3. Attribute-based checks: Testing permissions depending on object attributes
  4. List objects: Finding objects a user has relationships with
  5. List users: Finding users with relationships to an object
model:
  # ...
tuples:
  # ...
tests:
  - name: Test basic relations
    check:
      - user: user:anne
        object: cat_sitting:1
        assertions:
          sitter: true

      - user: user:bob
        object: cat_sitting:1
        assertions:
          owner: true

  - name: Test role access
    check:
      - user: user:jenny
        object: cat:romeo
        assertions:
          can_manage: true

      - user: user:bob
        object: cat:romeo
        assertions:
          can_manage: true

      - user: user:anne
        object: cat:romeo
        assertions:
          can_manage: false

  - name: Test temporal access
    check:
      - user: user:anne
        object: cat_sitting:1
        context:
          current_time: '2023-01-01T00:10:00Z'
        assertions:
          active_sitter: true

      - user: user:anne
        object: cat_sitting:1
        context:
          current_time: '2023-01-04T00:00:00Z'
        assertions:
          active_sitter: false

  - name: Test attribute access
    check:
      - user: user:bob
        object: cat_sitting:1
        context:
          cat_sitting_attributes:
            status: 'completed'
        assertions:
          can_review: true

      - user: user:bob
        object: cat_sitting:1
        context:
          cat_sitting_attributes:
            status: 'in_progress'
        assertions:
          can_review: false

  - name: Test the cat sitting that anne is sitting
    list_objects:
      - user: user:anne
        type: cat_sitting
        context:
          current_time: '2023-01-01T00:00:01Z'
        assertions:
          active_sitter:
            - cat_sitting:1
          sitter:
            - cat_sitting:1

  - name: Test the review that bob can edit
    list_objects:
      - user: user:bob
        type: review
        assertions:
          can_edit:
            - review:1

  - name: Test that reviews are public
    list_users:
      - object: review:1
        user_filter:
          - type: user
        assertions:
          can_view:
            users:
              - user:*
Enter fullscreen mode Exit fullscreen mode

πŸ‘‹ You can find store.fga.yml in the demo repository.

Testing During Adoption

These testing capabilities help when adopting OpenFGA:

  • Validate models against business rules
  • Verify permissions match the old system during migration
  • Compare results with your existing system in shadow mode
  • Prevent regressions with CI pipeline tests

Including tests in your workflow reduces authorization errors and builds confidence in your implementation.

βœ… Checkpoint II: Can You Answer These?

Have you read carefully the previous sections? If so, you should be able to answer:

  1. Can you list objects a user has relationships with?
  2. Can you list users with relationships to an object?
  3. Can you make an object public to all users?

Answers
  1. List Objects: Yes, you can use the list-objects command to find objects a user has relationships with, like finding all cat sittings where a user is an active sitter.

  2. List Users: Yes, if you have a relationship that connects users to objects, you can use the list-users command to find users with relationships to an object, like finding all users who can view a specific review.

  3. Public Objects: Make an object public by adding a relation that allows all users to access it, like granting user:* permission on the object as I showed you in this example

Adoption Challenges and Strategies [β–“β–“β–“β–“β–“β–“β–‘]

As good as this tool is, adopting OpenFGA in existing systems presents challenges.

Mental Model Shift

ReBAC requires a paradigm shift for developers:

  • Mental model adjustment: Developers familiar with RBAC or ABAC need time to think in relationships.
  • Training investment: Workshops and examples help teams translate existing rules into relationship models.

Data Synchronization

This is probably the most challenging aspect of adopting OpenFGA, especially if you have an existing database with complex permissions.

  • Dual writes: Applications must write to both their database and OpenFGA.
  • Synchronization strategies:
    • Event-driven synchronization through message queues
    • Centralized hooks for database operations
    • Transactional outbox pattern for consistency
    • Background jobs for existing data

Read this excellent article πŸ‘‡ about dual writes in distributed systems. It will surely help you understand strategies for synchronizing data between your applications' DB and OpenFGA.

Handling the Dual-Write Problem in Distributed Systems | Auth0

The dual-write problem exists in distributed systems. Let's look at what it is and some of the most common strategies to mitigate it usin...

favicon auth0.com

Progressive Adoption

It's going to be hard (and unwise) to convince your team to rewrite the entire authorization logic in OpenFGA, big-bang refactoring style. Instead, consider a progressive adoption strategy:

1. Start with Coarse-Grained Permissions

Begin with your existing structure:

  • Replicate your current RBAC model
  • Add organization-level permissions
  • Gradually introduce finer-grained controls

2. Shadow Mode Implementation

Before switching fully:

  • Run existing authorization alongside OpenFGA
  • Compare results to identify discrepancies
  • Build confidence before making the switch

3. Use Contextual Tuples for Hybrid Implementations

Reduce synchronization burden:

  • Send data as contextual tuples initially
  • Gradually move to persistent relationship tuples
  • Use contextual tuples for frequently changing data

ℹ️ Read more about this technique in the OpenFGA documentation.

Managing Organizational Adoption

For large organizations:

  • Start with a single application where OpenFGA delivers immediate value
  • Use modular models for independent team control
  • Leverage access control for team-specific credentials

Your Next Move [β–“β–“β–“β–“β–“β–“β–“]

Complex policies doesn't have to mean complex code. OpenFGA's ReBAC model simplifies permissions into relationships, making your authorization logic more maintainable and scalable.

Ready to get started? Here's your roadmap:

  1. Read in details the PurrfectSitter's authorization model
  2. Draw inspiration from the Purrfect Sitter Fastify API
  3. Adapt it to your domain
  4. Watch complex permission logic become simple relationship definitions.
  5. Get in touch with me for some deep-dive into performance characteristics, monitoring, and production deployment patterns πŸ˜‰
  6. If you want to show your appreciation, give those repositories a ⭐️ on GitHub. πŸ‘‡

GitHub logo getlarge / purrfect-sitter

A cat sitting management application to showcase OpenFGA

Purrfect Sitter

A cat sitting management application with dual authorization strategies.

Architecture

Core Application

  • Fastify-based API
  • User authentication with Ory Kratos
  • Core models: User, Cat, CatSitting, Review
  • TypeBox for JSON Schema validation
  • Drizzle ORM for database access
  • OpenFGA for fine-grained authorization

NX Workspace Structure

apps/
  purrfect-sitter/       # Main Fastify application
  purrfect-sitter-e2e/   # End-to-end tests

libs/                    # Domain-specific libraries
  database/              # Database schema and repositories
  models/                # DTOs and validation schemas
  auth/                  # Authentication and authorization
  cats/                  # Cats domain business logic
  cat-sittings/          # Cat sittings domain business logic
  reviews/               # Reviews domain business logic

Authorization Strategies

This application implements two authorization strategies that can be toggled via environment variables:

  1. Database Lookups (AUTH_STRATEGY=db)

    • Traditional database queries to check permissions
    • Uses JOINs and WHERE clauses for relationship checks
    • Direct SQL conditions for time-based rules
  2. OpenFGA (AUTH_STRATEGY=openfga)

    • Relationship-based authorization using OpenFGA
    • Declarative authorization model (authorization-model.fga)
    • Uses relationship tuples for…

GitHub logo openfga / openfga

A high performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar

OpenFGA

Go Reference GitHub release (latest SemVer) Docker Pulls Codecov Go Report CII Best Practices Join our community Twitter FOSSA Status Artifact HUB OpenSSF Scorecard SLSA 3

A high-performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.

OpenFGA is designed to make it easy for developers to model their application permissions and add and integrate fine-grained authorization into their applications.

It allows in-memory data storage for quick development, as well as pluggable database modules. It currently supports PostgreSQL 14, MySQL 8 and SQLite (currently in beta).

It offers an HTTP API and a gRPC API. It has SDKs for Java, Node.js/JavaScript, GoLang, Python and .NET. Look in our Community section for third-party SDKs and tools. It can also be used as a library.

Getting Started

The following section aims to help you get started quickly. Please look at our official documentation for in-depth information.

Setup and Installation

ℹ️ The following sections setup an OpenFGA server using the default configuration values. These are for rapid development…

Your future self will thank you for choosing relationships over nested IF statements.


References

Top comments (2)

Collapse
 
duske profile image
Dustin

Great and well structured post! I'm curious to try it out πŸ‘€

Collapse
 
bansikah profile image
Tandap Noel Bansikah

Great post, i have implemented this one spring boot and Rbac is really an important concept