Skip to content
CloudOps
Newsletter Sign up
All guides
AI for Slack · 9 min read

Building Approval Workflows in Slack for Deploys and Access

How to build Slack approval workflows for production deploys and access requests — interactive buttons, authorization, audit trails, and timeouts.

  • #slack
  • #approvals
  • #chatops
  • #deploys
  • #access-control
  • #compliance

Some actions should never be one person’s decision. A production deploy on a Friday, a temporary grant of admin access, a database migration — these want a second set of eyes. The traditional answer is a ticketing system nobody checks, which means approvals either rubber-stamp or rot. After 25 years of running ChatOps, I’ve found Slack is the right place for approvals, because that’s where people already are and the request is impossible to ignore.

Here’s how I build approval workflows that are fast for the requester and real for the approver.

What a good approval workflow guarantees

Three properties, non-negotiable:

  • The action cannot proceed without an authorized approval. The gate is real, not advisory.
  • Every decision is recorded — who requested, who approved or denied, when, and why. That’s your audit trail.
  • It’s fast enough that people don’t route around it. An approval workflow people bypass is worse than none, because it gives false comfort.

The request

A workflow starts with a request that carries everything the approver needs to decide without asking follow-up questions. For a deploy:

{
  "blocks": [
    { "type": "header", "text": { "type": "plain_text", "text": ":lock: Prod deploy approval needed" } },
    { "type": "section", "fields": [
      { "type": "mrkdwn", "text": "*Service:*\ncheckout-api" },
      { "type": "mrkdwn", "text": "*Version:*\nv2.14.3 (3 commits)" },
      { "type": "mrkdwn", "text": "*Requested by:*\n<@U123>" },
      { "type": "mrkdwn", "text": "*Changes:*\nbug fix, dep bump" }
    ]},
    { "type": "actions", "elements": [
      { "type": "button", "style": "primary", "action_id": "approve",
        "text": { "type": "plain_text", "text": "Approve" } },
      { "type": "button", "style": "danger", "action_id": "deny",
        "text": { "type": "plain_text", "text": "Deny" } }
    ]}
  ]
}

The richer the request, the faster the decision. If the approver has to go read the diff in GitHub to decide, your request is missing context.

Authorize the approver, not just the click

The single most important rule: the requester cannot approve their own request, and only designated approvers can approve at all. Check it on the button click:

app.action('approve', async ({ ack, body, client }) => {
  await ack();
  const approver = body.user.id;
  if (approver === request.requestedBy) {
    return client.chat.postEphemeral({ /* "you can't approve your own request" */ });
  }
  if (!approvers.includes(approver)) {
    return client.chat.postEphemeral({ /* "you're not an approver" */ });
  }
  await recordDecision(request, approver, 'approved');
  await proceedWithDeploy(request);
});

Without this, the button is theater — anyone could click it, including the person who needs the approval. The authorization check is what makes the gate real.

Record the decision immutably

When a decision lands, update the message to show the outcome (approved by whom, when) and write the decision to a durable store, not just Slack. Slack history can be edited or expire under retention policy; your audit trail can’t depend on it. The message tells the channel; the store satisfies the auditor.

For regulated environments, this audit trail is often the whole reason the workflow exists, so treat the store as the source of truth and Slack as the friendly interface on top.

Handle timeouts and escalation

Approvals that hang forever are useless. Build in time:

  • Set an expiry. If a deploy approval isn’t answered in, say, 30 minutes, it auto-denies and the message updates to “expired.” A request that just sits there is an ambiguous state nobody trusts.
  • Escalate. If the primary approver doesn’t respond, ping a backup after a delay. Don’t let one person’s lunch break block every deploy.

Multi-step approvals when you need them

High-stakes actions — a production database migration, a broad access grant — may need two approvers or a specific role. The pattern extends naturally: track required approvals as a list, only proceed when all are satisfied, and show progress in the message (“1 of 2 approvals”). Keep the count and roles deterministic; don’t let the requester negotiate their way to fewer approvers.

Access requests, not just deploys

The same machinery handles temporary access grants. Someone requests elevated DB access; an approver grants it; the bot provisions a time-boxed credential and schedules its automatic revocation. The auto-expiry is the key feature — standing access that nobody remembers to revoke is how least-privilege quietly dies. Approve generously when it expires on its own.

Where AI fits

AI helps the approver decide faster without ever holding the gate:

  • Risk summary on the request. The bot sends the diff and change context to an LLM and posts a one-line risk read alongside the buttons: “Low risk — bug fix in a non-critical path, no schema or config changes.” The approver still decides; they just decide better-informed.
  • Flagging surprises. AI can flag “this deploy also touches the auth module, which wasn’t mentioned” — catching the thing a fast approver would miss.

The boundary is absolute: AI summarizes risk to inform the human; it never approves, denies, or proceeds. The approval gate is a human authorization check, full stop. A model’s risk read is advice on the request, not a vote on it.

A rollout that builds trust

  1. Request-and-approve for non-prod or low-stakes actions first, so the team learns the flow.
  2. Prod deploy approvals with authorization and audit.
  3. Timeouts and escalation.
  4. Access requests with auto-expiry.
  5. AI risk summaries last, as a decision aid.

The bottom line

A Slack approval workflow makes the right thing the easy thing: the requester clicks a button, the approver gets full context in the place they already live, the decision is recorded, and dangerous actions can’t proceed unapproved. Keep the gate a real human authorization check, let AI inform the decision, and you get safety without the friction that makes people route around it.

For AI prompts that summarize deploy and access risk, see our Slack approval prompts and the prompt library.

The approval gate is a human authorization check. AI summarizes risk to inform it; it never makes the decision.

Newsletter

Free: the DevOps AI Incident-Triage Cheat Sheet

Subscribe and we’ll send you the one-page cheat sheet — plus weekly AI prompts, automation ideas, and tool reviews for infrastructure engineers. One email a week. No spam, unsubscribe anytime.

  • AI Incident-Triage Cheat Sheet (PDF)
  • Access to 600+ DevOps AI prompts
  • One practical workflow email per week