aws/internal/providers/imds
IMDSv2 (Instance Metadata Service version 2) flow.
- PUT
<endpoint>/latest/api/tokenwith anX-aws-ec2-metadata-token- ttl-secondsheader → session token in body. - GET
<endpoint>/latest/meta-data/iam/security-credentials/with the token inX-aws-ec2-metadata-token→ role name in body. - GET
<endpoint>/latest/meta-data/iam/security-credentials/<role>with the same token → JSON body withAccessKeyId,SecretAccessKey,Token,Expiration.
The PUT in step 1 is what makes this “v2”: it requires a session token that an SSRF attacker bouncing requests off the instance can’t easily obtain. v1 is intentionally not implemented.
Errors are classified so the chain can do the right thing:
- Step 1 fails (DNS, connect, non-200) →
NotOnInstanceso the chain falls through to the next provider quietly. - Anything after step 1 succeeds-then-fails →
Failedso the user sees a loud “you’re on EC2 but IMDS is misbehaving” signal.
Types
pub type Error {
NotOnInstance(reason: String)
Failed(reason: String)
}
Constructors
-
NotOnInstance(reason: String)Step 1 failed (connect refused, 401, 404, timeout). The standard signal that we’re not running on EC2 / Lambda. Chain should keep going.
-
Failed(reason: String)Anything past step 1 — the instance answered the token PUT but the downstream calls failed. Worth surfacing to the user.
Decoded credentials, kept as a flat record so this module doesn’t depend
on aws/credentials. The caller wraps these into the canonical
credentials.Credentials value.
pub type ImdsCredentials {
ImdsCredentials(
access_key_id: String,
secret_access_key: String,
session_token: String,
expires_at: Int,
)
}
Constructors
-
ImdsCredentials( access_key_id: String, secret_access_key: String, session_token: String, expires_at: Int, )
Values
pub fn default_options() -> Options
pub fn fetch(
send: fn(request.Request(BitArray)) -> Result(
response.Response(BitArray),
http_send.HttpError,
),
options: Options,
) -> Result(ImdsCredentials, Error)
Run the full IMDSv2 flow. Returns decoded credentials or a categorised
error. The send callback is the only side-effect surface — tests pass
a stub here.