Skip to main content

Prompt Allowlist Policy

The prompt-allowlist policy category constrains which named system-prompt templates are permitted for a run. Cross-references the prompt-management system (Prompt rows).

Use case: enterprise compliance where prompts are vetted assets. Tenants pin to a curated set of prompt names; ad-hoc prompts get flagged.

Rules

RuleTypeDefaultDescription
allowed_promptsstring[][]Allowlist of template names. Empty = all allowed
blocked_promptsstring[][]Always-deny list. Wins over allowlist
action_on_violationstringblockAction on violation: block or warn

How It Works

The handler runs at before_workflow only -- the prompt template is known at run start. after_workflow is a no-op.

Reads the prompt name from context.prompt_name first, then falls back to context.metadata["prompt_name"]. Absent / empty = no enforcement (ALLOW).

Semantics:

  1. Empty allowed_prompts -> only blocked_prompts applies
  2. Non-empty allowed_prompts -> ONLY those templates are permitted
  3. blocked_prompts wins (deny overrides allow)

Context Attributes Read

AttributePhasePurpose
context.prompt_namebefore_workflowNamed template loaded by runtime
context.metadata["prompt_name"]before_workflowFallback resolver

Example Policy

Vetted-prompt enterprise mode

{
"name": "Vetted prompts only",
"category": "prompt-allowlist",
"rules": {
"allowed_prompts": [
"research-v3-vetted",
"summarize-v2-legal",
"code-review-v1-approved"
],
"action_on_violation": "block"
},
"scope": {
"agents": ["*"]
},
"enabled": true
}

Block a deprecated prompt

{
"rules": {
"blocked_prompts": ["research-v1-deprecated"],
"action_on_violation": "warn"
}
}

SDK Integration

Set the prompt name via metadata when invoking the agent:

import waxell_observe as waxell
waxell.init()

@waxell.observe(
agent_name="research-assistant",
enforce_policy=True,
metadata={"prompt_name": "research-v3-vetted"},
)
async def research(query: str) -> str:
return await run_with_prompt(query)

Or set context.prompt_name directly if your runtime layer exposes it as an attribute.

Observability

FieldExample (BLOCK)
Categoryprompt-allowlist
Actionblock
ReasonPrompt 'ad-hoc-debug' is not on the allowlist
Metadata{"blocked_prompt": "ad-hoc-debug", "allowed_prompts": [...]}

Common Gotchas

  • No prompt_name on context = ALLOW. This category is opt-in: runs that don't carry a named template are never blocked. Ensure your runtime populates prompt_name for every governed run.
  • Exact match. "research" does not match "research-v3-vetted". Use the full canonical name.
  • Empty allowlist = NO allowlist. Same trap as the other allowlists. Setting allowed_prompts: [] does not block all runs.
  • Only fires at before_workflow. The prompt name is locked at run start; mid-run prompt swaps aren't checked. If your runtime supports prompt swapping mid-workflow, you need to re-evaluate at the swap point.
  • Cross-reference with Prompt rows. The allowlist is just a string match -- it does not validate that the prompt actually exists in the prompt registry. Pair with deployment hygiene to keep the two in sync.
  • Three handlers, one module. tool-allowlist, mcp-server-allowlist, and prompt-allowlist share allowlists.py.

Next Steps