Secure Grafana with OAuth authentication and RBAC integration

Intermediate 45 min Apr 19, 2026 128 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Configure Grafana with OAuth SSO authentication, implement role-based access control (RBAC), and harden security with SSL certificates for enterprise-grade monitoring dashboard access.

Prerequisites

  • Domain name with DNS access
  • GitHub organization or similar OAuth provider
  • SSL certificate or ability to generate one

What this solves

Grafana's default admin login creates security risks in production environments where multiple teams need different access levels. OAuth authentication integrates with existing identity providers like Google, GitHub, or Azure AD, while RBAC ensures users only access appropriate dashboards and data sources.

Prerequisites and OAuth provider setup

Update system packages

Start with fresh package lists and security updates.

sudo apt update && sudo apt upgrade -y
sudo dnf update -y

Install Grafana if not already present

Install the latest Grafana version from the official repository.

sudo apt install -y apt-transport-https software-properties-common wget
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
sudo apt update
sudo apt install -y grafana
sudo dnf install -y wget
wget -q -O - https://packages.grafana.com/gpg.key | sudo rpm --import -
echo '[grafana]
name=grafana
baseurl=https://packages.grafana.com/oss/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packages.grafana.com/gpg.key' | sudo tee /etc/yum.repos.d/grafana.repo
sudo dnf install -y grafana

Create GitHub OAuth application

Register a new OAuth app in GitHub to enable authentication. Go to GitHub Settings > Developer settings > OAuth Apps > New OAuth App.

Use these settings:

  • Application name: Grafana Production
  • Homepage URL: https://monitoring.example.com
  • Authorization callback URL: https://monitoring.example.com/login/github

Save the Client ID and generate a new Client Secret. You'll need both for Grafana configuration.

Configure Grafana OAuth settings

Configure OAuth authentication

Edit the main Grafana configuration to enable GitHub OAuth and disable local signups.

[server]
protocol = https
http_port = 3000
domain = monitoring.example.com
root_url = https://monitoring.example.com/

[security]
admin_user = admin
admin_password = $__file{/etc/grafana/admin_password}
secret_key = $__file{/etc/grafana/secret_key}
disable_gravatar = true
cookie_secure = true
cookie_samesite = strict

[auth]
disable_login_form = false
disable_signout_menu = false
oauth_auto_login = false

[auth.github]
enabled = true
allow_sign_up = true
client_id = your_github_client_id_here
client_secret = $__file{/etc/grafana/github_client_secret}
scopes = user:email,read:org
auth_url = https://github.com/login/oauth/authorize
token_url = https://github.com/login/oauth/access_token
api_url = https://api.github.com/user
team_ids =
allowed_organizations = your-org-name
role_attribute_path = 
allow_assign_grafana_admin = false

[users]
allowed_sign_up = false
auto_assign_org = true
auto_assign_org_id = 1
auto_assign_org_role = Viewer
default_theme = dark

Store sensitive credentials securely

Create separate files for secrets to avoid exposing them in the main config.

sudo mkdir -p /etc/grafana/secrets
sudo chmod 750 /etc/grafana/secrets
sudo chown grafana:grafana /etc/grafana/secrets
echo "your_github_client_secret_here" | sudo tee /etc/grafana/github_client_secret
echo "$(openssl rand -hex 32)" | sudo tee /etc/grafana/secret_key
echo "$(openssl rand -base64 32)" | sudo tee /etc/grafana/admin_password
sudo chmod 640 /etc/grafana/github_client_secret /etc/grafana/secret_key /etc/grafana/admin_password
sudo chown root:grafana /etc/grafana/github_client_secret /etc/grafana/secret_key /etc/grafana/admin_password

Configure SSL certificates

Install SSL certificates for secure authentication. This example uses Let's Encrypt certificates.

sudo apt install -y certbot
sudo certbot certonly --standalone -d monitoring.example.com
sudo dnf install -y certbot
sudo certbot certonly --standalone -d monitoring.example.com

Update Grafana configuration with SSL certificate paths:

[server]
protocol = https
http_port = 3000
cert_file = /etc/letsencrypt/live/monitoring.example.com/fullchain.pem
cert_key = /etc/letsencrypt/live/monitoring.example.com/privkey.pem

Set up RBAC and team mapping

Enable RBAC in Grafana configuration

Configure role-based access control for fine-grained permissions.

[rbac]
permission_cache = true

[feature_toggles]
enable = accesscontrol

[auth.github]
role_attribute_path = contains(groups[], 'monitoring-admins') && 'Admin' || contains(groups[], 'monitoring-editors') && 'Editor' || 'Viewer'

Create team mapping configuration

Set up automatic team assignment based on GitHub organization membership.

sudo mkdir -p /etc/grafana/provisioning/access-control
sudo mkdir -p /etc/grafana/provisioning/teams
apiVersion: 1

teams:
  - name: monitoring-admins
    email: monitoring-admins@example.com
    orgId: 1
  - name: monitoring-editors
    email: monitoring-editors@example.com
    orgId: 1
  - name: monitoring-viewers
    email: monitoring-viewers@example.com
    orgId: 1

Configure role permissions

Define granular permissions for each role using RBAC policies.

apiVersion: 1

roles:
  - name: monitoring:viewer:restricted
    description: "Restricted viewer with limited dashboard access"
    version: 1
    orgId: 1
    permissions:
      - action: dashboards:read
        scope: dashboards:*
      - action: datasources:query
        scope: datasources:*

  - name: monitoring:editor:infrastructure
    description: "Infrastructure team editor permissions"
    version: 1
    orgId: 1
    permissions:
      - action: dashboards:read
        scope: dashboards:*
      - action: dashboards:write
        scope: dashboards:*
      - action: datasources:query
        scope: datasources:*
      - action: alerts:read
        scope: alerts:*
      - action: alerts:write
        scope: alerts:*

role_assignments:
  - role_uid: monitoring:viewer:restricted
    teams:
      - monitoring-viewers
  - role_uid: monitoring:editor:infrastructure
    teams:
      - monitoring-editors

Security hardening

Configure security headers and session settings

Implement additional security measures to protect against common web vulnerabilities.

[security]
content_type_protection_header = true
x_content_type_options = nosniff
x_xss_protection = true
strict_transport_security = true
strict_transport_security_max_age_seconds = 86400
strict_transport_security_preload = true
strict_transport_security_subdomains = true
x_frame_options = deny
cookie_secure = true
cookie_samesite = strict
session_life_time = 86400
token_rotation_interval_minutes = 10

[log]
mode = syslog
level = warn
filters = oauth:debug

Configure firewall rules

Restrict access to Grafana to authorized networks only.

sudo ufw allow from 203.0.113.0/24 to any port 3000
sudo ufw allow from 198.51.100.0/24 to any port 3000
sudo ufw --force enable
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='203.0.113.0/24' port protocol='tcp' port='3000' accept"
sudo firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='198.51.100.0/24' port protocol='tcp' port='3000' accept"
sudo firewall-cmd --reload

Set correct file permissions

Secure configuration files with appropriate ownership and permissions.

sudo chown -R grafana:grafana /etc/grafana/
sudo chmod 640 /etc/grafana/grafana.ini
sudo chmod -R 640 /etc/grafana/provisioning/
sudo chmod 750 /etc/grafana/provisioning/
sudo find /etc/grafana/provisioning/ -type d -exec chmod 750 {} \;
Never use chmod 777. It gives every user on the system full access to your files. Instead, fix ownership with chown and use minimal permissions like 640 for config files.

Start and enable Grafana service

Enable automatic startup and start the Grafana service with new configuration.

sudo systemctl daemon-reload
sudo systemctl enable grafana-server
sudo systemctl restart grafana-server
sudo systemctl status grafana-server

Verify your setup

Test OAuth authentication and RBAC configuration.

sudo systemctl status grafana-server
sudo journalctl -u grafana-server -f --no-pager

Visit https://monitoring.example.com:3000 and verify:

  • SSL certificate is valid and secure
  • "Sign in with GitHub" button appears
  • OAuth flow redirects to GitHub and back successfully
  • User roles are assigned based on GitHub organization membership
curl -k -I https://monitoring.example.com:3000/api/health

Common issues

SymptomCauseFix
OAuth callback errorWrong callback URL in GitHub appUpdate GitHub OAuth app callback URL to match root_url + /login/github
SSL certificate errorsGrafana can't read certificate filesCheck ownership: sudo chown grafana:grafana /etc/letsencrypt/live/monitoring.example.com/*.pem
Users assigned wrong rolesGitHub team mapping not workingVerify GitHub organization visibility and user membership in teams
Grafana won't startConfiguration syntax errorCheck logs: sudo journalctl -u grafana-server and validate config syntax
Permission denied for secretsWrong file ownershipFix with: sudo chown root:grafana /etc/grafana/github_client_secret && sudo chmod 640 /etc/grafana/github_client_secret

Next steps

Running this in production?

Want this handled for you? Setting this up once is straightforward. Keeping it patched, monitored, backed up and performant across environments is the harder part. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle infrastructure security hardening for businesses that depend on uptime. From initial setup to ongoing operations.