Intermediate

Human-in-the-Loop Controls

When AI agents need to perform destructive operations, humans should remain in the approval loop. This lesson covers practical patterns for building approval workflows into agent-driven cloud operations.

Approval Workflows for Destructive Operations

The principle is straightforward: any operation that modifies or destroys production resources should require explicit human approval before execution. Here are proven patterns:

Pre-Execution Review

The agent generates the command or plan but does NOT execute it. A human reviews the exact command, verifies the target resources, and manually triggers execution.

Dual Authorization

Two team members must approve destructive operations. The developer who requested the change and a peer reviewer both sign off before the agent proceeds.

Time-Delayed Execution

Destructive commands are queued with a configurable delay (15 minutes to 24 hours). During this window, any team member can cancel the operation.

Environment-Based Gates

Agents can auto-execute in development, require single approval for staging, and require dual approval plus MFA for production environments.

CI/CD Pipeline Gates

The safest pattern is to never let AI agents execute infrastructure changes directly. Instead, have them create pull requests that trigger CI/CD pipelines with built-in approval gates:

GitHub Actions - Terraform with Manual Approval Gate
name: Terraform Apply with Approval
on:
  pull_request:
    paths: ['terraform/**']

jobs:
  plan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Terraform Plan
        run: |
          cd terraform
          terraform init
          terraform plan -out=tfplan
          terraform show -no-color tfplan > plan-output.txt

      - name: Comment Plan on PR
        uses: actions/github-script@v7
        with:
          script: |
            const plan = require('fs').readFileSync('terraform/plan-output.txt', 'utf8');
            github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: '## Terraform Plan\n```\n' + plan + '\n```\n\n**Review carefully before approving.**'
            });

  apply:
    needs: plan
    runs-on: ubuntu-latest
    environment: production  # Requires manual approval in GitHub
    steps:
      - uses: actions/checkout@v4
      - name: Terraform Apply
        run: |
          cd terraform
          terraform init
          terraform apply -auto-approve

How Tools Like Claude Code Implement Permission Prompts

Modern AI coding tools are building safety controls directly into their agent frameworks:

Tool Safety Mechanism How It Works
Claude Code Permission prompts Asks user to approve bash commands before execution. Users can allow/deny per command or set allow rules.
GitHub Copilot Suggestion-only mode Suggests commands but requires the user to manually accept and execute them in the terminal.
Cursor Agent Tool approval Shows the command it intends to run and waits for user confirmation before executing shell commands.
Warning: Do not configure AI agents to auto-approve all shell commands. Some agents support "YOLO mode" or auto-accept patterns. While convenient for development tasks, this removes the critical safety gate for cloud operations. Always keep manual approval enabled for shell commands that interact with cloud CLIs.

Building Confirmation Dialogs into Agent Workflows

If you are building custom agent workflows, implement a confirmation step for any command matching destructive patterns:

Python - Agent wrapper with destructive command detection
import re
import subprocess

DESTRUCTIVE_PATTERNS = [
    r'terraform\s+destroy',
    r'aws\s+\S+\s+(delete|terminate|remove)',
    r'az\s+\S+\s+delete',
    r'gcloud\s+\S+\s+delete',
    r'pulumi\s+destroy',
    r'kubectl\s+delete\s+(namespace|deployment|service)',
    r'rm\s+-rf?\s+/',
    r'--force|--yes|-auto-approve|--quiet',
]

def is_destructive(command: str) -> bool:
    """Check if a command matches any destructive pattern."""
    return any(re.search(p, command, re.IGNORECASE) for p in DESTRUCTIVE_PATTERNS)

def execute_with_approval(command: str) -> str:
    """Execute a command, requiring human approval if destructive."""
    if is_destructive(command):
        print(f"\n{'='*60}")
        print(f"DESTRUCTIVE COMMAND DETECTED:")
        print(f"  {command}")
        print(f"{'='*60}")
        approval = input("Type 'APPROVE' to execute, anything else to cancel: ")
        if approval != 'APPROVE':
            return "Command cancelled by user."

    result = subprocess.run(command, shell=True, capture_output=True, text=True)
    return result.stdout + result.stderr

Audit Logging Every Agent Action

Every command an AI agent executes should be logged with full context for forensic analysis and compliance:

Structured audit log entry for agent actions
{
  "timestamp": "2026-03-20T14:32:05Z",
  "agent": "claude-code-cli",
  "session_id": "sess_abc123",
  "user": "developer@company.com",
  "command": "aws ec2 terminate-instances --instance-ids i-0abc123",
  "approval_status": "approved",
  "approved_by": "developer@company.com",
  "approval_method": "interactive_prompt",
  "environment": "staging",
  "aws_account": "123456789012",
  "aws_region": "us-east-1",
  "result": "success",
  "resources_affected": ["i-0abc123"],
  "risk_level": "high"
}

MFA Requirements for Destructive Operations

For the highest-risk operations, require MFA even when the agent has the correct IAM permissions:

AWS - IAM Policy requiring MFA for delete operations
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyDeleteWithoutMFA",
      "Effect": "Deny",
      "Action": [
        "ec2:TerminateInstances",
        "rds:DeleteDBInstance",
        "s3:DeleteBucket",
        "cloudformation:DeleteStack"
      ],
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {
          "aws:MultiFactorAuthPresent": "false"
        }
      }
    }
  ]
}
Key Takeaway: The combination of least-privilege permissions (previous lesson) and human-in-the-loop controls creates a defense-in-depth strategy. Even if permissions are misconfigured, the human approval gate catches dangerous operations before they execute.
💡
Next Up: The next lesson covers Infrastructure as Code safety - how Terraform, Pulumi, and CloudFormation provide their own safety mechanisms like prevent_destroy and stack policies.

Ready to Go Deeper?

Live instructor-led courses from our partners. Affiliate disclosure.