CIS Grafana Benchmark

Security configuration recommendations for Grafana observability platform

v1.0.0 01-2025

Overview

▶

This benchmark provides prescriptive guidance for establishing a secure configuration posture for Grafana. It covers authentication, access control, data source security, plugin governance, alerting configuration, logging, and web security for Grafana instances deployed in enterprise environments.

16Recommendations
7Sections
2Profile Levels
SectionAreaFocus
1AuthenticationAnonymous access control and external identity provider integration
2Access ControlOrganization roles and dashboard/folder permission management
3Data Source SecurityProxy mode enforcement and infrastructure-as-code provisioning
4Plugin GovernanceSignature verification and plugin lifecycle management
5AlertingNotification channels and evaluation interval configuration
6Logging & MonitoringDetailed audit logging and SIEM integration
7Web SecurityHTTPS, CSP headers, and secret key management

Profile Definitions

▶
ProfileDescriptionIntended Use
L1Level 1 — StandardEssential security for all Grafana deployments; minimal performance impact.
L2Level 2 — HardenedAdvanced hardening for PCI-DSS, HIPAA, or high-security environments.

1 — Authentication

▶

1.1 Identity Providers

▶
1.1.1 Ensure anonymous access is disabled (Automated)
L1 Auto
Description

This recommendation verifies that anonymous access is disabled on the Grafana observability platform. Disabling or removing unnecessary components reduces the attack surface and limits potential vectors for exploitation.

Rationale

Running unnecessary components on the Grafana observability platform increases the attack surface and the risk of exploitation. Disabling or removing them follows the principle of least functionality and reduces exposure to known vulnerabilities.

Audit
# Check anonymous access:
grep -E '^\[auth\.anonymous\]' -A5 /etc/grafana/grafana.ini

# Via API:
curl -s http://localhost:3000/api/org/preferences | jq .
Remediation
# Disable anonymous access:
# /etc/grafana/grafana.ini:
[auth.anonymous]
enabled = false

sudo systemctl restart grafana-server
1.1.2 Ensure external authentication is configured (Automated)
L1 Auto
Description

This recommendation verifies that external authentication is configured on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check LDAP/OAuth configuration:
grep -E '^\[auth\.(ldap|generic_oauth|saml)\]' -A10 /etc/grafana/grafana.ini

# Check LDAP config:
cat /etc/grafana/ldap.toml | grep -v '^#' | grep -v '^$'
Remediation
# Configure LDAP authentication:
# /etc/grafana/grafana.ini:
[auth.ldap]
enabled = true
config_file = /etc/grafana/ldap.toml
allow_sign_up = true

# /etc/grafana/ldap.toml:
[[servers]]
host = "ldap.example.com"
port = 636
use_ssl = true
ssl_skip_verify = false
bind_dn = "cn=grafana,ou=svc,dc=example,dc=com"
bind_password = '${LDAP_BIND_PW}'
search_filter = "(sAMAccountName=%s)"
search_base_dns = ["ou=users,dc=example,dc=com"]

2 — Access Control

▶

2.1 Roles & Permissions

▶
2.1.1 Ensure least privilege organization roles are set (Automated)
L1 Auto
Description

This recommendation verifies that least privilege organization roles are set on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check organization role defaults:
curl -s -u admin:admin http://localhost:3000/api/org | jq .

# List all users with roles:
curl -s -u admin:admin http://localhost:3000/api/org/users | \
  jq '.[] | {login, role}'
Remediation
# Set restrictive default org role:
# /etc/grafana/grafana.ini:
[users]
auto_assign_org_role = Viewer

# Disable org creation:
allow_org_create = false

# Disable user sign-up:
[users]
allow_sign_up = false
2.1.2 Ensure dashboard and folder permissions are configured (Manual)
L1 Manual
Description

This recommendation verifies that dashboard and folder permissions are configured on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check dashboard permissions:
curl -s -u admin:admin \
  http://localhost:3000/api/dashboards/uid/DASH_UID/permissions | jq .

# Check folder permissions:
curl -s -u admin:admin \
  http://localhost:3000/api/folders | jq '.[].title'
Remediation
# Set folder-level permissions:
curl -s -u admin:admin -X POST \
  http://localhost:3000/api/folders/FOLDER_UID/permissions \
  -H 'Content-Type: application/json' \
  -d '{
    "items": [
      {"role": "Viewer", "permission": 1},
      {"role": "Editor", "permission": 2},
      {"teamId": 1, "permission": 4}
    ]
  }'

3 — Data Source Security

▶

3.1 Connection & Provisioning

▶
3.1.1 Ensure data source proxy mode is used (Automated)
L1 Auto
Description

This recommendation verifies that data source proxy mode is used on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check data source access mode:
curl -s -u admin:admin \
  http://localhost:3000/api/datasources | \
  jq '.[] | {name, type, access, basicAuth}'
Remediation
# Configure data source with proxy access:
curl -s -u admin:admin -X PUT \
  http://localhost:3000/api/datasources/1 \
  -H 'Content-Type: application/json' \
  -d '{
    "access": "proxy",
    "basicAuth": true,
    "withCredentials": true,
    "secureJsonData": {
      "basicAuthPassword": "secure-password"
    }
  }'
3.1.2 Ensure data sources are provisioned as code (Manual)
L2 Manual
Description

This recommendation verifies that data sources are provisioned as code on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check data source provisioning:
ls -la /etc/grafana/provisioning/datasources/
cat /etc/grafana/provisioning/datasources/*.yaml 2>/dev/null | \
  grep -v '^#'
Remediation
# Use provisioning for data sources:
# /etc/grafana/provisioning/datasources/ds.yaml:
apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
    editable: false
    secureJsonData:
      httpHeaderValue1: 'Bearer ${PROM_TOKEN}'

4 — Plugin Governance

▶

4.1 Plugin Management

▶
4.1.1 Ensure plugin signature verification is enforced (Automated)
L1 Auto
Description

This recommendation ensures that plugin signature verification is enforced on the Grafana observability platform. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.

Rationale

Without this enforcement, the Grafana observability platform may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.

Audit
# Check plugin signature verification:
grep -E 'plugin_admin_enabled|allow_loading_unsigned_plugins' \
  /etc/grafana/grafana.ini

# List installed plugins:
grafana-cli plugins ls
Remediation
# Enforce plugin signature verification:
# /etc/grafana/grafana.ini:
[plugins]
enable_alpha = false
allow_loading_unsigned_plugins =
plugin_admin_enabled = true
plugin_admin_external_manage_enabled = false

# Only install signed plugins:
grafana-cli plugins install grafana-piechart-panel
4.1.2 Ensure plugins are kept up to date (Automated)
L1 Auto
Description

This recommendation verifies that plugins are kept up to date on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check for outdated plugins:
grafana-cli plugins ls 2>/dev/null | grep -i update

# Check plugin catalog:
curl -s -u admin:admin \
  http://localhost:3000/api/plugins?embedded=0 | \
  jq '.[] | {id, name, type, info: .info.version}'
Remediation
# Update all plugins:
grafana-cli plugins update-all
sudo systemctl restart grafana-server

# Remove unused plugins:
grafana-cli plugins remove <plugin-id>

5 — Alerting

▶

5.1 Alert Configuration

▶
5.1.1 Ensure alert notification channels are configured (Automated)
L1 Auto
Description

This recommendation verifies that alert notification channels are configured on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check alerting configuration:
curl -s -u admin:admin \
  http://localhost:3000/api/v1/provisioning/alert-rules | jq '.[0]'

# Check notification channels:
curl -s -u admin:admin \
  http://localhost:3000/api/v1/provisioning/contact-points | jq .
Remediation
# Configure alert notification channels:
# /etc/grafana/provisioning/alerting/notifications.yaml:
apiVersion: 1
contactPoints:
  - orgId: 1
    name: ops-team
    receivers:
      - uid: email-ops
        type: email
        settings:
          addresses: ops@example.com
      - uid: slack-ops
        type: slack
        settings:
          url: https://hooks.slack.com/services/xxx
          channel: '#alerts'
5.1.2 Ensure alert evaluation intervals are appropriate (Automated)
L1 Auto
Description

This recommendation verifies that alert evaluation intervals are appropriate on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check alert rule evaluation:
curl -s -u admin:admin \
  http://localhost:3000/api/v1/provisioning/alert-rules | \
  jq '.[].for'
Remediation
# Set minimum evaluation interval:
# /etc/grafana/grafana.ini:
[unified_alerting]
enabled = true
min_interval = 10s

# Ensure alert rules have appropriate 'for' duration:
# to avoid flapping alerts and excessive notifications

6 — Logging & Monitoring

▶

6.1 Audit Logging

▶
6.1.1 Ensure detailed logging is enabled (Automated)
L1 Auto
Description

This recommendation verifies that detailed logging is enabled on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check audit logging:
grep -E '^\[log\]' -A10 /etc/grafana/grafana.ini
grep 'audit' /etc/grafana/grafana.ini
Remediation
# Enable detailed logging:
# /etc/grafana/grafana.ini:
[log]
mode = file console
level = info
filters = rendering:debug

[log.file]
log_rotate = true
max_lines = 1000000
max_size_shift = 28
daily_rotate = true
max_days = 90
6.1.2 Ensure request logging is forwarded to SIEM (Automated)
L2 Auto
Description

This recommendation verifies that request logging is forwarded to SIEM on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check request logging:
grep 'router_logging' /etc/grafana/grafana.ini
Remediation
# Enable request logging:
# /etc/grafana/grafana.ini:
[server]
router_logging = true

# Forward to SIEM:
# Filebeat config:
filebeat.inputs:
- type: log
  paths:
    - /var/log/grafana/grafana.log
  fields:
    app: grafana
output.elasticsearch:
  hosts: ["siem.example.com:9200"]

7 — Web Security

▶

7.1 Transport & Content Security

▶
7.1.1 Ensure HTTPS and secure cookies are configured (Automated)
L1 Auto
Description

This recommendation verifies that HTTPS and secure cookies are configured on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check HTTPS configuration:
grep -E '^protocol|^cert_file|^cert_key' /etc/grafana/grafana.ini

# Check cookies:
grep -E 'cookie_secure|cookie_samesite|strict_transport' \
  /etc/grafana/grafana.ini
Remediation
# Enable HTTPS:
# /etc/grafana/grafana.ini:
[server]
protocol = https
cert_file = /etc/grafana/ssl/grafana.crt
cert_key = /etc/grafana/ssl/grafana.key

[security]
cookie_secure = true
cookie_samesite = strict
strict_transport_security = true
strict_transport_security_max_age_seconds = 31536000
7.1.2 Ensure content security policy is enforced (Automated)
L1 Auto
Description

This recommendation ensures that content security policy is enforced on the Grafana observability platform. Enforcing this requirement establishes a minimum security standard and prevents insecure configurations.

Rationale

Without this enforcement, the Grafana observability platform may accept insecure configurations that weaken overall security posture. Mandating this control ensures consistent protection against common attack vectors.

Audit
# Check embedding and CSP:
grep -E 'allow_embedding|content_security_policy' \
  /etc/grafana/grafana.ini
Remediation
# Disable embedding and set CSP:
# /etc/grafana/grafana.ini:
[security]
allow_embedding = false
content_security_policy = true
content_security_policy_template = """script-src 'self' 'unsafe-eval' 'unsafe-inline' 'strict-dynamic' $NONCE; object-src 'none'; font-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; base-uri 'self'; connect-src 'self' grafana.com ws://$ROOT_PATH wss://$ROOT_PATH; manifest-src 'self'; media-src 'none'; form-action 'self';"""

[security]
x_content_type_options = true
x_xss_protection = true
7.1.3 Ensure a strong secret key is configured (Automated)
L1 Auto
Description

This recommendation verifies that a strong secret key is configured on the Grafana observability platform. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.

Rationale

Failure to implement this control may leave the Grafana observability platform vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.

Audit
# Check secret key configuration:
grep 'secret_key' /etc/grafana/grafana.ini | grep -v '^;'
Remediation
# Set a strong secret key:
# /etc/grafana/grafana.ini:
[security]
secret_key = $(openssl rand -hex 32)

# Rotate the secret key periodically
# Ensure grafana.ini is owned by grafana:grafana with 0640 perms:
sudo chown grafana:grafana /etc/grafana/grafana.ini
sudo chmod 0640 /etc/grafana/grafana.ini