Open-Source Wikis

/

Grafana

/

Backend

/

Auth

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/password
  • oauth — Generic OAuth, Google, GitHub, GitLab, Azure AD, Okta, Grafana.com, Hosted Grafana
  • jwt — JWT in headers / query param
  • session — cookie-backed sessions
  • service_account — service account tokens
  • anonymous — unauthenticated identity
  • render — short-lived render-job tokens
  • password — password reset / signup helpers
  • proxy — 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

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 in pkg/services/accesscontrol/roles.go and per-service roles.go files.
  • Scope — string like dashboards:uid:abc or folders:uid:xyz that narrows an action. Scopes are resolved by pkg/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.go wraps 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 declarations

How 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 and org_user rows (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.Client in pkg/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 call accesscontrol.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.

Auth – Grafana wiki | Factory