Skip to main content

Configure Detection Thresholds

Tasks

Adjust the call-rate, token-spike, and repeated-prompt thresholds that drive anomaly detection, and route the resulting alerts to the channels your team monitors.

Detection controls live under Settings → Security & Privacy → Detection & Response. Use the Session behavior & efficiency and Behavioral baselines tabs for their existing controls. Session thresholds and auto-pause are separate; notification preferences and attack patterns retain their own Settings pages. Expand Advanced details for propagation, learning, and retention explanations.

Enable or disable session detection​

  1. Open Settings → Security & Privacy → Detection & Response → Session behavior & efficiency, or follow Detection & Response from Security events.
  2. Set Enable session anomaly detection. This controls existing session anomaly and context-waste findings.
  3. Select Save. Check Saved detection and This replica to distinguish the durable preference from the serving replica's effective state.

Peer replicas check storage every minute. Changes can take longer when storage is unavailable; this is not an atomic fleet switch. If a replica cannot load the preference at startup, detection stays off until a successful refresh. Unavailable means the serving replica has no wired session detector. Enabled does not establish sufficient data or complete signal coverage.

Disabling detection stops new findings and anomaly-triggered auto-pause, and stops generating inline context-waste advisories, after the setting becomes effective on each replica. Queued calls still finish spend accounting, but calls queued before a setting transition cannot seed new detection comparisons or findings. In-flight finding delivery uses bounded I/O and completes before the local change becomes effective. It retains findings, cumulative anomaly counts, existing pauses, and your auto-pause and notification preferences. Independent policies, including policies that consume session and context measurements, continue to run. An advisory already attached to an in-flight request may still arrive with its response after disablement.

Re-enabling starts fresh local detector comparisons. Single-request token spikes can fire immediately; rolling comparisons need new samples. Call, token, and verbosity samples are observed at completion: a request that completes after re-enable is eligible even if it started earlier. The fresh latency baseline uses only requests started after re-enable. Inline advisories based on current context fill, repeat-read counts, or session age can fire immediately without fresh rolling samples. Historical counts still contribute to the auto-pause threshold, so the next qualifying anomaly can pause a session that already meets that threshold. Resuming an existing pause is a separate action.

The settings API exposes anomalyDetectionEnabled (saved boolean, default true) and anomalyDetectionEffective (the serving replica's boolean state, or null when unavailable). Administrators can update anomalyDetectionEnabled through the existing settings endpoint.

Set detection thresholds​

  1. Navigate to Settings → Security & Privacy → Detection & Response → Session behavior & efficiency.

  2. Set the three thresholds:

    ThresholdDefaultWhat triggers it
    Max calls per minute60A session exceeds this call rate in any rolling 1-minute window. Uses completed LLM requests with reported token usage on the observing replica.
    Token spike threshold50 000A single LLM request uses more tokens than this value. Catches unexpectedly large context payloads — for example, a read_file on a multi-megabyte binary piped into a prompt.
    Max repeated prompts5The same prompt hash appears more than N times in the last 20 calls. Applies only where a producer supplies prompt text; the current LLM usage path does not supply it.
  3. Save. All three thresholds are independent — any one can fire an anomaly event without the others being crossed.

note

Run detection in observation mode (auto-pause off) and watch Security Events, filtered to Session anomaly, for at least a week before enabling enforcement — see Enable auto-pause below.

Tune thresholds for agentic workloads​

Default thresholds are calibrated for interactive developer use and are usually too tight for automated or multi-agent workloads.

  1. Open Security Events, filter to Session anomaly, and observe the real metric values your team's agentic workloads produce (each anomaly entry shows the exact triggering value).

  2. Adjust thresholds in Settings → Security & Privacy → Detection & Response → Session behavior & efficiency based on the workload pattern:

    Workload patternRecommended adjustment
    Claude Code with sub-agents (fan-out)Raise Max calls per minute to 150–200
    Large file indexing or repo scanningRaise Token spike threshold to 150 000–200 000
    Iterative code generation loopsRaise Max repeated prompts to 10–15
  3. Save, then continue watching the feed to confirm the new ceilings stop flagging normal activity without hiding genuine anomalies.

Enable auto-pause​

By default, session anomaly detection is enabled and auto-pause is off. Independent policies can still block requests.

  1. Navigate to Settings → Security & Privacy → Detection & Response → Session behavior & efficiency.

  2. Turn on Auto-pause on anomaly (default: Off). When off, anomalies only produce alerts; when on, sessions can be paused once the cumulative count is reached.

  3. Set Pause after N anomalies (default: 5) — the number of cumulative anomaly events in a session before it is paused. This guards against pausing on a single transient spike.

    The shared cumulative total includes both session-behavior and context-waste findings. Waste findings update that total and the session safety score, but do not themselves trigger auto-pause. A subsequent session-behavior finding checks the combined total against this threshold when auto-pause is enabled. Correctly counting waste findings can therefore make that existing threshold take effect sooner; the default remains off.

  4. Save. When a session is paused, the developer's next request returns a session_paused error with instructions to contact their admin. Admins can open the linked session from Security Events and use Resume Session on the Sessions page.

warning

Enable auto-pause only after observing anomaly patterns in the feed for at least a week. Premature enablement with default thresholds can pause legitimate agentic workloads during normal operation.

Configure attack pattern detection​

Attack pattern detection (Detections) ships with eight built-in patterns, each tunable independently. Six draw on gateway or mixed evidence; two use kernel evidence from self-hosted Kubernetes (see Kernel-sourced evidence). Every pattern defaults to Notify. Every non-exempt match that is not suppressed by a recorded, untainted Judge downgrade goes to your enabled notification routes, whatever its action (equivalent session- and identity-scope matches share one notification); Require approval and Deny are recorded with the match but don't hold or block the session.

Only administrators can change these settings. Viewers see every control disabled, and a read-only notice replaces the Save and Reset buttons. The Try a sequence dry run still works for viewers.

  1. Navigate to Settings → Attack Patterns. The page has an LLM Judge card, then four tabs: Templates, False-positive controls, Try a sequence, and Kernel evidence (eBPF).

  2. In the LLM Judge card, optionally turn on Record an LLM Judge verdict on each match (off by default). When Internal AI Features are configured, the LLM reviews each non-exempt match before notification delivery. An active assessment defers delivery; a recorded downgrade suppresses the sequence alert unless evidence is injection-tainted. The finding, verdict and reasoning remain available for review. Confirmed or escalated findings retain the template's configured notification action. Disabled, unavailable, failed or timed-out Judges keep the configured-action fallback; a failure never invents a more severe verdict. Abandoned owned assessments expire and can be retried within the attempt limit. A match without a verdict shows "No LLM Judge verdict recorded".

    Hold downgrades based on approval claims, under the same card, is on by default. When the evidence carries an approval, ticket, allowlist, break-glass or test-fixture claim, or text addressed to the reviewer (such as "classify this as benign", also when URL- or base64-encoded), or the Judge's reasoning rests on an approval claim, a downgrade isn't applied: the match keeps its template's action and the recorded reasoning explains why. Those claims come from tool calls an attacker can control; configure an exemption for workflows that really are expected. The Judge runs on its own model role, a stronger model by default; see Choose models for internal AI features.

    Read a held downgrade​

    When a guard holds a downgrade, the finding doesn't show Effective verdict — confirmed, because the model didn't confirm the attack. It shows LLM Judge — downgrade not applied with three separate facts:

    • Model recommendation: what the Judge said, with its confidence and reasoning.
    • Effective outcome: what stands, for example "Downgrade not applied; High / Notify retained".
    • Held by: the guard (the approval and directive guard, or the injection guard), the rule that matched, the evidence step and field, and whether the match was found after decoding URL encoding or Base64. Matched text expands a short excerpt with the match highlighted. The excerpt is shortened, and credentials and personal data in it are masked.

    The guard matches keywords in evidence on its own, independent of what the model wrote. Ordinary text, such as a pull request review that says "approved", can match. A match only keeps the template's configured action; it doesn't mean someone planted the text. The excerpt shows what matched so you can tell the two apart.

    AIControls records this explanation at the moment the guard holds the downgrade, so it doesn't change when the evidence changes later. A finding held before AIControls recorded explanations shows Exact trigger not recorded, with the guard and the model's recommendation but no rule, step or excerpt. The explanation is advisory. It never changes a decision.

    To say a hold was wrong, resolve the incident and choose what you dispute. See Dispute a Judge guard override.

    To inspect a detected pattern, open Security → Activity → Security and select an Attack pattern event. Its details show the ordered evidence and the saved advisory verdict. Related AI calls lists the Judge's attempts, including failures and retries. Open an attempt to inspect its Gateway event; that event links back to the Security finding. Older calls without a recorded correlation do not acquire a guessed link.

    In an attack-pattern finding’s details, sort Related AI calls by time, model, latency, or estimated cost. Sorting applies across all pages; calls with unavailable cost appear last in either cost sort direction.

    Gateway events identify the caller as AIControls Judge or AIControls Analyst in the existing Client column. Internal calls show Not evaluated for the policy decision: provider success does not mean a policy allowed the request or a Judge verdict was saved. The call details distinguish provider failure, invalid Judge output, a failed verdict save, and a recorded verdict. Prompt and response content is available through View full capture when capture was enabled and the payload remains retained; content that was never captured cannot be recovered.

    Open Settings → AI Features to compare internal call counts, failures, reported input/output tokens, and estimated cost by feature for the selected period. Each Judge retry counts as another call attempt. Missing usage or pricing is reported as unavailable rather than zero cost; totals include only known estimates. Follow a feature's calls link to inspect the same period in Gateway Activity. Operational service status remains in Health.

    For each gateway step, the judge sees the tool name plus the call's context: the MCP server, that server's trust tier and datasource classification at the time of the call, the destination (the recorded resource, or a url, uri, or host argument), and the call's arguments. Credentials and personal data are redacted from the destination and arguments before the match is stored, whether or not audit log PII redaction is on. Each step's arguments are capped at 1 KB and all steps together at 8 KB, and the judge is told when arguments were cut short or left out. Kernel steps show the rule and the observed path or destination.

  3. Under Templates, set these columns for each pattern:

    ColumnWhat it does
    EnabledTurns detection for that pattern on or off. A disabled pattern never fires, and its Action, Max gap (minutes), and Kernel evidence controls are disabled.
    ActionNotify, Require approval, or Deny. Ships as Notify on every pattern. The action is recorded with each match. Every non-exempt match that is not suppressed by a recorded, untainted Judge downgrade goes to your enabled notification routes, whatever its action; Require approval and Deny don't hold or block the session.
    Max gap (minutes)Whole minutes, from 1 to 43,200 (30 days). This is the longest time allowed between one step and the next. If the next step arrives later, the sequence starts over and doesn't count as a match. Lower it to catch only rapid, clearly chained activity. Raise it to catch slower, more deliberate attempts.
    Kernel evidenceNever (gateway only), Mixed, or Only (kernel only). Sets which evidence source may satisfy the pattern's steps. A pattern that uses kernel evidence shows a "Mixed evidence" or "Kernel (eBPF)" badge next to its name.

    Each pattern's severity tag uses the same colors as its match cards: medium is gold, high is orange, and critical is red.

    The Bulk read → Egress row expands to show its bulk-read thresholds. A read counts toward them only when it comes from the same MCP server, that server's datasource is classified internal or unclassified, and its response reached the agent successfully. Failed upstream calls do not count. Reads from public, confidential, or restricted datasources don't count; confidential and restricted reads are already caught by Sensitive read → Egress.

    FieldWhat it does
    Minimum readsFrom 1 to 4,999. The threshold is crossed when this many qualifying reads from one server fall within the aggregation window. Default: 50.
    Minimum response size (MB)From 1 MB to 10,240 MB (10 GB). The threshold is crossed when the qualifying reads' combined response size reaches this value. Default: 5 MB.
    Aggregation window (minutes)From 1 to 1,440 (24 hours). Only reads within this long of the most recent one count toward the thresholds. Default: 60.
    Minimum reads across all serversFrom 1 to 4,999. The same kind of threshold, counted across all of one agent's servers together within the aggregation window, so a harvest spread over several servers still adds up. It is higher than the per-server count because it pools more traffic. Default: 100.
    Minimum reads in the long windowFrom 1 to 4,999. Counted for one server over the long window below, so a slow trickle that never fills the aggregation window still adds up. Default: 100 (about four reads an hour over a day).
    Long window (minutes)From 1 to 10,080 (7 days). Default: 1,440 (24 hours). Per-session checks only see a session's last 24 hours, so a longer window is counted in full only when the whole agent's history is checked. The window is tracked in buckets of about one percent of its length (at least a minute), so it can count reads up to one bucket older than the window but never misses one inside it, and it keeps counters rather than the reads themselves.

    Any one of the thresholds is enough, and the pattern still needs an egress after the reads. A burst that one scope has already flagged is not flagged again by another, so you get one finding per burst rather than one per scope. Clearing a field restores its default. You can't turn off one threshold on its own; to stop bulk-read detection, disable the pattern. Once a window crosses either threshold, the burst stays eligible while qualifying reads continue without a gap longer than that threshold's window (the aggregation window, or the long window for the long-window count). Sparse reads keep it eligible even if the rolling totals later fall below threshold. An egress must follow the latest contributing read within both the pattern's Max gap and that window; a full quiet window expires the old burst. Evidence retains the original qualifying window and subsequent reads, including their security findings and mixed attribution. It shows the burst's read count, combined response size, first and latest contributing read, server (none for a count across all servers), and up to five sample tool names instead of each individual read.

  4. Under False-positive controls, adjust which activity counts toward a pattern:

    ControlWhat it does
    Approved egress destinations (never count as a matching "egress" step)Tool names or destination hosts that are trusted. A gateway call or a kernel-observed connection to one of these never counts as an egress step.
    Egress sink toolsTool names, glob patterns allowed (for example *__post_message), that do count as an egress step. Messaging, email, and gist-style MCP tools would otherwise count as a plain write, and a template that needs an egress step would never match them. The list comes pre-filled with common sink tools.
    Egress shell programsCommands (for example curl) that do count as an egress step when a bash or shell tool runs them, including inside a pipe or bash -c.
    Also treat flagged content-scan findings as a sensitive readIn the Sensitive datasources section. A read of a datasource classified confidential or restricted in Datasources → Edit always counts as a sensitive read. With this on, a call whose content the scanner flags for credentials or PII also counts as a sensitive read, even if that data never came through a classified datasource. This applies to attack-pattern detection only; the session.exercised.sensitiveReadThenEgress policy signal still requires a classified datasource read.
    Exempt skill names / Exempt agent IDsSkills or agents to exempt. A match is exempt only when every evidence step belongs to an exempt agent, or every step is attributed to an exempt skill. Exempt matches are still recorded, but aren't notified or reviewed by the LLM Judge. Workload-scope matches built only from kernel evidence carry no agent or skill name, so these lists can't exempt them. Each field suggests skills and agents AIControls already knows about; the agent field searches every known agent as you type its display name, agent ID, or email. You can also type a name that isn't listed yet. Every save is recorded in the configuration audit log with who made it and when; the list contents are redacted there.

    Known limitation: an MCP tool's access type depends on the server's own self-reported read-only hint and tool description. A compromised server could label a destructive tool read-only so its calls never count as write or delete steps. Egress steps don't depend on these hints; they come from the request type, Egress sink tools, Egress shell programs, and skill indicators. To correct a misclassified tool, override its access type.

  5. Click Save. Changes apply to the next detection sweep, which runs within a few minutes. Matches already recorded don't change. Reset discards your unsaved edits.

Try a sequence before saving​

The Try a sequence tab checks a hypothetical ordered sequence of up to five steps against your unsaved template settings. It is a dry run that doesn't touch live traffic.

  1. For each step, pick a category and a kind, and optionally enter a name or command. The kind Kernel (eBPF) stands for an observation from the runtime detection engine. Every other kind (Skill, HTTP call, Bash / shell, MCP write, MCP delete) is a gateway call.
  2. Click Check sequence. Each enabled template is checked only against the steps its Kernel evidence setting allows:
    • Never (gateway only) ignores kernel steps.
    • Only (kernel only) ignores gateway steps.
    • When Enable kernel-sourced (eBPF) evidence is off, kernel steps never count.

The dry run doesn't simulate max gaps, attribution tiers, or the declared/undeclared distinction, so a sequence it matches can still miss in production if a step's evidence doesn't qualify. The Simulate LLM Judge verdict button on a match is illustrative only and doesn't call a live model.

Configure kernel evidence (self-hosted Kubernetes)​

The Kernel evidence (eBPF) tab controls whether attack pattern detection correlates gateway-audited calls with what the runtime detection engine observes at the kernel level. It has an effect only when Runtime Controls is enabled on the cluster.

  1. Navigate to Settings → Attack Patterns → Kernel evidence (eBPF). The coverage banner at the top reports whether kernel evidence is available, degraded, unavailable, or unknown, with the reason. Most often it is unavailable because no node has the open/exec hooks (bpffs isn't mounted at /sys/fs/bpf), or because Enable kernel-sourced (eBPF) evidence is turned off here. unknown means coverage couldn't be checked. degraded means kernel evidence is collected, but the last attack-pattern sweep checked only part of it; the reason says what was skipped (for example, less recently active workloads beyond the per-sweep limit, observations beyond the 24-hour read limit, an agent, session, or workload checked against only its newest observations, a sweep that stopped before it checked every subject, or a sweep that could not read the kernel evidence at all). With Include ungoverned workloads off, a workload's Runtime tab reports that workload attack-pattern checks are turned off instead of an empty match list.

  2. Toggle Enable kernel-sourced (eBPF) evidence (on by default). When it is off, no kernel-sourced steps exist, so every pattern behaves as gateway-only whatever its own Kernel evidence setting. A kernel-only pattern then never matches.

  3. Toggle Include ungoverned workloads (on by default) to also sweep workloads the gateway never saw a call from. Without it, a fully ungoverned agent is invisible to this detector. It shows up only as two unrelated, unordered findings on the Runtime page.

  4. Set Minimum attribution tier. This is the weakest identity attribution a kernel-sourced step may carry and still satisfy a pattern step. The options, strongest first, are UID-bound (strongest), Content-corroborated, Service-account name, and Name-based (weakest allowed). Unconfirmed attribution never satisfies a step, whatever this setting.

  5. Edit Watched credential paths. These are file path suffixes whose open counts as a sensitive read. The defaults cover common infrastructure and agent-CLI credential files, such as ~/.aws/credentials, .env, ~/.kube/config, and SSH keys. The runtime detection engine reports opens only for files it is configured to watch, which is set in the Helm chart. A path added here that the sensor doesn't watch has no effect.

  6. Click Save.

Configure alert delivery channels​

  1. Navigate to Settings → Notifications.

  2. Choose delivery channels: Slack, email, Microsoft Teams, and in-app (the bell icon).

  3. Configure routing per event type — for example, route anomaly alerts to Slack while sending budget alerts only via email.

  4. Save. Channel delivery is best-effort. Stored session anomaly and baseline findings remain available in Security Events, subject to retention limits, independently of notification delivery.

See also​

Gateway sweeps examine at most 5,000 events per agent or session. Other activity can crowd out reads, and a byte threshold may require more rows than this bound. The Session and Identity attack-pattern panels show a global partial-coverage warning if any subject was capped or failed in the last sweep, and unknown coverage when a recent completed sweep is unavailable. An empty result in either state does not establish that no attack pattern occurred. This warning describes the sweep as a whole, rather than asserting that the currently viewed subject was truncated.

Coverage is the last durable sweep checkpoint, with its timestamp, rather than a guarantee about current activity. If status writes fail, the affected replica reports unknown coverage and continues detection. Other replicas can still read the older checkpoint until it expires or a new sweep records its status; a storage outage cannot durably record its own write failure. Empty results therefore say no patterns were recorded, rather than claiming all current activity was checked.

Each template retains at most 50 matches per subject per sweep. Reaching that limit also reports partial coverage, conservatively including the exactly-50 case, because additional occurrences may have been omitted.

Repeated checks of the same matched export reuse its finding. As older events leave the detection window, a later export from a continuing burst can become a separate finding and notification.

Control behavioral baseline alerts​

  1. Open Settings → Security & Privacy → Detection & Response → Behavioral baselines.
  2. Review the saved preference and the reported evaluation status. If the worker is unavailable, have your platform administrator enable it before using detection. Administrators can still repair an invalid saved preference while the worker is unavailable.
  3. As an administrator, change Enable baseline alerts and select Save baseline setting. Viewers can inspect the status but cannot save changes.

Under Alerts covered, administrators can enable or disable each existing alert type globally, then select Save alert selections:

  • Tool-call rate
  • Tokens per call
  • Policy denial rate
  • Distinct tools per hour
  • Off-hours activity
  • Newly observed tools

Both the master switch and the individual switch must be enabled for new alerts and notifications. Turning off the master retains the individual selections. Saving merges only your edited selections with the latest saved values, preserving concurrent changes to other alert types. Missing saved selections preserve the existing default: all six types enabled, subject to the master and detector prerequisites. View baseline alerts opens Activity → All activity → Source: Behavioral baseline. Filter by identity, severity, time and acknowledgement status; open a finding to investigate or acknowledge it. These filters change what is displayed, not which detectors are enabled.

These switches govern alert delivery, not independently configured policy evaluation. Statistical alerts require enough learned history. The new-tool comparison uses retained audit history; it cannot prove first-ever use. Re-enabling evaluates the current comparison window using the existing freshness and deduplication rules, rather than replaying retained alert history. The saved selections and this replica's effective selections are shown separately when propagation is pending.

Disabling this control stops new behavioral baseline alerts and their notifications. With an available worker, learning, baseline state updates, and policy measurements continue. Independently configured policies remain active. Historical findings remain available under normal retention settings. Notification delivery is best-effort: disabling stops new attempts, but an in-flight notification may arrive after the settings save completes, including when an integration does not honor cancellation. This setting does not retract an already-started send. Slow integrations are bounded so they cannot indefinitely block a settings save; delivery can be skipped when all notification slots are occupied. Re-enabling uses the existing learned baselines on a fresh evaluation; it does not reset learning.

The saved preference and the serving worker's status are separate. Other workers receive changes within one minute when settings storage is reachable. A successful save does not establish that every worker has applied it. An unavailable worker, stale comparison data, insufficient baseline samples, or an evaluation that has not run is not a healthy detection result. An invalid saved preference is shown explicitly and can be corrected by saving the desired setting. An empty alert list does not establish coverage.

The deployment prerequisite is separate from this runtime control: enabling a worker disabled by deployment configuration requires a deployment change and restart. Existing baseline history remains readable when storage is available, even while the worker is disabled.

Baseline comparisons use agent IDs. They do not establish workload or cluster isolation. The identity baseline view and the existing admin MCP baseline tool expose detection status and persisted-data freshness; the tool uses the configured baseline window.

A Read-only refresh; no alert evaluation status means this replica refreshed policy facts without holding the alert-evaluation lease. Its last successful cycle does not establish that new alerts were evaluated. If the local settings reread fails after a save, this replica stops alert delivery until a successful refresh can apply the authoritative preference.

On Identities, the Recent baseline alerts filter describes only the loaded sample of up to 200 unacknowledged alerts for the current identity page. No alerts loaded does not mean no learned baseline, and it does not establish detection coverage. Session security narratives label stored baseline state as historical and report comparison freshness. Portal users also receive the serving worker's evaluation status; shared developer responses omit this global status.