If you build web systems long enough, your instincts about identity start from a pretty stable place. Use OAuth when users need delegated access. Use OIDC when you want identity on top. Use API keys or service accounts when software needs to talk to software. Those patterns are well understood, broadly interoperable, and usually good enough.
Autonomous agents are where that mental model starts to wobble.
An autonomous agent is not a user with a nicer UI, and it is not just another backend service hidden behind a load balancer. It may be created dynamically, operate before any human is present, pick up an owner later, spawn sub-agents, and ask downstream systems for tightly scoped authority as it goes. That lifecycle does not map cleanly to browser-era auth patterns.
That is the problem we have been working on with SAL, the Sovereign Agent Lifecycle Protocol. The protocol spec is at sal-protocol.dev, and the reference implementation is live in Vibebase.
OAuth still assumes a person exists somewhere
The core issue with OAuth is not that it is bad. It is that it assumes a human exists somewhere in the chain of trust.
The authorization code flow begins with a browser redirect. That is great for a SaaS app. It is not useful for an agent that does not have a browser, does not own a cookie jar, and cannot stop what it is doing while waiting for a human to approve a consent screen.
Device code flows soften that, but they do not remove the human dependency. They just move it to a second screen. A person still has to appear and complete the flow.
OIDC inherits the same problem. Its output is usually a token representing a human login event or a user-mediated authorization relationship. That is useful when software is acting on behalf of a person. It is less useful when the principal itself is meant to be a first-class autonomous actor.
Static secrets are a fallback, not a lifecycle
Once teams realize browser flows do not work, they often fall back to API keys.
API keys are easy to understand, but they force a human provisioning step into a place where the system should be able to bootstrap itself. Somebody has to create the key, copy it into the right place, store it, rotate it, and hope it never leaks through logs, screenshots, repos, or support tooling.
That is not just inconvenient. It shapes the architecture in the wrong direction. Instead of an agent generating identity locally, you end up with a human distributing secrets to software. That is the inverse of what you want when trying to build systems that can come online and operate without ceremony.
Service accounts get closer, but they still assume centralized issuance from an existing control plane. A service account is not a sovereign identity. It is a credential object created by another system. If your model is "every agent is really just a named credential we minted centrally," then you still have not solved agent identity. You have just automated service account sprawl.
The missing capability is agent birth
The thing most existing auth models do not handle well is agent birth.
A real autonomous system needs a coherent answer to basic lifecycle questions:
- How does an agent come into existence with identity before any human is involved?
- How does it authenticate without receiving a static shared secret?
- How does a human later claim it without taking custody of its credentials?
- How does a downstream service know where the agent came from and what authorized it?
SAL starts from the idea that an agent should self-generate an Ed25519 keypair at birth. No browser, no copied secret, no manual bootstrap step. From that moment on, the agent has a cryptographic identity that it controls.
The first response from the network is not full access. It is constrained access.
{
"success": true,
"data": {
"agent_id": "agt_01JY8H8JQW9VG7J2Y5M3F4K2D1",
"state": "orphan",
"grants": [
{
"scope": "workspace:bootstrap",
"ttl_seconds": 300
}
]
}
}
That orphan state matters because it acknowledges a missing phase in existing identity systems: software that is real, authenticated, and useful before it is owned.
Why we built SAL instead
SAL is the protocol we built for that lifecycle.
An agent generates its own keypair. It begins in an orphan state with constrained scope. A human can later claim the agent through a cryptographic handshake without ever holding the agent's private key. Token exchange is challenge-based, so no static secret is transmitted. And every spawned agent can carry lineage that proves where it came from and what authorization created it.
That last part is especially important. Most systems rely on logs for provenance. SAL treats provenance as identity structure. Instead of asking "what do the logs say happened," downstream systems can verify "what cryptographic chain of delegation produced this agent?"
Here is a simplified claims payload shape:
{
"success": true,
"data": {
"claims": {
"sub": "agt_01JY8H8JQW9VG7J2Y5M3F4K2D1",
"state": "claimed",
"scope": ["doc:read", "task:append"],
"lineage": [
{
"agent_id": "agt_parent_01JY8H4A2N",
"grant_id": "grt_parent_spawn"
}
]
}
}
}
That gives gateways and services something stronger than "this token is valid." It gives them context about authority, delegation, and provenance.
Where this lives today
The SAL spec is public at sal-protocol.dev. Vibebase is the live reference implementation where these ideas are exercised in a real product instead of as a slide deck.
I do not think this is a solved standards space yet. The whole point of publishing the spec and implementation is to get pressure from people building real agent systems. If you have already hit this problem and solved it differently, I want to compare notes. If you think this should be an extension to an existing standard rather than a separate protocol, I want that feedback too.
Because the problem is not "how do we get agents to use OAuth." The problem is "what does a real identity lifecycle for autonomous software actually look like?"
Top comments (0)