Grafana Grafana

Configure Authentication and Access Through Config

Set up login, OAuth, and role mapping in grafana.ini, and handle users and teams as code.

12 min Intermediate

Who can log in, and with what role, is part of the platform and belongs in version control as much as dashboards do. Most of it lives in grafana.ini. The rest, such as users, teams, and service accounts, has no provisioning file format, so this guide also shows how to manage those as code. Option names below match the Grafana configuration reference, but verify them against defaults.ini for your version before relying on them.

Basic settings

[users]
allow_sign_up = false          # no self-registration
auto_assign_org = true
auto_assign_org_role = Viewer  # default role for new users

[auth]
disable_login_form = false     # set true once SSO works and you no longer need the form

[auth.anonymous]
enabled = false

Keep allow_sign_up = false unless you deliberately want an open instance. If you do enable anonymous access, give it the least role possible:

[auth.anonymous]
enabled = true
org_role = Viewer

Single sign-on with generic OAuth

Any OpenID Connect or OAuth 2 provider can be wired up in the file. Secrets come from the environment:

[server]
root_url = https://grafana.example.com/

[auth.generic_oauth]
enabled = true
name = Company SSO
allow_sign_up = true
client_id = grafana
client_secret = ${OAUTH_CLIENT_SECRET}
scopes = openid profile email groups
auth_url = https://sso.example.com/oauth2/authorize
token_url = https://sso.example.com/oauth2/token
api_url = https://sso.example.com/oauth2/userinfo
login_attribute_path = preferred_username
email_attribute_path = email
role_attribute_path = contains(groups[*], 'grafana-admins') && 'Admin' || contains(groups[*], 'grafana-editors') && 'Editor' || 'Viewer'

What to know:

  • The provider’s redirect URI is <root_url>login/generic_oauth, so root_url must be exact.
  • role_attribute_path is a JMESPath expression evaluated against the user’s token or userinfo. It maps identity-provider groups to Grafana roles (Admin, Editor, Viewer), so role changes happen in the identity provider, not in Grafana.
  • allow_sign_up here means “create a Grafana user on first SSO login”, which is what you want even when [users] allow_sign_up is false.
  • Dedicated sections exist for common providers ([auth.github], [auth.google], [auth.azuread], [auth.gitlab], and others), and SAML and LDAP are available in Grafana Enterprise and Grafana Cloud. LDAP also reads a separate ldap.toml file.

Once SSO works, set disable_login_form = true and keep the admin account only as a break-glass option, or leave the form enabled but protect it by network rules.

Roles and what files can’t set

Grafana has organization roles (Admin, Editor, Viewer), and RBAC adds fine-grained roles in Enterprise and Cloud. These resources have no provisioning file format in open source Grafana:

ResourceHow to manage it as code
UsersCreate through SSO, or the Admin API in a bootstrap script
Teams and team membershipTerraform (grafana_team), the API, or team sync from the identity provider
OrganizationsTerraform (grafana_organization) or the API
Service accounts and tokensTerraform (grafana_service_account, grafana_service_account_token) or the API
Folder and dashboard permissionsTerraform (grafana_folder_permission, grafana_dashboard_permission), the Operator, or the API

The Terraform guide shows the pattern. For a small setup, a one-off script that calls the HTTP API with an admin credential, kept in the repository and run in CI, is a reasonable alternative.

Bootstrap service accounts for automation

Tools like Terraform, the Operator, and CI need a non-human identity. Create a service account once, with the lowest role that works, and store its token as a secret:

# create the service account (Admin API, basic auth)
curl -s -X POST -u admin:$GRAFANA_ADMIN_PASSWORD \
  -H 'Content-Type: application/json' \
  -d '{"name":"terraform","role":"Admin"}' \
  http://localhost:3000/api/serviceaccounts

# create a token for it, using the id returned above
curl -s -X POST -u admin:$GRAFANA_ADMIN_PASSWORD \
  -H 'Content-Type: application/json' \
  -d '{"name":"terraform-token"}' \
  http://localhost:3000/api/serviceaccounts/<id>/tokens

The token is shown once. Put it straight into your secret store, and set an expiry or rotate it on a schedule.

Hardening settings worth committing

[security]
cookie_secure = true
cookie_samesite = lax
disable_gravatar = true
allow_embedding = false

[auth]
login_maximum_lifetime_duration = 30d
login_maximum_inactive_lifetime_duration = 7d

Review them when you upgrade, and keep them identical across environments except where a value genuinely differs, such as root_url.

Verify without the UI

curl -s -u admin:$GRAFANA_ADMIN_PASSWORD http://localhost:3000/api/admin/settings | jq '."auth.generic_oauth" | {enabled, name}'
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD http://localhost:3000/api/users | jq '.[] | {login, isAdmin}'
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD http://localhost:3000/api/teams/search | jq '.teams[].name'

For the full list of options per provider, see the Grafana authentication documentation.

Popular Guides