Does BYOC Work With IMDSv2 Required?

Yes. Require IMDSv2 is a documented per-runner setting on AWS BYOC custom runners, so GitHub Actions jobs read instance credentials only with a session token.

Answer

Yes. The AWS BYOC configuration guide documents Require IMDSv2 as a setting on the custom runner: both IMDS v1 and v2 answer by default, and you switch a runner to the session-token version from the Update Runner page under Runner Specs, with the same field available when you first create the runner (AWS BYOC configuration).

The security hardening guide lists the same toggle as hardening step 6 and ends its checklist with the line "IMDSv2 required on all runners". The setting lands on the runner class rather than on the stack, so one stack can carry a hardened runner and an unmodified one while you work through the rollout. Nothing in the workflow changes: the runs-on label stays the same, and the EC2 instance WarpBuild launches for the job comes up with the metadata service configured the way that runner class specifies.

Detail

Where the setting lives

ItemValue
Default on a new custom runnerBoth IMDS v1 and v2 answer
Where the field livesCustom runner configuration, Runner Specs section, "Require IMDSv2"
When you can set itAt runner creation, and later on the Update Runner page
ScopeOne runner class, so classes in the same stack decide independently
What it applies toThe EC2 instances launched in your AWS account for jobs on that class

Rows come from the AWS BYOC configuration guide, checked on 2026-08-13. Because each job runs on a freshly provisioned instance that is terminated when the job finishes, the change takes effect on the next job queued to that class rather than needing a fleet restart (security hardening guide).

Why the session-token version matters

Version 1 answers a plain GET to the link-local address. Version 2 makes the caller open a session first: a PUT to /latest/api/token returns a token, and every later GET carries that token in a header. AWS also has the endpoint reject requests carrying X-Forwarded-For and applies a hop limit to the response (AWS instance metadata service configuration).

Those three properties close the request-forgery path. A service on the instance that can be tricked into fetching an attacker-supplied URL will happily fetch the credentials path under version 1 and hand back the body. Under version 2 the same trick fails, because the forged request is a GET with no session token and no way to add the header. The WarpBuild security guide states the defense in exactly those terms: require IMDSv2 to protect against attacks that attempt to steal instance credentials (security hardening guide).

The value of the setting scales with what the runner can reach. A runner class with no instance profile has no role credentials at the endpoint to steal. A class carrying an ECR push profile or a deploy profile does, and that is the class to harden first (instance profile setup).

Check your build tools before you enforce it fleet wide

Enforcement is a one-click change with a blast radius equal to every tool on the machine that reads metadata. Work through the consumers first.

Metadata consumerWhat to checkTypical outcome
AWS CLI and AWS SDKs in the runner imageVersion currency; current releases request a token before reading credentialsWorks unchanged
Shell steps calling 169.254.169.254 directlyWhether the curl command sends a token headerFails until the PUT is added
Agents baked into a custom AMIWhether the vendor build supports the session-token versionVendor-dependent, so test it
Steps reading metadata from inside a containerWhether the extra network hop still reaches the endpoint under the documented hop limitTest before enforcing

A probe job settles the question in one run. Point it at the class you just changed:

.github/workflows/imds-probe.yml
name: imds-probe
on: workflow_dispatch

jobs:
  probe:
    runs-on: warp-custom-build-use1-8x
    steps:
      - name: Read credentials with a session token
        run: |
          TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" \
            -H "X-aws-ec2-metadata-token-ttl-seconds: 300")
          curl -sf -H "X-aws-ec2-metadata-token: $TOKEN" \
            http://169.254.169.254/latest/meta-data/iam/security-credentials/

      - name: Fail if a tokenless read still works
        run: |
          if curl -sf --max-time 2 http://169.254.169.254/latest/meta-data/ > /dev/null; then
            echo "the metadata service still answers without a token" >&2
            exit 1
          fi

      - name: Run the real build steps
        run: make build

The first step proves the credential path your jobs depend on still resolves. The second proves the old path is closed. The third catches the tools you forgot about, which is the failure everyone actually hits.

Before the switch, AWS publishes a per-instance CloudWatch metric that counts metadata calls made without a token, which is the way to find version 1 callers while they are still succeeding (AWS instance metadata service configuration). A workable order is: enable on one low-traffic runner class, run the probe, leave it for a day of real jobs, then move through the remaining classes and tick the checklist line on the security checklist for BYOC on AWS. The longer setup walkthrough lives on requiring IMDSv2 on BYOC runners, and the endpoint itself is defined on instance metadata service.

What the hardening costs

Nothing on top of the runner rate. BYOC Linux runners and BYOC Windows runners both bill $0.002 per runner minute in WarpBuild fees, and AWS bills your own account for the EC2 capacity those jobs consume (pricing page, checked on 2026-08-13).

BYOC runs on AWS, GCP, and Azure, so read this setting as the AWS-specific one in a wider set of metadata endpoints.

Does requiring IMDSv2 break jobs that use an instance profile?

No, as long as the tools reading credentials request a session token first. Current AWS SDKs and the AWS CLI do that automatically, so a job that assumes its role through the instance profile keeps working (instance profile setup). What breaks is a script that curls http://169.254.169.254 with no token header, or an agent baked into a custom image that still speaks the single-request version. The probe job above finds both in one run.

Can I require it on some runners and not others?

Yes. Require IMDSv2 sits on the custom runner configuration under Runner Specs, so each runner class in a stack decides independently (AWS BYOC configuration). Enable it on one low-traffic class, run a probe job, then work through the rest of the fleet. The class-by-class walkthrough is on requiring IMDSv2 on BYOC runners.

What about GCP and Azure BYOC runners?

BYOC runs on AWS, GCP, and Azure. The Require IMDSv2 toggle documented by WarpBuild is the AWS one, and GCP and Azure expose their own metadata endpoints with their own required request headers, so the compatibility check has to be run per cloud. The shared concept behind all three is covered on instance metadata service, and the AWS stack layout is on the AWS BYOC page.

Start with $10 in free credits

Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.