Fly.io plugin
The Fly.io plugin lets a Vaubaan Gateway mission use Fly.io without handing the agent a credential. Apps on Fly.io: machines, images, volumes and snapshots, secrets, IP addresses and certificates — one resource per app.
- Version:
0.1.0(package@vaubaan/plugin-fly) - Status: stable
- Health: not enough reports yet — what this means
- Source: plugins/fly, catalog risk-catalog.yaml version 1 of 2026-10-16
- How to connect an account: Connect Fly.io
- How it is modelled: handbook
One account is one Fly organization token; one resource is one app of that organization. The owner labels each app staging or prod, and writes are held per label. Machines only run images pinned by digest under the allowed prefixes of the account, secret values are never read back, and running a command inside a machine is its own permission.
Permissions
Each permission is a named risk of the plugin's catalog: a mission holds an explicit list of them, never "all". The severity is computed from the permission's six axes (undo, blast radius, data, cost, visible to, lasts); nothing is decided from it.
| Permission | What it allows | Severity | Why it is a risk |
|---|---|---|---|
fly.read-org | List the apps and regions of the organization | low | App names, ids and networks, and the platform regions. In an organization that hosts one app per customer, the list of apps is the list of customers; the answer is filtered to the apps of the mission. |
fly.read-runtime | Read machines, volumes, snapshots, IP addresses and certificates | low | Machine configurations (image, region, size, services, plain environment variables), events, processes, volumes and their snapshots, the app's addresses and certificates. People sometimes put secrets in plain environment variables. |
fly.read-secret-names | List the names of the app secrets | low | Names, digests and dates of the secrets set on an app, never their values: any value in Fly's answer is replaced before the agent sees it. |
fly.read-logs | Read the app logs | low | What the app printed recently. Logs can carry customer data, and secrets when an app prints them. |
fly.app-create | Create an app in the organization | medium | A new app on a private network of its own. Costs nothing until it runs machines. It is not part of the mission until its owner labels it and adds it. |
fly.app-destroy | Destroy an app | critical (only for staging, prod) | Removes the app with its machines, addresses, certificates, volumes and their snapshots. For a customer instance, its data is gone for good. |
fly.machine-create | Create a machine | low (only for staging, prod) | A new VM in the app, billed while it runs. A creation sets a whole configuration and an image: a mission needs those two permissions too. |
fly.machine-config-write | Set a machine configuration | high (medium on staging; only for staging, prod) | Environment variables, start command, files written at boot, mounted volumes, autostop and the services the machine exposes. A configuration can start any command with the app's secrets in its environment. |
fly.deploy | Change the image a machine runs | medium (low on staging; only for staging, prod) | The machine restarts on the new image, which runs with the app's secrets and volume. Only images pinned by digest under the connection's allowed prefixes are accepted, and a mounted volume needs a fresh snapshot first. |
fly.scale | Resize a machine | low (only for staging, prod) | CPU and memory of a machine, billed while it runs. The machine restarts. |
fly.machine-power | Start, stop, restart, suspend or cordon a machine | low (only for staging, prod) | A stopped or cordoned machine serves no traffic until it starts again or a request wakes it. Changes no data. |
fly.machine-destroy | Destroy a machine | medium (only for staging, prod) | The machine and its root filesystem are gone; a volume it mounted stays. A stopped machine only: a running one must be stopped first. |
fly.machine-exec | Run a command inside a machine | high (only for staging, prod) | Any command, with the app's secrets in its environment and its volume mounted; the output comes back to the agent. On a Vaubaan instance this reaches the master key and every account it seals. |
fly.volume-create | Create an empty volume | low | Persistent storage billed by size, in one region. Holds no data yet. |
fly.volume-restore | Create a volume from a snapshot or another volume | medium (only for staging, prod) | Copies data into a new volume. A machine that mounts it serves that data, which may be older than the live one. The source must belong to the same app. |
fly.volume-extend | Extend a volume | medium (only for staging, prod) | A volume grows and never shrinks: the extra size is billed for as long as it exists. |
fly.volume-backup-settings | Change automatic snapshots of a volume | medium (only for staging, prod) | Turns daily snapshots on or off and sets how many days they are kept. Off, or a shorter retention, leaves less to restore from. |
fly.volume-snapshot | Take a volume snapshot | low | A point-in-time copy, kept for the volume retention period. Changes nothing that runs. |
fly.volume-destroy | Destroy a volume | high (only for staging, prod) | Cannot be undone. The data survives only in snapshots still within their retention period. |
fly.secret-write | Set or remove app secrets | medium (only for staging, prod) | Machines pick up new values when they are next updated. A wrong or missing value, such as a master key or a sign-in setting, can lock everyone out of an instance or make its sealed data unreadable. |
fly.ip-write | Allocate an IP address | medium (only for staging, prod) | A public address makes the app reachable from the internet; a dedicated IPv4 address is billed monthly. |
fly.ip-release | Release an IP address | medium (only for staging, prod) | The app stops answering on that address and DNS pointing at it breaks. A released dedicated address is not given back. |
fly.certificate-write | Request or re-check a certificate | medium (only for staging, prod) | Asks Fly to issue a certificate for a hostname, or to validate it again. Issuance succeeds only when the hostname's DNS points at the app. |
fly.certificate-remove | Remove a certificate | medium (only for staging, prod) | HTTPS on that hostname fails until a certificate is issued again. |
fly.uncategorized-write | Uncategorized write | medium (the catch-all: touched only by a call no other permission covers) | Catch-all for a write no other entry covers. Seeing it in the activity means the catalog misses an entry. |
Presets
A preset pre-fills the permissions of a mission for one account, with a limit per period, a rate and whether each permission runs freely or asks the mission creator first. The person creating the mission adjusts it; the mission stores the explicit list.
Read-only
read-only — Look at apps, machines, volumes, secret names and logs. Changes nothing.
| Permission | What it allows | Limit per period | Rate | Runs |
|---|---|---|---|---|
fly.read-org | List the apps and regions of the organization | 2000 | 60 per minute | runs freely |
fly.read-runtime | Read machines, volumes, snapshots, IP addresses and certificates | 5000 | 120 per minute | runs freely |
fly.read-secret-names | List the names of the app secrets | 500 | 30 per minute | runs freely |
fly.read-logs | Read the app logs | 1000 | 30 per minute | runs freely |
Operator
operator — Day-to-day care of existing instances: staging runs freely; production configuration, upgrades, resizes, secrets, commands inside a machine and anything destructive ask first.
| Permission | What it allows | Limit per period | Rate | Runs |
|---|---|---|---|---|
fly.read-org | List the apps and regions of the organization | 2000 | 60 per minute | runs freely |
fly.read-runtime | Read machines, volumes, snapshots, IP addresses and certificates | 5000 | 120 per minute | runs freely |
fly.read-secret-names | List the names of the app secrets | 500 | 30 per minute | runs freely |
fly.read-logs | Read the app logs | 1000 | 30 per minute | runs freely |
fly[staging].machine-config-write | 50 | 10 per minute | runs freely | |
fly[prod].machine-config-write | 10 | 2 per minute | ask me first | |
fly[staging].deploy | 100 | 10 per minute | runs freely | |
fly[prod].deploy | 20 | 5 per minute | ask me first | |
fly[staging].scale | 20 | 5 per minute | runs freely | |
fly[prod].scale | 10 | 2 per minute | ask me first | |
fly[staging].machine-power | 200 | 20 per minute | runs freely | |
fly[prod].machine-power | 200 | 20 per minute | runs freely | |
fly[staging].machine-destroy | 20 | 5 per minute | runs freely | |
fly[prod].machine-destroy | 5 | 1 per minute | ask me first | |
fly[staging].machine-exec | 10 | 2 per minute | ask me first | |
fly[prod].machine-exec | 10 | 2 per minute | ask me first | |
fly.volume-create | Create an empty volume | 10 | 2 per minute | runs freely |
fly[staging].volume-restore | 5 | 1 per minute | ask me first | |
fly[prod].volume-restore | 5 | 1 per minute | ask me first | |
fly[staging].volume-extend | 10 | 2 per minute | runs freely | |
fly[prod].volume-extend | 5 | 1 per minute | ask me first | |
fly[staging].volume-backup-settings | 10 | 2 per minute | ask me first | |
fly[prod].volume-backup-settings | 10 | 2 per minute | ask me first | |
fly.volume-snapshot | Take a volume snapshot | 100 | 10 per minute | runs freely |
fly[staging].volume-destroy | 5 | 1 per minute | ask me first | |
fly[staging].secret-write | 20 | 5 per minute | ask me first | |
fly[prod].secret-write | 20 | 5 per minute | ask me first | |
fly[staging].ip-write | 5 | 1 per minute | ask me first | |
fly[prod].ip-write | 5 | 1 per minute | ask me first | |
fly[staging].ip-release | 5 | 1 per minute | ask me first | |
fly[prod].ip-release | 5 | 1 per minute | ask me first | |
fly[staging].certificate-write | 20 | 5 per minute | runs freely | |
fly[prod].certificate-write | 20 | 5 per minute | runs freely | |
fly[staging].certificate-remove | 5 | 1 per minute | ask me first | |
fly[prod].certificate-remove | 5 | 1 per minute | ask me first |
Fleet upgrade
fleet-upgrade — Roll a new image across many instances: snapshot each volume, then change the image and restart, without asking each time. Only pinned images under the allowed prefixes, after a fresh snapshot. Nothing else.
| Permission | What it allows | Limit per period | Rate | Runs |
|---|---|---|---|---|
fly.read-org | List the apps and regions of the organization | 2000 | 60 per minute | runs freely |
fly.read-runtime | Read machines, volumes, snapshots, IP addresses and certificates | 5000 | 120 per minute | runs freely |
fly.read-logs | Read the app logs | 1000 | 30 per minute | runs freely |
fly.volume-snapshot | Take a volume snapshot | 500 | 10 per minute | runs freely |
fly[staging].deploy | 200 | 10 per minute | runs freely | |
fly[prod].deploy | 500 | 10 per minute | runs freely | |
fly[staging].machine-power | 500 | 20 per minute | runs freely | |
fly[prod].machine-power | 500 | 20 per minute | runs freely |
Provisioner
provisioner — Create and configure customer instances: apps, machines, volumes, addresses, certificates. Secrets, restores and destruction ask first; commands inside a machine are not included.
| Permission | What it allows | Limit per period | Rate | Runs |
|---|---|---|---|---|
fly.read-org | List the apps and regions of the organization | 2000 | 60 per minute | runs freely |
fly.read-runtime | Read machines, volumes, snapshots, IP addresses and certificates | 5000 | 120 per minute | runs freely |
fly.read-secret-names | List the names of the app secrets | 500 | 30 per minute | runs freely |
fly.read-logs | Read the app logs | 1000 | 30 per minute | runs freely |
fly.app-create | Create an app in the organization | 10 | 2 per minute | runs freely |
fly[staging].app-destroy | 5 | 1 per minute | ask me first | |
fly[prod].app-destroy | 2 | 1 per minute | ask me first | |
fly[staging].machine-create | 20 | 5 per minute | runs freely | |
fly[prod].machine-create | 20 | 5 per minute | runs freely | |
fly[staging].machine-config-write | 50 | 10 per minute | runs freely | |
fly[prod].machine-config-write | 20 | 5 per minute | runs freely | |
fly[staging].deploy | 50 | 10 per minute | runs freely | |
fly[prod].deploy | 20 | 5 per minute | runs freely | |
fly[staging].scale | 20 | 5 per minute | runs freely | |
fly[prod].scale | 20 | 5 per minute | runs freely | |
fly[staging].machine-power | 100 | 20 per minute | runs freely | |
fly[prod].machine-power | 100 | 20 per minute | runs freely | |
fly[staging].machine-destroy | 20 | 5 per minute | runs freely | |
fly[prod].machine-destroy | 10 | 2 per minute | ask me first | |
fly.volume-create | Create an empty volume | 20 | 5 per minute | runs freely |
fly[staging].volume-restore | 5 | 1 per minute | ask me first | |
fly[prod].volume-restore | 5 | 1 per minute | ask me first | |
fly[staging].volume-extend | 10 | 2 per minute | runs freely | |
fly[prod].volume-extend | 10 | 2 per minute | runs freely | |
fly[staging].volume-backup-settings | 20 | 5 per minute | runs freely | |
fly[prod].volume-backup-settings | 20 | 5 per minute | runs freely | |
fly.volume-snapshot | Take a volume snapshot | 50 | 10 per minute | runs freely |
fly[staging].volume-destroy | 5 | 1 per minute | ask me first | |
fly[prod].volume-destroy | 2 | 1 per minute | ask me first | |
fly[staging].secret-write | 50 | 10 per minute | ask me first | |
fly[prod].secret-write | 50 | 10 per minute | ask me first | |
fly[staging].ip-write | 20 | 5 per minute | runs freely | |
fly[prod].ip-write | 20 | 5 per minute | runs freely | |
fly[staging].ip-release | 5 | 1 per minute | ask me first | |
fly[prod].ip-release | 5 | 1 per minute | ask me first | |
fly[staging].certificate-write | 20 | 5 per minute | runs freely | |
fly[prod].certificate-write | 20 | 5 per minute | runs freely | |
fly[staging].certificate-remove | 5 | 1 per minute | ask me first | |
fly[prod].certificate-remove | 5 | 1 per minute | ask me first |
Tools
| Tool | What it does |
|---|---|
fly__list_regions | List regions |
fly__list_apps | List apps |
fly__get_app | Read an app |
fly__create_app | Create an app |
fly__destroy_app | Destroy an app |
fly__list_machines | List machines |
fly__get_machine | Read a machine |
fly__list_machine_events | List machine events |
fly__list_machine_processes | List machine processes |
fly__wait_machine | Wait for a machine state |
fly__create_machine | Create a machine |
fly__update_machine | Replace a machine configuration |
fly__deploy_image | Change the image of a machine |
fly__scale_machine | Resize a machine |
fly__start_machine | Start a machine |
fly__stop_machine | Stop a machine |
fly__restart_machine | Restart a machine |
fly__suspend_machine | Suspend a machine |
fly__cordon_machine | Route traffic away from a machine |
fly__uncordon_machine | Route traffic back to a machine |
fly__destroy_machine | Destroy a machine |
fly__exec_machine | Run a command inside a machine |
fly__list_volumes | List volumes |
fly__get_volume | Read a volume |
fly__list_snapshots | List volume snapshots |
fly__create_volume | Create a volume |
fly__extend_volume | Extend a volume |
fly__update_volume | Change automatic snapshots |
fly__create_snapshot | Take a volume snapshot |
fly__destroy_volume | Destroy a volume |
fly__list_secrets | List secret names |
fly__set_secrets | Set app secrets |
fly__unset_secret | Remove an app secret |
fly__list_ips | List IP addresses |
fly__allocate_ip | Allocate an IP address |
fly__release_ip | Release an IP address |
fly__list_certificates | List certificates |
fly__get_certificate | Read a certificate |
fly__request_certificate | Request a certificate |
fly__check_certificate | Check a certificate |
fly__remove_certificate | Remove a certificate |
fly__get_logs | Read app logs |
Health
Health: not enough reports yet. A plugin version is deemed validated by the community with at least 200 reports and 90 % of them successful, over the last 90 days, as reported by the instances whose operators turned community telemetry on. It is a community signal, not a security guarantee.