On October 19, PingCAP, the company behind the TiDB database, published an incident report. The way in was ordinary: stolen service-account credentials, used from September 9 to October 7. The report found no evidence that customer data stored in TiDB was touched. What turned a stolen login into a wider exposure is where other credentials had been left, in Jira tickets and in env files.

TLDR

PingCAP was not breached by a novel agent exploit. Someone used a stolen service-account credential, and the damage grew because other credentials were sitting in Jira tickets and env files.

Vibe coding and agentic deploys multiply the risk surface. An agent writes insecure code, config, and ticket text faster than a developer can read it, so the scan that used to catch a pasted secret no longer happens. A systematic focus on security is needed to mitigate it. On ForeStrat that focus is the platform: vault references instead of secrets in files, a credential that opens one door, an agent that asks before it deploys, and a trace of every model call.

Vibe coding outruns the review

A developer used to write the change and then read it. Vibe coding splits those two acts. The agent writes the file, often a whole service, and the reviewer is left with more than they will line-read. Most of it is glanced at, or not opened. The insecure line sits in the middle of generated code: a secret dropped into an env file, a permission set to whatever made the script run, a check the model skipped because the happy path worked. It does not look like an exploit. It looks like working code, and working code gets merged when the queue is long. A pasted credential, a world-readable bucket, or a dependency pinned to whatever the model remembered can ship inside a diff nobody finished.

Agentic deploys make the same gap wider. The agent does not stop at the pull request. It can open the ticket, paste the config, and push the change into an environment. Each of those is another place a credential can sit, and each of them is produced faster than a second person will scan. The PingCAP habit, secrets in Jira tickets and env files, is what that workflow produces when nothing refuses it.

The incident

Everything here comes from PingCAP's security update, dated October 19, 2026. Other claims are circulating, including large data volumes from a group that says it did this. PingCAP has not confirmed them, so we leave them out.

The exported data included account and project metadata, SQL editor text and errors, billing records, and a table of encrypted API-key values. PingCAP says it has no evidence of commands run or persistent access in the production systems that were reviewed.

The entry itself was a stolen credential, the kind any company with a service account already has. The exposure grew because credentials were also sitting in Jira tickets and env files, copied there so a person or a script could keep working. PingCAP's report confirms the stolen service-account login. It says the attacker's claims about what those support materials contained have not been verified, so this post does not repeat the volumes or the keys in those claims. Tickets and env files are where secrets go when a team is moving fast, and they travel with every export of the tracker and the repo.

How it would have been different with ForeStrat

The same facts, run through the controls we already ship. This is a comparison, not a claim that ForeStrat would have made PingCAP's incident impossible. It is what changes when the platform, rather than a later review, is what stops the risky behavior.

RiskWhat the incident exposedWith ForeStrat
Way inA stolen service-account credential was enoughThe agent uses the signed-in user's token. A production change needs that person's admin rights, checked by the backend
ReachThe credential also opened other cloud projectsProduction secrets sit in their own vault. The server's managed identity can read that vault only. We tested the other vault: 403 Forbidden
Where secrets satJira tickets and env filesProduction secrets are vault references. The files and tickets agents edit do not hold the value
ReviewGenerated and pasted material was there to copyThe default is that the agent asks before it deploys. Generated code can be tested in a process with no network
Time to noticeSeptember 9 to October 7Every model call is traced with its app, cost, and content. A session stops at 5 million tokens
Provider keysAPI-key material was in the exportProvider keys live in the router. An app, and an agent writing one, holds only its own router key

A stolen credential, and how far it reached

PingCAP's intruder signed in with a service-account credential and stayed from September 9 to October 7. On October 10 PingCAP removed excess permissions between cloud projects. A credential that also opens the next door is how a month-long incident happens.

StratOps, our agent for data pipelines, calls the backend with the signed-in user's token. A production change needs that person's admin role, and an unidentified environment is refused. The check is in the backend, so a prompt cannot talk past it. Outside AI tools on our tool server cannot deploy to production at all. The default autonomy is ask. Supervised and auto exist, and a team has to choose them. When a tool has real consequences, the backend warns the user on a channel the model never sees.

How a StratOps change reaches production: the agent proposes a change, the user approves it, and a backend role check sends it to test environments or, for admins only, to production. A risky tool call sends the user a warning outside the model's context.
The agent proposes and you approve. The backend decides what can reach production, and risky tool calls raise a warning the model cannot hide.

Reach is the vault, which is how we are separating secrets while moving production pipelines from AWS to Azure. Production values sit in their own Azure Key Vault. The server uses a managed identity, so there is no vault password on disk, and that identity can read the production vault only. Tested from the machine: the production vault answered, and the general vault returned 403 Forbidden. Teammates who needed a new cache were granted three secrets, not the vault.

The production pipeline server uses an Azure managed identity. Reading the production vault returns 200 OK; reading the general vault returns 403 Forbidden.
Tested from the machine itself: the production vault answers, and the general vault refuses.

Secrets in tickets and env files

Credentials had been copied into Jira tickets and env files so a person or a script could keep working. Once the tracker and the repo were reachable, one stolen credential opened many more. SQL editor text in the export is the same habit.

On ForeStrat, production secrets reach the flows as vault references, fetched when the pipeline starts. They are not typed into the definitions, env files, or comments that people and agents edit. A vibe-coded change can still be wrong. It cannot lift a production secret out of the file it is rewriting, because the value was never there.

The model key is the credential an agent is most likely to paste, and it turns straight into spend. ForeStrat Router holds the provider keys. Each app holds only its own router key, so a leak is one revocation and not a provider rotation. An agent writing a new service gets a router key, not a provider key for an env file or a ticket. Content safety filters run on every model deployment, for prompts and responses.

Five apps, each holding only its own router key, call ForeStrat Router. The router holds the provider keys, calls content-filtered models on Azure OpenAI and Azure AI Foundry, and sends every call's trace to self-hosted Langfuse.
Each app holds only its own router key. Provider keys sit in the middle box, and every call leaves a trace.

Generated code can be tested on a real sample before deploy, inside a process with CPU, memory, file, and time limits. An audit hook refuses network access, new processes, and writes outside a scratch folder. The model sees the shape of the output, never the data. That does not replace reading the diff. It does stop a generated script from using the test to send a secret home.

Four weeks before anyone noticed

PingCAP's intruder had from September 9 to October 7. Extra storage logging went on three days after the company found out.

Every model call through the router is written to self-hosted Langfuse, with the prompt, the response, the model, the app, the cost, and the latency. A review of one day's traffic found that about one request in six was an exact repeat of an earlier one. The same record is where a spend spike, a new model on an old app, a loop, or a prompt fishing for credentials shows up while it is still small.

One agent task as a trace: a model call via the router, a tool call, a second model call, and the final response. Each model call is recorded with its prompt and response, model and app, tokens and cost, and latency.
Every model call inside a task is recorded with its prompt, response, model, app, tokens, cost and latency.

A session also has a budget. The cap in production today is 5 million tokens. The agent warns as a session gets close, and stops when it hits the cap. A runaway loop ends at the cap instead of on the invoice.

One control is still ahead of us. Every machine credential needs an owner and a rotation date, reviewed monthly. The keys an agent stack collects are only as safe as the last time someone changed them. Scoped reach and a trace do not retire a key that should have been rotated.

Frequently Asked Questions

Could what happened to PingCAP happen to you?

The way in was a stolen service-account credential, made worse because other credentials sat in Jira tickets and env files. Any company that uses service accounts can have one stolen, including us. Vibe coding and agentic deploys multiply the risk surface, because the volume of generated code outruns a human scan. What we can control is that spread: how far a stolen credential reaches, whether the value was ever in a file an agent can rewrite, and whether anyone is looking at the trace.

Do your agents ever act without a human?

Only where a team has chosen that for a specific process. The default is to ask first. In every mode, the agent works with the signed-in user's permissions, so it can never reach further than that person can.

Can a prompt injection make the agent hide what it is doing?

It can change what the model writes. It cannot stop the warnings our backend sends when a consequential tool runs, because those never pass through the model.

How would you know if an agent started misbehaving?

From the record. Every model call through the router is traced with the app that made it, its cost, and its content. A spike in spend, an app calling a model it never used, or prompts fishing for credentials would all show up there, where we can catch them early.

Where does our data go when the agent calls a model?

Calls through the router go to model deployments in our own Azure subscription. Traces are stored in our self-hosted Langfuse instance, not a shared logging service.

How do you keep test credentials away from production?

Production pipeline secrets live in their own vault. The production server reaches it with a managed identity that can read that vault only. We tested it against our general vault, and the request was refused.

Learn more

If you are putting agents near production data, the PingCAP incident is the baseline. Stolen credentials are ordinary. Jira tickets and env files are where they accumulate, and vibe coding writes both faster than a team can scan. A systematic focus on security is what mitigates that, and it has to live in the platform rather than in a review nobody finishes. We are happy to show how ours works and compare notes.

Book a demo →