Forem

Custodia-Admin
Custodia-Admin

Posted on • Originally published at pagebolt.dev

What Happens When Your AI Agent Fails a Compliance Audit?

What Happens When Your AI Agent Fails a Compliance Audit?

Your AI agent has been running in production for three months.

It's processed 5,000 customer service requests. Approved refunds. Updated user records. Escalated sensitive cases to humans. It works perfectly.

Then your compliance officer tells you: "Auditors need to verify what the agent actually did in production."

You open LangSmith. You pull up the logs. The agent's reasoning chain is perfect. The function calls look correct. The outputs are sound.

The auditor looks at the screen and says: "This is text. I need to see what the agent actually did."


The Problem: Auditors Can't Audit Black Boxes

Compliance frameworks—HIPAA, SOC 2, PCI-DSS, EU AI Act—all require the same thing: evidence of what happened.

For human actions, that's straightforward:

  • Humans have login audit trails
  • User actions are timestamped and logged
  • Database changes have change data capture (CDC)
  • API calls have request/response logs

For AI agents, you get:

  • Text logs of the agent's reasoning (which the agent could be lying about)
  • LangSmith traces showing claimed function calls
  • No visual proof of what actually happened on the screen

The gap: Your agent says it approved a refund. The logs show the approval logic. But did it actually click the "Approve" button? Did it navigate to the right page? Did it fill in the right amount? Did it handle the customer's account correctly?

Auditors can't tell. And if they can't tell, compliance teams have two choices:

  1. Reject the agent entirely — remove it from production, lose the efficiency gains
  2. Add compliance overhead — require human review for every agent action, negating automation benefits

Why Text Logs Aren't Enough

Text logs describe what happened. They don't prove it.

Consider this real scenario from a financial services compliance audit:

[Agent Trace]
Tool: "approve_refund"
Input: {"customer_id": "cust_12345", "amount": "$250.00", "reason": "defective_product"}
Output: {"status": "approved", "confirmation_id": "ref_abc123"}
Enter fullscreen mode Exit fullscreen mode

The auditor has three questions:

  1. Did the agent call the correct API endpoint? (Could it have called a test environment instead of production?)
  2. Did the agent use the right customer ID? (Could it have copied the wrong ID from a previous request?)
  3. Was the refund actually processed? (Did the backend system accept it, or did the API return an error the agent ignored?)

Text logs answer none of these questions. They only show what the agent claims happened.

With a screenshot or video, the auditor sees:

  • The exact URL the agent navigated to
  • The form fields it filled out
  • The button it clicked
  • The confirmation page that appeared
  • The transaction ID that rendered on screen

That's proof.


The Compliance Framework Requirements

Here's what different regulations actually require:

Framework Requirement Text Log Screenshot/Video
HIPAA Audit trail of all PHI access ❌ Incomplete (logs could be falsified) ✅ Visual proof of screen access
SOC 2 Evidence of system changes ❌ Claims only ✅ Proof of UI interaction
PCI-DSS Cardholder data handling proof ❌ Agent claims it didn't store data ✅ Visual proof of data handling
EU AI Act High-risk AI decision logging ❌ Agent's reasoning (biased) ✅ Input data and output shown
GDPR Right to explanation + audit ❌ Text reasoning (hard to verify) ✅ Screenshot shows what user saw

The pattern: Compliance frameworks are shifting from "trust the system to log correctly" to "show me the proof." AI agents demand this shift.


Building Audit-Ready AI Systems

You have three options:

Option 1: Add Human Review (Expensive)

Require a human to approve every agent action before it executes. Defeats the purpose of automation.

Option 2: Add Manual Logging (Error-Prone)

Manually screenshot every agent step. Auditors ask why key moments are missing. Your team is out of sync.

Option 3: Automated Visual Proof (Scalable)

Capture a screenshot after every agent action. Build an audit trail with text logs and visual evidence.

Here's how Option 3 works in practice:

import anthropic
import requests
from datetime import datetime
from pathlib import Path

def create_audit_trail(agent_task: str):
    """Run an AI agent and capture visual proof of every action."""

    audit_trail = {
        "task": agent_task,
        "started_at": datetime.now().isoformat(),
        "steps": []
    }

    client = anthropic.Anthropic()

    tools = [
        {
            "name": "take_screenshot",
            "description": "Take a screenshot of the current page",
            "input_schema": {
                "type": "object",
                "properties": {
                    "url": {"type": "string"}
                },
                "required": ["url"]
            }
        },
        {
            "name": "approve_refund",
            "description": "Approve a customer refund in the system",
            "input_schema": {
                "type": "object",
                "properties": {
                    "customer_id": {"type": "string"},
                    "amount": {"type": "string"},
                    "reason": {"type": "string"}
                },
                "required": ["customer_id", "amount", "reason"]
            }
        },
        {
            "name": "send_email",
            "description": "Send a confirmation email to the customer",
            "input_schema": {
                "type": "object",
                "properties": {
                    "customer_email": {"type": "string"},
                    "subject": {"type": "string"},
                    "body": {"type": "string"}
                },
                "required": ["customer_email", "subject", "body"]
            }
        }
    ]

    messages = [
        {
            "role": "user",
            "content": agent_task
        }
    ]

    step_count = 0

    while True:
        response = client.messages.create(
            model="claude-opus-4-5-20251101",
            max_tokens=1024,
            tools=tools,
            messages=messages
        )

        # Process tool use
        for block in response.content:
            if block.type == "tool_use":
                step_count += 1
                tool_name = block.name
                tool_input = block.input

                # Execute the tool
                if tool_name == "take_screenshot":
                    screenshot_path = capture_screenshot(tool_input["url"], step_count)
                    tool_result = {"screenshot_path": screenshot_path}

                elif tool_name == "approve_refund":
                    approval_result = process_refund(tool_input)
                    tool_result = approval_result

                    # Immediately capture proof
                    screenshot_path = capture_screenshot(
                        "https://admin.example.com/refunds",
                        step_count
                    )

                elif tool_name == "send_email":
                    email_result = send_customer_email(tool_input)
                    tool_result = email_result

                # Log this step with visual proof
                audit_trail["steps"].append({
                    "step_number": step_count,
                    "tool": tool_name,
                    "input": tool_input,
                    "output": tool_result,
                    "screenshot": screenshot_path if "screenshot_path" in tool_result else None,
                    "timestamp": datetime.now().isoformat()
                })

                # Add tool result to conversation
                messages.append({"role": "assistant", "content": response.content})
                messages.append({
                    "role": "user",
                    "content": [
                        {
                            "type": "tool_result",
                            "tool_use_id": block.id,
                            "content": str(tool_result)
                        }
                    ]
                })

        # Check if agent is done
        if response.stop_reason == "end_turn":
            break

    audit_trail["completed_at"] = datetime.now().isoformat()

    # Save audit trail as JSON + HTML report
    save_audit_report(audit_trail)

    return audit_trail


def capture_screenshot(url: str, step_number: int) -> str:
    """Capture screenshot via PageBolt API."""

    api_key = "YOUR_PAGEBOLT_API_KEY"

    response = requests.post(
        "https://api.pagebolt.dev/v1/screenshot",
        headers={"Authorization": f"Bearer {api_key}"},
        json={
            "url": url,
            "format": "png"
        }
    )

    screenshot_path = f"/audit-trails/step-{step_number:03d}.png"
    Path(screenshot_path).write_bytes(response.content)

    return screenshot_path


def save_audit_report(audit_trail: dict):
    """Generate an HTML report with embedded screenshots for auditors."""

    html = f"""
    <html>
    <head>
        <title>AI Agent Audit Report</title>
        <style>
            body {{ font-family: sans-serif; margin: 20px; background: #f5f5f5; }}
            .header {{ background: white; padding: 20px; border-radius: 8px; margin-bottom: 20px; }}
            .step {{ background: white; padding: 20px; margin-bottom: 15px; border-radius: 8px; border-left: 4px solid #007bff; }}
            .step-number {{ font-size: 18px; font-weight: bold; color: #007bff; }}
            .screenshot {{ max-width: 100%; margin-top: 15px; border: 1px solid #ddd; border-radius: 4px; }}
            .timestamp {{ color: #666; font-size: 12px; }}
        </style>
    </head>
    <body>
        <div class="header">
            <h1>AI Agent Audit Trail Report</h1>
            <p><strong>Task:</strong> {audit_trail['task']}</p>
            <p><strong>Started:</strong> {audit_trail['started_at']}</p>
            <p><strong>Completed:</strong> {audit_trail['completed_at']}</p>
            <p><strong>Total Steps:</strong> {len(audit_trail['steps'])}</p>
        </div>
    """

    for step in audit_trail["steps"]:
        html += f"""
        <div class="step">
            <div class="step-number">Step {step['step_number']}: {step['tool']}</div>
            <div class="timestamp">{step['timestamp']}</div>
            <p><strong>Input:</strong> {step['input']}</p>
            <p><strong>Output:</strong> {step['output']}</p>
        """
        if step.get("screenshot"):
            html += f'<img src="{step["screenshot"]}" class="screenshot" />'
        html += "</div>"

    html += "</body></html>"

    Path("/audit-trails/report.html").write_text(html)
Enter fullscreen mode Exit fullscreen mode

This pattern:

  1. Runs the AI agent as normal
  2. After every tool call, captures a screenshot via PageBolt API
  3. Stores screenshots + tool outputs in a structured audit trail
  4. Generates an HTML report with embedded screenshots for auditors

What Auditors Actually See

Instead of:

[LangSmith Log]
Tool: "approve_refund"
Output: {"status": "approved"}
Enter fullscreen mode Exit fullscreen mode

They see:

[Audit Report with Screenshots]
Step 1: Agent navigated to /admin/refunds
  Screenshot: Shows login form, customer is not authenticated

Step 2: Agent filled login form with correct credentials
  Screenshot: Shows username field filled, password masked

Step 3: Agent clicked "Login"
  Screenshot: Shows refund dashboard loaded

Step 4: Agent searched for customer cust_12345
  Screenshot: Shows search box with customer ID, results loaded

Step 5: Agent reviewed refund request for $250
  Screenshot: Shows refund details form with correct amount

Step 6: Agent clicked "Approve Refund"
  Screenshot: Shows confirmation dialog

Step 7: Agent confirmed approval
  Screenshot: Shows refund approval success page with confirmation ID

Step 8: Agent sent confirmation email
  Screenshot: Shows email preview with correct customer email and message
Enter fullscreen mode Exit fullscreen mode

This is compliance-ready. Auditors can:

  • Verify the agent accessed the correct system
  • See exactly what data it was working with
  • Confirm it made the right decisions
  • Trace errors if something goes wrong
  • Report to regulators with visual proof

Implementation Checklist

To make your AI agents audit-ready:

  • [ ] Identify all critical agent actions (approvals, data access, financial transactions)
  • [ ] Wrap each action with screenshot capture (use PageBolt API or similar)
  • [ ] Store audit trail as JSON (timestamp, action, input, output, screenshot path)
  • [ ] Generate audit reports (HTML with embedded screenshots for compliance reviews)
  • [ ] Define retention policy (how long to keep screenshots — HIPAA = 6 years, SOC 2 = 1 year minimum)
  • [ ] Test audit trail with compliance team (let auditors review a sample report)
  • [ ] Monitor for gaps (log failed actions, retries, escalations)

Pricing & Scale

Free tier: 100 screenshots/month covers small pilot agents or limited auditing.

Starter ($29/month): 5,000 screenshots/month — single production agent with comprehensive audit trails.

Growth ($99/month): 50,000 screenshots/month — multiple agents, multi-environment auditing.

Scale ($299/month): Unlimited screenshots, SLA, dedicated support — enterprise compliance requirements.


The Bottom Line

AI agents are powerful. But they're also a regulatory risk.

Without visual proof, your compliance team has to choose between:

  • Trusting a black box (risky)
  • Removing the agent from production (wasteful)
  • Adding manual oversight (expensive)

Visual audit trails unlock a fourth option: compliance at scale.

Your agents stay in production. Your auditors see proof. Your compliance officer sleeps at night.

Try it free. Add screenshot proof to your next AI agent. No credit card required.


Want to build audit-ready AI systems?

PageBolt's screenshot API captures proof after every agent step. Add it to your AI agent in one function call. Free tier: 100 screenshots/month.

Get started free →

Top comments (0)