Skip to content

Configuration Reference

Oktsec is configured via YAML. All commands accept --config <path> to specify the config file explicitly.

Config resolution cascade

When no explicit --config flag is provided, Oktsec resolves the config file using this 4-step cascade (first match wins):

Priority Source Path
1 --config flag Explicit path passed on the command line
2 $OKTSEC_CONFIG env var Path from the environment variable
3 Working directory ./oktsec.yaml
4 Home directory ~/.oktsec/config.yaml

Centralized home directory

Oktsec stores all state in ~/.oktsec/:

~/.oktsec/
  config.yaml    # Main configuration
  .env           # Secrets (API keys)
  keys/          # Ed25519 keypairs
  oktsec.db      # SQLite audit database

The oktsec run command creates this directory structure automatically on first run. Run oktsec doctor to verify it.

Secrets separation

Sensitive values are stored in ~/.oktsec/.env, separate from the main config:

OKTSEC_API_KEY=oks_a1b2c3d4e5f6...

This file is auto-generated on first run with a random OKTSEC_API_KEY. Keeping secrets out of the YAML config makes it safe to commit config.yaml to version control.

Config backup

When Oktsec writes to the config file (e.g., via dashboard settings or oktsec wrap), it creates a .bak backup of the previous version in the same directory before writing.


Minimal config

version: "1"

server:
  port: 8080

identity:
  keys_dir: "./keys"
  require_signature: false   # observe mode

agents:
  coordinator:
    can_message: ["researcher", "coder"]
  researcher:
    can_message: ["coordinator"]
  coder:
    can_message: ["coordinator"]

This is enough to start. The security pipeline runs with defaults for everything not specified.


Full schema

Every field, its type, default, and behavior.

server

Field Type Default Description
port int 8080 HTTP port. Auto-increments up to +10 if in use
bind string 127.0.0.1 Bind address. Use 0.0.0.0 for network access
log_level string info Log verbosity: debug, info, warn, error

identity

Field Type Default Description
keys_dir string ./keys Directory containing .pub and .key files
require_signature bool true Reject unsigned messages (enforce mode). Set false for observe mode

Observe vs enforce

require_signature: false = observe mode — logs everything, blocks nothing. This is the recommended starting mode. Set true when ready to enforce identity verification.

default_policy

Value Behavior
allow (default) Accept messages from unknown agents
deny Reject messages from agents not listed in agents

db_path

Type Default Description
string oktsec.db SQLite database for audit trail and quarantine. Resolved to absolute path at load time. Use :memory: for in-memory (testing only)

custom_rules_dir

Type Default Description
string "" Directory for org-specific YAML detection rules. Loaded alongside the 175 built-in rules

agents

Map of agent name to configuration. Agent names must match ^[a-zA-Z0-9][a-zA-Z0-9_-]*$.

agents:
  coordinator:
    description: "Orchestrator agent"
    can_message: ["researcher", "reporter"]
    blocked_content: [credentials, pii]
    allowed_tools: []
    suspended: false
    location: "us-east-1"
    tags: ["prod", "critical"]
    egress:
      allowed_domains: [api.google.com]
      blocked_domains: [pastebin.com]
      scan_requests: true
      blocked_categories: [credentials]
      rate_limit: 100
      rate_window: 60
Field Type Default Description
can_message []string [] Agents this agent can message. ["*"] = any agent. An agent cannot list itself
blocked_content []string [] Aguara categories that force block verdict for this agent
allowed_tools []string [] MCP tool names this agent can call. Empty = all tools allowed
suspended bool false Immediately block all messages from/to this agent
description string "" Human-readable description
created_by string "" Who created the agent (set by API)
created_at string "" Creation timestamp (set by API)
location string "" Deployment location tag
tags []string [] Arbitrary tags for filtering
egress object null Per-agent outbound controls (see below)

agents.*.egress

Per-agent outbound traffic controls. Omit entirely to use global forward_proxy settings.

Field Type Default Description
allowed_domains []string [] Only these domains are reachable. Additive with global allowed_domains
blocked_domains []string [] Block these domains. Additive with global blocked_domains
scan_requests bool* null Scan outbound bodies. null = inherit global setting
scan_responses bool* null Scan inbound responses. null = inherit global setting
blocked_categories []string [] DLP: block outbound content matching these Aguara categories
rate_limit int 0 Max outbound requests per window (0 = no agent-specific limit)
rate_window int 60 Window size in seconds

*Uses pointer semantics: null/omitted inherits from global, explicit true/false overrides.


gateway

MCP gateway mode — fronts multiple backend MCP servers through a single endpoint.

gateway:
  enabled: true
  port: 9090
  bind: "127.0.0.1"
  endpoint_path: "/mcp"
  scan_responses: true
Field Type Default Description
enabled bool false Enable the gateway
port int 9090 Gateway HTTP port. Auto-increments up to +10 if in use
bind string 127.0.0.1 Bind address
endpoint_path string /mcp MCP endpoint path
scan_responses bool false Scan backend responses before passing to agents

mcp_servers

Backend MCP servers for gateway mode. Map of server name to config.

mcp_servers:
  filesystem:
    transport: stdio
    command: npx
    args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
    env:
      NODE_ENV: production
mcp_servers:
  github:
    transport: http
    url: https://api.github.com/mcp
    headers:
      Authorization: "Bearer ghp_xxx"
Field Type Required Description
transport string yes stdio or http
command string stdio only Command to launch
args []string no Command arguments
env map no Environment variables (stdio only)
url string http only Remote MCP server URL
headers map no HTTP headers (http only)

forward_proxy

HTTP forward proxy for outbound agent traffic. Used with Docker Sandbox or any agent that routes through HTTP_PROXY.

forward_proxy:
  enabled: true
  scan_requests: true
  scan_responses: false
  max_body_size: 1048576
  allowed_domains: []
  blocked_domains:
    - pastebin.com
    - transfer.sh
    - file.io
Field Type Default Description
enabled bool false Enable the forward proxy
scan_requests bool true Scan outbound request bodies with Aguara
scan_responses bool false Scan inbound response bodies
max_body_size int64 1048576 Max body size to scan (bytes). Bodies larger than this are passed through unscanned
allowed_domains []string [] Global domain allowlist. Empty = all domains allowed
blocked_domains []string [] Global domain blocklist. Takes precedence over allowlist

Open proxy protection

Validation rejects configs where forward_proxy.enabled: true but neither allowed_domains nor blocked_domains are set. This prevents accidentally running an open proxy.


quarantine

quarantine:
  enabled: true
  expiry_hours: 24
  retention_days: 30
Field Type Default Description
enabled bool true Enable the quarantine queue
expiry_hours int 24 Auto-expire pending items after this many hours
retention_days int 0 Auto-purge audit entries older than N days. 0 = keep forever

rate_limit

Global per-agent message rate limiting.

rate_limit:
  per_agent: 20
  window: 60
Field Type Default Description
per_agent int 0 Max messages per agent per window. 0 = disabled
window int 60 Window size in seconds

anomaly

Automatic risk-based alerting and optional auto-suspension.

anomaly:
  check_interval: 60
  risk_threshold: 50
  min_messages: 5
  auto_suspend: false
Field Type Default Description
check_interval int 60 Seconds between anomaly checks
risk_threshold float64 0 Risk score (0-100) to trigger alert. 0 = disabled
min_messages int 0 Minimum messages before evaluating risk
auto_suspend bool false Automatically suspend agents exceeding the threshold

rules

Per-rule enforcement overrides. Override the default severity-based verdict for any detection rule.

rules:
  - id: "IAP-001"
    severity: "critical"
    action: "block"
    notify: [slack-security]
    template: |
      *{{RULE}}* — {{RULE_NAME}}
      Severity: {{SEVERITY}} | Agents: {{FROM}} -> {{TO}}
      Match: `{{MATCH}}`
Field Type Required Description
id string yes Rule ID (e.g., IAP-001, PI-001)
severity string no Override severity
action string yes block, quarantine, allow-and-flag, or ignore
notify []string no Named webhook channels or raw URLs
template string no Custom webhook body template

Duplicate detection

Validation rejects configs with duplicate rule IDs in the rules list.


category_webhooks

Default notification channels for all rules in a category. Rules with explicit notify take precedence.

category_webhooks:
  - category: credential-leak
    notify: [slack-security]
  - category: prompt-injection
    notify: [slack-security, discord-alerts]

webhooks

Named notification endpoints referenced by notify in rules and category webhooks.

webhooks:
  - name: slack-security
    url: https://hooks.slack.com/services/T00/B00/xxx
    events: [blocked, quarantined]
  - name: discord-alerts
    url: https://discord.com/api/webhooks/xxx
    events: [blocked]
Field Type Required Description
name string no Friendly name for referencing in notify
url string yes Webhook endpoint URL
events []string yes Events to send: blocked, quarantined, rejected

Template variables

Available in rules[].template:

Variable Description
{{RULE}} Rule ID (e.g., IAP-001)
{{RULE_NAME}} Rule name
{{SEVERITY}} Severity level
{{CATEGORY}} Rule category
{{FROM}} Sender agent
{{TO}} Recipient agent
{{MATCH}} Matched content snippet
{{ACTION}} Verdict taken

Validation

oktsec verify --config oktsec.yaml

Validation checks:

  • Port in range 1-65535
  • keys_dir set when require_signature: true
  • default_policy is allow or deny
  • No agent lists itself in can_message
  • No duplicate rule overrides
  • Rule actions are valid (block, quarantine, allow-and-flag, ignore)
  • Gateway port valid and MCP server transports correct
  • Forward proxy not enabled without domain policies (open proxy prevention)
  • max_body_size non-negative

Environment-specific examples

version: "1"
server:
  port: 8080
  log_level: debug
identity:
  keys_dir: ./keys
  require_signature: false    # observe mode
agents:
  my-agent:
    can_message: ["*"]
version: "1"
server:
  port: 8080
  log_level: info
identity:
  keys_dir: ./keys
  require_signature: true     # enforce mode
default_policy: deny
agents:
  coordinator:
    can_message: [researcher, coder]
    blocked_content: [credentials]
  researcher:
    can_message: [coordinator]
    allowed_tools: [read_file, search_files]
    blocked_content: [credentials, pii]
  coder:
    can_message: [coordinator]
    allowed_tools: [read_file, write_file, list_dir]
    blocked_content: [credentials]
rate_limit:
  per_agent: 50
  window: 60
version: "1"
server:
  port: 8080
  bind: "127.0.0.1"
  log_level: warn
identity:
  keys_dir: /etc/oktsec/keys
  require_signature: true
default_policy: deny
db_path: /var/lib/oktsec/oktsec.db
agents:
  coordinator:
    can_message: [researcher, coder, reporter]
    blocked_content: [credentials, pii]
  researcher:
    can_message: [coordinator]
    allowed_tools: [read_file, search_files]
    blocked_content: [credentials, pii, exfiltration]
    egress:
      allowed_domains: [api.arxiv.org, api.semanticscholar.org]
      blocked_categories: [credentials, pii]
      rate_limit: 200
  coder:
    can_message: [coordinator]
    allowed_tools: [read_file, write_file, list_dir]
    blocked_content: [credentials, exfiltration]
    egress:
      allowed_domains: [api.github.com, registry.npmjs.org]
      rate_limit: 100
forward_proxy:
  enabled: true
  scan_requests: true
  blocked_domains: [pastebin.com, transfer.sh, file.io]
quarantine:
  enabled: true
  expiry_hours: 24
  retention_days: 90
rate_limit:
  per_agent: 20
  window: 60
anomaly:
  check_interval: 60
  risk_threshold: 70
  min_messages: 10
  auto_suspend: true
rules:
  - id: IAP-001
    action: block
    notify: [slack-security]
  - id: IAP-003
    action: block
    notify: [slack-security]
  - id: IAP-007
    action: block
    notify: [slack-security]
category_webhooks:
  - category: credential-leak
    notify: [slack-security]
webhooks:
  - name: slack-security
    url: https://hooks.slack.com/services/T00/B00/xxx
    events: [blocked, quarantined]