Skip to content

How to Block Agents From Reaching the Cloud Metadata Endpoint (169.254.169.254)

Block metadata endpoint AI agent access: layered IMDS lockdown, SSRF-safe egress rules, and proxy enforcement that survives redirects. Request beta access.

By Agent G Engineering7

To block metadata endpoint AI agent access, you need three enforcement points working together: an IMDSv2-only instance configuration with a hop limit of 1, a host or network rule dropping traffic to 169.254.169.254 and its IPv6 equivalents, and a default-deny egress proxy that resolves every hostname, rejects link-local destinations, and refuses to follow redirects into private address space.

Why the metadata service is the first thing an agent gets pointed at

Every autonomous agent that can fetch a URL is one prompt away from being a credential thief. The cloud instance metadata service (IMDS) sits at a fixed, unauthenticated, link-local address: 169.254.169.254 on AWS, Azure, and (via metadata.google.internal) GCP. A single plain HTTP GET returns instance identity, user data, and, on many configurations, short-lived IAM credentials for the role attached to the workload running the agent.

The dangerous part is not that the endpoint exists. It is that the agent has a legitimate, sanctioned tool called something like http_get or fetch_url, and the LLM decides at runtime what that tool points at. A poisoned web page, a malicious README in a cloned repo, or a compromised MCP tool response can supply the target. The agent has no concept of link-local address space. It just makes the call.

The output is worse than a normal SSRF. The agent will often summarize the JSON it receives back into a chat transcript, a pull request comment, or a webhook payload, which means stolen credentials leave the trust boundary in a channel your DLP tooling does not classify as a credential dump. For the broader pattern, see our walkthrough on SSRF in AI agents.

How to block metadata endpoint AI agent traffic in five steps

  1. Enforce IMDSv2 with a hop limit of 1. Require the session token flow (PUT /latest/api/token with X-aws-ec2-metadata-token-ttl-seconds) and set http-put-response-hop-limit to 1. This breaks the simple GET that most injected payloads attempt and prevents containers on a bridged network from reaching IMDS through an extra hop.
  2. Drop link-local egress at the host. Add a rule such as iptables -I OUTPUT -d 169.254.169.254 -j REJECT in the agent container's network namespace, plus the full 169.254.0.0/16 range and IPv6 fd00:ec2::254 and fe80::/10. On GCP also cover metadata.google.internal; on Alibaba Cloud, 100.100.100.100.
  3. Give the agent workload a separate, minimal role. If the credentials IMDS hands out are scoped to read one bucket prefix, a leak is an incident, not a breach. Never run agents under a node role that carries cluster-admin or broad iam:PassRole permissions.
  4. Force all agent HTTP egress through a proxy. Set HTTP_PROXY, HTTPS_PROXY, and NO_PROXY deliberately, and make the network path unroutable except through the proxy so the environment variables are not the only control. Note that a careless NO_PROXY=169.254.169.254 entry (which some SDK docs suggest) reopens the exact hole you are closing.
  5. Deny at the proxy after DNS resolution, not before. Policy must evaluate the resolved IP, not the string the agent supplied, and re-evaluate on every redirect hop. This is the layer that catches encoded addresses and DNS rebinding.

169.254.169.254 lockdown: what each layer actually covers

ControlBlocksMisses
IMDSv2 + hop limit 1Naive GET-based payloads, container hop abuseAgents running on the host that can perform the PUT/GET token dance themselves
Host iptables / nftables ruleDirect connections to link-local IPs from that namespaceCalls made through a sidecar, a remote MCP server, or a headless browser in another pod
Kubernetes NetworkPolicyPod-level egress to CIDR blocks you enumerateAlternate metadata hostnames, redirect chains, anything resolved at request time
Cloud firewall / security groupNorth-south traffic to public rangesLink-local traffic, which never leaves the host and is invisible to the VPC firewall
Egress proxy with post-resolution policyEncoded IPs, DNS rebinding, redirects, alternate metadata hosts, and it logs the attemptNothing at the HTTP layer, provided every agent path is routed through it

The row that surprises most teams is the cloud firewall. Security groups and NSGs do not filter link-local traffic, because that traffic is answered by the hypervisor and never traverses the virtual network. If your only egress control is a security group, IMDS is wide open to anything running on the box. Our GCP egress control guide walks the equivalent gap for VPC firewall rules and the GCP metadata server.

Cloud metadata SSRF agent bypasses your denylist must normalize

A literal string match on 169.254.169.254 is a speed bump. An attacker who can influence agent input has a long list of equivalent representations, and the LLM will happily pass any of them through to the HTTP client:

  • Decimal: http://2852039166/latest/meta-data/
  • Octal: http://0251.0376.0251.0376/
  • Hex: http://0xa9fea9fe/
  • IPv4-mapped IPv6: http://[::ffff:169.254.169.254]/
  • Wildcard DNS services that resolve any subdomain to a chosen A record, including link-local addresses
  • DNS rebinding: a hostname that resolves to a public IP during your validation check and to 169.254.169.254 at connect time
  • Redirect chains: an allowed public host returning 302 Location: http://169.254.169.254/latest/meta-data/iam/security-credentials/
  • Alternate names: metadata.google.internal, metadata.goog, or a private DNS zone entry someone added for convenience

Every one of these collapses if policy is evaluated after resolution against the connected socket address, and re-evaluated on each hop of a redirect. That is why the enforcement point has to be the thing that owns the connection. A validation function inside the agent framework runs before the HTTP client does its own resolution, which is exactly the window DNS rebinding exploits.

IMDS protection for LLM tool calls at the egress proxy

Agent G runs as a drop-in forward proxy in front of every outbound call an agent makes, including tool calls, MCP requests, headless browser fetches, and package installs. The metadata controls are enforced by default rather than configured:

  • Link-local deny is unconditional. 169.254.0.0/16, fe80::/10, fd00:ec2::/64, 100.100.100.100, and known metadata hostnames are denied regardless of what the allowlist says, because no legitimate agent tool needs them.
  • Policy runs on the resolved address. Hostnames are resolved by the proxy, the resulting IP is checked against private and link-local ranges, and the connection is pinned to that address so a second resolution cannot swap it.
  • Redirects are re-evaluated. A 3xx response pointing into private space is denied at the proxy, not followed, and the deny is logged with the original request that triggered it.
  • Denials are evidence. Each blocked attempt produces a structured record with agent identity, tool name, requested URL, resolved IP, decision, and policy rule. An agent trying to read IAM credentials is a high-signal detection, not a silent 403.

Layer this on top of a default-deny egress allowlist and the metadata endpoint stops being a special case: it is simply one of the infinite destinations that are not on the list.

Verify the block before you trust it

Run these from inside the exact runtime your agent uses (same pod, same container, same proxy environment), not from a bastion host:

  • curl -s -m 3 http://169.254.169.254/latest/meta-data/ should fail closed, fast.
  • curl -s -m 3 http://2852039166/ should produce the same denial, proving normalization works.
  • curl -s -m 3 -L https://your-test-host.example/redirect-to-imds should be denied at the redirect hop.
  • Point the agent's real tool at a test page containing an injected instruction to fetch metadata, then confirm a deny event appears in your logs with the correct agent identity.

Fold these probes into CI so a future network change cannot silently reopen the path. Our egress red-team playbook covers the full probe set, including DNS and encoded-payload channels.

Frequently Asked Questions

Does IMDSv2 alone stop an AI agent from stealing credentials?

No. IMDSv2 blocks naive single-GET SSRF payloads, but an agent with shell access can perform the token PUT and follow-up GET itself. Treat IMDSv2 as one layer, and pair it with a host-level 169.254.169.254 lockdown plus proxy-side denial of link-local destinations.

Can I just add 169.254.169.254 to a denylist in my agent framework?

String denylists fail against decimal, octal, hex, IPv6-mapped forms, DNS rebinding, and redirects. Effective blocking evaluates the resolved socket address on every hop, which only the component that owns the connection (an egress proxy) can reliably do.

Will blocking the metadata endpoint break my SDK credential chain?

It can, if your workload relies on instance role credentials. Prefer workload identity, IRSA, or an injected short-lived credential file for the agent process, and keep IMDS blocked for the agent's own outbound HTTP path so tool calls can never reach it.

What about agents calling remote MCP servers?

A remote MCP server can reach its own metadata service on your behalf. Constrain outbound MCP traffic and inspect tool arguments for URLs pointing at link-local space. See the Agent G MCP gateway for argument-level inspection of those calls.

Close the last hop

You block metadata endpoint AI agent access properly when the decision is made on the resolved IP, at the connection boundary, for every tool call the agent makes, and every denial produces an audit record you can hand to an incident responder. Everything above that layer is defense in depth; the proxy is where the guarantee lives.

Agent G enforces link-local denial, post-resolution policy, redirect re-evaluation, and structured deny logging out of the box. Request access to the Agent G private beta to put a default-deny egress boundary in front of your agents.

Agent G

Drop-in guardrails for the agentic era.

Intercept every network call your AI makes. Block destructive actions, enforce approvals, log everything.

Request access