# Approving a deploy

> Where requests reach you, what is worth looking at before you decide, and the one rule that has no exceptions.

Source: https://docs.buildgate.dev/approving-a-deploy
Documentation: https://docs.buildgate.dev

## Where requests reach you

All of these land in the same place and run through the same checks — the rule about who may decide, the role check and the expiry are enforced once, wherever you happen to click:

- **The console.** The Approvals screen holds the pending queue and the whole history. Each request opens as a screen of its own with an address you can paste into a ticket.
- **A Slack DM or an email**, on whichever channels your organization has turned on.
- **The Bubble editor.** If you open the branch a request was raised from, the panel over it lists what is waiting and lets you decide there.
- **Your own tooling.** BuildGate is a remote MCP server, so an assistant or a terminal can list what is waiting on you, read the change and decide it — see [approving from your own tooling](https://docs.buildgate.dev/integrations#mcp).
- **A pull request**, where an administrator has switched that on for the app — see [Git](https://docs.buildgate.dev/integrations#git).

Note what is never a way to decide: a button in Slack, or a link in an email that approves on click. Both authenticate as whoever controls that account rather than as you, so every message links to a page where the decision is made under a Google sign-in and recorded against your name.

## What to look at before you decide

The request is laid out the way a pull request is:

- **The change and the two versions it moves between** — `source → target`, as recorded when the request was raised.
- **The linked Linear issue**, the change description and the rollback plan.
- **The automated review**, where one ran. Each finding is marked as one that would have held the deploy or one it could have waved through, and the review names which agent ran and what that agent could see. A review still running says so; one that errored is never shown as "nothing found"; one that could not see the whole change is never drawn as clean.
- **What actually changed**, where an administrator has switched on *Show approvers what a deploy changes*: which pages, workflows, data types, option sets and API calls were added, removed or changed, with privacy-rule, API and plugin changes called out, plus a pull request holding the full diff.
- **The timeline**, which is the audit chain filtered to this one request — the same events an auditor exports, not a friendlier copy kept alongside.

You can also just ask. Anyone who can open a request can comment on it, including after it has been decided, and comments are chain events like everything else: they cannot be edited or deleted and they export with the rest. Your question and the answer are part of how the change was reviewed — in a Slack thread, they are not.

## Approving, rejecting, or handing it on

One box, one piece of text: what you write is recorded either as a comment on its own or as the note on your decision.

- **Approving** opens the gate for that one deploy, for fifteen minutes. It does not deploy anything — the person who raised it still has to.
- **Rejecting cannot be undone.** The note is the feedback the requester reads, so say what would need to change. If you only have a question, comment instead and leave it pending.
- **Re-routing** moves the name the notifications go to, with a note saying why. It grants nobody anything — any approver could always have decided it — and a request can never be routed to the person who raised it.

## Who can decide, and who cannot

The request names an approver, and that is **routing rather than permission**. Anyone in the organization with an approving role — `owner`, `admin` or `approver` — can decide any request they did not raise, from any of the places above.

One rule has no exceptions: **whoever raised a deploy can never decide it**, whatever role they hold. That is what the independent approval means, and it is enforced in the service, at every route, and by a constraint in the database. Requests you raised do not appear in your pending list at all.

Requiring the one nominated person instead would add no independence — a colleague on a flight is not a control — and it is how an approval queue quietly stops moving.

## Roles

Held per organization, not per account: the same person can be an owner of one and a deployer in another.

| Role | Can |
| --- | --- |
| `owner` | Everything, including transferring ownership. Cannot be removed by an admin |
| `admin` | Manage apps, members and integrations; approve deploys |
| `approver` | Approve a deploy someone else raised |
| `deployer` | Request a deploy |

Roles also decide how much of the history somebody reads. Anyone who can approve sees every request the organization has raised — that is what makes the Approvals screen a record rather than a personal inbox. A `deployer` sees the ones they raised.

## Automated approval, and what it is not

An app can be set to approve its own deploys when its review agent finds nothing wrong. It is a per-app switch, **off by default**, and it is the one setting in this product that removes the second person from the control — so it is worth understanding before turning it on.

**What counts as clean:** the review completed without error, it saw the whole change, and every open finding is a low-or-no-priority comment whose title does not read as a security concern. Anything asked to be changed or tested, anything above low priority, and anything security-shaped holds the deploy for a person. A run that errored is never clean, and neither is one that read no comparison or a comparison cut short — *could not look* must never read as *looked, and it was fine*.

What it cannot do:

- **It cannot reject, and it cannot deploy.** A review that finds something, fails, or never runs leaves the request pending for its human approver, exactly where it was.
- **It cannot outrun you.** The assigned approver is notified as usual and can decide at any time; whoever gets there first wins, and a human decision is never overwritten.
- **It cannot pretend to be a person.** The decision is recorded as automated, never as compliant, and it names which agent gave it. Bubble's own deploy description says there was no human approver.

> SOC2 CC8.1 expects an independent approval. For any app where this is on, be ready to justify it — and know which agent the app is set to, because a clean review from one of them is a statement about *scope* rather than correctness. See [the two review agents](https://docs.buildgate.dev/integrations#review-agents).
