Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion blog/fine-grained-news-2024-10.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@ Check out our roadmap to see what’s in the works. Feature requests and ideas c

## See you Next Month

Fine-Grained News is published every month. If you have any feedback, want to share your OpenFGA story, or have a noteworthy update, please let us know on any of our [community channels](https://openfga.dev/community) or at [community@openfga.dev](mailto:community@openfga.dev).
Fine-Grained News is published every month. If you have any feedback, want to share your OpenFGA story, or have a noteworthy update, please let us know on any of our [community channels](https://openfga.dev/community) or at [community@openfga.dev](mailto:community@openfga.dev).
53 changes: 53 additions & 0 deletions docs/content/adopters/agicap.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: Agicap Case Study
description: How European fintech Agicap runs OpenFGA in production for 8,000+ customers at 250 RPS with conditional ReBAC across every backend service.
sidebar_position: 2
slug: /adopters/agicap
---

# Agicap: Fine-grained authorization for a European fintech platform

[Agicap](https://agicap.com) is a European fintech that helps small, medium, and large enterprises manage cash flow in real time. Its SaaS platform serves more than 8,000 customers across industries, and every backend service in the platform validates access through OpenFGA.

## At a glance

| | |
| --- | --- |
| **Industry** | Fintech / cash flow management |
| **In production since** | April 2023 |
| **Scale** | ~250 requests per second, 8,000+ customers |
| **Deployment** | Self-hosted, on-premises |
| **Key features used** | ReBAC, conditional relationships |

## Why OpenFGA

Agicap needed an open-source authorization layer with a strong community, on-premises deployment for compliance, and a model flexible enough to express financial-product permissions that pure RBAC could not. They evaluated alternatives such as Oso and concluded OpenFGA was the most stable option that fit those requirements, with approachable maintainers and clear documentation.

The team specifically chose ReBAC over an RBAC redesign because it let them express fine-grained relationships without re-inventing authorization logic inside every service. Learn more about that trade-off in [RBAC vs ReBAC](/docs/authorization-concepts).

## Architecture and scale

- All backend services call OpenFGA via an internal **secure facade** rather than the OpenFGA API directly. The facade enforces application-level rules on top of OpenFGA so the data plane is never exposed.
- Authorization is enforced consistently across development, pre-production, load-test, and production environments.
- Performance work over time pushed Agicap from a deeper hierarchy to a flatter authorization model, which improved both query latency and scalability — a pattern documented in the [performance best practices](/docs/best-practices).

## Engineering with the community

Agicap is an active upstream contributor:

- Engineers from the platform and SRE teams open pull requests against `openfga/openfga` to fix bugs and tune performance.
- The team participates in the monthly OpenFGA community call.
- Agicap has co-presented OpenFGA talks with maintainers at KubeCon EU 2024 (Paris) and KubeCon NA 2024 (Salt Lake City).

When the team filed a critical performance issue, the upstream maintainers shipped a fix within 24 hours.

## Outcomes

- A single, evolvable authorization layer behind every backend service.
- Faster delivery of new permissions — schema changes replace code changes.
- Cost savings from running self-hosted instead of a proprietary alternative.
- Confidence at production scale with 8,000+ customers and continuous traffic.

## Source

This case study is based on the public CNCF TOC adopter interview with Pauline Jamin, Head of Engineering – Finance and Core at Agicap, available in the [`cncf/toc` repository](https://github.com/cncf/toc/tree/main/projects/openfga), and a [presentation in the OpenFGA community meeting on Agicap's OpenFGA deployment](https://www.youtube.com/watch?v=XBHqGFfe-K4).
46 changes: 46 additions & 0 deletions docs/content/adopters/docker.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
title: Docker Case Study
description: How Docker migrated to OpenFGA with a parallel-run strategy and now uses ReBAC to centralize permissions across products.
sidebar_position: 3
slug: /adopters/docker
---

# Docker: Centralizing permissions with ReBAC

[Docker](https://www.docker.com) provides tools that help developers build, share, run, and verify applications across environments. Docker adopted OpenFGA in early 2024 and uses it to centralize authorization across an expanding set of products.

## At a glance

| | |
| --- | --- |
| **Industry** | Developer tools / platform |
| **In production since** | March 2024 |
| **Scale** | 100-150 requests per second |
| **Deployment** | Self-hosted |
| **Key features used** | ReBAC, DSL, SDKs and CLI |

## Why OpenFGA

Docker evaluated several access-control systems before choosing OpenFGA. The decision came down to:

- **ReBAC** as a more flexible model than RBAC for the products Docker builds.
- **Self-hosted, open source**, easy to run locally (a working stack via Docker Compose in under five minutes).
- **CNCF backing** and contributors with strong security pedigree.
- Mature **SDKs, APIs, and testing tools**.
- A responsive maintainer community.

## Migration approach

Docker ran OpenFGA in **parallel with the existing authorization system**: every permission check went to both engines, and results were compared. Once both systems consistently agreed, traffic was incrementally cut over to OpenFGA. The parallel-run pattern is one we recommend for any production migration — see the [adoption patterns guide](/docs/best-practices).

## Outcomes

- Permission changes that previously required code changes are now centralized in the authorization model file.
- New Docker products integrate into the access-control system faster.
- Operational overhead for permission updates dropped substantially.

The early scaling pain points the team hit — particularly batch checks across many records — were addressed quickly by upstream releases.

## Source

This case study is based on the public CNCF TOC adopter interview with Gurleen Sethi, Senior Software Engineer at Docker, Inc., available in the [`cncf/toc` repository](https://github.com/cncf/toc/tree/main/projects/openfga).
54 changes: 54 additions & 0 deletions docs/content/adopters/grafana.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: Grafana Labs Case Study
description: Why Grafana Labs replaced its single-tenant access control engine with OpenFGA to power multi-tenant Grafana Cloud and embedded OSS deployments.
sidebar_position: 4
slug: /adopters/grafana
---

# Grafana Labs: From single-tenant engine to multi-tenant ReBAC

[Grafana Labs](https://grafana.com) is the company behind Grafana, Loki, Tempo, Mimir, and the LGTM observability stack. Grafana adopted OpenFGA to replace an internal single-tenant access-control engine that no longer fit the multi-tenant architecture of Grafana Cloud.

## At a glance

| | |
| --- | --- |
| **Industry** | Observability |
| **First experiments** | February 2024 |
| **Mainline integration** | August 2024 |
| **Version** | v1.10.0 |
| **Deployment** | Multi-tenant SaaS, embedded OSS, on-premises |

## Why OpenFGA

Grafana needed an engine that did **two** things competitors did not bundle:

1. **Authorization evaluation** — like an OPA-style policy engine.
2. **A storage layer for permissions** — a tuple store with a per-tenant schema.

That combination, plus OpenFGA's **CNCF affiliation** and explicit governance policy, made it preferable to building yet another in-house system or adopting a project that could change its license later.

## Architecture and scale

OpenFGA runs in three Grafana environments:

- **Development and staging** — already serving internal production workloads.
- **External production** — deployed to a single cluster in a pre-production capacity, shadowing real traffic to validate consistency and performance before broader rollout.

The team standardized on the **PostgreSQL adapter** after finding the MySQL adapter less mature. Refactoring Grafana's legacy schema toward OpenFGA-native modeling produced significant performance gains — an outcome echoed by the [source-of-truth best practice](/docs/best-practices).

## Upstream investment

- Grafana **maintains the SQLite adapter**, which was contributed back to OpenFGA so it can ship with embedded Grafana.
- Future areas of contribution include **pluggable storage** (so non-core storage adapters work without rebuilding OpenFGA) and **observability** improvements.
- KubeCon EU 2025 talk: *From Chaos To Control: Migrating Access Control* by Jo Guerreiro and Poovamraj Thanganadar Thiagarajan.

## Outcomes

- One authorization platform spans Grafana Cloud (multi-tenant SaaS) and Grafana OSS (embedded), removing the need to maintain separate engines.
- Schema-driven iteration replaced engine-tuning work the team used to do manually.
- The team is targeting **list-users** to enable reverse permission search — showing all users who can access a given resource — a capability the legacy engine never had.

## Source

This case study is based on the public CNCF TOC adopter interview with Joao Guerreiro, Senior Engineering Manager at Grafana Labs, available in the [`cncf/toc` repository](https://github.com/cncf/toc/tree/main/projects/openfga).
46 changes: 46 additions & 0 deletions docs/content/adopters/headspace.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
title: Headspace Case Study
description: How Headspace authorizes Ebb, its empathetic AI companion, with OpenFGA — driving end-to-end checks down from 10–15 seconds to 10–15 milliseconds.
sidebar_position: 6
slug: /adopters/headspace
---

# Headspace: Authorizing an empathetic AI companion at consumer scale

[Headspace](https://www.headspace.com) is a global mental-health platform with over 105 million app downloads and 90 million lives reached. Its AI companion, Ebb, has handled more than 6 million conversations since launching, and every message Ebb processes runs through an OpenFGA authorization check.

## At a glance

| | |
| --- | --- |
| **Industry** | Mental health / consumer health |
| **Use case** | AI companion (Ebb) gating |
| **Scale** | 90M+ lives, 105M+ downloads, 6M+ Ebb messages |
| **Deployment** | Self-hosted |
| **Key features used** | BatchCheck, contextual tuples, graph design, Terraform-managed model |

## Why OpenFGA

Ebb is gated on a combination of business rules: who the member is contracted through, which country they are messaging from, which language their app is set to, and whether their employer has opted them out. A pure RBAC system could not express this without exploding into a role per combination, and a hand-rolled SQL check ran 10–15 seconds in the worst case — unacceptable for a chat experience.

The Headspace team chose OpenFGA so the AI gating rules could live in a single relationship graph the platform team owned, with the same model evaluated from every service that fronts Ebb.

## Architecture

- **Wrapper API in front of OpenFGA.** Application services do not call the OpenFGA store directly. They call an internal authorization service that fans out **four parallel [BatchCheck](/docs/interacting/relationship-queries) requests** — assigned-to-Ebb, country-allowed, language-allowed, and not-blocked-by-org — and combines the results.
- **Inverted graph for performance.** The original model put the AI feature at the top with users below; a check meant traversing the entire user population. Flipping the direction so the user is the object and Ebb access is reached through unions of small relations dropped end-to-end latency from 10–15 seconds to 10–15 milliseconds.
- **Bidirectional tuple writes.** When a member-to-feature relationship is written, the inverse tuple is written at the same time, keeping reads cheap in either direction.
- **Terraform-managed model and static tuples.** The authorization model and the static enablement tuples (countries, languages, default org policies) ship through the Headspace [OpenFGA Terraform provider](https://github.com/openfga/terraform-provider-openfga), so model changes go through the same review pipeline as infrastructure.
- **Hidden model version.** The wrapper API does not expose the OpenFGA model ID to consumers; rolling forward to a new model version is a deploy of the wrapper, not a coordinated change across every caller.
- **SDK 1.10 conflict resolution.** The team adopted the conflict-resolution behavior shipped in SDK 1.10 to safely handle concurrent tuple writes during high-traffic enrollment events.

## Outcomes

- **End-to-end Ebb authorization in 10-15 ms**, down from 10-15 seconds.
- **Per-user blocking added without touching call sites** — a new relation in the model and a tuple write was enough; no service had to ship code.
- **Single source of truth** for AI gating rules, owned by the platform team and reviewed in Terraform.
- **Operational headroom** to extend Ebb gating (new languages, new contracts, new opt-out criteria) without rewriting application code.

## Source

This case study is based on a [presentation in the OpenFGA community meeting by Jeremy, principal engineer at Headspace](https://www.youtube.com/watch?v=xCu39aG7B1A). Supporting public material on Ebb is available at [headspace.com](https://www.headspace.com).
44 changes: 44 additions & 0 deletions docs/content/adopters/openlane.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
title: OpenLane Case Study
description: How compliance-automation startup OpenLane wires OpenFGA into ent at the data-access layer, with overfetch + BatchCheck replacing slow ListObjects.
sidebar_position: 7
slug: /adopters/openlane
---

# OpenLane: Authorization at the data-access layer for compliance automation

[OpenLane](https://theopenlane.io) is an open-source compliance automation platform that helps teams achieve and maintain SOC 2, ISO 27001, and similar attestations. OpenFGA is wired into its data-access layer, so every GraphQL query and mutation is authorized without each resolver having to remember to ask.

## At a glance

| | |
| --- | --- |
| **Industry** | Compliance automation (GRC) |
| **Stack** | Go, GraphQL (gqlgen), [ent](https://entgo.io/) ORM, PostgreSQL, Kubernetes |
| **Deployment** | Self-hosted; separate Postgres databases for application data and OpenFGA |
| **Key features used** | BatchCheck, contextual tuples, object-owned cascading permissions, FGA-driven feature flags |

## Why OpenFGA

OpenLane builds the kind of platform whose customers will themselves be audited. Authorization had to be defensible end-to-end — every read, every write, every export — and could not live in a `if user.role == "admin"` switch sprinkled across resolvers. The team picked OpenFGA so authorization decisions were centralized, modeled as relationships, and could evolve without code changes in every service.

A second motivation was packaging: OpenLane sells modules, and the same engine that grants access to a record can grant access to a feature. OpenFGA is the source of truth for **both**.

## Architecture

- **Authorization as ent middleware.** OpenLane uses [ent](https://entgo.io/) hooks to write tuples on every mutation and interceptors plus policies to evaluate every query. Resolvers do not call the OpenFGA SDK directly; the data-access layer does.
- **Object-owned mixin.** A reusable ent mixin attaches `owner` and parent relations to any record type, so cascading permissions ("an editor of the parent program can edit each control") are declared once and applied uniformly.
- **Overfetch + BatchCheck instead of ListObjects.** An early implementation used [ListObjects](/docs/interacting/relationship-queries) and saw ~8-second worst-case latency for large result sets. The team switched to overfetching candidates from Postgres (capped at 100 per page, up to 1,000 overfetched) and running [BatchCheck](/docs/interacting/relationship-queries) to filter in a single round trip. Total counts are computed via a separate query that short-circuits when the user is an admin.
- **In-house wrapper packages.** Three small Go packages — `FGX` (typed helpers around the OpenFGA SDK), `NFGA` (no-op fakes for unit tests), and `access-map` (declarative relation registration) — keep callers honest and make adding a new entity type a few lines of mixin configuration.
- **OpenFGA-as-feature-flags.** Module entitlements ("does this tenant have the policy module?") live in the same OpenFGA store as record-level permissions, so a check that returns `false` because the user is not an editor and a check that returns `false` because the tenant did not buy the module use the same call site.

## Outcomes

- **Authorization can't be forgotten.** Hooks and interceptors mean a new entity type inherits authorization automatically.
- **List-style endpoints went from ~8 s worst case to comfortably under a second** at expected page sizes, without changing the public API.
- **One store, two jobs.** Record permissions and feature entitlements live in OpenFGA, so packaging changes don't require a second policy system.
- **Auditable end-to-end.** Tuple writes happen in the same transaction boundary as the underlying data mutation, so the access graph and the data it protects don't drift.

## Source

This case study is based on a [presentation in the OpenFGA community meeting by Sarah Funkhouser, co-founder and head of engineering at OpenLane](https://www.youtube.com/watch?v=ZdlftEKQ0UA). The OpenLane platform itself is open source — the integration patterns above are visible in the [theopenlane GitHub organization](https://github.com/theopenlane).
Loading