Managing policy
Policy is the heart of Kilasec: an ordered list of rules that decides what happens to every AI request. This page is how to write, order, test, and ship it. For the exact matching semantics, see Policy semantics; for rule-writing detail, Writing policy rules.
Where you do this: Cloud dashboard — kilasec.com/app/ → Policy Rules (visual editor and YAML), Live Traffic (verify), Destinations (scope). Requires the tenant_admin role. No host commands.
The model: first match wins
Rules are evaluated top to bottom, and the first one that matches decides the verdict. If nothing matches, the policy's default action applies. Order matters — a broad allow above a narrow deny means the deny never fires. Put specific rules above general ones.
Each rule produces one verdict:
- allow — forward unchanged.
- redact — mask matched secrets/PII, then forward.
- deny — stop the request; it never reaches the provider.
- require_approval — hold for a human decision (see Approvals).
- log — allow, but record (observe-only).
What a rule can match on
- Agent — the calling tool/SDK (
openai-python,claude-cli,browser, …). - Destination — host, tool, or model (
api.openai.com, a specific model). - User / AD group — when identity is wired:
group:engineering. - Time window — hours/days, e.g. block off-hours.
- Content — a scan of the request body (secrets, PII, custom
arg_regex). - Cost —
daily_cost_overa dollar threshold for an agent. - Rate —
calls_per_minute_overa request-rate threshold for an agent (60s sliding window). The runaway-loop gate: pair withdenyfor a hard rate limit, orrequire_approvalto hold a hammering agent for a human. Example:
- name: rate_limit_eval_loops
match:
calls_per_minute_over: 30
destination_is_ai_provider: true
action: deny
reason: "agent exceeded 30 model calls/min — likely a runaway loop"- First contact —
destination_is_new_for_agent: truefires when an agent with an established baseline reaches a host / tool / model it has never used before. The approve-once gate: hold the first call for a human, and once it's allowed it's part of the agent's known-good set and won't fire again. Suppressed during an agent's warm-up so a brand-new agent doesn't flood the queue. - Shadow AI —
destination_is_unknown_ai: truefires on AI-shaped traffic to a host on no allowlist;destination_is_ai_provider: truematches any known provider.
Building an approval policy
require_approval holds the request for a human (see Approvals) — so reserve it for things that are irreversible, privileged, first-contact, or over a threshold, and let allow / redact / deny handle everything routine. Starter rules for each category (paste into Policy Rules → YAML and tune):
# Irreversible — external writes an agent is about to make on your behalf
- name: approve_external_writes
match:
action: [http_request, tool_call]
arg_regex: { method: "^(POST|PUT|DELETE)$" }
action: require_approval
reason: "external write — review before it happens"
# Privileged — an agent reaching a sensitive tool / endpoint
- name: approve_privileged_tools
match:
destination: { tool: ["shell.exec", "secrets.read", "iam.*"] }
action: require_approval
reason: "privileged action requires human sign-off"
# First-contact — a vetted agent hitting a destination it's never used
- name: approve_first_contact
match:
destination_is_new_for_agent: true
action: require_approval
reason: "first time this agent used this destination"
# Threshold — over a daily spend limit
- name: approve_over_budget
match:
daily_cost_over: 50
action: require_approval
reason: "agent exceeded its $50/day budget"Pending approvals are pushed to your Settings → Notifications channel (Slack-compatible webhook / email) the moment they arrive, so you don't have to watch the screen — see Approvals.
Scope vs policy
Two different controls, easy to conflate:
- Scope decides what gets decrypted and inspected at all — the list of AI destinations the collector intercepts. Everything outside scope bypasses the collector entirely.
- Policy decides what happens to the traffic that is inspected.
Widen scope to see more; write policy to act on it. Manage scope on Destinations (labelled "Scope" in some views).
Test before you enforce: log first
There's no dry-run page — the way to see what a rule will do is to let it match real traffic without acting on it:
- Save the rule with
action: log(same match, same position in the order). - Watch Live Traffic filtered by that rule name for a day. Every row it would have hit shows up there — including the legitimate calls you didn't expect.
- When the matches are what you intended, switch the action to
deny,redactorrequire_approval.
The editor's preview bar reads the rule back in plain English as you build it, and Policy Rules shows each rule's 24h match count and flags a rule that an earlier one shadows.
Applying changes
Edit rules on Policy Rules — add/edit/delete/reorder in the visual editor, or use Policy Rules → YAML for the full-file editor. Saved changes are versioned in the cloud and pulled by collectors on their next cycle. To apply immediately across the fleet, hit Apply now on the same page — it restarts collectors to re-read config. Every change is recorded in the Audit Log.
A safe rollout pattern
- Start permissive — default
allow/log, redaction on for obvious secret patterns. Don't block what you haven't observed. - Observe — watch Live Traffic, Agents, Incidents for a week to learn the real providers/agents/users.
- Add targeted rules — one risk at a time (block a shadow provider, require approval over a spend threshold, redact PII to a support agent), each starting as
log. - Tighten the default last — only move the default from
allowtodenyonce yourallowrules cover legitimate traffic, or you'll block the business.
A note on rule regexes
Custom arg_regex patterns are yours to author. A malformed regex is a policy bug — roll rules that use them out as log first, and prefer the built-in secret/PII matchers where they cover your case.