Skip to content

feat(permissions): add the sandbox permission sets - #395

Open
ItamarZand88 wants to merge 1 commit into
itamar/alien-75-sandbox-2-agentfrom
itamar/alien-75-sandbox-3-permissions
Open

feat(permissions): add the sandbox permission sets#395
ItamarZand88 wants to merge 1 commit into
itamar/alien-75-sandbox-2-agentfrom
itamar/alien-75-sandbox-3-permissions

Conversation

@ItamarZand88

Copy link
Copy Markdown
Contributor

Summary

Adds the four cloud permission sets a sandbox needs — provision, management, execute and heartbeat — so a deployment can build a sandbox image, start and stop sessions, and run code in one, each with only the access that job requires.

The sets divide along one line: reaching inside a live session is separate from managing sessions.

  1. provision builds and tears down the image a session launches from, and tags it — that tag is the boundary everything else scopes against.
  2. management starts, stops and lists sessions. It can end a session it cannot read.
  3. execute mints the credential that reaches inside a session, and is the only set that does. This is the line the whole split exists to draw.
  4. heartbeat counts sessions and reads image metadata, and nothing else.

A resource link hands a workload execute, so anything a workload should not have has to live outside it.

What I did

Each cloud authorizes these operations differently, and the sets follow the platform rather than a house shape:

  • AWS authorizes every MicroVM operation against the image, not the running MicroVM — there is no resource type for a running one. So RunMicrovm, TerminateMicrovm, SuspendMicrovm, ResumeMicrovm, GetMicrovm and the auth-token mint are all scoped to this sandbox's own image ARNs. Three actions (CreateMicrovmImage, ListMicrovmImages, ListMicrovms) are authorized against no resource type at all; creation is bounded by boundary tags in the request instead, and the two list actions are name-only reads.
  • Azure exposes session lifecycle and session contents as separate data actions, so management takes the lifecycle four and execute takes the role that carries the data plane.
  • GCP has no entry, and needs none: a GCP sandbox is a subprocess of the workload's own instance, so it creates no cloud resource.

Files touched

  • crates/alien-permissions/permission-sets/sandbox/*.jsonc — the four sets.
  • crates/alien-permissions/src/generators/azure_runtime.rs — one role-id mapping.
  • crates/alien-permissions/tests/* — the invariant and coverage tests below.

How I tested

  • Checked every action in the four sets against the pinned AWS IAM dataset and the Azure provider-operations dataset the repository already validates against, confirming each action's required resource type matches what the set binds it to. This is what a scoped role will actually enforce, and it is not something a deployment test would surface — broad credentials never refuse.
  • Extended the sensitive-content invariant to name the Azure actions that reach inside a session, then confirmed by mutation that putting one of them into management fails the test. It passed before the change, which is why the test was extended.
  • Confirmed by mutation that the tag condition on image creation is load-bearing: removing it fails the wildcard-resource test.
  • Confirmed by mutation that an unscoped MicroVM ARN now fails the scoping test. Two exemptions previously described these actions as impossible to scope; both were removed, and the statements they covered are checked again.
  • cargo test -p alien-permissions — 134 tests.

Security review of this diff, since these grants are what a customer's cloud enforces:

  • A management, provision or heartbeat holder reaching session contents — refused by construction and pinned by test on both clouds; the auth-token mint and the Azure data-plane role appear in execute alone.
  • A workload reaching another stack's sandbox — every MicroVM statement is scoped to image ARNs carrying this stack's prefix, and image creation carries the stack, resource and managed-by tags in the request.
  • A workload reaching another sandbox in its own stack — the resource binding narrows further, to the sandbox's own name.
  • An interactive shell into a session — CreateMicrovmShellAuthToken is granted nowhere, and is named in the test constants so adding it has to be deliberate.
  • Wildcard resources — the three that carry one are the actions AWS authorizes with no resource type; creation is tag-conditioned and the other two are reads.

Nothing turned up.

@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds least-privilege sandbox permission sets for provisioning, lifecycle management, execution, and heartbeat operations across AWS and Azure.

  • Separates session-content access from lifecycle and parent-resource management.
  • Narrows Azure runtime grants to individual sandbox groups while retaining setup-time provisioning at resource-group scope.
  • Removes account-wide AWS session enumeration and adds permission-boundary regression tests.
  • Updates Azure permission generation to support permission entries that intentionally decline a binding target.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
crates/alien-permissions/permission-sets/sandbox/provision.jsonc Adds setup-tier AWS image and Azure sandbox-group provisioning permissions while excluding role-assignment authority.
crates/alien-permissions/permission-sets/sandbox/execute.jsonc Restricts session-content credentials to the explicit execute set and scopes Azure access to one sandbox group.
crates/alien-permissions/permission-sets/sandbox/management.jsonc Adds image-scoped AWS and resource-scoped Azure session lifecycle permissions without session-content access.
crates/alien-permissions/permission-sets/sandbox/heartbeat.jsonc Adds parent metadata reads while excluding account-wide AWS session enumeration and Azure stack scope.
crates/alien-permissions/src/generators/azure_runtime.rs Allows individual Azure permission entries to decline a target while preserving an error when the entire set does not support that target.
crates/alien-infra/src/remote_stack_management/azure.rs Skips permission sets that deliberately provide no Azure stack binding during management-role generation.
crates/alien-terraform/src/emitters/azure/helpers.rs Aligns Terraform stack-role emission with the Azure runtime generator's binding-target behavior.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Setup["Setup identity"] --> Provision["sandbox/provision"]
  Runtime["Runtime management identity"] --> Management["sandbox/management"]
  Workload["Resource-linked workload"] --> Execute["sandbox/execute"]
  HeartbeatIdentity["Heartbeat identity"] --> Heartbeat["sandbox/heartbeat"]
  Provision --> Parent["Sandbox image or group"]
  Management --> Sessions["Session lifecycle"]
  Execute --> Contents["Session commands and files"]
  Heartbeat --> Metadata["Parent metadata"]
Loading

Reviews (33): Last reviewed commit: "feat(permissions): add the sandbox permi..." | Re-trigger Greptile

Comment thread crates/alien-permissions/permission-sets/sandbox/provision.jsonc
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from b03c4c7 to 454d8f0 Compare August 11, 2026 09:10
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 454d8f0 to e7e0597 Compare August 11, 2026 12:11
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from e7e0597 to 53618cb Compare August 11, 2026 13:19
Comment thread crates/alien-permissions/permission-sets/sandbox/execute.jsonc Outdated
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 53618cb to 20a0772 Compare August 11, 2026 13:51
Comment thread crates/alien-permissions/permission-sets/sandbox/management.jsonc Outdated
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 20a0772 to 1170ea7 Compare August 11, 2026 16:53
Comment thread crates/alien-permissions/permission-sets/sandbox/provision.jsonc
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 1170ea7 to b84c357 Compare August 11, 2026 17:11
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from b84c357 to c129036 Compare August 11, 2026 17:28
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from c129036 to 64d14df Compare August 11, 2026 18:40
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 64d14df to e7785d8 Compare August 11, 2026 18:49
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from e7785d8 to 49bfe79 Compare August 11, 2026 19:16
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 49bfe79 to 3561d35 Compare August 11, 2026 19:24
Comment thread crates/alien-permissions/permission-sets/sandbox/heartbeat.jsonc Outdated
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 3561d35 to cf18963 Compare August 11, 2026 19:49
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 3f47f93 to 7801481 Compare August 11, 2026 22:16
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 7801481 to 47b76f5 Compare August 11, 2026 22:24
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 47b76f5 to 3af5cf7 Compare August 12, 2026 06:32
Comment thread crates/alien-permissions/permission-sets/sandbox/heartbeat.jsonc Outdated
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 3af5cf7 to 4a18a68 Compare August 12, 2026 06:55
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 4a18a68 to d9496dc Compare August 12, 2026 07:05
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from d9496dc to c812f47 Compare August 12, 2026 07:22
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from c812f47 to b180b21 Compare August 12, 2026 07:49
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from b180b21 to 1fe705b Compare August 12, 2026 08:11
Comment thread crates/alien-permissions/permission-sets/sandbox/management.jsonc Outdated
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 1fe705b to c694998 Compare August 12, 2026 08:15
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch 2 times, most recently from 8706810 to 5a9e2fb Compare August 12, 2026 11:01
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 5a9e2fb to b60343f Compare August 12, 2026 11:18
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from b60343f to 8b3326c Compare August 12, 2026 12:14
@ItamarZand88
ItamarZand88 force-pushed the itamar/alien-75-sandbox-3-permissions branch from 8b3326c to c494a33 Compare August 12, 2026 13:25
@ItamarZand88

Copy link
Copy Markdown
Contributor Author

The sandbox/provision Azure grant is a setup-tier permission, not a persistent runtime capability, so there is no durable principal that can reach a sibling sandbox group with it.

  • A sandbox is Frozen under every valid configuration: frozen_with_runtime_cleanup() sets allow_live = false (crates/alien-core/src/ownership.rs:114), and a Live sandbox is rejected at compile time (crates/alien-preflights/src/compile_time/frozen_resource_lifecycle.rs:29-37).
  • <type>/provision enters the runtime management profile only on the Live arm (crates/alien-preflights/src/mutations/management_permission_profile.rs:144-148); a Frozen resource contributes <type>/management instead (:149-151). So sandbox/provision can never reach the runtime profile.
  • It is collected only into the one-time initial-setup tier (crates/alien-permissions/src/initial_setup.rs:26-47) — the deployer/setup identity.
  • The shared Azure runtime identity is built from the management profile, and sandbox/management's Azure binding is resource-scoped only: it declines stack scope (crates/alien-infra/src/remote_stack_management/azure.rs:1281-1290) and the per-resource path filters /provision out anyway (crates/alien-infra/src/core/azure_permissions_helper.rs:906). No path places sandboxGroups/write or /delete on a runtime identity.
  • Runtime teardown uses sandbox/management's resource-scoped session dataActions; the group-level delete is never needed by a runtime principal.

The RG-scope write/delete therefore belongs to the setup identity, which already applies the entire stack — resource group, storage account, container-apps environment, service account — into that same resource group; sandboxGroups/write is not a new capability there. It also can't be narrowed below the resource group in Azure RBAC (there is no scope between a group and its RG, and conditions don't reach control-plane writes — documented at provision.jsonc:98-114). The only thing that would remove shared-RG exposure is a per-sandbox resource group, which isn't warranted for a one-time setup identity.

@greptile-apps please re-review.

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