fix(sandbox): make a remote-bound sandbox reachable, healthy and diagnosable - #509
Open
ItamarZand88 wants to merge 6 commits into
Open
fix(sandbox): make a remote-bound sandbox reachable, healthy and diagnosable#509ItamarZand88 wants to merge 6 commits into
ItamarZand88 wants to merge 6 commits into
Conversation
Remote Bindings resolved every handle against the storage capability, so a customer running only a sandbox was never found. Resolve per binding instead. The remote grant withheld lambda:PassNetworkConnector on the premise that AWS authorizes it against no resource. AWS authorizes it against the connector ARN and attaches its own connectors to an open-egress session, so the only sandbox shape remote access permits could not start. Grant it, scoped to AWS-managed connectors, which a customer-declared one can never match. The CloudFormation emitter dropped every <type>/* management set when a resource had a remote binding, taking <type>/heartbeat with it. That reaches further than sandboxes: storage and ai are remote-binding types too, so every bring-your-own-bucket and BYO-AI deployment lost the grant its management identity reports with. Exclude only the binding's own set, and for a sandbox also whatever reaches a session. Sandbox errors discarded the cloud's refusal, and the CLI trusted tracked deployments the platform had already deleted.
The management filter dropped session-reaching sets whenever the stack held any remote binding, so a stack pairing remote-bound storage with an ordinary frozen sandbox lost that sandbox's session cleanup. Gate on the binding's own kind. Also corrects the recorded reason the two wildcard connector grants stay unbounded: a connector's ARN ends in an AWS-assigned id rather than the name the template sets, so a prefix scope would deny a real one.
Terraform's ManagementRole emitter applied no remote-binding filter, so for a stack CloudFormation now filters it still compiled sandbox/management into the cross-account role. Both call remote_binding_claims_management_set, so the two cannot drift again, and each generator test pins its own side. The Terraform twin of the remote-grant test still asserted PassNetworkConnector stays out; it carried the same disproved premise the CloudFormation one did.
Storage and AI are remote-binding types too, so the prefix match stripped `<type>/heartbeat` from every bring-your-own-bucket and BYO-AI deployment's management identity, not only from sandboxes. Fails against the prefix filter.
Greptile SummaryThe PR makes customer-owned sandbox bindings resolve by capability, restores required heartbeat and AWS connector permissions, preserves bounded internal cloud diagnostics, and improves stale deployment tracking.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| crates/alien-bindings/src/remote.rs | Introduces lazy per-capability environment discovery while retaining a single provider for deployment-scoped handles. |
| crates/alien-bindings/src/providers/sandbox/refusal.rs | Extracts bounded provider refusal details while preserving internal-error visibility and external sanitization. |
| crates/alien-core/src/remote_bindings.rs | Centralizes the predicate used to exclude remote-owned and session-reaching permission sets from management identities. |
| crates/alien-permissions/permission-sets/sandbox/remote-execute.jsonc | Grants remote sandbox execution access to AWS-managed network connectors through an account-pinned ARN scope. |
| crates/alien-cli/src/deployment_tracking.rs | Validates tracked deployment credentials, removes stale records, and supports explicit untracking through a testable storage abstraction. |
| crates/alien-cloudformation/src/emitters/aws/remote_stack_management.rs | Applies the shared remote-binding permission filter while retaining heartbeat access. |
| crates/alien-terraform/src/emitters/aws/remote_stack_management.rs | Mirrors CloudFormation management filtering through the same shared predicate. |
Sequence Diagram
sequenceDiagram
participant App
participant Bindings as Remote Bindings
participant Platform
participant Manager
participant AWS
App->>Bindings: sandbox(name)
Bindings->>Platform: Resolve customer + sandbox capability
Platform-->>Bindings: Deployment-scoped manager access
Bindings->>Manager: Resolve sandbox binding
Manager-->>Bindings: Sandbox configuration and credentials
Bindings->>AWS: RunMicrovm with managed connector
alt Session starts
AWS-->>Bindings: MicroVM endpoint
Bindings-->>App: Healthy sandbox session
else Cloud refuses request
AWS-->>Bindings: Bounded refusal detail
Bindings-->>App: Sanitized external error
end
Reviews (2): Last reviewed commit: "test(sandbox): assert refusal shape with..." | Re-trigger Greptile
A reason carries a cloud's own sentence, role ARNs included, and this repository's CI logs are public. Name the expectation in the assertion message and leave the value to the condition.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A sandbox running in a customer's own cloud account could never be found, could never
start, and said nothing useful when it failed. This fixes all three, plus a management
filter that was stripping the heartbeat grant from every remote-bound resource type.
Step-by-step flow when an app calls
bindings.sandbox()against a customer-owned deployment:capability, rather than resolving every handle against storage.
lambda:RunMicrovmandlambda:PassNetworkConnectorfor the AWS-managed connectors an open-egress sessionattaches. ← the fix lives here
the error instead of a generic failure.
This PR changes a remote sandbox that could not be located or started into one that starts,
reports healthy, and says why when it doesn't.
What was broken
Remote Bindings resolved every handle against the storage capability, so a customer running
only a sandbox was never found. Even once found, the remote grant deliberately withheld
lambda:PassNetworkConnectoron the belief that AWS authorizes it against no resource — itauthorizes it against the connector ARN, and attaches its own connectors to an open-egress
session, so the one sandbox shape remote access permits could not start at all. Separately,
the setup emitter dropped every
<type>/*management set whenever a resource had a remotebinding, and
<type>/heartbeatwent with it.What I did
storage;
sandbox()resolves the sandbox binding.lambda:PassNetworkConnector, scoped to the AWS-managed connector ARN segment. Acustomer-declared connector can never match that scope, so the grant cannot be used to
attach a connector the customer defined.
sandbox specifically, whatever reaches a live session.
<type>/heartbeatsurvives, whichis what the management identity reports with. The blast radius here was wider than
sandboxes:
storageandaiare remote-binding types too.so the two cannot drift again, with a generator test pinning each side.
when the whole error chain is internal — a public wrapper never quotes an internal layer.
deployments untrackfor the case where it hasn't.Files touched
crates/alien-bindings/src/remote.rs,remote/access.rs— per-capability resolution; thesandbox capability now maps to its wire variant instead of erroring.
crates/alien-bindings/src/providers/sandbox/refusal.rs(new) — lifts the service messageout of a captured refusal body.
crates/alien-permissions/permission-sets/sandbox/remote-execute.jsonc— thePassNetworkConnectorgrant, scoped to AWS-managed connectors.crates/alien-core/src/remote_bindings.rs— the shared management-filter predicate.crates/alien-cloudformation/…/remote_stack_management.rs,crates/alien-terraform/…/remote_stack_management.rs— both call it.crates/alien-cli/src/deployment_tracking.rs,commands/deployments.rs,commands/deploy.rs,commands/onboard.rs— stale-entry detection,untrack,--setup-item.client-sdks/platform/*.json— regenerated; the CLI could not deserialize a sandboxdeployment against the committed spec.
How I tested
CloudFormation template, with no hand-added IAM. Started a MicroVM through
bindings.sandbox()and ran a 14-check suite over the sandbox surface — exec with exitcodes and stderr, file read/write, working directory, environment, port exposure, session
timeout, teardown. 14/14 passed on the template's grants alone. Before the
PassNetworkConnectorgrant the same run failed at session start; before the resolutionfix it never got as far as a deployment.
aws_remote_sandbox_management_role_heartbeats_without_reaching_a_session(CloudFormation and Terraform),
aws_remote_storage_management_role_keeps_its_heartbeat(fails against the old prefix filter — this is the regression proof for the storage/AI
blast radius),
frozen_remote_sandbox_heartbeat_permission_is_added_to_management,a_refused_create_reports_what_aws_refused_it_withplus four refusal-formatting cases,and nine deployment-tracking tests against a fake platform.
observed on a live bring-your-own-bucket deployment. Azure and GCP sandbox paths are
untouched and unexercised here. An already-installed deployment picks up the new grant only
when its setup package is regenerated.
I also ran a security review on the diff. What it checked:
PassNetworkConnectorgrant attach a connector the customer declared? No — theARN scope pins the account segment to the literal
aws, and a customer connector's ARNcarries the customer account id (
sandbox/remote-execute.jsonc).No — asserted directly in
frozen_remote_sandbox_heartbeat_permission_is_added_to_management.only when the wrapper carrying it is itself internal, and the text is length-bounded
(
refusal.rs, withan_internal_layer_is_not_quoted_into_a_public_wrappercovering it).the external id and token are unchanged per lookup; only which deployment answers changes.
Nothing turned up.