[← log]
kubereach

From one cracked room to the whole cloud account

You get a shell in a single Kubernetes pod. That is the whole starting position. This walks the two things I proved from there, against real infrastructure, and where I am taking it next.

GoKubernetesAWSIRSA2 proof spikes
EKS CLUSTERworker nodepodappweb:1.27runningsidecarfluent-bitrunningshell/bin/sh -iyour laptopoff-box · no path backAWS accountwarehouses across town1 · escapes the cluster

one container is compromised · its token escapes the cluster to your laptop, then to AWS

00

The starting point

One container. One room, somewhere inside a building you cannot see the rest of. The only honest question is not what the cluster can do in theory. It is what this one stolen key can reach, from this exact spot.

kubereach was my answer: drop a single binary into the foothold, map what your identity can really touch, and follow the trail out of the cluster into the AWS account behind it. Partway in I found a competing tool had already shipped most of it, so instead of building, I went to break the two claims that scared me most. If either was hollow, the whole idea was hollow.

00

Bet one: the front desk lies

Almost every tool here asks the API server one polite question, "what am I allowed to do?", and trusts the answer. On managed clusters (EKS, GKE, AKS) a second gatekeeper sits behind the desk that the desk cannot fully see. So the summary under-reports, and the tool never knows it missed real access.

interactive · try both calls
the summary every tool trusts
GET  my rules in namespace: restricted
  pods                 ->  list
  secrets/restricted   ->  (not in the list)

[INCOMPLETE] the webhook rules are hidden
             from this call
verdictreports "no access"

Same identity, same permission. The two calls disagree, and only one is right.

The summary said no. The exact question said yes, and reality agreed: the secret came back, 200 OK. Sweeping around ninety of those precise checks one at a time took roughly seventeen seconds on my laptop, so a real tool has to fan them out. Slow and correct beats fast and wrong, especially on the clusters people are paid to get into.

00

Bet two: carrying the key out

Some pods carry a golden key, an IRSA token. It opens nothing inside the building. What it opens is the company warehouses across town, the AWS account behind the cluster. The question: can you carry that key out of the building entirely and use it from your own laptop, with no live connection back to the cluster?

interactive · click any hop
Result · You are the pod's IAM role
$ aws sts get-caller-identity
Arn: .../role/s2-irsa-readonly/<your-session>

$ aws s3 ls               ->  allowed
$ aws iam list-users      ->  AccessDenied

# holding the pod's cloud powers on your laptop,
# across town from a cluster you no longer talk to.
blast radius · what the stolen role can touch

With those credentials I asked AWS who am I, and it answered with the pod's own role. Then I probed the edges of what it could touch.

allowed
  • s3:ListBucket
  • s3:GetObject
denied
  • iam:ListUsers
  • ec2:*
  • sts:AssumeRole (others)
00

The real run

I proved the plumbing locally against a fake AWS first, to get the call shape right. A mock proves nothing about the real thing, so I did the whole pivot for real, against real infrastructure and real money.

Account
a fresh AWS account, on credits
Cluster
s2-probe · EKS · us-east-1
Version
Kubernetes 1.34, one small node
The switch
OIDC provider on, the trust anchor
  1. 01
    as the careless owner

    Made an IAM role tied to the cluster identity, scoped to read-only S3, and attached it to a service account.

  2. 02
    as the careless owner

    Ran a throwaway busybox pod on that account. EKS auto-injected the golden key into the pod as a file.

  3. 03
    as the intruder

    I am in the room, so the key is just a file. I read it straight off the pod and copied it to my laptop.

  4. 04
    as the intruder

    From my laptop, off-box, traded it with AWS for live credentials. No connection back to the cluster at that moment.

the assumption that turned out wrong
My local test signed the request to AWS with my own credentials, and real AWS rejects that outright. The whole point is that the stolen token is the credential, so the request has to go out unsigned. A four-line fix, and exactly the kind of detail that decides whether the attack works or quietly fails. I only found it by doing it for real instead of trusting the mock.

AWS answered with the pod's own role wearing my session name. S3: allowed. List IAM users: denied. Exactly right. Then I tore it all down, because a real cluster costs real money by the hour, and the whole proof had cost about a coffee.

00

How I worked

Risk-first. Prove the scariest bets as throwaway spikes before writing any product code.

  1. 1
    S1

    Correctness, on a local cluster

    A kind cluster wired with the two-gatekeeper chain, to drag the SSRR-vs-SAR disagreement into the open. This is the finding worth keeping.

  2. 2
    S2 · phase 1

    Plumbing, against a fake AWS

    Ran the token exchange against a local mock to get the exact call shape right before spending anything.

  3. 3
    S2 · phase 2

    The real pivot, real money

    A genuine EKS cluster and a live redemption at AWS STS. The mock had hidden the unsigned-request detail; only the real run surfaced it.

00

Work in progress

This is where kubereach is right now. The two parts that worried me most both held up against real infrastructure. The one I am most sure about is the correctness finding: nearly every tool here under-reports what a stolen identity can really do on the managed clusters that matter most. That is the piece I want to lead with.

I am still actively working on it and brainstorming what the most advanced, most useful version looks like. One piece of the demo, the off-box IRSA pivot, narrows as EKS Pod Identity becomes the default, so I am pushing the parts that stay valuable further instead.

This is what I tried and what worked. I am looking to make it more advanced, I am open to suggestions, and if this is your kind of problem I would be glad to have people build on it with me.

where this belongs
Every bit of this ran against my own lab and a throwaway AWS account I owned and then deleted. That is the only place any of it belongs. It exists to understand and defend these paths, not to point at anyone.