This document provides a complete reference for all XZEPR configuration options.
XZEPR uses a layered configuration system with three levels of precedence:
- Default configuration (
config/default.yaml) - Lowest priority - Environment-specific configuration (
config/{environment}.yaml) - Medium priority - Environment variables - Highest priority
Configuration files are located in the config/ directory:
config/
├── default.yaml # Base configuration
├── development.yaml # Development overrides
└── production.yaml # Production overrides
Set the RUST_ENV environment variable to choose which configuration file to
load:
export RUST_ENV=development # Loads config/development.yaml
export RUST_ENV=production # Loads config/production.yamlDefault: development
server:
host: "0.0.0.0"
port: 8443
enable_https: true- Type: String
- Default:
"0.0.0.0" - Description: IP address to bind the server to
- Values:
"0.0.0.0"- Bind to all interfaces"127.0.0.1"- Localhost only- Specific IP address
- Type: Integer
- Default:
8443 - Description: Port number for the server
- Range: 1-65535
- Common values:
8443- HTTPS (recommended)8080- HTTP alternative3000- Alternative development port
- Type: Boolean
- Default:
true - Description: Enable TLS/HTTPS
- Values:
true- Use HTTPS (requires certificates)false- Use HTTP (development only)
database:
url: "postgres://xzepr:password@localhost:5432/xzepr"- Type: String
- Required: Yes
- Description: PostgreSQL connection string
- Format:
postgres://username:password@host:port/database - Example:
postgres://xzepr:password@localhost:5432/xzepr - Security: Should be overridden with environment variable in production
auth:
jwt_secret: "your-secret-key-min-32-chars"
jwt_expiration_hours: 24
enable_local_auth: true
enable_oidc: false
keycloak:
issuer_url: "http://localhost:8080/realms/xzepr"
client_id: "xzepr-client"
client_secret: "change-me-in-production"
redirect_url: "https://localhost:8443/auth/callback"- Type: String
- Required: Yes
- Description: Secret key for signing JWT tokens
- Minimum length: 32 characters
- Security: Must be cryptographically random in production
- Generation:
openssl rand -base64 32 - Important: Never commit to version control
- Type: Integer
- Default:
24 - Description: JWT token lifetime in hours
- Range: 1-168 (1 hour to 7 days)
- Recommended:
- Development: 168 (7 days)
- Production: 24 (1 day)
- Type: Boolean
- Default:
true - Description: Enable local username/password authentication
- Type: Boolean
- Default:
false - Description: Enable OpenID Connect authentication
- Type: String
- Required: If OIDC is enabled
- Description: Keycloak realm URL
- Format:
https://keycloak.example.com/realms/{realm-name} - Example:
http://localhost:8080/realms/xzepr
- Type: String
- Required: If OIDC is enabled
- Description: OAuth2 client identifier
- Example:
xzepr-client
- Type: String
- Required: If OIDC is enabled
- Description: OAuth2 client secret
- Security: Must be kept confidential
- Type: String
- Required: If OIDC is enabled
- Description: OAuth2 callback URL
- Format: Must match registered redirect URI in Keycloak
- Example:
https://localhost:8443/auth/callback
tls:
cert_path: "certs/cert.pem"
key_path: "certs/key.pem"- Type: String
- Required: If HTTPS is enabled
- Description: Path to TLS certificate file
- Format: PEM format
- Default:
certs/cert.pem
- Type: String
- Required: If HTTPS is enabled
- Description: Path to TLS private key file
- Format: PEM format
- Default:
certs/key.pem - Security: File should have 600 permissions
kafka:
brokers: "localhost:19092"- Type: String
- Default:
"localhost:19092" - Description: Comma-separated list of Kafka/Redpanda broker addresses
- Format:
host:port[,host:port] - Examples:
- Single broker:
"localhost:19092" - Multiple brokers:
"broker1:9092,broker2:9092,broker3:9092"
- Single broker:
Override any configuration value using environment variables with the XZEPR__
prefix.
Format: XZEPR__SECTION__SUBSECTION__KEY
- Use double underscores (
__) to separate levels - All uppercase
- Maps directly to YAML structure
# Server configuration
export XZEPR__SERVER__HOST="0.0.0.0"
export XZEPR__SERVER__PORT="9443"
export XZEPR__SERVER__ENABLE_HTTPS="true"
# Database configuration
export XZEPR__DATABASE__URL="postgres://user:pass@db:5432/xzepr"
# Authentication configuration
export XZEPR__AUTH__JWT_SECRET="my-super-secret-key-at-least-32-chars"
export XZEPR__AUTH__JWT_EXPIRATION_HOURS="48"
export XZEPR__AUTH__ENABLE_LOCAL_AUTH="true"
export XZEPR__AUTH__ENABLE_OIDC="true"
# Keycloak configuration (nested)
export XZEPR__AUTH__KEYCLOAK__ISSUER_URL="https://auth.example.com/realms/prod"
export XZEPR__AUTH__KEYCLOAK__CLIENT_ID="xzepr-prod"
export XZEPR__AUTH__KEYCLOAK__CLIENT_SECRET="secret-value"
export XZEPR__AUTH__KEYCLOAK__REDIRECT_URL="https://xzepr.example.com/auth/callback"
# TLS configuration
export XZEPR__TLS__CERT_PATH="/etc/xzepr/tls/cert.pem"
export XZEPR__TLS__KEY_PATH="/etc/xzepr/tls/key.pem"
# Kafka configuration
export XZEPR__KAFKA__BROKERS="kafka1:9092,kafka2:9092"When the same setting is defined in multiple places, this is the order of precedence (highest to lowest):
- Environment variables
- Environment-specific YAML file
- Default YAML file
Example: If server.port is defined in all three places:
# config/default.yaml
server:
port: 8443# config/production.yaml
server:
port: 8080# Environment variable
export XZEPR__SERVER__PORT="9000"Result: Server will use port 9000 (environment variable wins)
config/development.yaml:
server:
host: "127.0.0.1"
port: 8443
enable_https: true
database:
url: "postgres://xzepr:password@localhost:5432/xzepr"
auth:
jwt_secret: "dev-secret-not-for-production-use"
jwt_expiration_hours: 168 # 7 days for convenience
enable_local_auth: true
enable_oidc: true
tls:
cert_path: "certs/cert.pem"
key_path: "certs/key.pem"
kafka:
brokers: "localhost:19092"config/production.yaml:
server:
host: "0.0.0.0"
port: 8443
enable_https: true
database:
url: "postgres://xzepr:CHANGE_ME@postgres:5432/xzepr"
auth:
jwt_secret: "CHANGE_ME_TO_SECURE_RANDOM_STRING"
jwt_expiration_hours: 24
enable_local_auth: true
enable_oidc: true
keycloak:
issuer_url: "https://keycloak.example.com/realms/xzepr"
client_id: "xzepr-client"
client_secret: "CHANGE_ME_TO_KEYCLOAK_CLIENT_SECRET"
redirect_url: "https://xzepr.example.com/auth/callback"
tls:
cert_path: "/etc/xzepr/tls/cert.pem"
key_path: "/etc/xzepr/tls/key.pem"
kafka:
brokers: "redpanda-0:9092"Never commit secrets to version control:
- JWT secret
- Database passwords
- Keycloak client secrets
- TLS private keys
Use environment variables or secrets management:
# Read from secrets management system
export XZEPR__AUTH__JWT_SECRET=$(vault read -field=value secret/xzepr/jwt_secret)
export XZEPR__DATABASE__URL=$(vault read -field=value secret/xzepr/db_url)Generate secure JWT secret:
openssl rand -base64 32Requirements:
- Minimum 32 characters
- Cryptographically random
- Unique per environment
- Rotated regularly
Best practices:
- Use strong passwords (16+ characters)
- Different credentials per environment
- Limit database user permissions
- Enable SSL/TLS for connections
- Rotate credentials regularly
Production requirements:
- Valid certificates from trusted CA
- Private key file permissions: 600
- Regular renewal before expiration
- Use cert-manager for Kubernetes
Configuration is validated on startup. Common errors:
Error: missing field `jwt_secret`
Solution: Set XZEPR__AUTH__JWT_SECRET environment variable
Error: invalid value for server.port: 0
Solution: Use valid port number (1-65535)
Error: TLS certificate not found: certs/cert.pem
Solution: Generate certificates or correct path
Check file existence:
ls -la config/default.yaml
ls -la config/development.yamlCheck YAML syntax:
yamllint config/*.yamlVerify format:
env | grep XZEPR__Ensure double underscores and uppercase.
Check environment:
echo $RUST_ENVVerify loading order in logs.
Full production configuration using environment variables:
#!/bin/bash
# Production environment configuration
# Environment selection
export RUST_ENV=production
# Server
export XZEPR__SERVER__HOST="0.0.0.0"
export XZEPR__SERVER__PORT="8443"
export XZEPR__SERVER__ENABLE_HTTPS="true"
# Database
export XZEPR__DATABASE__URL="postgres://xzepr:${DB_PASSWORD}@postgres.prod:5432/xzepr"
# Authentication
export XZEPR__AUTH__JWT_SECRET="${JWT_SECRET}"
export XZEPR__AUTH__JWT_EXPIRATION_HOURS="24"
export XZEPR__AUTH__ENABLE_LOCAL_AUTH="true"
export XZEPR__AUTH__ENABLE_OIDC="true"
# Keycloak
export XZEPR__AUTH__KEYCLOAK__ISSUER_URL="https://auth.example.com/realms/prod"
export XZEPR__AUTH__KEYCLOAK__CLIENT_ID="xzepr-prod"
export XZEPR__AUTH__KEYCLOAK__CLIENT_SECRET="${KEYCLOAK_SECRET}"
export XZEPR__AUTH__KEYCLOAK__REDIRECT_URL="https://xzepr.example.com/auth/callback"
# TLS
export XZEPR__TLS__CERT_PATH="/etc/xzepr/tls/cert.pem"
export XZEPR__TLS__KEY_PATH="/etc/xzepr/tls/key.pem"
# Kafka
export XZEPR__KAFKA__BROKERS="kafka1.prod:9092,kafka2.prod:9092,kafka3.prod:9092"
# Start server
./target/release/xzepr- Running the Server - How to use configuration
- Environment Variables Reference - Complete variable list
- Deployment Guide - Production deployment