# Building Human-in-the-Loop AI Workflows with Slack Interactive Cards

_By Tayyab Mughal, Founder & Chief Architect · 29 October 2026 · 3 min read_

> Autonomous AI agents need supervision before emailing clients. Learn how to implement human approval queues, HMAC Slack webhooks, and race-free card updates.

When an autonomous agent drafts high-stakes customer communications, an unverified send can lose a client. Here is how to build resilient Slack approval gates.

## Why autonomous agent outreach demands supervisory controls

Autonomous AI agents excel at synthesizing context, retrieving CRM records, and drafting personalized communications. However, when an LLM is given unrestricted dispatch authority, minor prompt variations can lead to catastrophic customer outcomes.

An agent misinterpreting a contract negotiation email might offer an unauthorized 40% discount, promise an unbuilt feature roadmap, or send a sensitive account summary to the wrong contact.

System prompts such as "always confirm with a manager" provide zero architectural safety. The model can ignore its own instructions under unexpected inputs. True safety requires an infrastructure-level quarantine that intercepts agent messages before transmission.

> Supervised execution is not a bottleneck; it is an audit trail. High-stakes agent actions must be quarantined at the network layer until verified by an authorized human operator.

## Configuring approval mode and message quarantine

With SadaSend, any agent tool call can specify approval mode. When active, the API accepts the message, assigns a tracking ID, and immediately places the payload into an isolated pending approval queue:

```typescript
const response = await sadasend.emails.send({
  from: 'Concierge <concierge@enterprise.com>',
  to: 'procurement@client.com',
  subject: 'Updated enterprise agreement proposal',
  html: agentDraftedHtml,
  mode: 'approval', // Quarantines email in pending_approval
  metadata: {
    agentId: 'contract-negotiator-v2',
    dealSize: '50000',
  },
});

// Outbox status: 'pending_approval' (No email sent over the wire)
console.log('Quarantined message ID:', response.id);
```

## Verifying Slack interactive webhooks with HMAC-SHA256

When an email enters pending approval, your server formats a Slack Block Kit card featuring the recipient, subject preview, and Approve / Reject action buttons.

To ensure actions originate from Slack and prevent forged decisions, the incoming webhook handler must verify Slack's cryptographic signature using the raw request body and timestamp header:

```typescript
import crypto from 'node:crypto';

export function verifySlackSignature(
  rawBody: string,
  timestamp: string,
  signature: string,
  signingSecret: string,
): boolean {
  // Reject replay attacks older than 5 minutes
  const fiveMinutesAgo = Math.floor(Date.now() / 1000) - 300;
  if (parseInt(timestamp, 10) < fiveMinutesAgo) return false;

  const sigBasestring = `v0:${timestamp}:${rawBody}`;
  const computedHash = 'v0=' + crypto
    .createHmac('sha256', signingSecret)
    .update(sigBasestring, 'utf8')
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(computedHash, 'utf8'),
    Buffer.from(signature, 'utf8'),
  );
}
```

## Preventing double-decision race conditions in Slack

When multiple team members view the same Slack approval card, simultaneous clicks can trigger race conditions. If Operator A clicks Approve and Operator B clicks Reject half a second later, an uncoordinated system might dispatch the message and then flag it as rejected.

To guarantee atomic decision resolution:

- Atomic Database Check-and-Set: Execute the state transition using a single SQL UPDATE with a WHERE status = "pending_approval" clause to guarantee only the first click succeeds.
- In-Place Block Kit Replacement: Return an immediate HTTP 200 with an updated view payload via Slack's response_url, replacing interactive buttons with an immutable banner recording the reviewer's name and timestamp.
- Audit Log Persistence: Record the approving human's Slack user ID, IP address, and decision timestamp into an immutable tamper-proof audit trail.

---

_Tags: AI agents, Slack, Security_
