Skip to content

fix(sandbox): delete an AWS MicroVM image without sweeping its versions - #714

Merged
ItamarZand88 merged 4 commits into
mainfrom
itamar/alien-957-sandbox-teardown-fails-on-aws-the-version-sweep-cannot
Sep 25, 2026
Merged

ItamarZand88 merged 4 commits into
mainfrom
itamar/alien-957-sandbox-teardown-fails-on-aws-the-version-sweep-cannot

Conversation

@ItamarZand88

Copy link
Copy Markdown
Contributor

Summary

Tearing down an AWS sandbox failed whenever its image had only ever been built once. Teardown now deletes the image directly instead of sweeping its versions first.

Step-by-step flow when a sandbox is deleted:

  1. Teardown deleted every image version, then the image.
  2. AWS refuses to delete an image's last version ("This is the last version. Please delete the entire image"), so a sandbox that was never rolled could not be torn down. ← the bug
  3. It now deletes the image, which removes all of its versions.

This PR changes sandbox teardown from "sweep versions, then delete the image" to "delete the image".

What was broken

Every AWS sandbox that built once and was never rolled failed to delete. The deletion used up its retries, and the customer's stack could not be removed.

What I did

  • Removed the version sweep. The sweep assumed deleting an image leaves its versions behind; against the live API, deleting an image with two versions left neither.
  • Left the retired-version reaper alone. It removes versions a roll replaced while the image keeps serving, which is a different job.

Files touched

  • crates/alien-infra/src/sandbox/aws.rs: teardown without the sweep, and its tests.

How I tested

  • Manually: in us-west-2, deleted an image with two versions: no versions remained. A full alien-deploy destroy then removed four sandbox images, one of which had two versions, and left nothing behind.
  • Unit tests: the delete tests assert one image delete and no version deletes. The alien-infra lib suite passes.
  • Anything I couldn't test: none.

@greptile-apps

greptile-apps Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[High risk] Changes how sandbox images are deleted in AWS.

The PR appears safe to merge; no outstanding finding was identified.

Summary

The PR removes the AWS sandbox teardown’s per-version sweep so teardown deletes the MicroVM image directly.

  • Updates the client documentation to describe whole-image deletion.
  • Updates teardown tests to reject version-deletion calls.

Reviews (5) · Last reviewed commit: "docs(aws-clients): say what the image-de..."

Comment thread crates/alien-infra/src/sandbox/aws.rs
@ItamarZand88

Copy link
Copy Markdown
Contributor Author

@greptile review

@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-957-sandbox-teardown-fails-on-aws-the-version-sweep-cannot branch from 077f5ea to 6f0f6e6 Compare September 24, 2026 18:17
@ItamarZand88

Copy link
Copy Markdown
Contributor Author

@greptile review

@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-955-a-live-aws-sandbox-that-fails-during-create-is-unrecoverable branch from d85f984 to 9147a84 Compare September 25, 2026 07:49
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-957-sandbox-teardown-fails-on-aws-the-version-sweep-cannot branch from efb28c4 to 9dc0f01 Compare September 25, 2026 08:03
@ItamarZand88

Copy link
Copy Markdown
Contributor Author

@greptile review

Base automatically changed from itamar/alien-955-a-live-aws-sandbox-that-fails-during-create-is-unrecoverable to main September 25, 2026 08:36
Teardown deleted every version and then the image. AWS refuses to delete an
image's last version — "This is the last version. Please delete the entire
image" — so every sandbox that built once and was never rolled failed to tear
down, burned its retry budget, and left the customer's stack undeletable.

The sweep was there because the image delete was believed to remove nothing
while versions remained. It does remove them: against the live API, deleting an
image carrying two versions left neither behind. So the sweep goes rather than
being taught which version to skip.

The retired-version reaper is untouched. It deletes versions a roll replaced
while the image keeps serving, which is not what teardown does.
…re it is described

Two comments still claimed the image delete removes nothing while versions
remain, which is what the removed sweep was built on. The CloudControl probe
keeps its claim, scoped to CloudControl.
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-957-sandbox-teardown-fails-on-aws-the-version-sweep-cannot branch from 9dc0f01 to 1fe202a Compare September 25, 2026 08:39
@ItamarZand88

Copy link
Copy Markdown
Contributor Author

@greptile review

@ItamarZand88
ItamarZand88 merged commit 67afba2 into main Sep 25, 2026
22 checks passed
@ItamarZand88
ItamarZand88 deleted the itamar/alien-957-sandbox-teardown-fails-on-aws-the-version-sweep-cannot branch September 25, 2026 09:22
ItamarZand88 added a commit that referenced this pull request Sep 25, 2026
## Summary

AWS sandboxes can now be deployed with `alien-deploy`, the direct path
with no Terraform or CloudFormation. Setup creates everything the
runtime identity is never allowed to create itself, and the runtime
builds only what it is granted.

Step-by-step flow when `alien-deploy deploy` sets up a stack with a
sandbox:

1. **Setup, using the deployer's credentials, creates the sandbox's
build role. For `egress: deny` it also creates an operator role, a
loopback-only security group and a network connector. It records each
object and passes them to the sandbox's controller.** ← the heart
2. A Frozen sandbox's image is built during setup and rolled once when
setup runs again with a new bundle. A Live sandbox's image is built
later by the runtime, which passes the setup-made role.
3. Destroy removes the images, then everything setup created, in
dependency order.

This PR changes AWS sandboxes from template-only to deployable directly,
with the same objects the templates create.

## What was broken

`alien-deploy` could not deploy an AWS sandbox. The build role, the deny
egress objects and the remote-access grant exist only in the Terraform
and CloudFormation setups. The runtime identity is deliberately never
given `iam:CreateRole`, so it cannot make them.

## What I did

- **Setup scaffolding.** A setup step creates the build role, and for
deny egress an operator role, a loopback-only security group and a
network connector (through Cloud Control). It also writes a published
sandbox's remote-access grant onto the Remote Bindings role. Each object
is tagged, recorded in the deployment's runtime metadata and verified
before it is adopted.
- **Frozen sandboxes on the direct path.** Setup builds the image. A
setup re-run with a new bundle re-grants the role and rolls the image
once. The runtime never builds or deletes a Frozen image.
- **Guards.** Two Deny statements on the management identity block it
from writing to setup's sandbox roles and to its own role. The drift
check lets an update add either guard, since a Deny only narrows the
identity, but not remove one. An earlier version must accept stacks
carrying them, and a separate PR (#718) adds that tolerance on main. It
has to land first.
- **Updates that need setup are refused.** A runtime update that would
change scaffolding (a new sandbox, a different egress, network or build
policy, or publishing and unpublishing) is refused with the reason,
until setup runs again.
- **Teardown.** It deletes the image, then the connector, the security
group (after the connector's network interfaces are released), the roles
and the grant. Anything already gone is skipped.
- **Destroy after a failed setup.** When setup fails before the
management identity exists, and nothing runtime cleanup acts on has come
up, the manager skips runtime cleanup. The destroy goes straight to
setup teardown. Before this, it ended in `delete-failed`, and the build
role stayed in the account.

## Files touched

- `crates/alien-infra/src/setup_scaffolding/`: the scaffolding step, AWS
sandbox roles and egress, seeding and teardown.
- `crates/alien-infra/src/sandbox/aws.rs`: Frozen build, roll and
ownership rules on the direct path.
- `crates/alien-deployment/src/`: runs the scaffolding in initial setup,
refuses updates that need setup, and tears scaffolding down.
- `crates/alien-core/src/`: the runtime-metadata record and the build
role naming.
- `crates/alien-permissions/permission-sets/`: the two management
guards.
- `crates/alien-preflights/src/`: the build role name budget and the
guard exemption.
- `crates/alien-aws-clients/src/`: the Cloud Control, EC2 and IAM calls
the scaffolding needs.
- CloudFormation and Terraform generator snapshots, updated for the
guards.

## How I tested

- **Manually (us-west-2):** did a direct deployment with the local
control plane, using a Live and a Frozen sandbox with open egress.
- Setup created both build roles and built the Frozen image under setup
tags.
- A remote-access session on the Live sandbox started in 2.4s and ran a
probe.
- Setup re-run with a new Frozen bundle rolled that image exactly once.
- Added Live and Frozen `deny` sandboxes. Setup created their operator
roles, loopback-only groups and ACTIVE connectors. Sessions started and
TCP out was blocked.
- `alien-deploy destroy` removed every object setup and the runtime
created. The account inventory matched its pre-run baseline.
- With a standalone manager, `alien deploy` failed in setup after
creating the build role. `alien destroy` then reached `deleted` and
removed the role.
- **Unit tests:** `alien-infra` 741, `alien-deployment` 141,
`alien-manager` 263, plus preflights and core. Tests use strict mocks
for every IAM, EC2, Cloud Control and MicroVM call, and the behavioural
fixes are mutation-tested.
- **Anything I couldn't test:**
- Deny sessions were started with admin credentials; the compute grant
comes from `sandbox/management` and was checked by configuration only.
- Under `egress: deny`, DNS still resolves, because the security group
doesn't cover the VPC resolver. That gap also exists in the template
setups and is tracked separately.

I also ran a security review on the diff. What it checked:
- **The runtime minting a role:** `sandbox/provision` grants
`iam:PassRole` on the setup-made role only and never `iam:CreateRole`.
The management guards deny writes to setup's sandbox roles and to the
management role (`aws_management_role_guards` snapshot).
- **Adopting a role someone else made:** a same-named role is adopted
only if it carries setup's tags and its trust, inline and attached
policies match exactly. Otherwise setup refuses (`aws_sandbox.rs`
adoption tests).
- **Leaving a remote grant behind:** unpublishing requires setup, and
setup revokes the grant even when the stack no longer declares the
Remote Bindings role.
- **A destroy that skips cleanup it owes:** the rule returns nothing
once a Live resource, a synced secrets vault or a Frozen type with
runtime cleanup has come up. It also returns nothing on any resource
without a lifecycle (`deleting.rs` tests).
- **Deny egress holes:** the group has no ingress and egress only to
`127.0.0.1/32`, and a tagged group that allows more is repaired or
refused (`aws_sandbox_egress.rs` tests).
Nothing turned up.

Depends on #700 (base), #715 (image tagging) and the #712 → #713 → #714
chain (image read, build inputs, teardown). This branch merges #714 and
#715 and will rebase once they land.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant