ChatOps Agents: Slack Human-in-the-Loop
Deploying enterprise autonomous agents with interactive human approval gates in Slack. Learn asynchronous pause-and-resume state machines (LangGraph & Temporal), cryptographic approval payloads, and immutable audit logs.
01 Why Fully Autonomous Agents Fail in Enterprise
GovernanceIn real enterprises, autonomous agents cannot be granted unchecked authority to delete production databases, issue customer financial refunds, or deploy code to Kubernetes clusters. Human-in-the-Loop (HITL) introduces a dual-control governance model where the agent performs research and drafts the action, but a designated human supervisor clicks Approve or Reject in Slack before irreversible state changes occur.
02 Slack Bolt Agent with Interactive Buttons
Python ImplementationHere is a production Slack Bolt service handling agent task requests and posting interactive Block Kit approval cards:
import os
import hmac
import hashlib
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))
def generate_approval_token(task_id: str, secret_key: str) -> str:
"""Generates an HMAC-SHA256 signature to prevent button tampering."""
return hmac.new(secret_key.encode(), task_id.encode(), hashlib.sha256).hexdigest()
def send_approval_request_to_slack(channel_id: str, task_id: str, action_summary: str):
token = generate_approval_token(task_id, os.environ.get("APPROVAL_SECRET", "super-secret"))
app.client.chat_postMessage(
channel=channel_id,
text=f"⚠️ Human Approval Required: {action_summary}",
blocks=[
{
"type": "section",
"text": {"type": "mrkdwn", "text": f"*Agent Action Pending Approval*\n>{action_summary}"}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {"type": "plain_text", "text": "✅ Approve Action"},
"style": "primary",
"action_id": "agent_action_approve",
"value": f"{task_id}:{token}"
},
{
"type": "button",
"text": {"type": "plain_text", "text": "❌ Reject"},
"style": "danger",
"action_id": "agent_action_reject",
"value": f"{task_id}:{token}"
}
]
}
]
)
@app.action("agent_action_approve")
def handle_approval(ack, body, client):
ack()
user_id = body["user"]["id"]
val = body["actions"][0]["value"]
task_id, token = val.split(":")
# Verify HMAC token validity
expected_token = generate_approval_token(task_id, os.environ.get("APPROVAL_SECRET", "super-secret"))
if token != expected_token:
client.chat_postMessage(channel=body["channel"]["id"], text="❌ Tampering detected. Invalid token.")
return
# Update Slack message to show approved state
client.chat_update(
channel=body["channel"]["id"],
ts=body["message"]["ts"],
text="Action Approved",
blocks=[{
"type": "section",
"text": {"type": "mrkdwn", "text": f"✅ *Approved by <@{user_id}>* — Resuming autonomous workflow..."}
}]
)
# Resume LangGraph / Temporal workflow execution
print(f"Resuming Task {task_id} approved by user {user_id}")
if __name__ == "__main__":
handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])
handler.start()
03 Stateful Graph Interruption (LangGraph Checkpoints)
State Machine
By setting interrupt_before=["execute_critical_tool"] in LangGraph, the agent graph serializes its entire execution state into a PostgreSQL checkpointer and halts. Once the human clicks Approve in Slack, the server fetches the checkpoint by thread ID and executes graph.invoke(None, config) to resume seamlessly where it left off.
Frequently Asked Questions
What happens if the human supervisor never responds to the Slack button? →
Production workflows implement an expiration timer (e.g. 2 hours). If no response is received, the checkpoint transitions to a TIMED_OUT status, releases acquired resource locks, and posts an escalation notification to a secondary on-call rotation channel.
How does this architecture satisfy SOC 2 and ISO 27001 audit controls? →
Every approval event logs the immutable Slack user ID, timestamp, HMAC hash, action diff, and execution status into an append-only audit database (like AWS CloudWatch Logs or BigQuery). Auditors have complete proof that destructive operations were explicitly authorized by verified human engineers.