Per-Tool Justification¶
Require or optionally request agents to explain why a tool is being called before approval.
Availability
Per-tool justification is available in all editions.
Overview¶
When an AI agent calls a tool, it may not always be clear why. Per-tool justification adds a justification parameter to tool calls, allowing you to:
- Require agents to provide a reason before the tool can execute
- Optionally accept a reason if the agent provides one
- Log the justification in audit trails and approval requests
Reviewers see the agent's reasoning in the approval notification, making it easier to make informed decisions.
Configuration¶
Via Policy YAML¶
Set the justification field on a tool definition:
version: "1.0"
metadata:
name: justified-tools
tools:
- name: "bash"
source: mcp
justification: required # Agent MUST explain the call
approval_workflow: "ops-review"
- name: "create_issue"
source: mcp
justification: optional # Agent MAY explain (logged if provided)
| Value | Behaviour |
|---|---|
required |
Tool call is rejected if no justification is provided |
optional |
Justification is accepted and logged but not enforced |
| (omitted) | No justification parameter is injected |
Via Web UI¶
- Navigate to Tools → select a tool
- Under Justification, choose Required or Optional
- Save
How It Works¶
1. Parameter Injection¶
When a tool has justification configured, Preloop dynamically injects a justification parameter into the tool's schema. The agent sees it in the tool definition:
{
"name": "bash",
"description": "Execute a shell command",
"parameters": {
"properties": {
"command": {"type": "string"},
"justification": {
"type": "string",
"description": "Provide your reasoning and context for why this tool is being called."
}
},
"required": ["command", "justification"]
}
}
2. Agent Provides Reasoning¶
The agent includes its reasoning in the tool call:
{
"tool": "bash",
"arguments": {
"command": "kubectl rollout restart deployment/api",
"justification": "The API pods are returning 503 errors after the config change. Restarting to pick up the corrected config."
}
}
3. Server-Side Enforcement¶
requiredmode: Ifjustificationis missing or empty, the tool call is rejected with an error message.optionalmode: The tool call proceeds regardless, but any provided justification is logged.
4. Approval Integration¶
When the tool also requires approval, the justification appears as agent_reasoning in:
- Approval notifications (email, Slack, mobile push)
- Approval request detail page in the web UI
- Audit logs for compliance review
Justification in Approval Requests¶
The justification text flows through the system as follows:
- Agent includes
justificationin tool arguments - Preloop strips it from arguments and stores it as
agent_reasoning - Approval request is created with the reasoning attached
- Reviewers see the reasoning in their notification:
🔔 Approval Required: bash
Agent reasoning: "The API pods are returning 503 errors after the config change."
Arguments: {"command": "kubectl rollout restart deployment/api"}
[Approve] [Decline]
Audit Trail¶
Justifications are persisted in the audit log alongside the tool call:
| Field | Description |
|---|---|
tool_name |
Name of the tool called |
tool_args |
Arguments (without justification) |
agent_reasoning |
The justification text provided by the agent |
action_taken |
allow / deny / require_approval |
timestamp |
When the call was made |
Best Practices¶
- Use
requiredfor high-risk tools. Tools likebash,delete_issue, or deployment commands benefit from mandatory explanations. - Use
optionalfor audit-only. When you want to encourage reasoning without blocking the agent. - Combine with async approvals. Justification + async approval gives reviewers full context without blocking the agent.
- Review audit logs regularly. Justifications provide valuable insight into agent behaviour patterns.