View Source ReqIMDSv2 (req_imdsv2 v0.1.2)
Provides a way to automatically authenticate Req requests with the Instance Metadata Service on an Amazon AWS EC2 instance.
It does this by making a request to IMDSv2 to get a token before the main request, then attaches that token to the request.
The EC2 docs specify that it's perfectly fine to request a new token for each request, but if you're making a
lot in a row, it's possible to extract the token from the response and reuse it for subsequent requests. See
get_metadata_token/1
for more info.
Examples
{:ok, response} =
Req.new(url: "http://169.254.169.254/latest/meta-data/instance-id")
|> ReqIMDSv2.attach()
|> Req.get()
{:ok, %Req.Response{body: "i-1234567890abcdef0", ...}
If you use a different host for IMDS data, such as for tests, the token will be fetched from that same URL:
iex> req = Req.new(url: "http://localhost:4000/latest/meta-data/instance-id")
iex> req = ReqIMDSv2.attach(req)
iex> {:ok, resp} = Req.get(req)
# ReqIMDSv2 will make a request to http://localhost:4000/latest/api/token to get the token.
iex> resp.body
"i-1234567890abcdef0"
You can extract the token from the response and reuse it for subsequent requests:
iex> req = Req.new(url: "http://169.254.169.254/latest/meta-data/instance-id")
iex> req = ReqIMDSv2.attach(req)
iex> {:ok, resp} = Req.get(req)
iex> token = ReqIMDSv2.get_metadata_token(resp)
iex> req = Req.new(url: "http://169.254.169.254/latest/meta-data/hostname")
...> |> ReqIMDSv2.attach(metadata_token: token)
iex> Req.get!(req).body
"ip-10-0-1-1.us-west-1.compute.internal"
See attach/2
for options.
Summary
Functions
Attaches the IMDSv2 authentication steps to the request.
Extracts the metadata token from a response.
Functions
@spec attach(Req.Request.t(), Keyword.t()) :: Req.Request.t()
Attaches the IMDSv2 authentication steps to the request.
Once attached to a Req.Request, an extra request to get a IMDSv2 token will be made just prior to the original request is made. The token will be attached to the request as a header, and also attached to the response so it can be extracted and reused for subsequent requests.
The request for the token will use the same scheme, host and port to connect to for the token as the original request.
Options
:metadata_token
- A token to use for authentication. If not provided, a new token will be fetched from the IMDSv2 service. Seeget_metadata_token/1
for more info on extracting a token from a response.:metadata_token_ttl_seconds
- The TTL for the token. Defaults to the max allowed of 21600 (6 hours).:fallback_to_imdsv1
- If true, will fall back to IMDSv1 if IMDSv2 is not available, otherwise the request will return an error. Defaults to false.
@spec get_metadata_token(Req.Response.t()) :: String.t() | nil
Extracts the metadata token from a response.
This can be used to reuse the token for subsequent requests. Returns nil
if the token is not present, such as if
the token request failed and the request fell back to IMDSv1.
Example
req =
Req.new(url: "http://169.254.169.254/latest/meta-data/instance-id")
|> ReqIMDSv2.attach(req)
{:ok, resp} = Req.get(req)
token = ReqIMDSv2.get_metadata_token(resp)