Approvals & permission modes
How much autonomy you've given the swarm, what always stops for a human regardless of mode, and every place — desktop or mobile — where you make that call.
Why this page exists
SnapFlow never leaves your infrastructure to chance: two systems work together to decide what the swarm can do on its own and what it must ask you about first. Your permission mode sets the default level of autonomy for the whole agency; individual approvals are the moments — inside a mission, in Triage, or from a shared link — where SnapFlow actually stops and asks. This page explains both.
The four permission modes
Set from the pill button on the left of the top bar (only agency founders can change it — everyone else sees it read-only). It forms a ladder from strictest to loosest:
| Mode | What runs unattended, and what still stops for you |
|---|---|
| Plan only | Agents investigate and propose only. Nothing is created, changed, or deleted — every step that would modify anything is automatically rerouted to a read-only analysis instead. Nothing further needs your approval, because nothing runs. |
| Guarded (default) | Reads and non-destructive writes run without asking. Creating new cloud resources ("provisioning") and any destructive action still require your approval. |
| Autonomous | Reads, writes, and provisioning all run without asking. Destructive actions, renaming, and permission/IAM changes still require your approval. |
| Unattended | Everything runs without stopping — the most hands-off mode. The critical floor below still applies; nothing can turn it off. |
The critical floor — what no mode can turn off
Deleting or tearing down resources, moving or renaming things, permission/IAM changes, and anything targeting a production environment. Even in Unattended mode, SnapFlow stops and asks first. A footer note under the mode dropdown always reminds you of this. The one exception: a removal you already approved as part of a job's plan (see One approval per plan). Production is never covered that way.
"Permission changes" means any of them, in any AWS service — not just IAM. SnapFlow rates every AWS command against AWS's own list of its APIs (the Service Authorization Reference, kept current automatically), so a Lambda resource policy, a KMS key policy, an ECR repository policy, a Secrets Manager resource policy or a KMS grant stops and asks just like an IAM role does. Setting an attribute counts only when it carries a policy: changing an SQS queue's visibility timeout is an ordinary change.
One approval per plan
When you approve a job's plan and its quote in the conversation, you're approving everything the plan card showed, so the job doesn't stop to ask again for those things:
| On the plan card | After you approve |
|---|---|
| Steps that create something | Marked Creates on the card. They can create cloud resources without stopping. |
| Steps that remove something | Marked Removes. They can remove what they said they would. |
| Approval steps in the plan | Pass on their own. For an OpenTofu step, SnapFlow still computes the real diff first. If the diff removes anything the plan didn't say it would remove, the job stops and asks. |
Under the steps, the card says exactly what approving covers (e.g. "creates resources (step 3) and removes resources (step 5)"). When you reply in a job and the new plan does something no earlier approval in that conversation covered, the card says so first: "New in this reply: it removes resources."
Anything a step tries that its own description didn't say (a "launch an instance" step that tries to terminate one), permission and IAM changes, a migration's cutover, and anything in a production environment. Those still stop and ask. So do jobs that don't start from a plan card, such as scheduled runs, monitoring fixes and the CLI.
SnapFlow can also automatically tighten your mode for a specific mission — for example, if the target environment is marked production, the effective mode is capped at Guarded even if your agency-wide setting is looser. When this happens, the Pre-Flight Manifest shows a note explaining why (e.g. "Clamped to Guarded: the target environment is production.").
SnapFlow used to have a simpler two-state toggle. It's been replaced by the four-mode ladder above — "Read-Only" maps to Plan only, and "Write-Enabled" maps to Guarded.
Every change can be undone — or you are told before it runs
Each step you approve says how it can be undone, right on the approval card:
| On the card | What it means |
|---|---|
| Can be undone | SnapFlow records the configuration of everything it changes before it changes it, and removes what it creates. A rollback puts it all back. |
| Retired, not deleted | Deleting something that holds data (a database, table, volume, bucket, cache or file system). It is kept, protected and stopped for 7 days, then deleted. Until then, rolling the job back brings it back as it was. |
| Data comes back from a recovery point | A delete you asked to run permanently or immediately (outside production). Its configuration can be put back; its data comes back from a recovery point taken before the delete. |
| Cannot be undone | A sent email or message, a deleted snapshot or backup, a released IP address, a version upgrade, or a delete you asked to run without a copy. SnapFlow always asks you to confirm these. |
Rolling a job back
Roll back on a finished or stopped job works through what the job did, newest first:
- What it created is removed.
- What it changed on resources that already existed is put back to the configuration SnapFlow recorded before the change. Those resources are never deleted, even if the job tagged them.
- What it deleted that held data is offered for restore from the recovery point SnapFlow named, as a new resource, so nothing written since is overwritten.
A rollback that takes longer than a minute keeps running after you close the dialog; its result appears in the job's timeline.
Deleting something that holds data: retired for 7 days
When a job deletes a database, table, volume, bucket, cache or file system, SnapFlow retires it instead: it takes a recovery point, stops it (or closes a bucket to public access), keeps deletion protection on, and tags it snapflow:retire-at with the date it will be deleted, 7 days later. On that date SnapFlow deletes it, unless the tag was removed, moved later, or the resource is protected. Until then:
- Roll the job back and the resource comes back exactly as it was.
- Or open Cloud → Changes and choose Keep it: it stays and is never deleted.
To delete something at once, say so: "Permanently delete the table orders". The approval card then says it cannot be brought back except from a recovery point. In a production environment this is not possible: removal always goes through the 7 days.
No recovery point, no delete
SnapFlow will not delete a database, table, volume, cache or file system until a recovery point exists: a snapshot or backup taken during the job, a final snapshot named in the delete, or DynamoDB's own backup when point-in-time recovery is on. If none exists, the step stops and shows the one command that makes the delete safe. If your request says to delete without a final snapshot, SnapFlow does as you asked and marks the step Cannot be undone.
A change interrupted half-way
If SnapFlow stops in the middle of applying a change (a crash, a restart), it picks the change up again: it finds what was already made, adopts it instead of making it twice, and finishes what you approved. It never applies anything beyond the plan you approved; if the account has changed so much that the plan no longer holds, it stops and asks.
Verified only while health holds
Before a job's first change in AWS, SnapFlow notes which CloudWatch alarms are already in ALARM and how many targets behind each load balancer are unhealthy. When the work is done and checked, it looks again. If a new alarm has gone off, or more targets are unhealthy, the job is not marked verified (nothing is charged): it stops and names what got worse. In an environment set to auto-revert (production, by default) SnapFlow also rolls the job back. Alarms already going off before the job are ignored.
Back to how it was before SnapFlow
Cloud → Changes lists every resource SnapFlow has changed, when it first did and in which jobs. Restore original puts one back exactly as it was before SnapFlow first touched it, across all of those jobs (owners only).
Production environments
Mark an environment as production (Cloud → Environments) and, on top of approving every change:
- Change window — optional days and hours (in your time zone) when changes may run. Outside them a job stops before its first change and carries on when you resume it in the window. Reading and diagnosing run any time.
- Change limit — one job changes at most 10 existing resources (you can set the number). A bigger change is refused with the reason; split it into smaller jobs.
- No interruption — a change that would replace a resource (delete it and make it again, taking it down meanwhile) does not run unless your request says the replacement is fine. Every approval card names such resources, in any environment.
- Least access — each step gets AWS credentials that can read everything but change only the services its own words name. If a step needs something it did not name, it stops and says what.
- Removal always retires — "permanently" is not honoured; the 7-day window always applies.
Every step's AWS session is named after its job and step (snapflow-<job>-s<step>-…), so CloudTrail shows which job made each call.
Protected resources
Tag any AWS resource snapflow:protected=true and SnapFlow can never delete it, and never remove or change that tag. AWS itself enforces this, through a rule in SnapFlow's own permissions, so not even a bug in SnapFlow could get past it. Only a person in your AWS account can take the protection off.
Disconnect now
Cloud → Accounts & servers → Disconnect on AWS ends SnapFlow's access at once on SnapFlow's side: no new credentials are made, and every running AWS job stops. SnapFlow cannot delete its own role in your account (its ceiling forbids it changing its own access), so it then shows you:
- a script to run in AWS CloudShell that revokes every session SnapFlow already holds and deletes its role, policies and ceiling;
- what SnapFlow made that still exists, and what it had retired (kept now: nothing will delete it).
SnapFlow's ceiling in your AWS account
When you connect AWS, SnapFlow sets a ceiling: the most it, and any role it creates, can ever do in your account. The default, Operate, covers everything except billing, AWS Organizations, account settings, and IAM users and access keys. SnapFlow cannot change its own ceiling.
Under the ceiling, you never need to go to the AWS console after connecting:
- Permissions a job needs: a stopped job shows Grant these permissions. One click (owners only) adds exactly what the job needs to SnapFlow's access, capped by the ceiling.
- Roles your workloads need (a Lambda function's role, an instance's role): SnapFlow creates them under
/snapflow/, each capped by the same ceiling. Every IAM change still asks for your approval on its own. - Existing workloads: SnapFlow never edits a role it did not create. To give one more permissions, it creates a capped copy with the addition, switches the workload to it, and keeps the old role so you can switch back.
Your connection keeps working as before: SnapFlow does not create IAM, and permission fixes are CloudShell commands. Run the AWS setup again once (Cloud → AWS → Reconfigure) to get the ceiling.
Where you'll actually be asked to approve something
An "approval" is a specific decision on a specific proposed action. You'll encounter it in four places:
1. The Pre-Flight Manifest
Every request goes through this confirmation screen before it starts. See Mission Control → The Pre-Flight Manifest for the full breakdown of its chips, verdict banner, and checklist.
2. Inside a running mission
If a step is gated, the mission pauses and shows a Gate Evidence card — the action, target environment, why it was gated, affected resources, and a rollback plan — with Approve and Reject & stop mission buttons, each behind a confirm step. See Mission Control → When a mission needs your approval.
3. The Triage queue
Every pending approval across your whole agency also lands in Triage & Gates → Queue, sorted by urgency, alongside incidents. Opening one shows the same plan viewer and Approve/Reject buttons, plus a "Share as mobile link" option — see below. Full detail: Triage & Gates → Queue.
4. A one-time mobile link — no login required
From Triage, click "Share as mobile link" on any approval to mint a one-time link — SnapFlow shows it as: "One-time link — expires in 1h, works without logging in." Anyone with that link (for example, on your phone) can open it and see:
- The requesting agent's name and the proposed change (as a plan viewer or summary).
- Two buttons: ❌ Deny and ✅ Approve.
- A required confirmation step before anything commits — "Approve this plan?" / "Reject this plan?" — with the same "cannot be undone" warning as everywhere else. Unlike the desktop flow, this mobile confirm step has no notes/reason field.
- A final "Approved" or "Rejected" screen: "This link has now been used and can't be opened again."
This page sits outside the normal signed-in app on purpose — possessing a valid, unexpired, unused link is enough to act on it. That's why it expires after an hour and can only ever be used once.
SnapFlow