Blog

BYO runner, governed secrets

A lot of "add a control plane" pitches quietly mean "move your agents onto our compute." Runkite's pitch is the opposite: your agent code keeps running exactly where it already runs — your laptop, your Kubernetes cluster, your VPC — and the plane never asks to own that compute. What it does ask to own is something narrower and, honestly, more important: which credentials your agent can reach, and for how long.

The part nobody wants to admit about agent secrets

Here's the uncomfortable default in most agent setups: the GitHub token, the Salesforce API key, the Slack bot token — they all end up sitting in the agent process's environment variables, loaded once at startup and alive for as long as the process is. That's not a criticism of any particular team; it's just what happens when you wire up os.environ["GITHUB_TOKEN"] and move on, because the framework you're using doesn't have an opinion about credential lifetime and neither does anyone's deadline.

The problem shows up later, when something goes wrong. An agent process that's been compromised, or is simply running code you didn't fully review because an LLM wrote part of it, has standing access to every long-lived credential you ever loaded into its environment — not just the one it's using right now, but every one you ever gave it, for as long as the process lives. The blast radius of "this agent did something it shouldn't have" is exactly as large as "everything this agent's environment variables could reach," and for most setups, that's everything.

What changes: short-lived sessions, minted on demand

Runkite's connectors don't hand your agent a long-lived key at all. When your agent code calls get_connector_session(config, "salesforce") — the same call whether you're in Python or TypeScript — the plane mints a session that's good for exactly one connector, bound to the run that's asking for it, and expires in fifteen minutes. Nothing about that session is reusable outside the run it was minted for. If the run finishes, or gets cancelled, or the fifteen minutes run out, the session is dead — not "should be treated as dead," actually dead, because the plane holds the real, long-lived secret and only ever hands out a short-lived proxy to it.

This is the difference between "the agent has a Salesforce key" and "the agent can, for the next few minutes, while this specific run is active, make Salesforce calls through a session the plane is watching." The second one is a much smaller thing to have gone wrong if it goes wrong. A leaked fifteen-minute session that already expired by the time anyone notices is a non-event. A leaked API key with no expiry is an incident.

Where the real secret actually lives

None of this works if the plane itself is a second place your long-lived secrets have to be copy-pasted into — that just moves the problem instead of solving it. So the real credential is never baked into a config file at all. It's referenced, using a small, deliberately boring syntax: secret_ref: env:GITHUB_TOKEN reads it from the plane's own environment, secret_ref: file:/var/run/secrets/github_token reads it from a mounted file (the pattern that matches how Kubernetes secrets and projected service account tokens already show up on disk), and secret_ref: vault:secret/data/runkite/connectors/github#token resolves it from HashiCorp Vault — KV v1 or v2 — at the moment a session is actually being minted, not once at boot and then cached forever.

That last detail matters more than it looks like it should. Resolving the secret at session-mint time instead of at process-start time means rotating a credential in Vault takes effect on the very next session a run asks for — no restart, no redeploy, no window where the plane is quietly using a secret that was already revoked somewhere else. The plane is deliberately not trying to be a second Vault UI with its own rotation schedule and its own audit trail to reconcile against your real one. It defers to whatever secret store you already trust, and just asks it the question fresh, every time.

What this doesn't pretend to solve

It would be dishonest to stop there without saying what this doesn't cover. If your own agent code independently has a different, hardcoded credential to the same service — pasted into a notebook, committed to a repo by accident, sitting in a `.env` file the plane never sees — none of the above helps you, because the plane can only govern access it hands out itself. Short-lived, run-bound connector sessions are a real, meaningful reduction in blast radius for the access path they cover. They are not a promise that every credential in your organization suddenly became safe the day you adopted a control plane. Nothing is.

Try it

Previous: two protocols, one plane · Connectors (docs) · Secrets · Security · Blog index

Next in this series: Spend without becoming a billco — the other thing a control plane has to be honest about.