As part of migrating Grafana's authorization system to Zanzana (OpenFGA), we need to ensure that role permissions defined in the IAM API are automatically synced to the authorization backend. Without this sync, roles created through the API would not be enforced by Zanzana, creating an inconsistency between defined permissions and actual authorization decisions.
This is a critical piece of the dual-write pattern during the migration to Zanzana, ensuring that:
Role permissions are immediately available for authorization checks
The legacy RBAC system and new Zanzana system remain in sync
Users experience consistent permission enforcement regardless of which backend is queried
safe to revert
* Create and use common ResourceInfo struct
* Add support for formatting group resource with subresource
* Add initial support for handling subresource
* Add test for checking subresource for generic resource
* Bump authlib
* Zanzana: Pass contextual tuples for authorization
* global reconciler for fixed roles
* inject tuples from global store
* fix adding contextual tuples
* cleanup
* don't error on auth context fail
* add todo
* add context for List
* add caching
* remove unused
* use constant for global namespace
* Rename global namespace to cluster namespace
* Replace sql query with folder service call when collecting folder tree
* Update provider for folder service implementation for wire
* Refactor provisioning of oss service in folder permissions test util
* add service account to the schema
* sync managed permissions for service accounts
* sync SA basic roles
* sync SA roles
* Fix endless loop in reconciler while read openfga
* Zanzana: Search with list
* Allow to pass werb into list request
* split list search into 2 functions
* fix listing resources
* remove unused
* refactor
* remove unused function
* Add more logging to reconciler
* Fix search for users with access to all resources
* fix findFoldersZanzanaList
* search for folders as well by default
* refactor
* use compile for list and search
* remove list from client
* remove only from client
* remove list from interface
* run compile once
* refactor
* refactor
* add search tests
* fix tests
* Fix linter
* Move server init into server package
* map store name to id
* refactor model loading
* pass namespace into reconcilers and collectors
* refactor
* Extend authz server with Read and Write methods
* use new read/write in reconciler
* implement server side read and write
* Sync permissions for every org
* handle namespace in check and list
* split read and write
* provide conditions
* Fix client implementation
* fix nil conditions
* remove unused client code
* use lock for store access
* move type translators to common package
* fix folder collector
* fix store creation
* remove unused AuthorizationModelId
* fix server tests
* fix linter
* Remove collectors
* Remove zanzana search check, we need to rewrite that part to the new schema
* Only use generic resource schema and cleanup code we don't want to keep / need to re-write
* Rename to CheckObject
* Implement authz.AccessClient
* Move folder tree to reconciler and use new schema
* Move shared functionality to common package
* Add reconciler for managed permissions and resource translations
* Add support for folder resources
* Rewrite zanzana collector to fetch all available pages
* Register access control as a background service
* If zanzana is enabled we run Syncs and start Reconciliation job
* Update pkg/services/authz/zanzana/client/client.go
Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>
* Use server lock when doing performing reconciliation