Authorization / Access control
Description
The commit extends the Zanzana authorization schema to include create permissions for user and service-account resources. Previously, create operations on these resources were not defined in the authorization checks, which could allow a user with read/list permissions to trigger creation of users or service accounts without proper authorization. This patch ensures that create actions are evaluated by the authorization layer, addressing an authorization/access-control vulnerability related to resource creation.
Proof of Concept
PoC (illustrative, to reproduce in a test environment):
Prerequisites:
- Grafana instance with Zanzana authorization enabled, running a pre-fix version (<= 12.4.0).
- A user with at least read/list permissions on user/service-account resources but WITHOUT create permissions.
- A test admin account to observe the difference between vulnerable and fixed behavior.
Reproduction in vulnerable version (before the patch):
1) Authenticate as a non-admin user who has read/list access to users and service accounts.
2) Attempt to create a new user via the Grafana API (endpoint names may vary by version, examples shown for illustration):
POST https://grafana.example.com/api/org/users
Headers: Authorization: Bearer <non-admin-token>
Content-Type: application/json
{
"name": "pwnedUser",
"login": "pwnedUser",
"email": "pwned@example.com",
"password": "P@ssw0rd!"
}
3) Expected (vulnerable) outcome: API responds 200 OK (or 201 Created) and the user is created despite lacking create permission, due to missing create checks in the authorization schema.
Fixed behavior after this patch:
1) Repeat the same steps as above with the patched Grafana instance.
2) Expected outcome: API responds with 403 Forbidden (or appropriate access denied) and the user is not created, because the create permission is now defined and enforced by Zanzana.
Optional service-account example (illustrative):
POST https://grafana.example.com/api/service-accounts
Headers: Authorization: Bearer <non-admin-token>
Body:
{
"name": "pwned-sa",
"roles": ["viewer"]
}
Expected vulnerable result: 200 OK; Fixed result: 403 Forbidden.
Notes:
- Endpoints above are representative; actual Grafana API paths may differ by version.
- The PoC is intended to reproduce in a controlled test environment to verify enforcement of create permissions for user and service-account resources.
Commit Details
Author: Alexander Zobnin
Date: 2026-06-29 14:23 UTC
Message:
Zanzana: Add create relation for users and service accounts (#127450)
Follow-up to #127321, adds the create relation for user and service-account
core types so authorization checks for create on these resources don't fail.
Triage Assessment
Vulnerability Type: Authorization / Access control
Confidence: HIGH
Reasoning:
The commit extends the authorization schema to include create permissions for user and service-account resources, ensuring that creation operations are subject to access control checks. This prevents potential unauthorized creation actions that could bypass existing security checks, addressing an authorization-related vulnerability.
Verification Assessment
Vulnerability Type: Authorization / Access control
Confidence: HIGH
Affected Versions: Grafana <= 12.4.0 (prior to this patch)
Code Diff
diff --git a/pkg/services/authz/zanzana/schema/schema_core.fga b/pkg/services/authz/zanzana/schema/schema_core.fga
index a8fa990bc6091..01c94cd6a5d86 100644
--- a/pkg/services/authz/zanzana/schema/schema_core.fga
+++ b/pkg/services/authz/zanzana/schema/schema_core.fga
@@ -3,6 +3,7 @@ module core
type user
relations
define get: [user, service-account, team#member, role#assignee]
+ define create: [user, service-account, team#member, role#assignee]
define update: [user, service-account, team#member, role#assignee]
define delete: [user, service-account, team#member, role#assignee]
@@ -12,6 +13,7 @@ type user
type service-account
relations
define get: [user, service-account, team#member, role#assignee]
+ define create: [user, service-account, team#member, role#assignee]
define update: [user, service-account, team#member, role#assignee]
define delete: [user, service-account, team#member, role#assignee]