Configure Authentication and Access Through Config
Set up login, OAuth, and role mapping in grafana.ini, and handle users and teams as code.
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, soroot_urlmust be exact. role_attribute_pathis 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_uphere means “create a Grafana user on first SSO login”, which is what you want even when[users] allow_sign_upis 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 separateldap.tomlfile.
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:
| Resource | How to manage it as code |
|---|---|
| Users | Create through SSO, or the Admin API in a bootstrap script |
| Teams and team membership | Terraform (grafana_team), the API, or team sync from the identity provider |
| Organizations | Terraform (grafana_organization) or the API |
| Service accounts and tokens | Terraform (grafana_service_account, grafana_service_account_token) or the API |
| Folder and dashboard permissions | Terraform (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
-
Operate Grafana as Code: The Big Picture What can live in files, what needs an API, and how the pieces fit together. -
Configure the Grafana Server with grafana.ini and Environment Variables Know where config files live, how overrides are ordered, and how to keep settings in Git. -
Provision Dashboards from JSON Files Load dashboards from disk, map folders from directories, and author them without losing changes. -
Provision Alert Rules, Contact Points, and Notification Policies Define the whole alerting pipeline in YAML so it is reviewed and versioned like code. -
Deploy Grafana on Kubernetes with Helm and Provisioning Values Run Grafana from a Helm chart where data sources, dashboards, and settings all come from values files. -
Reload, Verify, and Troubleshoot Provisioning from the Command Line Find out what Grafana loaded, reload without a restart, and fix the usual provisioning errors.