Skip to main content
This guide provides comprehensive security recommendations for deploying and operating Grafana in production environments.

Overview

Security in Grafana involves multiple layers:
  • Network security and TLS/SSL
  • Authentication and authorization
  • Session management
  • Application security
  • Data protection
  • Monitoring and auditing

Network Security

Use HTTPS Everywhere

Always use HTTPS in production:
[server]
protocol = https
cert_file = /path/to/cert.pem
cert_key = /path/to/key.pem
min_tls_version = "TLS1.2"

[security]
cookie_secure = true
strict_transport_security = true
strict_transport_security_max_age_seconds = 31536000

Restrict Network Access

  1. Bind to specific interfaces
    [server]
    http_addr = 127.0.0.1  # Only localhost
    
  2. Use firewall rules
    # Allow only specific IPs
    iptables -A INPUT -p tcp --dport 3000 -s 10.0.0.0/8 -j ACCEPT
    iptables -A INPUT -p tcp --dport 3000 -j DROP
    
  3. Deploy behind reverse proxy
    • Use nginx, Apache, or cloud load balancers
    • Terminate TLS at the proxy
    • Add security headers

Domain and Origin Validation

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

[security]
csrf_trusted_origins = grafana.example.com
Reference: conf/defaults.ini:53-60

Authentication Security

Disable Default Admin

Change default admin credentials immediately:
[security]
# Disable auto-creation of admin user
disable_initial_admin_creation = true

# Or change default credentials
admin_user = your_admin
admin_password = strong_random_password
Reference: conf/defaults.ini:374-384

Enforce Strong Passwords

[auth.basic]
enabled = true
# Require strong passwords (12+ chars, mixed case, numbers, symbols)
password_policy = true
Reference: conf/defaults.ini:950-959

Disable Anonymous Access

[auth.anonymous]
enabled = false

Use External Authentication

Prefer external authentication over basic auth:
  • OAuth 2.0 with your identity provider
  • LDAP/Active Directory integration
  • SAML single sign-on
  • JWT authentication

Enable Login Protection

[security]
# Brute force protection
disable_brute_force_login_protection = false
brute_force_login_protection_max_attempts = 5

# Per-IP rate limiting
disable_ip_address_login_protection = false
Reference: conf/defaults.ini:402-411

OAuth Security

When using OAuth:
[auth.generic_oauth]
# Use PKCE for public clients
use_pkce = true

# Validate ID tokens
validate_id_token = true
jwk_set_url = https://provider.com/.well-known/jwks.json

# Use refresh tokens
use_refresh_token = true

# Restrict domains
allowed_domains = company.com

# Verify TLS certificates
tls_skip_verify_insecure = false
tls_client_ca = /path/to/ca.crt

LDAP Security

Secure LDAP configuration:
[[servers]]
# Use TLS
use_ssl = true
start_tls = false
ssl_skip_verify = false
min_tls_version = "TLS1.2"

# Verify certificates
root_ca_cert = "/path/to/ca.crt"

# Use service account with minimal permissions
bind_dn = "cn=grafana,ou=services,dc=example,dc=com"
bind_password = "${LDAP_BIND_PASSWORD}"
Reference: pkg/services/ldap/settings.go:35-66

Authorization and Access Control

Principle of Least Privilege

Grant minimum necessary permissions:
  1. Use built-in roles appropriately
    • Viewer: Read-only access
    • Editor: Create/edit dashboards
    • Admin: Organization management
  2. Limit Grafana Admin role
    • Only for platform administrators
    • Avoid granting via OAuth/SAML
    [auth.generic_oauth]
    allow_assign_grafana_admin = false
    
  3. Use teams for group permissions
    // Assign permissions to teams, not individuals
    service.SetTeamPermission(ctx, orgID, teamID, resourceID, "View")
    

Restrict Sensitive Permissions

Limit access to:
  • User management (users:write, users:delete)
  • Organization settings (orgs:write)
  • Datasource configuration (datasources:write)
  • Plugin installation (plugins:write)
  • LDAP configuration (ldap.config:reload)
Reference: pkg/services/accesscontrol/models.go:347-532

Disable Self-Registration

[users]
allow_sign_up = false
allow_org_create = false

[auth.generic_oauth]
allow_sign_up = false

Organization Isolation

Use organizations to separate tenants:
[users]
# Users can only see their orgs
viewers_can_edit = false
editors_can_admin = false

[auth]
# Prevent automatic org assignment
auto_assign_org = false

Session Security

Session Configuration

[security]
# Secure cookies
cookie_secure = true
cookie_samesite = strict

# Sign cookies
secret_key = CHANGE_THIS_TO_RANDOM_STRING
Reference: conf/defaults.ini:387-417

Token Security

The authentication system manages tokens securely:
type UserTokenService interface {
    // Create token with user context
    CreateToken(ctx context.Context, cmd *CreateTokenCommand) (*UserToken, error)
    
    // Rotate tokens on use
    RotateToken(ctx context.Context, cmd RotateCommand) (*UserToken, error)
    
    // Revoke compromised tokens
    RevokeToken(ctx context.Context, token *UserToken, soft bool) error
    
    // Limit concurrent sessions
    ActiveTokenCount(ctx context.Context, userID *int64) (int64, error)
}
Reference: pkg/services/auth/auth.go:80-95

Session Limits

Limit concurrent sessions per user:
[quota]
enabled = true
global_session = 1000

# Per-organization session limits
org_session = 100
Reference: conf/defaults.ini:1296

Application Security

Security Headers

Enable all security headers:
[security]
# Content sniffing protection
x_content_type_options = true

# XSS protection
x_xss_protection = true

# Content Security Policy
content_security_policy = true

# Prevent embedding (unless needed)
allow_embedding = false
Reference: conf/defaults.ini:435-446

Content Security Policy

Configure strict CSP:
[security]
content_security_policy = true
content_security_policy_template = """script-src 'self' 'strict-dynamic' $NONCE;object-src 'none';base-uri 'self';connect-src 'self' wss://$ROOT_PATH;form-action 'self';"""
Reference: conf/defaults.ini:448-451

CSRF Protection

Enable CSRF protection:
[security]
# Check CSRF even without login cookie
csrf_always_check = true

# Trust specific origins
csrf_trusted_origins = grafana.example.com

# Additional validation headers
csrf_additional_headers = X-Forwarded-Host
The CSRF middleware validates requests:
func (c *CSRF) check(r *http.Request) error {
    // Skip safe methods (HEAD, OPTIONS, TRACE)
    // Validate Origin header matches request host
    // Check against trusted origins
    // Verify custom headers if configured
}
Reference: pkg/middleware/csrf/csrf.go:71-141

Input Validation

Grafana validates inputs to prevent:
  • SQL injection
  • Cross-site scripting (XSS)
  • Command injection
  • Path traversal

Action URL Validation

Restrict POST URLs in panel actions:
[security]
# Comma-separated list of allowed POST URLs
actions_allow_post_url = https://api.example.com/webhook
Reference: conf/defaults.ini:469 Implementation: pkg/middleware/validate_action_url.go

Data Protection

Secret Management

Use environment variables for secrets:
[database]
password = $__env{DB_PASSWORD}

[auth.generic_oauth]
client_secret = $__env{OAUTH_CLIENT_SECRET}

[smtp]
password = $__env{SMTP_PASSWORD}

Encryption at Rest

Grafana encrypts sensitive data:
[security]
# Encryption key (change this!)
secret_key = CHANGE_TO_RANDOM_STRING

# Current encryption provider
encryption_provider = secretKey.v1

# Additional providers (Enterprise)
available_encryption_providers = awskms.v1 azurekv.v1
Reference: conf/defaults.ini:387-393 Encrypted data includes:
  • Datasource passwords
  • OAuth tokens
  • Alert notification credentials
  • Plugin secrets

Encryption Key Management

[security.encryption]
# Cache TTL for decrypted keys
data_keys_cache_ttl = 15m

# Cache cleanup interval
data_keys_cache_cleanup_interval = 1m
Reference: conf/defaults.ini:472-478

Database Security

Secure database connections:
[database]
type = postgres
ssl_mode = verify-full
ca_cert_path = /path/to/ca.crt
client_cert_path = /path/to/client.crt
client_key_path = /path/to/client.key

Datasource Security

  1. Use proxy mode for datasources when possible
  2. Restrict datasource permissions
    // Only allow necessary users to edit datasources
    permission := Permission{
        Action: "datasources:write",
        Scope:  "datasources:uid:abc123",
    }
    
  3. Don’t store plaintext credentials in datasource configuration
  4. Use readonly database users for query datasources

Data Source Proxy Security

[dataproxy]
# Log proxy requests
logging = true

# Timeout settings
timeout = 30
dialTimeout = 10

# Limit response size
response_limit = 10485760  # 10MB

# Don't send user header
send_user_header = false
Reference: conf/defaults.ini:248-293

Plugin Security

Disable Unsigned Plugins

[plugins]
allow_loading_unsigned_plugins = false

Restrict Plugin Installation

Limit who can install plugins:
// Require specific permission
ac.Middleware(accessControl)(
    ac.EvalPermission("plugins:write"),
)
Reference: pkg/middleware/auth.go:127-139

Plugin Sandboxing

[security]
# Sandbox specific plugins in frontend
enable_frontend_sandbox_for_plugins = plugin1,plugin2
Reference: conf/defaults.ini:466

Review Plugin Permissions

Before installing plugins:
  1. Check plugin signature
  2. Review source code (if possible)
  3. Verify plugin permissions
  4. Test in non-production environment

External Communication

Datasource Whitelist

[security]
# Whitelist datasource proxy destinations
data_source_proxy_whitelist = internal-network.com:443 metrics.company.com:9090
Reference: conf/defaults.ini:399

External Image Rendering

Secure image renderer:
[rendering]
# Use authenticated callback URL
server_url = https://grafana.example.com/

# Use separate renderer service
mode = remote
renderer_url = http://renderer:8081/render

Alerting Security

  1. Validate notification URLs
  2. Use secure webhooks (HTTPS only)
  3. Authenticate alert notifications
  4. Rate limit alerts

Deployment Security

Run as Non-Root User

# Create dedicated user
useradd -r -s /bin/false grafana

# Set ownership
chown -R grafana:grafana /var/lib/grafana
chown -R grafana:grafana /etc/grafana

# Run as grafana user
su - grafana -c "grafana-server"

File Permissions

# Restrict configuration files
chmod 640 /etc/grafana/grafana.ini
chown root:grafana /etc/grafana/grafana.ini

# Restrict data directory
chmod 750 /var/lib/grafana
chown grafana:grafana /var/lib/grafana

# Restrict certificate files
chmod 600 /etc/grafana/cert.key
chown grafana:grafana /etc/grafana/cert.key

Container Security

# Use official image
FROM grafana/grafana:latest

# Run as non-root
USER grafana

# Read-only root filesystem
# docker run --read-only -v /var/lib/grafana:/var/lib/grafana

# Drop capabilities
# docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE

# Resource limits
# docker run --memory=1g --cpus=1

Kubernetes Security

apiVersion: v1
kind: Pod
metadata:
  name: grafana
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 472
    fsGroup: 472
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: grafana
    image: grafana/grafana:latest
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
    volumeMounts:
    - name: storage
      mountPath: /var/lib/grafana
    resources:
      limits:
        memory: "1Gi"
        cpu: "1"
      requests:
        memory: "512Mi"
        cpu: "500m"

Monitoring and Auditing

Enable Audit Logging

[log]
# Set appropriate log level
level = info

# Log to files
mode = console file

[log.file]
log_rotate = true
max_days = 7
Reference: conf/defaults.ini:1161-1203

Monitor Authentication

Track authentication events:
  • Failed login attempts
  • Password changes
  • Role changes
  • Permission modifications

Enable Metrics

Monitor security metrics:
[metrics]
enabled = true

[analytics]
reporting_enabled = true

Security Scanning

  1. Vulnerability scanning
    # Scan Docker image
    docker scan grafana/grafana:latest
    
    # Scan with Trivy
    trivy image grafana/grafana:latest
    
  2. Dependency scanning
    • Monitor for CVEs in dependencies
    • Keep Grafana updated
    • Apply security patches promptly

Incident Response

Token Revocation

Revoke compromised tokens:
# Via API
curl -X POST https://grafana.example.com/api/user/revoke-auth-token \
  -H "Authorization: Bearer $TOKEN"

# Revoke all user tokens
curl -X POST https://grafana.example.com/api/admin/users/:id/revoke-auth-token \
  -H "Authorization: Bearer $ADMIN_TOKEN"
Implementation: pkg/services/auth/auth.go:90-91

Password Reset

# Reset user password (CLI)
grafana-cli admin reset-admin-password newpassword

# Force password change via API
curl -X PUT https://grafana.example.com/api/admin/users/:id/password \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -d '{"password":"newpassword"}'

Security Breach Response

  1. Isolate affected systems
  2. Revoke all active sessions
    err := tokenService.RevokeAllUserTokens(ctx, userID)
    
  3. Rotate encryption keys
  4. Review access logs
  5. Update credentials
  6. Apply patches
  7. Notify stakeholders

Compliance

GDPR Compliance

  • Implement data retention policies
  • Enable user data export
  • Provide data deletion capabilities
  • Log data access

SOC 2 Compliance

  • Enable audit logging
  • Implement access controls
  • Use encryption in transit and at rest
  • Regular security reviews

HIPAA Compliance

  • Encrypt all data
  • Implement access controls
  • Enable comprehensive audit logging
  • Regular risk assessments

Regular Maintenance

Security Checklist

  • Keep Grafana updated
  • Review and rotate credentials quarterly
  • Audit user permissions monthly
  • Review access logs weekly
  • Test backup restoration monthly
  • Update TLS certificates before expiration
  • Review and update security policies annually
  • Conduct security training for users
  • Test incident response procedures
  • Scan for vulnerabilities regularly

Update Process

  1. Test updates in non-production environment
  2. Review changelog for security fixes
  3. Backup configuration and data
  4. Apply update during maintenance window
  5. Verify functionality
  6. Monitor for issues

Security Resources

Grafana Security

Security Standards