Skip to content

CONCEPT Cited by 1 source

Unix-socket API proxy

A Unix-socket API proxy is a local IPC endpoint — a Unix domain socket — that a privileged process inside a VM or container exposes to the rest of the guest, forwarding requests to an external API with the proxy adding authentication / identity material that the caller doesn't hold.

The canonical wiki instance is Fly init's /.fly/api socket: "a server for a Unix socket at /.fly/api, which exports a subset of the Fly Machines API to privileged processes in the Machine." (Source: sources/2024-06-19-flyio-aws-without-access-keys)

Why a Unix socket, not an HTTP endpoint?

The post states the security claim directly: "the API proxy [is] tricky to SSRF to." (Source: sources/2024-06-19-flyio-aws-without-access-keys)

Server-side request forgery (SSRF) is the class of vulnerability where a web application can be tricked into making HTTP requests on behalf of an attacker. Cloud metadata services on link-local HTTP addresses (http://169.254.169.254/...) are the classic SSRF target — the attacker sends a URL to a vulnerable endpoint like /fetch?url=... and the app obligingly fetches the metadata service for them.

A Unix socket has three SSRF-mitigation properties:

  1. Not HTTP-reachable by default. Most SSRF gadgets are HTTP clients (curl, fetch, HttpClient, the various image-loading libraries). Reaching a Unix socket requires a different primitive: the ability to open arbitrary file paths, then speak HTTP (or whatever protocol) over it. That's a much more specific attacker capability.
  2. Filesystem-gated. The socket lives at a file path (/.fly/api); access is controlled by filesystem permissions, not network namespaces.
  3. Not in anyone's default URL allow-list. A web-app SSRF allowlist is usually about blocking metadata-server IPs and localhost; a Unix socket isn't a URL at all, so the question doesn't come up.

Privilege-separation: what the proxy adds on the way out

The classic Unix-socket-API-proxy pattern is:

[guest app] ──(plain request)──▶ [proxy on Unix socket] ──(request + auth)──▶ [remote API]

The proxy holds the auth material; the app doesn't. The app couldn't exfiltrate the auth material even if it tried — it never receives it.

Fly's instantiation:

  • Every Machine is booted with a Machine-scoped Macaroon token — flyd passes it to init at boot.
  • init runs the /.fly/api proxy; init is the only process with the Macaroon.
  • The proxy attaches the Macaroon to outbound requests on the way to the Machines API.
  • "Ordinary code running in a Fly Machine never gets a copy of the token to begin with." (Source: sources/2024-06-19-flyio-aws-without-access-keys)

Net consequence: "You could rig up a local privilege escalation vulnerability and work out how to steal the Macaroon, but you can't exfiltrate it productively."

Property Link-local HTTP (EC2 IMDS classic) Unix socket (Fly /.fly/api)
Reachable via web-app SSRF Yes, trivially No (requires filesystem primitive)
Auth material flows through guest Yes (credentials returned) No (proxy attaches, strips)
Access control Network namespace + IMDSv2 handshake Filesystem permissions
Protocol diversity HTTP Any protocol the app + proxy agree on

IMDSv2's session-token handshake is AWS's answer to the SSRF problem on the link-local HTTP shape; the Unix socket shape makes the problem not exist in the first place.

General applicability beyond Fly.io

The pattern isn't Fly-specific. Adjacent instances on the broader web:

  • Docker's docker.sock — a Unix socket in the host that Docker clients connect to for container management. The security model is explicitly filesystem-gated.
  • Kubernetes CRI sockets — container runtime interfaces (containerd, CRI-O) expose Unix sockets to the kubelet.
  • Systemd socket activation — socket-based IPC for launching services on demand.
  • AWS IMDSv2's session-token handshake is a different mitigation for a different architecture (keeping the link- local HTTP endpoint but requiring a PUT-then-GET dance that typical SSRF primitives can't perform).

Seen in

  • sources/2024-06-19-flyio-aws-without-access-keys"/.fly/api, which exports a subset of the Fly Machines API to privileged processes in the Machine"; "the API proxy [is] tricky to SSRF to"; Macaroon-attaches-on-outbound model; application code never sees the Macaroon.
Last updated · 200 distilled / 1,178 read