AI Agents
·IdenticAPI

How to Design Safe Destructive Actions for AI Agents

Design safe destructive agent actions — deletion, cancellation, revocation — with preview, confirmation, authorization, and audit events.

Safe destructive AI agent actions — deletion, cancellation, revocation, archival purge — require the same rigor as manual admin operations: preview of scope, explicit confirmation, authorization checks, policy blocks or reviews, and immutable audit events. Autonomous agents must not perform irreversible mutations from a single model proposal without human gates unless the blast radius is provably tiny and credentials are tightly scoped.

Destructive tools are the highest-risk class in AI agent security. Agent Action Guard's default policy blocks actions matching destructive keywords in tool action or context. That baseline is necessary but not sufficient — your tool design and approval workflows carry most of the safety burden.

What counts as destructive

CategoryExamplesRisk
Data deletionDELETE rows, drop table, purge S3 prefixIrreversible data loss
Account lifecycleClose account, revoke access, disable userCustomer impact
FinancialVoid invoice, chargeback, refund without idempotencyMoney movement
InfrastructureTerminate VM, delete DNS recordOutage
SecurityRotate all keys, revoke all sessionsLockout

Map every agent tool action to this taxonomy during design. See Secure AI Agent Database Access for SQL-specific patterns.

Design principles

  1. Separate tools — do not combine search and delete in one action name
  2. Require identifiers — delete by primary key, not free-text filter from model
  3. Dry-run first — return affected count before mutating
  4. Idempotency keys — prevent double-delete on agent retries
  5. Soft delete default — hard delete only via approved admin path
  6. No destructive tools in general agents — dedicated maintenance agent with stricter controls

Preview before mutate

Implement a two-step tool pattern:

// Step 1: preview (read-only credential)
async function previewDelete(args: { userId: string; tenantId: string }) {
  const count = await db.users.count({
    where: { id: args.userId, tenantId: args.tenantId }
  });
  return { affectedRows: count, target: args.userId };
}

// Step 2: execute only after approval + guard allow
async function executeDelete(args: { userId: string; tenantId: string; approvalId: string }) {
  const approval = await approvals.verify(args.approvalId);
  if (!approval.valid) throw new Error("Invalid approval");
  // ...
}

Show preview output to human reviewers and to the model only as structured data — not as authorization to proceed automatically.

Policy: block by default

Submit destructive proposals to Agent Action Guard before execution:

curl -X POST https://www.identicapi.com/api/v1/security/agent-action \
  -H "Authorization: Bearer idapi_test_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "tool_name": "accounts",
    "action": "delete_user",
    "arguments": { "user_id": "usr_991", "tenant_id": "ten_acme" },
    "context": "User requested account deletion via support chat"
  }'

Default policy returns block for destructive patterns. Custom policies may route specific maintenance actions to review instead of allow — never default destructive to allow.

async function destructiveAction(proposal: ToolProposal, user: User) {
  const guard = await evaluateAgentAction(proposal);

  if (guard.decision === "block") {
    auditLog.record("destructive_blocked", { proposal, guard });
    return { error: guard.policy_reason };
  }

  if (guard.decision === "review") {
    const preview = await previewMutation(proposal);
    return approvalQueue.create({ proposal, preview, guard });
  }

  // guard.decision === "allow" — rare for destructive; still require authz
  if (!user.can("accounts:delete")) {
    return { error: "Not authorized" };
  }

  return executeMutation(proposal);
}

Agent Action Guard does not replace authorization. Both must pass.

Human confirmation

Pair review decisions with human-in-the-loop approval:

  • Reviewer sees preview counts, target IDs, tenant scope
  • Approval bound to proposal hash — arguments cannot change post-approval
  • TTL on approval tokens — expired proposals do not execute
  • Separate approver from requester when the agent acts on behalf of a user

For high-impact deletes, require two-person approval in your product layer.

Audit events

Record immutable audit entries:

  • Proposal received (tool, action, sanitized args)
  • Guard decision and policy_reason
  • Preview results
  • Approver identity and timestamp
  • Execution outcome and affected row count
  • Correlation ID linking agent session to audit trail

Avoid storing full PII from arguments in centralized logs; store IDs and references.

Naming and keyword limitations

Policy engines match metadata strings. A tool named remove_access may not match delete keywords — encode destructive intent in custom rules:

{
  "tool_name": "accounts",
  "action_pattern": "delete_*|purge_*|revoke_all",
  "decision": "block"
}

Test renamed tools in CI against your policy rules.

Destructive chains from untrusted input

Indirect injection may propose destructive actions after web or RAG content. Controls:

  • Block destructive tools when session flagged untrusted source
  • Never auto-approve because the model "explained" user intent in context
  • Rate-limit destructive proposals per session

Safer alternatives to expose

Prefer reversible operations in agent schemas:

Instead ofExpose
delete_ticketarchive_ticket
purge_usermark_inactive + scheduled job with human job approval
drop_tableNot exposed to agents

Batch destructive work into offline jobs with separate authentication.

Checklist

  • Inventory all destructive agent capabilities
  • Remove destructive tools from general-purpose agents where possible
  • Implement preview/dry-run before mutate
  • Default Agent Action Guard posture: block destructive
  • Require human approval for irreversible mutations
  • Bind approvals to proposal hashes with TTL
  • Verify authorization independently of guard
  • Emit immutable audit events with correlation IDs

Safe destructive agent actions are rare, explicit, previewed, policy-blocked or human-approved, and authorized — never a single unchecked tool call from a model that can be manipulated by untrusted text.

Frequently asked questions

What makes an AI agent action destructive?

Irreversible or high-impact mutations: deleting data, revoking access, terminating infrastructure, voiding financial records, or bulk purges without narrow scope.

What is the default policy for destructive proposals?

Agent Action Guard default policy blocks destructive keywords in action and context. Custom policies may route specific maintenance operations to review rather than allow.

Why use preview before destructive execution?

A dry-run shows affected row counts and targets for human reviewers and prevents accidental broad filters from executing without visibility.

How do I bind human approval to a destructive proposal?

Hash the proposal arguments, issue approval tokens tied to that hash, set TTL, and reject execution if arguments change after approval.

Should general-purpose agents expose delete tools?

Avoid it. Prefer soft-delete, archive, or offline jobs with separate authentication. If destructive tools exist, isolate them to maintenance agents with strict gates.

Related reading