Platform engineers integrating with policy engines like Open Policy Agent (OPA) need structured decision logs that capture every authorization evaluation. This prompt produces machine-parseable JSON records with input attributes, policy path, decision outcome, and evaluation duration. Use it when your authorization pipeline requires auditable, queryable decision logs that downstream systems can ingest without transformation.
Prompt
Authorization Decision Log Prompt for Policy Engines

When to Use This Prompt
Defines the ideal use case, required context, and boundaries for the authorization decision log prompt.
The prompt is designed for post-decision logging, not real-time enforcement. It assumes a policy decision has already been rendered by the engine. You supply the raw evaluation context—the input attributes, the policy path evaluated, the boolean or multi-valued decision, and the evaluation latency—and the prompt normalizes these into a consistent JSON schema. This is critical for teams shipping audit evidence to SIEMs, compliance databases, or internal observability platforms where field-level consistency across thousands of decisions determines queryability.
Do not use this prompt as a substitute for the policy engine itself. It does not evaluate policies, resolve conflicts, or make access decisions. It also should not be used for real-time request interception where latency added by an LLM call is unacceptable. For high-throughput enforcement paths, log asynchronously or batch records. For regulated environments, ensure the log record includes a trace ID linking back to the engine's own decision event to maintain a verifiable chain of custody.
Use Case Fit
Where this prompt works and where it does not. Understand the operational boundaries before integrating into a policy engine pipeline.
Good Fit: OPA-Style Decision Logging
Use when: integrating with Open Policy Agent (OPA) or similar policy engines that expect structured decision logs with input attributes, policy paths, and outcomes. Guardrail: Validate that the generated decision_id and policy_path match your engine's naming conventions before ingestion.
Bad Fit: Real-Time Admission Control
Avoid when: the prompt output is in the critical path of request admission (e.g., Kubernetes validating webhooks). LLM latency and non-determinism make it unsuitable for synchronous enforcement. Guardrail: Use this prompt for offline audit trails and asynchronous analysis only, never for inline policy decisions.
Required Inputs: Policy Context & Attributes
What to watch: The prompt requires a complete set of input attributes (user, resource, action, context) and the policy path being evaluated. Missing fields lead to hallucinated or empty values. Guardrail: Implement a pre-generation check that rejects requests with incomplete [INPUT_ATTRIBUTES] or [POLICY_PATH] before calling the model.
Operational Risk: Decision Enum Drift
What to watch: The model may produce decision outcomes outside your controlled vocabulary (e.g., 'maybe' instead of 'allow'/'deny'). This breaks downstream log parsers and SIEM rules. Guardrail: Enforce a strict enum check on the decision field post-generation. Reject and retry any output that does not match ["allow", "deny", "error"].
Operational Risk: Evaluation Duration Accuracy
What to watch: The model cannot measure actual evaluation time. Any evaluation_duration_ms it generates will be a hallucination, not a real measurement. Guardrail: Do not rely on the model for timing data. Inject the actual evaluation duration from your policy engine's instrumentation into the log record after generation.
Bad Fit: Unstructured Policy Explanations
Avoid when: you need a free-text explanation of why a policy decision was made. This prompt is designed for structured, machine-readable logs. Guardrail: If human-readable justification is required, use a separate summarization prompt that consumes the structured log as input, rather than mixing concerns in one generation step.
Copy-Ready Prompt Template
A ready-to-use prompt that generates structured authorization decision logs for policy engines like OPA.
This prompt template is designed to be pasted directly into your system instructions or user message. It instructs the model to produce a single, valid JSON object representing an authorization decision log entry. The template uses square-bracket placeholders for all dynamic inputs, such as the request attributes, the policy being evaluated, and the expected output schema. Before using this prompt, you must replace every placeholder with concrete values from your application context. The prompt is structured to enforce a strict output contract: a decision enum, a valid policy path, and a numeric evaluation duration, making the output safe for direct ingestion by a policy decision log aggregator or SIEM.
textYou are an authorization logging agent for a policy engine. Your only job is to output a single JSON object that conforms to the schema described below. Do not include any explanatory text, markdown fences, or additional keys. Evaluate the following authorization request against the provided policy context and produce a structured decision log. ## INPUT - Request Attributes: [REQUEST_ATTRIBUTES] - Policy Context: [POLICY_CONTEXT] ## OUTPUT_SCHEMA { "decision_id": "string, a unique UUID for this decision event", "timestamp": "string, ISO 8601 timestamp of the evaluation in UTC", "input": { "subject": "string, the principal making the request from [REQUEST_ATTRIBUTES]", "action": "string, the requested operation from [REQUEST_ATTRIBUTES]", "resource": "string, the target resource from [REQUEST_ATTRIBUTES]" }, "policy": { "path": "string, the fully qualified policy path from [POLICY_CONTEXT], e.g., 'app.rbac.allow'", "version": "string, the policy version from [POLICY_CONTEXT]" }, "decision": "string, must be one of: 'allow', 'deny', 'error'", "evaluation_duration_ms": "number, the evaluation time in milliseconds from [POLICY_CONTEXT]", "context": { "reason": "string, a concise, factual explanation for the decision based on the policy and input", "matched_rules": ["string, the specific rule names that matched from [POLICY_CONTEXT]"] } } ## CONSTRAINTS 1. The `decision` field MUST be exactly one of the allowed enum values: 'allow', 'deny', 'error'. 2. The `policy.path` MUST start with the package name from [POLICY_CONTEXT] and use dot notation. 3. All fields in the output schema are required. Do not omit any field. 4. If the policy evaluation results in an error, set `decision` to 'error' and explain the error in `context.reason`.
To adapt this template, start by replacing [REQUEST_ATTRIBUTES] with a structured representation of the incoming request—typically a JSON object containing subject, action, and resource. Replace [POLICY_CONTEXT] with the relevant details from your policy engine's evaluation trace, including the policy path, version, matched rules, and evaluation duration. For high-risk environments, such as financial or healthcare systems, you should add a post-processing validation step in your application code that checks the decision enum and policy.path format before the log is written to an immutable store. If the model fails to produce a valid output, implement a retry with a simplified version of the prompt or escalate to a human operator for manual log entry.
Prompt Variables
Every placeholder the Authorization Decision Log prompt expects, why it matters, and how to validate it before sending to the model.
| Placeholder | Purpose | Example | Validation Notes |
|---|---|---|---|
[POLICY_QUERY] | The input attributes sent to the policy engine for evaluation | {"user": "alice", "action": "read", "resource": "doc-123"} | Must be valid JSON. Parse check required. Reject if empty or not an object. |
[POLICY_PATH] | The fully qualified path to the policy rule that was evaluated | system.authz.reBAC.document_access | Must match pattern ^[a-z]+(.[a-z][a-z0-9_]*)+$. Reject on path traversal characters. |
[DECISION] | The authorization outcome returned by the policy engine | allow | Must be one of the controlled enum values: allow, deny, indeterminate. Case-sensitive check required. |
[EVALUATION_DURATION_MS] | Time taken by the policy engine to reach a decision in milliseconds | 12.4 | Must be a positive number. Reject if negative, zero, or non-numeric. Coerce strings to number and validate. |
[TRACE_ID] | Distributed trace identifier linking this decision to the upstream request | a1b2c3d4e5f6789012345678 | Must match W3C trace-id format: 32 lowercase hex characters. Reject on mismatch. |
[TIMESTAMP] | RFC 3339 timestamp when the decision was rendered | 2024-03-15T14:30:00Z | Must parse as valid RFC 3339. Reject if missing timezone offset or Z suffix. |
[POLICY_VERSION] | The version identifier of the policy bundle evaluated | v2.4.1 | Must match semver pattern ^v?\d+.\d+.\d+(-[a-zA-Z0-9.]+)?$. Reject on malformed versions. |
[REGO_QUERY_TRACE] | Optional full Rego query trace for debugging policy decisions | Enter data.authz.allow == true | Eval data.authz.allow... | Null allowed. If present, must be a non-empty string. Truncate to 4000 chars to prevent context overflow. |
Implementation Harness Notes
How to wire the authorization decision log prompt into a policy evaluation pipeline with validation, retries, and audit controls.
This prompt is designed to sit between a policy engine's decision endpoint and your audit storage. The model receives raw evaluation context and produces a structured decision log that downstream systems can ingest without manual transformation. The harness must enforce that the model output matches the expected schema before any record is written to the audit log, because a malformed decision entry can break compliance reporting or mask an incorrect authorization outcome.
Wire the prompt into an application pipeline that performs three stages: pre-validation, generation, and post-validation. In pre-validation, confirm that required inputs—[POLICY_PATH], [INPUT_ATTRIBUTES], and [DECISION_OUTCOME]—are present and that [POLICY_PATH] matches a known policy namespace pattern (e.g., ^[a-z]+\.[a-z]+\.[a-z_]+$). After generation, validate the output JSON against a strict schema: decision must be one of allow, deny, or error; evaluation_duration_ms must be a non-negative number; timestamp must be ISO 8601. If validation fails, retry once with the validation error injected into the prompt as a correction hint. If the retry also fails, log the raw output and the validation error to a dead-letter queue for human review—never silently drop a failed authorization record. For high-risk environments, require a human to acknowledge any deny decision log before it is committed to the audit trail.
Choose a model that reliably follows JSON schema constraints. GPT-4o and Claude 3.5 Sonnet perform well on this structured output task, but always run schema validation regardless of model choice. Store the validated decision log in an append-only audit store with the model version, prompt version, and trace ID attached as metadata. Avoid using this prompt for real-time enforcement—the model's output documents a decision that has already been made by the policy engine; it does not make the authorization decision itself.
Expected Output Contract
Every field the model must return for an authorization decision log, its required type, and the pass/fail condition for automated validation before the record enters the policy engine audit pipeline.
| Field or Element | Type or Format | Required | Validation Rule |
|---|---|---|---|
decision_id | string (UUID v4) | Must match UUID v4 regex. Reject on parse failure. | |
timestamp | string (ISO 8601 UTC) | Must parse as valid ISO 8601 with Z suffix. Reject on parse failure. | |
policy_path | string | Must match pattern ^[a-z]+(.[a-z]+)+$ (e.g., app.rbac.read). Reject on format mismatch. | |
input_principal | string | Must be non-empty string. Minimum length 1. Reject on empty or null. | |
input_resource | string | Must be non-empty string. Minimum length 1. Reject on empty or null. | |
input_action | string | Must be non-empty string. Minimum length 1. Reject on empty or null. | |
decision | string (enum) | Must be one of: allow, deny, error. Reject on out-of-vocabulary value. | |
evaluation_duration_ms | number (integer) | Must be non-negative integer. Reject on negative value or float. |
Common Failure Modes
What breaks first when generating authorization decision logs and how to prevent it in production.
Decision Enum Drift
What to watch: The model outputs decisions like 'allowed' or 'permitted' instead of the required 'allow' or 'deny' enum values. This breaks downstream policy engine ingestion and audit queries. Guardrail: Enforce a strict enum constraint in the output schema with explicit valid values. Add a post-generation validation step that rejects any output containing out-of-vocabulary decision strings before the log is written.
Missing Policy Path Reference
What to watch: The model omits the policy_path field or generates a path that doesn't match the actual policy structure in your OPA or Cedar deployment. This makes it impossible to trace which rule produced the decision. Guardrail: Require the policy path as a required input variable, not something the model invents. Validate the path against a known policy registry before accepting the log entry.
Timestamp Inconsistency Across Systems
What to watch: The model generates a timestamp that doesn't match the format or timezone of your observability stack, causing log correlation failures. Guardrail: Inject the timestamp as a pre-formatted input variable from your application clock. Never ask the model to generate the current time. Validate all timestamps against RFC 3339 format with timezone offset before ingestion.
Input Attribute Leakage into Decision Rationale
What to watch: The model copies sensitive input attributes (user roles, resource tags, IP addresses) into a free-text rationale field, creating a data spillage risk in logs that may have broader access. Guardrail: Restrict the rationale field to policy reasoning only. Use a separate redaction pass on the generated log before storage, or omit free-text rationale entirely and rely on structured fields for auditability.
Evaluation Duration Fabrication
What to watch: The model invents a plausible but incorrect evaluation_duration_ms value instead of using the actual measured latency from the policy engine. This corrupts performance monitoring. Guardrail: Always inject the measured evaluation duration from your application code as a required input variable. Never ask the model to estimate or generate timing data.
Schema Validation Bypass in Streaming
What to watch: When using streaming responses, partial JSON chunks may pass intermediate validation but the final assembled log object is malformed or missing required fields. Guardrail: Always run full schema validation on the complete assembled output after the stream ends. Reject and retry the entire log generation if validation fails, rather than attempting to patch a partial result.
Evaluation Rubric
How to test output quality before shipping this prompt to production. Use these criteria to build automated eval checks or manual review gates.
| Criterion | Pass Standard | Failure Signal | Test Method |
|---|---|---|---|
Decision Enum Validity | Output field [DECISION] is exactly one of: allow, deny, error, not_applicable | Field contains a value outside the controlled vocabulary or is missing | Enum assertion check in test suite; parse output and validate against allowed set |
Policy Path Format | Output field [POLICY_PATH] matches the pattern package.name.rule or is null when decision is not_applicable | Field contains a bare rule name without package prefix or is populated for not_applicable decisions | Regex validation: ^[a-z_]+.[a-z_]+.[a-z_]+$; conditional null check for not_applicable |
Evaluation Duration Range | Output field [EVALUATION_DURATION_MS] is a positive integer between 0 and 60000 | Field is negative, zero, exceeds 60 seconds, or is a non-integer float | Type check for integer; range assertion 0 < value <= 60000 |
Required Input Attribute Presence | Output field [INPUT_ATTRIBUTES] contains all keys present in the prompt's [INPUT_CONTEXT] | One or more input attribute keys are missing from the output record | Set comparison: input_context keys must be a subset of input_attributes keys |
Timestamp ISO 8601 Compliance | Output field [TIMESTAMP] is a valid ISO 8601 string with timezone offset | Field uses Unix epoch, missing timezone, or contains non-parseable date string | Parse with datetime library; confirm timezone component is present and valid |
Trace ID Correlation | Output field [TRACE_ID] matches the [TRACE_ID] injected in the prompt context exactly | Field is null, truncated, or contains a different trace ID than the one provided | String equality check between input trace_id and output trace_id |
Decision Reason Grounding | Output field [REASON] contains a non-empty string that references at least one policy rule or input attribute | Field is empty, contains only generic text like 'policy check', or hallucinates a rule not in [POLICY_PATH] | Length check > 0; substring search for policy path components or input attribute names |
Output Schema Completeness | All required fields (decision, policy_path, input_attributes, timestamp, trace_id, reason, evaluation_duration_ms) are present and non-null where required | Any required field is missing or null when the schema mandates presence | JSON Schema validation against the target output schema; field presence assertion |
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Adapt This Prompt
How to adapt
Start with the base prompt and a single policy engine target (e.g., OPA). Use a simplified output schema with only the core fields: decision_id, input_attributes, policy_path, decision, and timestamp. Skip evaluation duration and trace context fields.
Replace the strict enum validation instruction with a looser constraint:
code"decision" must be one of: "allow", "deny", "error"
Watch for
- The model inventing policy paths that don't exist in your engine
decisionvalues drifting outside the three allowed values when the input is ambiguous- Timestamps defaulting to the model's training cutoff instead of the provided [EVALUATION_TIMESTAMP]

About the author
Prasad Kumkar
CEO & MD, Inference Systems
Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.
His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us