Authentication Options
Introduction
Authentication is a critical component of any security strategy for your Grafana Loki deployment. It verifies the identity of users or services attempting to access your Loki instance, ensuring that only authorized entities can interact with your log data. This guide explores the various authentication options available in Grafana Loki, helping you choose and implement the most appropriate authentication method for your environment.
Authentication in Loki serves several important purposes:
- Preventing unauthorized access to sensitive log data
- Enabling multi-tenant deployments where different teams access only their own logs
- Tracking and auditing who has accessed what data
- Integrating with your organization's existing identity management systems
Basic Authentication Concepts
Before diving into Loki-specific authentication options, let's understand some fundamental authentication concepts:
Authentication vs. Authorization
While often used interchangeably, these terms refer to different aspects of security:
- Authentication: Verifies who you are (identity)
- Authorization: Determines what you're allowed to do (permissions)
Loki implements both, but this guide focuses primarily on authentication methods.
Multi-Factor Authentication (MFA)
Multi-factor authentication combines multiple verification methods:
- Something you know (password)
- Something you have (token device)
- Something you are (biometrics)
While Loki itself doesn't directly implement MFA, it can integrate with identity providers that do.
Authentication Methods in Grafana Loki
Loki supports several authentication mechanisms depending on your deployment model and security requirements.
No Authentication (Insecure)
For development or isolated environments, Loki can be configured without authentication:
auth_enabled: false
Running Loki without authentication is only recommended for development environments. Never deploy Loki without authentication in production environments.
Basic Authentication
Basic authentication uses a username and password combination sent in HTTP headers. In Loki, this is typically configured through a proxy or gateway service.
Example of configuring basic auth with Nginx as a reverse proxy:
server {
listen 80;
server_name loki.example.com;
location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:3100;
}
}
To create the password file:
htpasswd -c /etc/nginx/.htpasswd admin
Token-Based Authentication
Loki supports token-based authentication, where clients include an API token in their requests.
Configuration example in Loki's configuration file:
auth_enabled: true
server:
http_listen_port: 3100
distributor:
ring:
kvstore:
store: inmemory
ingester:
lifecycler:
ring:
kvstore:
store: inmemory
replication_factor: 1
final_sleep: 0s
chunk_idle_period: 5m
chunk_retain_period: 30s
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
storage_config:
boltdb_shipper:
active_index_directory: /tmp/loki/boltdb-shipper-active
cache_location: /tmp/loki/boltdb-shipper-cache
cache_ttl: 24h
shared_store: filesystem
filesystem:
directory: /tmp/loki/chunks
limits_config:
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
# Authentication configuration
auth:
type: token
token:
enabled: true
header: X-Scope-OrgID
With this configuration, clients must include the X-Scope-OrgID
header with a valid token:
curl -H "X-Scope-OrgID: tenant1" -X GET http://localhost:3100/loki/api/v1/labels
OAuth 2.0 Integration
For enterprise environments, OAuth 2.0 is often preferred. This allows Loki to delegate authentication to an identity provider like Google, GitHub, or an internal OAuth provider.
Typically, this is set up through a proxy that handles the OAuth flow, such as OAuth2 Proxy:
# Example docker-compose.yml for Loki with OAuth2 Proxy
version: '3'
services:
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
volumes:
- ./loki-config.yaml:/etc/loki/local-config.yaml
command: -config.file=/etc/loki/local-config.yaml
oauth2-proxy:
image: quay.io/oauth2-proxy/oauth2-proxy:latest
ports:
- "4180:4180"
environment:
- OAUTH2_PROXY_CLIENT_ID=your_client_id
- OAUTH2_PROXY_CLIENT_SECRET=your_client_secret
- OAUTH2_PROXY_COOKIE_SECRET=random_cookie_secret
- OAUTH2_PROXY_EMAIL_DOMAINS=*
- OAUTH2_PROXY_PROVIDER=github
- OAUTH2_PROXY_UPSTREAMS=http://loki:3100/
- OAUTH2_PROXY_HTTP_ADDRESS=0.0.0.0:4180
Multi-Tenancy with Authentication
Loki supports multi-tenancy, where different teams or applications can use the same Loki instance but only access their own data.
Configuration example for multi-tenancy:
auth_enabled: true
# Other config sections...
limits_config:
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
max_global_streams_per_user: 5000
ingestion_rate_mb: 10
ingestion_burst_size_mb: 20
# Multi-tenancy configuration with per-tenant limits
multi_tenancy_enabled: true
tenant_configs:
configs:
- tenant: team1
limits:
ingestion_rate_mb: 5
ingestion_burst_size_mb: 10
- tenant: team2
limits:
ingestion_rate_mb: 8
ingestion_burst_size_mb: 16
Implementing JWT Authentication
JSON Web Tokens (JWT) provide a secure way to transmit authentication information between parties. Here's how to set up JWT authentication with Loki:
- Configure a proxy to validate JWTs and inject the tenant ID into a header
// Example Express.js middleware for JWT validation
const jwt = require('jsonwebtoken');
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
const SECRET_KEY = process.env.JWT_SECRET;
// JWT validation middleware
app.use((req, res, next) => {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'No token provided' });
}
const token = authHeader.split(' ')[1];
try {
const decoded = jwt.verify(token, SECRET_KEY);
// Add tenant ID from JWT claim
req.headers['X-Scope-OrgID'] = decoded.tenant;
next();
} catch (err) {
return res.status(401).json({ error: 'Invalid token' });
}
});
// Proxy requests to Loki
app.use('/', createProxyMiddleware({
target: 'http://loki:3100',
changeOrigin: true
}));
app.listen(8080, () => {
console.log('JWT Proxy listening on port 8080');
});
- Configure clients to include the JWT in the Authorization header
# Example curl request with JWT
JWT="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnQiOiJ0ZWFtMSIsInN1YiI6InVzZXIxIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
curl -H "Authorization: Bearer $JWT" \
http://localhost:8080/loki/api/v1/query_range \
--data-urlencode "query={app=\"myapp\"}" \
--data-urlencode "start=1609455600000000000" \
--data-urlencode "end=1609459200000000000"
Authentication with Grafana as a Frontend
Most users interact with Loki via Grafana, which handles authentication on behalf of users.
To configure Loki as a data source in Grafana with authentication:
- In Grafana, go to Configuration > Data Sources > Add data source
- Select Loki
- Enter the URL of your Loki instance
- Under Auth, configure the authentication method
- For multi-tenancy, add Custom Headers:
- Name:
X-Scope-OrgID
- Value: The tenant ID
- Name:
Best Practices for Authentication
- Never run Loki without authentication in production
- Use HTTPS/TLS for all communications to prevent credential interception
- Implement proper token rotation for API keys and tokens
- Use the principle of least privilege when granting access
- Regularly audit authentication logs to detect suspicious activity
- Integrate with your organization's existing identity management where possible
- Use environment variables for sensitive authentication information
Troubleshooting Authentication Issues
Common Problems and Solutions
Problem | Possible Causes | Solution |
---|---|---|
"Unauthorized" errors | Missing or invalid token | Check that the X-Scope-OrgID header is being sent |
"Forbidden" errors | Valid authentication but insufficient permissions | Check tenant configuration and permissions |
Authentication working inconsistently | Load balancer or proxy issues | Ensure session affinity if needed |
Debugging Authentication
To troubleshoot authentication issues, enable debug logging in Loki:
server:
http_listen_port: 3100
log_level: debug
Then check logs for authentication-related messages:
docker logs loki-container 2>&1 | grep -i auth
Summary
Authentication is a critical aspect of securing your Grafana Loki deployment. This guide has covered:
- Basic authentication concepts
- Various authentication methods supported by Loki
- Implementation examples for different authentication options
- Multi-tenancy considerations
- JWT authentication setup
- Integration with Grafana
- Best practices and troubleshooting
By understanding and properly implementing these authentication options, you can ensure that your log data remains secure while being accessible to authorized users and services.
Additional Resources
Exercises
- Set up Loki with basic authentication using an Nginx reverse proxy
- Implement token-based authentication and test access with different tenant IDs
- Configure Grafana to connect to Loki with the appropriate authentication headers
- Create a simple JWT proxy using the example code and test authentication
- Design a multi-tenant authentication strategy for a hypothetical organization with three teams
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)