grafana/grafana
Authentication & access control
Authentication and authorization in Grafana are split across several services that interact through middleware.
Authentication (who is the user?)
graph TD
Req[Incoming HTTP request] --> CH[contexthandler<br/>pkg/services/contexthandler]
CH --> Resolve[Resolve identity]
Resolve --> Basic[basic auth client]
Resolve --> OAuth[oauth client]
Resolve --> JWT[jwt client]
Resolve --> SA[service account client]
Resolve --> Anon[anonymous client]
Resolve --> Render[render token client]
Resolve --> LDAP[ldap]
Basic & OAuth & JWT & SA & Anon & Render & LDAP --> Identity[identity.Requester<br/>SignedInUser]
Identity --> Ctx[ReqContext]pkg/services/contexthandler/contexthandler.go is the entry middleware: it consults the registered auth clients in order and produces an identity.Requester which is attached to the per-request *contextmodel.ReqContext.
The clients themselves live in pkg/services/authn/clients/. Each implements the authn.Client interface defined in pkg/services/authn/authn.go:
basic— username/passwordoauth— Generic OAuth, Google, GitHub, GitLab, Azure AD, Okta, Grafana.com, Hosted Grafanajwt— JWT in headers / query paramsession— cookie-backed sessionsservice_account— service account tokensanonymous— unauthenticated identityrender— short-lived render-job tokenspassword— password reset / signup helpersproxy— auth-proxy header
Configuration
Each provider has its own [auth.<name>] INI section (see conf/defaults.ini). For OAuth providers, configuration is increasingly persisted in the database via pkg/services/ssosettings/ so it can be edited from the UI without a server restart.
LDAP is configured via conf/ldap.toml and implemented in pkg/services/ldap/.
Identity primitives
The runtime identity is *user.SignedInUser (pkg/services/user/user.go) — it carries UserID, OrgID, role, permissions snapshot, and identity flags. Newer code prefers the identity.Requester interface (subsumed by SignedInUser) since it covers users, service accounts, and anonymous identities uniformly.
Sessions and tokens
- Session tokens are stored in the database and validated by
pkg/services/auth/authimpl/. - Refresh / rotate logic for OAuth tokens lives in
pkg/services/oauthtoken/. - Bruteforce protection is in
pkg/services/loginattempt/(rate limits per IP/username).
Anonymous
Anonymous users get a synthesized identity if [auth.anonymous] is enabled. Active anonymous sessions are tracked in pkg/services/anonymous/ for stats and quota.
Service accounts
Service accounts are user-like entities scoped to an org. Tokens are issued via pkg/services/serviceaccounts/ and authenticate identically to users via the service_account authn client. Legacy API keys still resolve via pkg/services/apikey/ but are migrated to service-account tokens internally.
Authorization (what can the user do?)
pkg/services/accesscontrol/ is the RBAC engine.
Concepts
- Action — string like
dashboards:read,users:write,alert.rules:create. Defined per-domain inpkg/services/accesscontrol/roles.goand per-serviceroles.gofiles. - Scope — string like
dashboards:uid:abcorfolders:uid:xyzthat narrows an action. Scopes are resolved bypkg/services/accesscontrol/resolvers.go. - Role — set of (action, scope) pairs. Built-in roles plus custom roles managed via the RBAC API.
- Evaluator — checks whether an identity has the requested permissions against a resource. The middleware in
pkg/services/accesscontrol/middleware.gowraps handlers with these checks.
Layout
pkg/services/accesscontrol/
├── accesscontrol.go # Service interface
├── acimpl/ # Implementation
├── ossaccesscontrol/ # OSS-specific resolution (built-in roles)
├── api/ # /api/access-control/* endpoints
├── database/ # Permission persistence
├── resourcepermissions/ # Per-resource permission CRUD (e.g. dashboard ACLs)
├── middleware.go # Authorize() middleware factory
├── evaluator.go # Evaluator implementation
├── filter.go # SQL filter helpers (so list queries respect ACLs)
├── resolvers.go # Scope resolvers (turn `dashboards:uid:*` → list)
└── roles.go # Built-in roles & action declarationsHow an authorized handler looks
// pkg/api/api.go
folderRoute.Get("/:uid",
middleware.ReqSignedIn,
accesscontrol.Middleware(ac, accesscontrol.EvalPermission("folders:read", folderUIDScope)),
routing.Wrap(hs.GetFolderByUID),
)The middleware delegates to evaluator.Evaluate(...). If the identity is missing the permissions, the request is rejected with 403 before reaching the handler.
List filtering
For list endpoints, a single ACL middleware would force returning 403 even if the user has access to some rows. Instead, services build SQL filters with pkg/services/accesscontrol/filter.go so that database queries only return rows the identity can see.
Resource permissions
Per-resource ACLs (the dashboard "Permissions" tab UI) are managed by pkg/services/accesscontrol/resourcepermissions/. It exposes a generic CRUD interface that every permissioned resource (dashboards, folders, datasources, …) reuses.
Org and team membership
pkg/services/org/— orgs andorg_userrows (role per (user, org)).pkg/services/team/— teams and team members. Roles can be granted to teams, and an identity inherits all role permissions of its teams.
Key source files
| File | Purpose |
|---|---|
pkg/services/contexthandler/contexthandler.go |
Authentication middleware |
pkg/services/authn/authn.go |
authn.Client interface |
pkg/services/authn/clients/ |
One file per auth method |
pkg/services/accesscontrol/middleware.go |
RBAC middleware |
pkg/services/accesscontrol/evaluator.go |
Permission evaluation |
pkg/services/accesscontrol/roles.go |
Built-in roles & action constants |
pkg/services/accesscontrol/filter.go |
SQL filter for list endpoints |
pkg/services/ssosettings/ |
DB-backed SSO config |
pkg/services/ldap/ |
LDAP client |
pkg/services/serviceaccounts/ |
Service accounts |
Where to start when modifying auth
- Add a new auth provider: implement
authn.Clientinpkg/services/authn/clients/<name>/, register it via Wire, add[auth.<name>]config keys, and update the SSO settings schema if the provider should be UI-configurable. - Add a new permission: pick the right service folder, add the action constant in its
roles.go, then callaccesscontrol.Middleware(ac, accesscontrol.EvalPermission(...))on the protected route. Don't forget the SQL filter for list endpoints. - Add a new resource type with ACLs: register it with
resourcepermissions.NewService(...)and let the generic CRUD do the rest.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.