Migrating Legacy Access Control to OpenFGA: Strategies, Challenges, and Lessons Learned

Migrating Legacy Access Control to OpenFGA: Strategies, Challenges, and Lessons Learned

This post is a summary of a talk I gave at Kubecon EU 2025 on April 04, 2025. If you're not familiar with the basics of OpenFGA, I recommend checking it out as Poovamraj, my co-host on the talk, does a great job of explaining the basics and the why of OpenFGA.

Migrating a legacy access control system, especially within a growing application or platform, presents significant challenges such as: response discrepancies, data migration, and performance concerns.

Why Choose OpenFGA?

When existing access control becomes complex, inconsistent, or a bottleneck due to decentralized logic, a standardized, fine-grained system is needed. OpenFGA, inspired by Google's Zanzibar, offers several advantages:

  • Fine-Grained Control: Its foundation in Relationship-Based Access Control (ReBAC) enables precise permissions.
  • Modularity and Uniformity: It provides a consistent authorization system that can scale.

There are other open source Zanzibar based engines like SpiceDB that are worth having a look at. Grafana chose OpenFGA as the project has been donated to the CNCF and its store concept works well with Grafana's multitenancy model.

Migrating years of legacy access control features isn't straightforward. A pragmatic, iterative approach is crucial:

  • Start Small: Don't attempt a full overhaul at once. Choose a representative resource (e.g., a specific feature set like folders and dashboards) to begin the migration. This allows for testing assumptions and gradual generalization.

  • Performance is not free: OpenFGA allows numerous relationship tuples, but excessive tuples can degrade performance. Complex schema designs also negatively impact performance. Carefully evaluate schema complexity and tuple volume. The best tuple is the one you don't have to write.

  • Database Choices Matter: OpenFGA supports various database integrations. Be aware that different database integrations have distinct performance characteristics. Currently Postgres is the most mature and performant option.

Multi-Tenancy Strategy with OpenFGA Stores

For multi-tenant environments, isolating tenant data is critical. At the same time, you want to avoid the overhead of a separate OpenFGA instance per tenant.

  • Regional Deployment: Consider running one OpenFGA instance per cluster or region to minimize latency. Avoid globally spanning instances if latency is a concern.

  • Leverage Stores: Use OpenFGA's store feature to create a dedicated namespace for each tenant. This prevents cross-tenant data leakage and simplifies deployment. Use middleware to map incoming requests to the correct tenant store.

What about the noisy neighbor problem, you might ask? By having your tenants in separate stores, in case of a noisy neighbor (superstar tenant), you can easily isolate the tenant by moving it to a separate instance.

Key Learnings for Data Migration

Migrating access control data requires robustness. This gets even more important when you have both on-premise and cloud deployments.

  • Plan for Toggles: Feature toggles controlling the migration will be flipped by users/customers. Ensure both legacy and new systems have the same behavior. If you fix an undesired corner case in the new system, fix it in the legacy system as well. That corner case is for sure going to be the reason a user clings to the legacy system. And to that effect:
  • Implement Shadow Calls: Implement shadow calls to verify the new access control service is working as expected.
  • Implement Dual-Write: Implement dual-write capabilities, ensuring changes write to both the legacy and new systems simultaneously.
  • Handle Upgrade/Downgrade Cycles: On-premise deployments frequently involve upgrades and downgrades. Don't rely solely on one-time data migrations. Continuously verify and reconcile the state between the old and new systems with periodic reconciliation jobs.
  • Contain the Legacy System: Migrations take time. Stabilize the legacy system but prevent its expansion by directing new development towards the new access control service.

The Challenge: Search with Fine-Grained Permissions

Integrating search functionality with granular permissions is complex. This is because you can't simply filter the results of a search query. You need to check permissions for each result. You need to account for data staleness, check latency, search volume, pagination, and more.

Several strategies exist as described in the OpenFGA docs:

  1. Search then Check: Query the database, then check permissions for each result with OpenFGA. Suitable for small datasets. If the user doesn't have access to many resources in a large dataset, this strategy will be slow.

If we imagine a search result of 1000 objects, and a user who has access to 100 objects, this strategy might check permissions for 1000 objects before filling a page.

Search then Check
  1. Filter by Allowed IDs: Retrieve allowed object IDs from OpenFGA and use these IDs to filter the database query. This becomes inefficient with many accessible objects due to extensive graph traversals and large query filters.
Filter by Allowed IDs
  1. Local Search Index: Use a local index for pre-filtering (helpful for high-cardinality access). This adds complexity in maintaining and syncing the index, though OpenFGA's watch endpoint can help, it's still an extra component to deploy and maintain.
Local Search Index

One option that is not listed in the docs is Pragmatic Filtering. Aggressively filter search results in your database before permission checks using readily available context (like tenant information from ID tokens). This often significantly reduces the scope, making simpler strategies like "Search then Check" viable again. If that is still not enough consider dynamically choosing strategies based on context or tenant statistics.

Pragmatic Filtering

To go further

You can check out Grafana's implementation and the OpenFGA adoption patterns for more implementation details and patterns. Hopefully, our lessons learned help you out! Huge thanks to the OpenFGA team and Poovamraj for their help prepping the talk for London. It was great to meet you all!