Approval — ai-tool-guard/approval¶
The approval module manages the lifecycle of human-in-the-loop approval requests. It creates correlation tokens, enforces TTL expiry, supports argument patching ("approve with edits"), and delegates the actual approval decision to a caller-supplied handler.
import { ApprovalManager } from "ai-tool-guard/approval";
import type { ApprovalFlowResult } from "ai-tool-guard/approval";
The related types ApprovalToken, ApprovalResolution, and ApprovalHandler are
defined in ai-tool-guard/types and re-exported from the root path.
Classes¶
ApprovalManager¶
Manages the full lifecycle of approval tokens: creation, handler invocation, TTL enforcement, and resolution.
Constructor¶
| Parameter | Type | Required | Description |
|---|---|---|---|
handler |
ApprovalHandler |
Yes | Async callback invoked with the approval token; must return an ApprovalResolution |
defaultTtlMs |
number |
No | Token time-to-live in milliseconds. Default: 300000 (5 minutes) |
Methods¶
requestApproval¶
Create an approval token for a tool call and invoke the handler. The token includes a SHA-256 hash of the call payload for correlation. Tokens are automatically removed from the pending set after the handler resolves.
| Parameter | Type | Required | Description |
|---|---|---|---|
ctx |
PolicyContext |
Yes | Policy context of the tool call requiring approval |
Returns Promise<ApprovalFlowResult>
The result indicates whether the call was approved, the final arguments to use (original or patched), and optional metadata from the approver.
getPendingTokens¶
Return a read-only snapshot of currently pending approval tokens. Useful for rendering an approval UI.
Returns ReadonlyArray<ApprovalToken>
Interfaces¶
ApprovalFlowResult¶
The complete result of a single approval flow cycle returned by
requestApproval().
| Field | Type | Required | Description |
|---|---|---|---|
approved |
boolean |
Yes | Whether the tool call was approved |
tokenId |
string |
Yes | The approval token ID for correlation and auditing |
args |
Record<string, unknown> |
Yes | The final arguments to pass to the tool (original or patched by the approver) |
patchedFields |
string[] |
No | Names of argument fields that were modified by the approver |
approvedBy |
string |
No | Identity of the approver, if provided by the handler |
reason |
string |
No | Human-readable reason for denial, if the call was not approved |
error |
string |
No | Error message if the approval flow itself failed (e.g., token not found or expired) |
Types (from ai-tool-guard)¶
ApprovalToken¶
Correlation token sent to the ApprovalHandler. Contains a snapshot of the
original arguments and a payload hash for tamper detection.
| Field | Type | Required | Description |
|---|---|---|---|
id |
string |
Yes | Randomly generated unique token ID |
payloadHash |
string |
Yes | SHA-256 hash of the canonical { toolName, args } payload |
toolName |
string |
Yes | Name of the tool awaiting approval |
originalArgs |
Record<string, unknown> |
Yes | Snapshot of the tool arguments at request time |
createdAt |
string |
Yes | ISO-8601 timestamp of token creation |
ttlMs |
number |
No | Token time-to-live in milliseconds |
ApprovalResolution¶
The response returned by the ApprovalHandler callback.
| Field | Type | Required | Description |
|---|---|---|---|
approved |
boolean |
Yes | Whether the tool call is approved |
patchedArgs |
Record<string, unknown> |
No | Partial argument overrides; merged with originalArgs when provided |
approvedBy |
string |
No | Identity of the approver for audit purposes |
reason |
string |
No | Reason for denial when approved is false |
ApprovalHandler¶
Callback type the consumer implements to handle approval requests. The handler receives the token, presents it to a human approver (or automated system), and resolves with the decision.
Example
const handler: ApprovalHandler = async (token) => {
const decision = await showApprovalModal({
toolName: token.toolName,
args: token.originalArgs,
});
return {
approved: decision.confirmed,
approvedBy: decision.userId,
patchedArgs: decision.edits,
reason: decision.reason,
};
};
const guard = createToolGuard({ onApprovalRequired: handler });