Set up enterprise-grade authentication for Jaeger distributed tracing using OAuth2 with Keycloak integration and role-based access control policies for secure production deployments.
Prerequisites
- Root or sudo access
- At least 4GB RAM
- Valid SSL certificates
- Network connectivity to OAuth2 provider
What this solves
Jaeger provides powerful distributed tracing capabilities, but out of the box it lacks authentication and authorization. This tutorial configures enterprise-grade security for Jaeger using OAuth2 authentication with Keycloak, implementing role-based access control (RBAC) policies, and adding SSL/TLS encryption for production environments.
Step-by-step configuration
Install Jaeger components
Start by installing Jaeger collector, query, and agent components with their dependencies.
sudo apt update
sudo apt install -y curl wget gnupg2 software-properties-common
wget https://github.com/jaegertracing/jaeger/releases/download/v1.52.0/jaeger-1.52.0-linux-amd64.tar.gz
tar -xzf jaeger-1.52.0-linux-amd64.tar.gz
sudo cp jaeger-1.52.0-linux-amd64/jaeger-* /usr/local/bin/
sudo chmod +x /usr/local/bin/jaeger-*Install and configure Elasticsearch backend
Set up Elasticsearch as the storage backend for Jaeger traces with security enabled.
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update
sudo apt install -y elasticsearchcluster.name: jaeger-cluster
node.name: jaeger-node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 127.0.0.1
http.port: 9200
xpack.security.enabled: true
xpack.security.authc.api_key.enabled: truesudo systemctl enable --now elasticsearch
sudo systemctl status elasticsearchInstall and configure Keycloak for OAuth2
Set up Keycloak as the OAuth2 identity provider for Jaeger authentication.
wget https://github.com/keycloak/keycloak/releases/download/22.0.5/keycloak-22.0.5.tar.gz
tar -xzf keycloak-22.0.5.tar.gz
sudo mv keycloak-22.0.5 /opt/keycloak
sudo useradd -r -s /bin/false keycloak
sudo chown -R keycloak:keycloak /opt/keycloak[Unit]
Description=Keycloak Authentication Server
After=network.target
[Service]
Type=idle
User=keycloak
Group=keycloak
ExecStart=/opt/keycloak/bin/kc.sh start --http-enabled=true --http-host=0.0.0.0 --http-port=8080
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now keycloak
sudo systemctl status keycloakConfigure Keycloak realm and client
Create a Keycloak realm and OAuth2 client for Jaeger authentication.
curl -X POST http://localhost:8080/admin/realms \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(curl -X POST http://localhost:8080/realms/master/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin&password=admin&grant_type=password&client_id=admin-cli" \
| jq -r .access_token)" \
-d '{
"realm": "jaeger",
"enabled": true,
"displayName": "Jaeger Tracing"
}'curl -X POST http://localhost:8080/admin/realms/jaeger/clients \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"clientId": "jaeger-query",
"enabled": true,
"protocol": "openid-connect",
"publicClient": false,
"redirectUris": ["https://example.com:16686/oauth/callback"],
"webOrigins": ["https://example.com:16686"]
}'Create Jaeger service configurations
Configure the Jaeger collector and query services with OAuth2 authentication.
[Unit]
Description=Jaeger Collector
After=network.target elasticsearch.service
[Service]
Type=simple
User=jaeger
Group=jaeger
ExecStart=/usr/local/bin/jaeger-collector \
--es.server-urls=http://localhost:9200 \
--es.username=elastic \
--es.password=changeme \
--collector.grpc-tls.enabled=true \
--collector.grpc-tls.cert=/etc/jaeger/tls/collector.crt \
--collector.grpc-tls.key=/etc/jaeger/tls/collector.key
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target[Unit]
Description=Jaeger Query Service
After=network.target elasticsearch.service keycloak.service
[Service]
Type=simple
User=jaeger
Group=jaeger
Environment=OAUTH2_PROXY_PROVIDER=keycloak-oidc
Environment=OAUTH2_PROXY_KEYCLOAK_GROUP=jaeger-users
Environment=OAUTH2_PROXY_CLIENT_ID=jaeger-query
Environment=OAUTH2_PROXY_CLIENT_SECRET=your-client-secret
Environment=OAUTH2_PROXY_OIDC_ISSUER_URL=http://localhost:8080/realms/jaeger
Environment=OAUTH2_PROXY_REDIRECT_URL=https://example.com:16686/oauth/callback
ExecStart=/usr/local/bin/jaeger-query \
--es.server-urls=http://localhost:9200 \
--es.username=elastic \
--es.password=changeme \
--query.bearer-token-propagation=true \
--query.ui-config=/etc/jaeger/ui-config.json
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetInstall OAuth2 proxy for authentication
Set up OAuth2 proxy to handle authentication between Jaeger and Keycloak.
wget https://github.com/oauth2-proxy/oauth2-proxy/releases/download/v7.5.1/oauth2-proxy-v7.5.1.linux-amd64.tar.gz
tar -xzf oauth2-proxy-v7.5.1.linux-amd64.tar.gz
sudo cp oauth2-proxy-v7.5.1.linux-amd64/oauth2-proxy /usr/local/bin/
sudo chmod +x /usr/local/bin/oauth2-proxyhttp_address = "0.0.0.0:4180"
upstreams = [
"http://127.0.0.1:16686"
]
provider = "keycloak-oidc"
oidc_issuer_url = "http://localhost:8080/realms/jaeger"
client_id = "jaeger-query"
client_secret = "your-client-secret-here"
email_domains = [
"*"
]
cookie_secret = "$(openssl rand -base64 32 | head -c 32)"
cookie_secure = true
cookie_httponly = true
cookie_samesite = "lax"
set_xauthrequest = true
pass_authorization_header = true
pass_access_token = true
pass_user_headers = true
authorized_groups = [
"/jaeger-admins",
"/jaeger-users"
]Configure RBAC policies
Set up role-based access control with different permission levels for Jaeger users.
apiVersion: rbac.jaeger.io/v1
kind: RoleBinding
metadata:
name: jaeger-admin-binding
subjects:
- kind: Group
name: jaeger-admins
apiGroup: rbac.jaeger.io
roleRef:
kind: Role
name: admin
apiGroup: rbac.jaeger.io
---
apiVersion: rbac.jaeger.io/v1
kind: RoleBinding
metadata:
name: jaeger-user-binding
subjects:
- kind: Group
name: jaeger-users
apiGroup: rbac.jaeger.io
roleRef:
kind: Role
name: viewer
apiGroup: rbac.jaeger.io
---
apiVersion: rbac.jaeger.io/v1
kind: Role
metadata:
name: admin
rules:
- apiGroups: [""]
resources: ["traces", "services", "operations"]
verbs: ["get", "list", "create", "update", "delete"]
---
apiVersion: rbac.jaeger.io/v1
kind: Role
metadata:
name: viewer
rules:
- apiGroups: [""]
resources: ["traces", "services", "operations"]
verbs: ["get", "list"]Generate SSL certificates
Create SSL certificates for secure communication between Jaeger components.
sudo mkdir -p /etc/jaeger/tls
sudo openssl req -x509 -newkey rsa:4096 -keyout /etc/jaeger/tls/jaeger.key -out /etc/jaeger/tls/jaeger.crt -days 365 -nodes -subj "/C=US/ST=State/L=City/O=Organization/OU=OrgUnit/CN=example.com"
sudo openssl req -x509 -newkey rsa:4096 -keyout /etc/jaeger/tls/collector.key -out /etc/jaeger/tls/collector.crt -days 365 -nodes -subj "/C=US/ST=State/L=City/O=Organization/OU=OrgUnit/CN=collector.example.com"
sudo chown -R jaeger:jaeger /etc/jaeger/tls
sudo chmod 600 /etc/jaeger/tls/*.key
sudo chmod 644 /etc/jaeger/tls/*.crtConfigure NGINX reverse proxy
Set up NGINX as a reverse proxy with SSL termination for Jaeger services.
sudo apt install -y nginxupstream oauth2_proxy {
server 127.0.0.1:4180;
}
upstream jaeger_query {
server 127.0.0.1:16686;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/jaeger/tls/jaeger.crt;
ssl_certificate_key /etc/jaeger/tls/jaeger.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
location /oauth/ {
proxy_pass http://oauth2_proxy;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
auth_request /oauth/auth;
error_page 401 = @error401;
proxy_pass http://jaeger_query;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Authorization $http_authorization;
}
location @error401 {
return 302 /oauth/start?rd=$request_uri;
}
}
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}sudo ln -s /etc/nginx/sites-available/jaeger /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxCreate system users and directories
Set up the jaeger system user and required directories with proper permissions.
sudo useradd -r -s /bin/false jaeger
sudo mkdir -p /var/log/jaeger /etc/jaeger
sudo chown -R jaeger:jaeger /var/log/jaeger /etc/jaeger
sudo chmod 755 /var/log/jaeger /etc/jaegerStart and enable all services
Enable and start all Jaeger services in the correct order.
sudo systemctl daemon-reload
sudo systemctl enable --now elasticsearch
sudo systemctl enable --now keycloak
sudo systemctl enable --now jaeger-collector
sudo systemctl enable --now jaeger-query[Unit]
Description=OAuth2 Proxy
After=network.target keycloak.service
[Service]
Type=simple
User=oauth2-proxy
Group=oauth2-proxy
ExecStart=/usr/local/bin/oauth2-proxy --config=/etc/oauth2-proxy/oauth2-proxy.cfg
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.targetsudo useradd -r -s /bin/false oauth2-proxy
sudo chown -R oauth2-proxy:oauth2-proxy /etc/oauth2-proxy
sudo systemctl enable --now oauth2-proxyConfigure Keycloak groups and users
Create user groups
Set up Keycloak groups for different access levels in Jaeger.
TOKEN=$(curl -X POST http://localhost:8080/realms/master/protocol/openid-connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin&password=admin&grant_type=password&client_id=admin-cli" \
| jq -r .access_token)
curl -X POST http://localhost:8080/admin/realms/jaeger/groups \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"name": "jaeger-admins"}'
curl -X POST http://localhost:8080/admin/realms/jaeger/groups \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"name": "jaeger-users"}'Create test users
Add test users with different permission levels for validation.
curl -X POST http://localhost:8080/admin/realms/jaeger/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"username": "admin@example.com",
"email": "admin@example.com",
"enabled": true,
"credentials": [{
"type": "password",
"value": "SecureP@ssw0rd123",
"temporary": false
}]
}'
curl -X POST http://localhost:8080/admin/realms/jaeger/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"username": "viewer@example.com",
"email": "viewer@example.com",
"enabled": true,
"credentials": [{
"type": "password",
"value": "ViewerP@ssw0rd123",
"temporary": false
}]
}'Verify your setup
Test that all components are running and authentication is working properly.
sudo systemctl status elasticsearch keycloak jaeger-collector jaeger-query oauth2-proxy nginx
curl -k https://example.com/api/services
curl http://localhost:8080/realms/jaeger/.well-known/openid_configurationAccess the Jaeger UI at https://example.com and verify that:
- You are redirected to Keycloak for authentication
- Login works with the test credentials
- Different users have appropriate access levels
- SSL certificates are properly configured
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| OAuth2 redirect fails | Incorrect redirect URI in Keycloak | Update client redirect URIs in Keycloak admin |
| SSL certificate errors | Self-signed certificates | Use Let's Encrypt or proper CA-signed certificates |
| Elasticsearch connection fails | Authentication credentials | Verify ES username/password in service configs |
| NGINX proxy errors | Upstream service not running | Check sudo systemctl status jaeger-query oauth2-proxy |
| Keycloak groups not working | Group mapping misconfiguration | Verify group assignments in Keycloak admin console |
| RBAC permissions denied | Role binding configuration | Check /etc/jaeger/rbac-config.yaml syntax |
Next steps
- Configure Jaeger alerting with Prometheus and Grafana for monitoring authentication events
- Setup Jaeger sampling strategies for high-volume production tracing to optimize performance
- Configure Keycloak high availability clustering for production for enterprise deployments
- Implement mutual TLS authentication between Jaeger components
- Configure Jaeger backup and disaster recovery procedures
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuration
JAEGER_VERSION="1.52.0"
KEYCLOAK_VERSION="22.0.5"
ELASTICSEARCH_VERSION="8.x"
JAEGER_DOMAIN="${1:-localhost}"
ADMIN_PASSWORD="${2:-$(openssl rand -base64 32)}"
usage() {
echo "Usage: $0 [domain] [admin_password]"
echo " domain: Domain for Jaeger (default: localhost)"
echo " admin_password: Keycloak admin password (default: auto-generated)"
exit 1
}
log() {
echo -e "${GREEN}[INFO]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
error() {
echo -e "${RED}[ERROR]${NC} $1"
}
cleanup() {
error "Installation failed. Cleaning up..."
systemctl stop jaeger-collector jaeger-query keycloak elasticsearch 2>/dev/null || true
userdel jaeger keycloak 2>/dev/null || true
rm -rf /opt/jaeger /opt/keycloak /tmp/jaeger-install 2>/dev/null || true
}
trap cleanup ERR
# Check prerequisites
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root"
exit 1
fi
# Detect distribution
if [[ ! -f /etc/os-release ]]; then
error "Cannot detect distribution"
exit 1
fi
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
;;
fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
;;
*)
error "Unsupported distribution: $ID"
exit 1
;;
esac
log "[1/8] Updating system and installing dependencies..."
$PKG_UPDATE
if [[ "$PKG_MGR" == "apt" ]]; then
$PKG_INSTALL curl wget gnupg2 software-properties-common jq openssl tar
else
$PKG_INSTALL curl wget gnupg2 jq openssl tar
fi
mkdir -p /tmp/jaeger-install
cd /tmp/jaeger-install
log "[2/8] Installing Jaeger components..."
wget -q "https://github.com/jaegertracing/jaeger/releases/download/v${JAEGER_VERSION}/jaeger-${JAEGER_VERSION}-linux-amd64.tar.gz"
tar -xzf "jaeger-${JAEGER_VERSION}-linux-amd64.tar.gz"
cp "jaeger-${JAEGER_VERSION}-linux-amd64/jaeger-"* /usr/local/bin/
chmod 755 /usr/local/bin/jaeger-*
useradd -r -s /bin/false jaeger || true
mkdir -p /etc/jaeger /var/log/jaeger
chown jaeger:jaeger /var/log/jaeger
chmod 750 /var/log/jaeger
log "[3/8] Installing and configuring Elasticsearch..."
if [[ "$PKG_MGR" == "apt" ]]; then
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/${ELASTICSEARCH_VERSION}/apt stable main" > /etc/apt/sources.list.d/elastic-8.x.list
apt update
$PKG_INSTALL elasticsearch
else
rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
cat > /etc/yum.repos.d/elasticsearch.repo << 'EOF'
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
EOF
$PKG_INSTALL elasticsearch
fi
cat > /etc/elasticsearch/elasticsearch.yml << EOF
cluster.name: jaeger-cluster
node.name: jaeger-node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 127.0.0.1
http.port: 9200
xpack.security.enabled: true
xpack.security.authc.api_key.enabled: true
EOF
chmod 644 /etc/elasticsearch/elasticsearch.yml
systemctl enable elasticsearch
systemctl start elasticsearch
# Wait for Elasticsearch to start
sleep 30
log "[4/8] Installing and configuring Keycloak..."
wget -q "https://github.com/keycloak/keycloak/releases/download/${KEYCLOAK_VERSION}/keycloak-${KEYCLOAK_VERSION}.tar.gz"
tar -xzf "keycloak-${KEYCLOAK_VERSION}.tar.gz"
mv "keycloak-${KEYCLOAK_VERSION}" /opt/keycloak
useradd -r -s /bin/false keycloak || true
chown -R keycloak:keycloak /opt/keycloak
chmod -R 750 /opt/keycloak
cat > /etc/systemd/system/keycloak.service << EOF
[Unit]
Description=Keycloak Authentication Server
After=network.target
[Service]
Type=exec
User=keycloak
Group=keycloak
Environment=KEYCLOAK_ADMIN=admin
Environment=KEYCLOAK_ADMIN_PASSWORD=$ADMIN_PASSWORD
ExecStart=/opt/keycloak/bin/kc.sh start-dev --http-enabled=true --http-host=0.0.0.0 --http-port=8080
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable keycloak
systemctl start keycloak
# Wait for Keycloak to start
sleep 60
log "[5/8] Configuring Keycloak realm and client..."
# Get admin token
TOKEN=$(curl -s -X POST "http://localhost:8080/realms/master/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin&password=$ADMIN_PASSWORD&grant_type=password&client_id=admin-cli" \
| jq -r .access_token)
# Create Jaeger realm
curl -s -X POST "http://localhost:8080/admin/realms" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"realm": "jaeger",
"enabled": true,
"displayName": "Jaeger Tracing"
}' || true
# Create Jaeger client
curl -s -X POST "http://localhost:8080/admin/realms/jaeger/clients" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{
"clientId": "jaeger-query",
"enabled": true,
"protocol": "openid-connect",
"publicClient": false,
"redirectUris": ["http://'"$JAEGER_DOMAIN"':16686/*"],
"webOrigins": ["http://'"$JAEGER_DOMAIN"':16686"]
}' || true
log "[6/8] Configuring Jaeger services..."
cat > /etc/jaeger/collector.yaml << 'EOF'
collector:
grpc-server:
host-port: 0.0.0.0:14250
http-server:
host-port: 0.0.0.0:14268
es:
server-urls: http://localhost:9200
username: elastic
EOF
cat > /etc/jaeger/query.yaml << EOF
query:
http-server:
host-port: 0.0.0.0:16686
grpc-server:
host-port: 0.0.0.0:16685
es:
server-urls: http://localhost:9200
username: elastic
query:
base-path: /
ui-config: |
{
"oauth": {
"issuer": "http://localhost:8080/realms/jaeger",
"client_id": "jaeger-query",
"redirect_uri": "http://$JAEGER_DOMAIN:16686/oauth2/callback"
}
}
EOF
chown jaeger:jaeger /etc/jaeger/*.yaml
chmod 644 /etc/jaeger/*.yaml
log "[7/8] Creating systemd services for Jaeger..."
cat > /etc/systemd/system/jaeger-collector.service << 'EOF'
[Unit]
Description=Jaeger Collector
After=network.target elasticsearch.service
[Service]
Type=simple
User=jaeger
Group=jaeger
ExecStart=/usr/local/bin/jaeger-collector --config-file=/etc/jaeger/collector.yaml
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
cat > /etc/systemd/system/jaeger-query.service << 'EOF'
[Unit]
Description=Jaeger Query
After=network.target elasticsearch.service
[Service]
Type=simple
User=jaeger
Group=jaeger
ExecStart=/usr/local/bin/jaeger-query --config-file=/etc/jaeger/query.yaml
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable jaeger-collector jaeger-query
systemctl start jaeger-collector jaeger-query
log "[8/8] Configuring firewall..."
if command -v ufw >/dev/null 2>&1; then
ufw allow 16686/tcp
ufw allow 14268/tcp
ufw allow 8080/tcp
elif command -v firewall-cmd >/dev/null 2>&1; then
firewall-cmd --permanent --add-port=16686/tcp
firewall-cmd --permanent --add-port=14268/tcp
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload
fi
# Verification
log "Verifying installation..."
sleep 10
if systemctl is-active --quiet elasticsearch && \
systemctl is-active --quiet keycloak && \
systemctl is-active --quiet jaeger-collector && \
systemctl is-active --quiet jaeger-query; then
log "✓ All services are running successfully"
else
error "Some services failed to start"
exit 1
fi
# Cleanup temp files
rm -rf /tmp/jaeger-install
log "Installation completed successfully!"
log "Jaeger Query UI: http://$JAEGER_DOMAIN:16686"
log "Keycloak Admin Console: http://localhost:8080"
log "Keycloak Admin Password: $ADMIN_PASSWORD"
warn "Please configure SSL/TLS certificates for production use"
Review the script before running. Execute with: bash install.sh