Settings System
AuroraSOC uses pydantic-settings for type-safe, validated configuration loaded from environment variables. The settings module at aurorasoc/config/settings.py is the single source of truth for all configuration.
Architecture
Subsystem Configurations
AuroraSOC does not use a global AURORA_ prefix. Root-level settings map directly to environment variables, while subsystem settings use focused prefixes like REDIS_, PG_, and MCP_.
Root Level Settings
Variables applied at the root of the Pydantic Settings class do not use prefixes:
JWT_SECRET_KEYDEBUGAPI_SERVICE_KEYJWT_EXPIRY_HOURSAPPROVAL_EXPIRES_MINUTESAPPROVAL_WAIT_TIMEOUT_SECONDSAPPROVAL_POLL_INTERVAL_SECONDSLLM_BACKENDSYSTEM_MODECORS_ORIGINS
Runtime model routing is controlled at root level:
VLLM_BASE_URLVLLM_MODELVLLM_ORCHESTRATOR_MODELOLLAMA_BASE_URLOLLAMA_MODELOLLAMA_ORCHESTRATOR_MODEL
LLMSettings
LLMSettings currently provides inference behavior knobs (temperature/max token budget) and compatibility defaults.
class LLMSettings(BaseSettings):
default_model: str = "ollama:granite4:8b"
orchestrator_model: str = "ollama:granite4:dense"
ollama_base_url: str = "http://localhost:11434"
temperature: float = 0.1
max_tokens: int = 4096
model_config = SettingsConfigDict(env_prefix="LLM_")
| Variable | Description |
|---|---|
LLM_DEFAULT_MODEL | Compatibility model alias (normalized to canonical Granite tags). |
LLM_ORCHESTRATOR_MODEL | Compatibility orchestrator alias. |
LLM_TEMPERATURE | Default generation temperature. |
LLM_MAX_TOKENS | Default generation token budget. |
RedisSettings
class RedisSettings(BaseSettings):
url: str = "redis://redis:6379"
max_connections: int = 50
ioc_ttl_seconds: int = 3600
model_config = SettingsConfigDict(env_prefix="REDIS_")
| Variable | Description | Default |
|---|---|---|
REDIS_URL | Redis connection string. | redis://redis:6379 |
REDIS_MAX_CONNECTIONS | Maximum connections in the async pool. | 50 |
REDIS_IOC_TTL_SECONDS | TTL for IOC cache entries in ThreatIntelMemory. | 3600 |
PostgresSettings
class PostgresSettings(BaseSettings):
host: str = "postgres"
port: int = 5432
user: str = "aurorasoc"
password: SecretStr = SecretStr("changeme")
database: str = "aurorasoc"
# Connection pool
pool_size: int = 20
max_overflow: int = 10
pool_recycle: int = 3600
pool_pre_ping: bool = True
pool_timeout: int = 30
statement_cache_size: int = 0 # Disable asyncpg statement cache for pgbouncer compat
# TLS / SSL
sslmode: str = "prefer"
sslrootcert: str = ""
model_config = SettingsConfigDict(env_prefix="PG_")
@property
def dsn(self) -> str:
pw = self.password.get_secret_value()
return f"postgresql+asyncpg://{self.user}:{pw}@{self.host}:{self.port}/{self.database}"
@property
def connect_args(self) -> dict:
args: dict = {"statement_cache_size": self.statement_cache_size}
if self.sslmode != "disable":
import ssl
ctx = ssl.create_default_context()
if self.sslrootcert:
ctx.load_verify_locations(self.sslrootcert)
else:
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
args["ssl"] = ctx
return args
| Variable | Description | Default |
|---|---|---|
PG_HOST | PostgreSQL host. | postgres |
PG_PORT | PostgreSQL port. | 5432 |
PG_USER | Database user. | aurorasoc |
PG_PASSWORD | Database password (stored as SecretStr). | changeme |
PG_DATABASE | Database name. | aurorasoc |
PG_POOL_SIZE | Base connection pool size. | 20 |
PG_MAX_OVERFLOW | Extra connections above pool_size. | 10 |
PG_POOL_RECYCLE | Max connection age in seconds before recycling. | 3600 |
PG_POOL_PRE_PING | Issue lightweight ping before checkout to detect stale connections. | True |
PG_POOL_TIMEOUT | Seconds to wait for a connection from the pool. | 30 |
PG_STATEMENT_CACHE_SIZE | asyncpg prepared-statement cache size. Set to 0 for pgbouncer. | 0 |
PG_SSLMODE | SSL mode (disable, prefer, require, verify-ca, verify-full). | prefer |
PG_SSLROOTCERT | Path to CA certificate for server verification. | "" |
Environment File
For local development, create a .env file referencing the specific subsystems:
# Root
DEBUG=true
JWT_SECRET_KEY=replace_with_min_32_char_secret
API_SERVICE_KEY=replace_with_secure_service_key
JWT_EXPIRY_HOURS=24
APPROVAL_EXPIRES_MINUTES=30
APPROVAL_WAIT_TIMEOUT_SECONDS=300
APPROVAL_POLL_INTERVAL_SECONDS=5
SYSTEM_MODE=real
CORS_ORIGINS=["http://localhost:3000","http://localhost:3001"]
# Runtime backend selector (root Settings)
LLM_BACKEND=vllm
VLLM_BASE_URL=http://vllm:8000/v1
VLLM_MODEL=granite-soc-specialist
VLLM_ORCHESTRATOR_MODEL=granite-soc-specialist
OLLAMA_BASE_URL=http://ollama:11434
OLLAMA_MODEL=granite4:8b
OLLAMA_ORCHESTRATOR_MODEL=granite4:dense
# Databases
PG_HOST=localhost
PG_PASSWORD=replace_with_secure_password
PG_POOL_SIZE=20
PG_MAX_OVERFLOW=10
PG_SSLMODE=prefer
REDIS_URL=redis://localhost:6379
REDIS_MAX_CONNECTIONS=50
NATS_URL=nats://localhost:4222
# Optional subsystem tuning
LLM_TEMPERATURE=0.1
LLM_MAX_TOKENS=4096
MCP_CLIENT_HOST=localhost
A2A_CLIENT_HOST=localhost
In docker-compose.yml, environment variables are propagated to all agents using the standard x-granite-env YAML anchor. Ensure you modify the anchor if you want changes to take effect across the fleet uniformly.