Configuration

agentic-route has two configuration files with two different schemas. Both live in /etc/agentic-route/ and both are hand-edited; the tool never writes either.

File Read by Schema Purpose
routes.json (AGENTIC_ROUTE_CONF) agentic-route enforce/check/status/diff/monitor/api/mcp (lib/core.sh) spec: rules, forbidden_rules, pinned_routes Full declarative desired rule set, applied directly
intent.json (AGENTIC_ROUTE_INTENT) agentic-route-reconcile, agentic-route-daemon intent: forbidden_rules, pinned_routes, custom_rules Constraints only; the reconciler discovers live kernel state and compiles intent + discovery into an effective spec at runtime

Use routes.json when you want to own every rule and route yourself. Use intent.json (with the daemon) when VPN clients own most of the routing table and you only want to pin, forbid or add a few things on top of what they do. You may run both — the daemon and the CLI agree on the shared forbidden_rules / pinned_routes semantics.

Examples: etc/routes.json.example, etc/intent.json.example (install.sh copies both into /etc/agentic-route/ if absent).

routes.json — spec

{
  "version": 1,
  "rules": [
    { "prio": 1000, "selector": "from all fwmark 0x80000/0xff0000", "action": "lookup main" }
  ],
  "forbidden_rules": [
    { "prio": 31580, "match": "suppress_prefixlength 0", "reason": "..." },
    { "match": "100.64.0.0/10 lookup main", "reason": "..." }
  ],
  "pinned_routes": [
    { "dst": "default", "via": "192.0.2.1", "dev": "eth0", "reason": "..." }
  ]
}

intent.json — intent

{
  "version": 1,
  "forbidden_rules": [
    { "prio": 31580, "match": "suppress_prefixlength 0", "reason": "..." },
    { "match": "100.64.0.0/10 lookup main", "reason": "..." }
  ],
  "pinned_routes": [
    { "dst": "default", "via": "192.0.2.1", "dev": "eth0", "reason": "..." }
  ],
  "custom_rules": [
    { "prio": 32765, "selector": "not from all fwmark 0xe1f1", "action": "lookup 205" }
  ]
}

Field reference

rules / custom_rules

In routes.json, rules is the complete set of rules that must exist. In intent.json, custom_rules are added on top of whatever the reconciler discovers live.

Field Type Description
prio int Rule priority (1-32767)
selector string ip rule selector, e.g. from all fwmark 0xe1f1
action string ip rule action, e.g. lookup 205

forbidden_rules

Live rules matching an entry are deleted.

Field Type Description
prio int Optional. If set, only a live rule at exactly this priority can match
match string Literal substring (not a regex) searched for in the live rule’s selector action text. CIDRs, 0x fwmarks and table numbers are matched byte-for-byte
reason string Free text

pinned_routes

Routes that must exist in main; re-added if a VPN client removes them.

Field Type Description
dst string Destination CIDR or default
via string Next hop (optional)
dev string Output interface (optional)
reason string Free text

Environment variables

Variable Default Used by
AGENTIC_ROUTE_CONF /etc/agentic-route/routes.json CLI, api, mcp
AGENTIC_ROUTE_INTENT /etc/agentic-route/intent.json agentic-route-reconcile
AGENTIC_ROUTE_API_PORT 8099 api
AGENTIC_ROUTE_TLS_CERT /etc/agentic-route/certs/api.crt api (mTLS, see PKI)
AGENTIC_ROUTE_TLS_KEY /etc/agentic-route/certs/api.key api
AGENTIC_ROUTE_TLS_CA /etc/agentic-route/certs/ca.crt api
AR_QUIET 0 all — suppress log lines