We got admin access to Baseten's production GitHub in 25 minutes September 1st, 2026We wanted to use Baseten for inference. We ended up with admin access to Baseten GitHub reposAlex SchapiroWe were a
By Coderz Club · 2026-09-16 · Tags: ai, git, go
We got admin access to Baseten's production GitHub in 25 minutes
September 1st, 2026We wanted to use Baseten for inference. We ended up with admin access to Baseten GitHub reposAlex SchapiroWe were about to trust Baseten with our own and our customers’ data. So to be safe, we ran Strix to ensure they were secure first. About 25 minutes later, it had a live GitHub token with repository-level admin rights on internal Baseten repos. We build Strix, an autonomous hacking agent, which of course means we need (cheap and fast) inference. We were exploring our options, and Baseten is one of the obvious choices. It's a great product, they're valued at $13 billion, and a lot of serious companies depend on them. But... we're a security company. Before we give a third party our data, models, or code, we scan them. We would much rather find a problem and help get it fixed before we start depending on that service (we do this with almost all of our vendors and have a high rate of finding serious issues). So... we pointed Strix at *.baseten.co and let it run without credentials or source code. It came back with an active GitHub personal access token for basetenbot. That token had admin and push access to Baseten's main product repo, the GitOps repo that drives their clusters, and their Homebrew tap, plus read/write access to other private repositories including specific repos per customers. The image build dated to March 2023, and the token still worked when we found it in July 2026. But before we get into the details, let's give some kudos to Baseten's security team. They confirmed the issue as critical, locked down the registry project, and rotated the token by the next afternoon. They were professional and very quick to deal with it (which is often not the case in these situations). How Strix actually found it Strix starts the way any good pentest does: recon. Many times the most severe vulnerability on your infra may be on a service on a subdomain you forgot about (which is why we always recommend black box testing alongside testing with code access)! So Strix enumerated hosts, looked through certificate logs, mapped the full surface. Eventually, it found a Harbor registry at gcp-us-east4-zlw.registry.baseten.co. Harbor stores container images and groups repositories into projects. One of these projects was public. Without any token or auth, Strix could list repositories, obtain anonymous pull tokens, and download the actual image manifests and blobs. That included an image called baseten/baseten-app. At this point, it would be easy to report an exposed registry and move on. But companies do intentionally publish images, and Strix never wants to report a false positive. The important question is what impact the images being exposed have. Strix decided to pull an image and see what was inside. Here's that part of the run as it appears in Strix (yes, the agent's own writing sounds like AI, for obvious reasons):Harbor Exposure Impact ReviewThinkingIf those Harbor projects are not meant to be public, this is a real exposure, not metadata noise. The chain is what matters: enumerate public projects, read artifact metadata, mint an anonymous service/token scoped to repository:baseten/baseten-app:pull, pull the manifest, then fetch the blob through a signed storage redirect. That proves real anonymous pull access. The way to make triage take it seriously is to prove one thing from a pulled image: proprietary code, internal binaries, hardcoded credentials, or internal hostnames.The first promising hit was a pair of AWS keys in baseten/baseten-app. Strix tried a read-only sts:GetCallerIdentity call, which tells you what account a credential belongs to. The response was InvalidClientTokenId. That key was dead, so Strix kept looking. Then, a token that actually worked It pulled the layers, ran TruffleHog (shout out to our open-source security friends!), and inspected the image config directly. And there it was: a classic GitHub personal access token, sitting in history[].created_by. I am not a Docker runtime expert, but luckily Strix is (thanks to it having pretty much all of human knowledge at its disposal). So it knew that that field records how a build step was created. In this case, it contained a RUN command with the value of GITHUB_TOKEN expanded directly into it. Strix used the token for a read-only GET /user request to GitHub and… VOILÀ. 200, with the account name basetenbot. The token in the Docker build history, followed by GitHub identifying it as basetenbot. The credential is redacted. Open image for full size. Notice where the token was found. As I learned, a Docker image has filesystem layers, but it also has a config containing information about the image and its build history. That config is downloadable along with the image. Cleaning up a credential file doesn't help if the build history still contains another copy of the token. And this one still worked more than three years later. Okay, what can basetenbot do?
September 1st, 2026We wanted to use Baseten for inference. We ended up with admin access to Baseten GitHub reposAlex SchapiroWe were about to trust Baseten with our own and our customers’ data. So to be safe, we ran Strix to ensure they were secure first. About 25 minutes later, it had a live GitHub token with repository-level admin rights on internal Baseten repos. We build Strix, an autonomous hacking agent, which of course means we need (cheap and fast) inference. We were exploring our options, and Baseten is one of the obvious choices. It's a great product, they're valued at $13 billion, and a lot of serious companies depend on them. But... we're a security company. Before we give a third party our data, models, or code, we scan them. We would much rather find a problem and help get it fixed before we start depending on that service (we do this with almost all of our vendors and have a high rate of finding serious issues). So... we pointed Strix at *.baseten.co and let it run without credentials or source code. It came back with an active GitHub personal access token for basetenbot. That token had admin and push access to Baseten's main product repo, the GitOps repo that drives their clusters, and their Homebrew tap, plus read/write access to other private repositories including specific repos per customers. The image build dated to March 2023, and the token still worked when we found it in July 2026. But before we get into the details, let's give some kudos to Baseten's security team. They confirmed the issue as critical, locked down the registry project, and rotated the token by the next afternoon. They were professional and very quick to deal with it (which is often not the case in these situations). How Strix actually found it Strix starts the way any good pentest does: recon. Many times the most severe vulnerability on your infra may be on a service on a subdomain you forgot about (which is why we always recommend black box testing alongside testing with code access)! So Strix enumerated hosts, looked through certificate logs, mapped the full surface. Eventually, it found a Harbor registry at gcp-us-east4-zlw.registry.baseten.co. Harbor stores container images and groups repositories into projects. One of these projects was public. Without any token or auth, Strix could list repositories, obtain anonymous pull tokens, and download the actual image manifests and blobs. That included an image called baseten/baseten-app. At this point, it would be easy to report an exposed registry and move on. But companies do intentionally publish images, and Strix never wants to report a false positive. The important question is what impact the images being exposed have. Strix decided to pull an image and see what was inside. Here's that part of the run as it appears in Strix (yes, the agent's own writing sounds like AI, for obvious reasons):Harbor Exposure Impact ReviewThinkingIf those Harbor projects are not meant to be public, this is a real exposure, not metadata noise. The chain is what matters: enumerate public projects, read artifact metadata, mint an anonymous service/token scoped to repository:baseten/baseten-app:pull, pull the manifest, then fetch the blob through a signed storage redirect. That proves real anonymous pull access. The way to make triage take it seriously is to prove one thing from a pulled image: proprietary code, internal binaries, hardcoded credentials, or internal hostnames.The first promising hit was a pair of AWS keys in baseten/baseten-app. Strix tried a read-only sts:GetCallerIdentity call, which tells you what account a credential belongs to. The response was InvalidClientTokenId. That key was dead, so Strix kept looking. Then, a token that actually worked It pulled the layers, ran TruffleHog (shout out to our open-source security friends!), and inspected the image config directly. And there it was: a classic GitHub personal access token, sitting in history[].created_by. I am not a Docker runtime expert, but luckily Strix is (thanks to it having pretty much all of human knowledge at its disposal). So it knew that that field records how a build step was created. In this case, it contained a RUN command with the value of GITHUB_TOKEN expanded directly into it. Strix used the token for a read-only GET /user request to GitHub and… VOILÀ. 200, with the account name basetenbot. The token in the Docker build history, followed by GitHub identifying it as basetenbot. The credential is redacted. Open image for full size. Notice where the token was found. As I learned, a Docker image has filesystem layers, but it also has a config containing information about the image and its build history. That config is downloadable along with the image. Cleaning up a credential file doesn't help if the build history still contains another copy of the token. And this one still worked more than three years later. Okay, what can basetenbot do?