Configuration Reference
Everything in RADIUS is controlled by a single YAML file. This page covers every section, every option, and the three built-in profiles.
Config file discovery
RADIUS looks for config files in this order:
radius.yamlradius.yml.radius.yaml
The first match wins. All paths are relative to the current working directory.
Full annotated example
# ── Global Settings ──────────────────────────────
global:
profile: standard # local | standard | unbounded
workspace: "${CWD}" # Agent workspace root
defaultAction: deny # deny | allow
requireSignedPolicy: false # Require signed policy file
onUndefinedTemplateVar: error # error | empty
# ── Module Pipeline ──────────────────────────────
# Order matters. First deny wins. Audit should be last.
modules:
- kill_switch
- skill_scanner
- tool_policy
- fs_guard
- command_guard
- exec_sandbox
- egress_guard
- output_dlp
- rate_budget
- approval_gate
- audit
# ── Module Configuration ─────────────────────────
moduleConfig:
kill_switch:
enabled: true
envVar: RADIUS_KILL_SWITCH # Set this env var to activate
filePath: ./.radius/KILL_SWITCH # Or create this file
denyPhases:
- pre_request
- pre_tool
reason: "emergency kill switch active: human safety override"
skill_scanner:
scanOnStartup: true
scanOnReload: true
actionOnCritical: challenge # deny | challenge | alert
requireSignature: false
requireSbom: false
requirePinnedSource: false
onProvenanceFailure: challenge
tool_policy:
default: deny # deny | allow
# rules: # Per-tool guidance: /docs/modules/
fs_guard:
allowedPaths:
- "${workspace}"
- "/tmp"
blockedPaths:
- "~/.ssh"
- "~/.aws"
- "/etc"
blockedBasenames:
- ".env"
- ".env.local"
- ".envrc"
command_guard:
denyPatterns:
- "(^|\\s)sudo\\s"
- "rm\\s+-rf\\s+/"
- "(^|\\s)(cat|less|more|head|tail|grep|awk|sed)\\s+[^\\n]*\\.env(?:\\.|\\s|$)"
exec_sandbox:
engine: bwrap # bwrap | none
required: false # true = deny if bwrap unavailable
egress_guard:
# allowedDomains: [] # Allowlist mode
# blockedDomains: [] # Blocklist mode
output_dlp:
action: redact # deny | redact | alert
# customPatterns: [] # Additional regex patterns
rate_budget:
windowSec: 60
maxCallsPerWindow: 60
approval_gate:
# enabled: false # Enable for human-in-the-loop
audit:
sink: file # file | stdout | webhook | otlp
path: .radius/audit.jsonl
# ── Audit Settings ───────────────────────────────
audit:
sink: file
path: .radius/audit.jsonl
includeArguments: true
includeResults: true
# webhookUrl: https://...
# otlpEndpoint: https://...
# headers: {}
# timeoutMs: 5000
# ── Approval Settings ────────────────────────────
approval:
enabled: false
mode: sync_wait # sync_wait | async_token
waitTimeoutSec: 300
onTimeout: deny # deny | alert
onConnectorError: deny # deny | alert
store:
engine: sqlite # sqlite | memory
path: .radius/approvals.db
channels:
telegram:
enabled: false
transport: polling # polling | webhook
botToken: "${TELEGRAM_BOT_TOKEN}"
allowedChatIds: []
approverUserIds: []
pollIntervalMs: 2000
global section
| Key | Type | Default | Description |
|---|---|---|---|
profile | local | standard | unbounded | standard | Base security profile |
workspace | string | ${CWD} | Agent workspace root directory |
defaultAction | deny | allow | deny | Action for tools not covered by rules |
requireSignedPolicy | boolean | false | Require policy file signature verification |
onUndefinedTemplateVar | error | empty | error | Behavior when a template variable is undefined |
Template variables
Use template variables anywhere in the YAML. They’re resolved at config load time.
| Variable | Resolves to |
|---|---|
${workspace} | The global.workspace value (after its own resolution) |
${CWD} | Current working directory |
${HOME} | User home directory |
${ENV_VAR_NAME} | Any environment variable |
Example:
fs_guard:
allowedPaths:
- "${workspace}" # /home/user/project
- "${HOME}/.config" # /home/user/.config
- "${CUSTOM_PATH}" # whatever CUSTOM_PATH is set to
modules array
The pipeline runs each module in array order. Order matters:
- kill_switch — check first, halt everything if triggered
- skill_scanner — scan artifacts before processing
- tool_policy — explicit allow/deny by tool name
- fs_guard — filesystem path constraints
- command_guard — shell command pattern blocking
- exec_sandbox — namespace isolation for commands
- egress_guard — outbound network filtering
- output_dlp — secret detection in outputs
- rate_budget — rate limiting
- approval_gate — human approval for remaining actions
- audit — log the final decision (always last)
You can remove modules you don’t need. You can reorder them (but the above order is recommended). You can add the same module twice with different configs if needed.
moduleConfig overview
Each key in moduleConfig maps to a module name. The config object is passed to that module’s configure() method.
Runtime note for agentradius@0.4.0: keep effective module settings inside moduleConfig.<moduleName>. For audit, set sink/path in moduleConfig.audit for hook adapters (OpenClaw/Nanobot), even if you also keep a top-level audit block for readability.
Detailed per-module guidance is now documented in Modules. The full annotated example above still provides the fastest complete reference.
audit section
For runtime compatibility in v0.4.0, prefer moduleConfig.audit as the source of truth.
| Key | Type | Default | Description |
|---|---|---|---|
sink | file | stdout | webhook | otlp | file | Where to write audit events |
path | string | .radius/audit.jsonl | File path (for file sink) |
webhookUrl | string | — | Webhook endpoint (for webhook sink) |
otlpEndpoint | string | — | OTLP endpoint (for otlp sink) |
headers | Record<string, string> | — | Custom headers for webhook/OTLP |
timeoutMs | number | 5000 | Request timeout for webhook/OTLP |
includeArguments | boolean | true | Include tool arguments in audit log |
includeResults | boolean | true | Include tool results in audit log |
approval section
| Key | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable human-in-the-loop approval |
mode | sync_wait | async_token | sync_wait | Wait for approval or return a token |
waitTimeoutSec | number | 300 | How long to wait for human response |
onTimeout | deny | alert | deny | Action when approval times out |
onConnectorError | deny | alert | deny | Action on channel error |
store.engine | sqlite | memory | sqlite | Approval state storage |
store.path | string | .radius/approvals.db | SQLite database path |
channels.telegram.enabled | boolean | false | Enable Telegram channel |
channels.telegram.transport | polling | webhook | polling | How to receive Telegram updates |
channels.telegram.botToken | string | — | Telegram bot token (use env var) |
channels.telegram.allowedChatIds | string[] | [] | Allowed Telegram chat IDs |
channels.telegram.approverUserIds | string[] | [] | Users who can approve |
channels.telegram.pollIntervalMs | number | 2000 | Polling interval |
Profiles comparison
Three profiles ship with RADIUS. Use them as starting points — every setting can be overridden in your radius.yaml.
| Setting | Local | Standard | Unbounded |
|---|---|---|---|
| Default action | deny | deny | allow |
| Module mode | enforce | enforce | observe |
| exec_sandbox | required | optional | not included |
| output_dlp action | deny | redact | alert |
| rate_budget | 30 calls/min | 60 calls/min | 120 calls/min |
| skill_scanner on critical | deny | challenge | alert |
| Provenance checks | signature + SBOM + pinned source required | challenge on failure | alert only |
| egress_guard | included | not included | not included |
| kill_switch | enforce | enforce | observe |
| Recommended for | production, billing, credentials | development, staging, daily work | research, migration, rollout |
Profile aliases
| Alias | Resolves to |
|---|---|
strict | local |
balanced | standard |
monitor | unbounded |
unleashed | unbounded |
Use either name in --profile or in the YAML global.profile field.
Local profile
Zero trust. Every tool is denied unless explicitly allowed. Sandbox is required for shell commands. Secrets in output cause an immediate deny. Supply chain provenance is enforced.
global:
profile: local
defaultAction: deny
modules:
- kill_switch
- skill_scanner
- tool_policy
- fs_guard
- command_guard
- exec_sandbox # required: true
- egress_guard # included in local only
- output_dlp # action: deny
- rate_budget # 30 calls/min
- audit
Use this for production environments, systems handling billing or credentials, and anywhere a compromised agent could cause real damage.
Standard profile
Trust but verify. Default deny, but the sandbox is optional, secrets are redacted (not blocked), and the rate limit is generous enough for normal development.
global:
profile: standard
defaultAction: deny
modules:
- kill_switch
- skill_scanner
- tool_policy
- fs_guard
- command_guard
- exec_sandbox # required: false
- output_dlp # action: redact
- rate_budget # 60 calls/min
- audit
This is the default for npx agentradius init. Good for development, staging, and daily work.
Unbounded profile
Safety off, logging only. All modules run in observe mode — they log what they would have blocked, but don’t actually block anything. The rate limit is high.
global:
profile: unbounded
defaultAction: allow
modules:
- kill_switch # observe mode
- skill_scanner # observe mode
- tool_policy # observe mode
- fs_guard # observe mode
- command_guard # observe mode
- output_dlp # action: alert, observe mode
- rate_budget # 120 calls/min, observe mode
- audit
Use this for initial migration: install RADIUS in unbounded mode, review the audit log to understand what would be blocked, then switch to standard or local.