Configuration Reference
All Ithil configuration lives under the Ithil:* key in appsettings.json. Every key can also be set via environment variable using __ as the separator (e.g., Ithil__Jwt__SigningKey).
Full example
{
"Ithil": {
"Jwt": {
"SigningKey": "your-32-byte-or-longer-hmac-signing-key-here",
"Issuer": "ithil-dev",
"Audience": "ithil-gateway"
},
"AgentStore": {
"UseInMemory": false
},
"Budget": {
"DefaultDailyTokenLimit": 100000
},
"SemanticCache": {
"ModelPath": "models/all-MiniLM-L6-v2.onnx",
"VocabPath": "models/vocab.txt",
"SimilarityThreshold": 0.92
},
"ToolRegistry": {
"DownstreamBaseUrl": "http://localhost:5200"
},
"CircuitBreaker": {
"MinimumThroughput": 5,
"FailureRatio": 1.0,
"SamplingDuration": "00:00:30",
"BreakDuration": "00:00:30"
},
"Audit": {
"DisableStdoutSink": false
},
"Trace": {
"BufferSize": 500
},
"Shutdown": {
"TimeoutSeconds": 25
},
"Privacy": {
"CustomRules": []
},
"LicenseKey": "eyJ..."
},
"ConnectionStrings": {
"Redis": "localhost:6379"
},
"ReverseProxy": {
"Routes": {
"ithil-route": {
"ClusterId": "ithil-cluster",
"Match": {
"Path": "/api/{**catch-all}"
}
}
},
"Clusters": {
"ithil-cluster": {
"Destinations": {
"destination1": {
"Address": "http://localhost:5200"
}
}
}
}
}
}Key reference
JWT
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:Jwt:SigningKey | string | (required) | HMAC-SHA256 signing key for agent JWTs. Must be at least 32 bytes. |
Ithil:Jwt:Issuer | string | ithil-dev | The iss claim the gateway emits when issuing tokens and validates on incoming requests. |
Ithil:Jwt:Audience | string | ithil-gateway | The aud claim. Agents must include this value in their JWT. |
Agent Store
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:AgentStore:UseInMemory | bool | false | Swaps agent config and API key storage to in-memory dictionaries. Intended for local development only — data is lost on restart. Redis is still required for budget enforcement and semantic caching regardless of this setting. |
Budget
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:Budget:DefaultDailyTokenLimit | int | 100000 | Daily token cap applied to any agent that does not have an explicit per-agent limit configured. Resets at midnight UTC. |
Semantic Cache
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:SemanticCache:ModelPath | string | models/all-MiniLM-L6-v2.onnx | Path to the ONNX embedding model file, relative to the gateway working directory or absolute. |
Ithil:SemanticCache:VocabPath | string | models/vocab.txt | Path to the tokenizer vocabulary file used by the embedding model. |
Ithil:SemanticCache:SimilarityThreshold | float | 0.92 | Cosine similarity threshold above which a cached response is returned. Lower values increase cache hit rate but risk returning stale or incorrect responses. |
Tool Registry
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:ToolRegistry:DownstreamBaseUrl | string | (required) | Base URL of the downstream ASP.NET API. The gateway polls {DownstreamBaseUrl}/ithil/schema at startup and forwards tool calls to this base URL. |
Circuit Breaker
The circuit breaker protects the downstream API from being hammered when it is unhealthy. Once the breaker opens, requests are rejected immediately until the break duration elapses and a probe request succeeds.
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:CircuitBreaker:MinimumThroughput | int | 5 | Minimum number of requests in the sampling window before the failure ratio is evaluated. The circuit will not open until at least this many requests have been observed. |
Ithil:CircuitBreaker:FailureRatio | float | 1.0 | Fraction of requests (0.0–1.0) that must fail before the circuit opens. 1.0 means every request in the window must fail. |
Ithil:CircuitBreaker:SamplingDuration | TimeSpan | 00:00:30 | The sliding window over which the failure ratio is measured. |
Ithil:CircuitBreaker:BreakDuration | TimeSpan | 00:00:30 | How long the circuit stays open before allowing one probe request (half-open state). |
Audit
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:Audit:DisableStdoutSink | bool | false | Set to true to suppress the built-in stdout audit sink. Useful when piping structured logs to an external collector that would double-count the records. |
Trace Buffer
The trace buffer holds recent request/response traces in memory for the live dashboard feed. It is a ring buffer — when full, the oldest entry is silently overwritten. Contents are lost on process restart by design.
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:Trace:BufferSize | int | 500 | Maximum number of trace events held in memory at once. Must be greater than 0. |
Shutdown
TimeoutSeconds must be less than the Kubernetes terminationGracePeriodSeconds on your pod spec. The recommended relationship is terminationGracePeriodSeconds = TimeoutSeconds + 5 to give .NET time to finish draining before the pod is force-killed.
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:Shutdown:TimeoutSeconds | int | 25 | Seconds to wait for in-flight requests and background workers to finish after SIGTERM. Must be greater than 0. |
Privacy Filter
Custom PII redaction rules are applied after the built-in rules (email addresses, SSNs, credit card numbers). Each rule is a regex pattern and a replacement string.
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:Privacy:CustomRules | array | [] | List of { "Pattern": "<regex>", "Replacement": "<text>" } objects. Applied in order after built-in rules. |
Example:
"Privacy": {
"CustomRules": [
{ "Pattern": "EMP-\\d{6}", "Replacement": "[EMPLOYEE-ID]" }
]
}Licensing
| Key | Type | Default | Description |
|---|---|---|---|
Ithil:LicenseKey | string | (required) | Signed JWT license key. Get a free non-commercial key at ithil.software/register . The gateway refuses to start if this is absent or invalid. See Licensing. |
Connection Strings
| Key | Type | Default | Description |
|---|---|---|---|
ConnectionStrings:Redis | string | (required) | Redis connection string in StackExchange.Redis format . Required even when UseInMemory is true — Redis backs budget enforcement and semantic caching. |
YARP (Reverse Proxy)
| Key | Type | Description |
|---|---|---|
ReverseProxy:Routes | object | YARP route configuration. Maps path patterns to cluster IDs. |
ReverseProxy:Clusters | object | YARP cluster configuration. Each cluster lists one or more destination addresses. |
The ReverseProxy section is standard YARP configuration. Ithil requires at minimum one route pointing to your downstream API. Advanced YARP features (load balancing, health checks, transforms) are fully supported — see the YARP documentation for details.
Environment variables
All appsettings.json keys can be overridden with environment variables. Replace : with __:
Ithil__Jwt__SigningKey=your-key-here
Ithil__ToolRegistry__DownstreamBaseUrl=http://your-api:5200
Ithil__Shutdown__TimeoutSeconds=25
ConnectionStrings__Redis=your-redis:6379Secrets management
Never commit Ithil:Jwt:SigningKey or Ithil:LicenseKey to source control.
Development: Use dotnet user-secrets:
dotnet user-secrets set "Ithil:Jwt:SigningKey" "your-key-here"Production: Use your platform’s secrets manager:
- Azure: Azure Key Vault
- AWS: AWS Secrets Manager
- Kubernetes: Kubernetes Secrets
- Docker: Docker Secrets