GitHub Actions runners are in private preview. Contact support to request access.
type=sandbox). It explains where a job’s AWS credentials come from, what can and can’t reach them, and how to get credentials into Docker containers safely.
How sandbox jobs get AWS credentials
Each job runs in its own Firecracker microVM. For each job, Ravion creates an IAM role in your execution environment’s AWS account. The role’s name starts withrvn-ci-, and its path is /rvn-ci/.
The sandbox host assumes that role with AWS STS and serves the credentials inside the microVM at the standard instance metadata endpoint, 169.254.169.254. The paths match EC2’s instance metadata service (IMDS). Each STS session lasts 15 minutes, and Ravion refreshes it automatically for as long as the job runs.
The AWS CLI and AWS SDKs running directly on the runner find these credentials with no setup:
- IMDSv2 only. Requests must first get a session token with
PUT /latest/api/token. IMDSv1 requests, which send no token, get401 Unauthorized. Current AWS CLI and SDK versions use IMDSv2 automatically. - No region. The endpoint doesn’t serve the instance’s placement or region. Set
AWS_REGIONandAWS_DEFAULT_REGIONyourself, as in the example above. - No policies by default. The job role has no IAM policies attached by default. Calls such as
aws sts get-caller-identitywork, but calls that need permissions returnAccessDenied. For jobs that need AWS access, use GitHub OIDC.
Docker containers can’t reach the endpoint
Docker containers in the job can’t reach169.254.169.254. That includes:
services:containers;container:jobs;docker runwith the default network;docker composestacks;- any other Docker bridge network.
docker run --network host share the microVM’s network, so they do reach the endpoint.
AWS SDKs inside containers probe the endpoint when they look for credentials, and wait for that probe to time out. For example, the AWS SDK for Ruby probes synchronously, with timeouts of about 1 second to open the connection and 1 second to read it. That can make an application slow to start, or make its first AWS call hang.
Get credentials into containers
Stop SDKs from probing the endpoint
In every container that can’t reach the endpoint, setAWS_EC2_METADATA_DISABLED=true. SDKs then skip the metadata endpoint instead of waiting for it to time out. Use this together with one of the options below to give the container credentials.
Run services with Docker Compose
services: containers start before any step runs, so a step can’t hand them credentials. Instead, start the containers with docker compose in a step, and pass the job’s credentials in an env file:
compose.yaml
docker compose config or print the env file, because both show the values.
Write the file under $RUNNER_TEMP and remove it when the job ends, as above, so it isn’t kept in the job’s disk cache.
Use the host network for one-off containers
Adocker run container on the host network reaches the endpoint directly, and SDKs inside it refresh credentials as usual. This example passes AWS_REGION from the job’s env:
Use GitHub OIDC
For roles that depend on the branch, environment or repository, use GitHub’s OpenID Connect provider withaws-actions/configure-aws-credentials. This works on Ravion runners the same way as on GitHub-hosted runners, and lets you attach exactly the policies the job needs.
-e AWS_ACCESS_KEY_ID), or write them to an env file for docker compose as in Run services with Docker Compose. In a container: job, steps already run inside the container, so the action’s credentials reach later steps there directly.
Keep keys out of the job log
Values you write intoservices.*.env, container.env or a docker run -e NAME=value argument can show up in the job log. Masking only covers values GitHub knows are secret.
-
Pass credentials with env files, or with
-e NAMEwithout a value. -
Reference credentials stored as GitHub secrets with
${{ secrets.NAME }}. GitHub masks them. -
Mask any other value before anything can print it:
Compared with other runners
If you’re moving from RunsOn, workflows whose
services: or container: code relied on the instance role need one of the options above. AWS calls made directly in steps find the job role instead of the instance role. The job role has no policies by default, so give those steps the permissions they need with GitHub OIDC.
Next steps
Runners
Labels, sizing and requirements.
Sandboxes
What runs inside a sandbox.