Skip to content

Configuration

contextunity.core uses Pydantic BaseModel as the configuration contract. Values are loaded from environment variables via load_shared_config_from_env().

SharedConfig

from contextunity.core.config import SharedConfig, load_shared_config_from_env
config = load_shared_config_from_env()

Environment Variables

VariableDefaultDescription
LOG_LEVELINFOLogging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
LOG_JSONfalseUse JSON log format (true/false)
REDIS_URLRedis connection URL (e.g., redis://localhost:6379/0)
OTEL_ENABLEDfalseEnable OpenTelemetry tracing
OTEL_ENDPOINTOpenTelemetry collector endpoint
SERVICE_NAMEService name for observability
SERVICE_VERSIONService version for observability
TENANT_IDDefault tenant ID for multi-tenant deployments

Security Environment Variables

Security is always on — no toggle needed. The signing backend is auto-detected from environment:

VariableDefaultDescription
CU_PROJECT_SECRETHMAC secret for Open Source mode. Generate with python -m contextunity.core.cli.mint hmac
CU_SHIELD_GRPC_URLShield gRPC endpoint for Enterprise mode (alternative to CU_PROJECT_SECRET)
REDIS_SECRET_KEYfalseEncryption key for Redis-stored secrets. Set false to disable

SharedConfig Fields

class SharedConfig(BaseModel):
log_level: LogLevel # DEBUG, INFO, WARNING, ERROR, CRITICAL
log_json: bool # JSON vs plain text logs
redis_url: str | None # Redis connection
otel_enabled: bool # OpenTelemetry tracing
otel_endpoint: str | None # OTEL collector endpoint
service_name: str | None # Service name for observability
service_version: str | None # Service version
tenant_id: str | None # Default tenant ID
security: SharedSecurityConfig # Nested security config

Adding New Config Options

  1. Add field to SharedConfig in config.py:
class SharedConfig(BaseModel):
my_new_option: str = Field(default="", description="My new option")
  1. Add env loading in load_shared_config_from_env():
my_new_option=os.getenv("MY_NEW_OPTION", ""),
  1. Document in README
  2. Add tests

Systemd Credentials (Production Hardening)

In production, secrets can be provisioned via systemd-creds instead of .env files. The _read_credential() helper in contextunity.core.config checks for systemd-managed credentials first, then falls back to environment variables:

from contextunity.core.config import _read_credential
# Returns credential value from CREDENTIALS_DIRECTORY if available,
# otherwise returns the fallback (env var value)
secret = _read_credential("shield_master_key", os.getenv("SHIELD_MASTER_KEY", ""))

How it works

  1. systemd sets CREDENTIALS_DIRECTORY when LoadCredentialEncrypted is configured in the unit file
  2. _read_credential(name) reads $CREDENTIALS_DIRECTORY/{name} if it exists
  3. Falls back to env var (from .env) if no credential file is found

Configuration priority

systemd-creds → .env → defaults

This is optional.env files remain the default for development. No code changes needed in services that read through SharedSecurityConfig.