# cortex.example.toml — example configuration # # Copy to cortex.toml and adjust for your environment. # # Environment variable overrides use CORTEX_ prefix with __ separators: # CORTEX_GATEWAY__LISTEN=0.0.0.0:31313 # Path to the model catalogue (limits, cost, pinning, aliases, feasibility). # Defaults to the packaged location below; uncomment to override for a # non-packaged / local run. # models_config = "/etc/cortex/models.toml" [gateway] listen = "0.0.0.0:31313" metrics_listen = "0.0.0.0:31314" [eviction] strategy = "lru" # Restart neurons after this many load/unload cycles to defragment VRAM. # Set to 0 to disable. defrag_after_cycles = 50 # -- Nodes --------------------------------------------------------------- # Each [[nodes]] entry declares a neuron daemon in the fleet. # Models are discovered by polling the neuron's /models endpoint. # Pinned models (see models.toml) are never evicted. [[nodes]] name = "gpu-large" endpoint = "http://gpu-large.internal:8080" vram_mb = 49152 # e.g. 2x RTX 4090 (48 GB combined) pinned = [ "your-org/large-model", ] [[nodes]] name = "gpu-medium" endpoint = "http://gpu-medium.internal:8080" vram_mb = 24576 # e.g. RTX 4090 (24 GB) pinned = [ "your-org/medium-model", ] [[nodes]] name = "gpu-small" endpoint = "http://gpu-small.internal:8080" vram_mb = 12288 # e.g. RTX 3060 (12 GB) pinned = [ "your-org/embedding-model", ] # -- Entitlements (multi-tenant governance, #47) ------------------------- # Identity + per-key token budgets. Omit this section entirely for the # legacy single-operator behaviour: requests are anonymous and uncapped. # # The local/static provider below is the source of truth for accounts, # keys, and hard caps until the upstream clearing house exists. Identity # rides standard bearer auth only — clients send # Authorization: Bearer # no custom headers or body fields. [entitlements] # Reject unauthenticated requests with 401 invalid_api_key. Leave false # (allow-anonymous) during rollout; flip to true once keys are issued. require_auth = false # One entry per API key. [[entitlements.keys]] key = "sk-example-rolling" # the bearer token the client sends account_id = "team-research" # billable account (keys may share one) key_id = "research-ci" # stable label for ledger/metrics (optional) hard_cap = 5_000_000 # hard token cap over the window # Rolling window that resets — over-cap requests get 429 rate_limit_exceeded # + Retry-After, so well-behaved clients (opencode/AI SDK) back off and retry. window = { kind = "rolling", seconds = 3600 } [[entitlements.keys]] key = "sk-example-balance" account_id = "team-research" key_id = "research-prepaid" hard_cap = 20_000_000 # Hard balance, no reset — exhaustion returns 429 insufficient_quota # (the client surfaces and stops). This is the default when `window` is # omitted. Never 402. window = { kind = "balance" } [[entitlements.keys]] key = "sk-example-infra" account_id = "operator" key_id = "infra" # No hard_cap → uncapped operator infra key (own fleet, own use). Still # metered for visibility.