/ Docs

Exfiltration scanning

How Botyard scans outbound bot requests for Runtime Vault secrets: what is scanned, redact, strict and log-only modes, where to set the mode, and rotation.

Exfiltration scanning is Botyard's safety check for outbound bot requests. It is designed to catch cases where a bot attempts to send a sensitive Runtime Vault value to an LLM, search provider, or other proxied upstream.

What is scanned

Provider proxy scans the outbound data that could reach an upstream provider:

  • request body
  • path
  • query string
  • forwarded custom headers

Internal transport headers, Botyard routing headers, and bot authentication headers are excluded because they are not forwarded upstream and create unnecessary false positives.

What values are scanned for

The scanner compares outbound payloads against Runtime Vault variables saved with Sensitive value turned on. Variables saved with it turned off are shown as Plain in the Runtime Vault list and are not scanned for. Values shorter than 8 characters are also not scanned for, because short strings match ordinary text too often.

The scanner can detect the raw value and common encodings such as base64, base64url, and URL encoding. Audit records store the matched key path and encoding, not the secret value or raw payload.

Where scanning happens

Scanning is centralized in the secrets service:

  1. Provider proxy builds a scannable payload from the outgoing request.
  2. Provider proxy sends that payload plus org, bot, call type, and endpoint metadata to the secrets service.
  3. The secrets service loads the organization's sensitive values from encrypted storage, using a short-lived per-org scanner cache.
  4. The scanner returns whether it matched a value. For a match in the request body it also returns the body with the match removed.
  5. Provider proxy forwards the request, forwards the redacted body, or refuses the request, depending on where the match was and the organization's scanner mode.

Plaintext sensitive values stay inside the secrets service scanner cache. They are not copied into provider proxy for scanning.

What happens on a match

What the proxy does depends on where the secret was found:

  • Request body. The matched value is cut out in flight and replaced with [redacted:<key_path>], and the redacted request is forwarded. The secret never reaches the provider, and the conversation keeps working. Botyard records a secrets.exfiltration.redacted audit event.
  • Path, query string, or forwarded headers. The request is refused with 403 Forbidden and nothing is sent upstream. A secret in these places points to deliberate exfiltration rather than an accidental paste, so there is no redact-and-continue path. Botyard records a secrets.exfiltration.blocked audit event with critical severity.

In log_only mode neither happens: the match is recorded as a secrets.exfiltration.detected audit event and the request is forwarded unchanged.

Scanner modes

Each row describes an organization whose mode the proxy has resolved:

ModeMatch in the bodyMatch in path, query, or headersIf the scanner cannot run
redact (default)Redact and forward.Refuse with 403.Forward the request unscanned (fail open).
strictRedact and forward.Refuse with 403.Refuse with 503 (fail closed).
log_onlyRecord and forward unchanged.Record and forward unchanged.Forward the request unscanned.

When the scanner cannot run, the proxy looks up the organization's mode separately. The mode is unknown if that lookup fails, or if the organization has not chosen a mode and the proxy has not recently learned the platform default. An unknown mode is treated as fail open by default, so the request is forwarded unscanned, even for a strict organization. The exception is an organization the proxy recently saw in strict: that cached strict is used instead. It also means an organization that leaves strict can keep getting 503 responses for up to 60 seconds (the default cache lifetime) while the scanner is unavailable.

redact is the default for every organization that has not chosen a mode. strict gives the same protection on a match, and is for organizations where letting an unscanned request through is worse than a bot request failing while the scanner is unavailable. log_only lets the secret reach the provider; use it only to investigate false positives or during a rollout.

Set the scanner mode

The mode is set per organization:

  1. Open User menu › Settings › General › Security.
  2. On the Exfiltration Scanner card, choose Redact, Strict, or Log only under Enforcement.

Changing the mode needs permission to update organization settings. By default that is the organization owner role. The API equivalent is PUT /v1/orgs/{org_id}/settings/scanner. A change normally applies to the next scan. If Botyard cannot clear the scanner's cached settings when you save, the old mode can stay in effect until that cache expires, by default after 60 seconds. While the scanner is unavailable, the outage rules under Scanner modes apply instead.

Rotation and cache invalidation

Runtime Vault writes invalidate the scanner cache after the database transaction commits. This avoids a race where a scan could refill the cache from old values while a rotation is still committing. If invalidation fails, the cache TTL still bounds how long stale scanner data can live.

Safety pattern

This is a data loss prevention control placed at the egress point. It is strongest when combined with Runtime Vault policy:

  • Runtime Vault controls which bot can request a secret.
  • Leases make plaintext access short-lived.
  • Exfiltration scanning checks whether sensitive values are leaving through provider calls.
  • Audit logs record lease and scanner events without storing raw payloads.

The scanner is not a substitute for least privilege or review. It is a tripwire at the point where model calls and search requests leave the platform.

On this page