Skip to main content

Policy model

A policy is a named, versioned object assigned to one or more collectors. It has two rule kinds:

  • Access rules — attribute conditions on metadata (identity, device, application, provider/model, network, time) that decide whether and how a request is processed, before any content is inspected: allow proceeds, deny blocks (an unsanctioned app, an unmanaged device), and mutate changes the processing mode (force log-only, or escalate to a stricter rule set). This is attribute-based access control over AI use.
  • Prompt rules — content detectors from the six detection classes, each with a threshold and an action.

Actions

ActionEffect
LogPass through and record. The only action a log-only collector supports.
RedactReplace matched spans with a placeholder — before submission for prompts, before delivery for responses. The interaction proceeds.
BlockStop the request or response; return a policy message.

Evaluation order

  1. Access rules first, in author order: deny short-circuits to Block, mutate caps downstream actions, allow proceeds.
  2. Prompt rules run — local inline for Redact/Block, cloud async for depth — collecting all matches; one interaction can hit several classes.
  3. Resolve to one effective action: Block > Redact > Log, most severe wins, ties broken by priority.
  4. Redaction is cumulative — every Redact rule contributes spans; overlapping spans are merged into one clean rewrite.

No match → the policy's default_action (log by default). A log-only mutate caps even that — such a policy cannot Block no matter what a rule says.

A complete example

policy:
id: pol_workforce_std
name: "Workforce - standard"
version: 7
default_action: log
access_rules:
- { id: ar_block_unsanctioned, when: { application.category: unsanctioned_ai }, effect: deny }
- { id: ar_monitor_byod, when: { device.managed: false }, effect: mutate, mode: log_only }
prompt_rules:
- { id: pr_injection, detector: prompt_injection, applies_to: [prompt],
threshold: 0.80, action: block, priority: 100 }
- { id: pr_secrets, detector: sensitive_data, subclasses: [credentials, financial, pii],
applies_to: [prompt, response], action: redact,
redaction: { placeholder: "[REDACTED:{class}]" } }
- { id: pr_malicious_url, detector: malicious_entity, applies_to: [response], action: block }
- { id: pr_topic, detector: topic, categories: [legal_advice, medical_advice],
threshold: 0.75, action: log }
- { id: pr_language, detector: language, allow: [en, es], action: block }
custom_definitions:
- { id: cd_caseid, kind: regex, pattern: "WZ-\\d{6}",
class: confidential.case_id, action: redact }

The BYOD access rule is worth reading twice: an unmanaged laptop gets watched, not policed — detections are still recorded, enforcement is withheld. Identical content produces a different verdict because policy reads the context. See demo 10.

Redaction spans

A span targets one field and carries a zero-based [start, end) character offset over the normalized text, the detection class, and the placeholder substituted. Spans are stored on the finding, so the console shows what class was redacted without ever storing the raw value.

Validating and inspecting

lumen-agent policy validate --policy /etc/lumen/policy.yaml
lumen-agent policy effective --config /etc/lumen/agent.yaml

policy effective resolves the policy exactly the way the daemon does, so it cannot report something the daemon does not run — see Configuration.