<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Steve Emmerich</title>
    <description>The latest articles on DEV Community by Steve Emmerich (@steveemmerich).</description>
    <link>https://dev.to/steveemmerich</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F92797%2F792f7168-6d40-432a-8795-66b1199f976d.jpeg</url>
      <title>DEV Community: Steve Emmerich</title>
      <link>https://dev.to/steveemmerich</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/steveemmerich"/>
    <language>en</language>
    <item>
      <title>What Vibebase implements today from the SAL protocol</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Wed, 16 Sep 2026 18:09:08 +0000</pubDate>
      <link>https://dev.to/steveemmerich/what-vibebase-implements-today-from-the-sal-protocol-4174</link>
      <guid>https://dev.to/steveemmerich/what-vibebase-implements-today-from-the-sal-protocol-4174</guid>
      <description>&lt;p&gt;One thing I care about with protocol work is resisting the temptation to stop at the whitepaper stage.&lt;/p&gt;

&lt;p&gt;Identity protocols are easy to make sound clean in diagrams. The harder and more useful step is implementing them in a system where requests fail, policies drift, edge cases show up, and real builders can decide whether the model is actually worth carrying forward.&lt;/p&gt;

&lt;p&gt;That is the role Vibebase plays for SAL.&lt;/p&gt;

&lt;p&gt;SAL, the Sovereign Agent Lifecycle Protocol, is the open protocol model published at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;. &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt; is the running implementation where we are exercising those ideas in an actual agent platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  SAL is the protocol surface
&lt;/h2&gt;

&lt;p&gt;SAL defines the lifecycle and trust semantics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;agents self-generate Ed25519 keypairs at birth&lt;/li&gt;
&lt;li&gt;they can begin in orphan state&lt;/li&gt;
&lt;li&gt;humans can claim them without taking key custody&lt;/li&gt;
&lt;li&gt;token exchange is challenge-based&lt;/li&gt;
&lt;li&gt;lineage carries delegation provenance&lt;/li&gt;
&lt;li&gt;service tokens are short-lived and scoped&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the conceptual layer. It is meant to be portable and implementable outside Vibebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vibebase is where the model gets tested
&lt;/h2&gt;

&lt;p&gt;Vibebase implements those ideas as working product behavior rather than just abstract spec language.&lt;/p&gt;

&lt;p&gt;That matters because a lot of design decisions only become visible when they hit running code. How small can orphan scope be while still being useful? What shape of claim handshake is ergonomic enough for builders to adopt? How much lineage needs to travel with a token to remain useful without becoming bloated? Where does challenge exchange create friction, and where does it buy real safety?&lt;/p&gt;

&lt;p&gt;Those are implementation questions, but they feed back into protocol quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I think the separation is healthy
&lt;/h2&gt;

&lt;p&gt;I do not want SAL to become "the Vibebase auth format." If the protocol only works inside one product, it is not really doing protocol work. It is doing product naming.&lt;/p&gt;

&lt;p&gt;Keeping the protocol public and the implementation concrete creates a better feedback loop. People can critique the concepts independently of the product. They can also inspect whether the product is honestly carrying the ideas through.&lt;/p&gt;

&lt;p&gt;That has already been useful for me as a builder. It forces precision. If a concept in the spec cannot survive contact with implementation, it probably was not as well-formed as it looked on paper.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I would read the two together
&lt;/h2&gt;

&lt;p&gt;If you are coming at this fresh, I would read &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt; to understand the lifecycle model and then use &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase docs&lt;/a&gt; to see how that model shows up in a real developer surface.&lt;/p&gt;

&lt;p&gt;The spec answers "what does this protocol claim should exist?"&lt;/p&gt;

&lt;p&gt;The implementation answers "what does this feel like when somebody actually has to build against it?"&lt;/p&gt;

&lt;p&gt;I think both views matter. Protocol work without implementation becomes vague quickly. Implementation without an open protocol tends to stay local and harder to reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  Still very much in motion
&lt;/h2&gt;

&lt;p&gt;Vibebase is not intended as proof that the problem is finished. It is proof that the problem is real enough to deserve a concrete attempt.&lt;/p&gt;

&lt;p&gt;If you are building agent systems and want to push on the model, that is exactly the kind of pressure I want. The more this can be tested by people outside my immediate assumptions, the better the protocol will get.&lt;/p&gt;

&lt;p&gt;The spec is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, the reference implementation is at &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;vibebase.app/docs&lt;/a&gt;, and the useful question is still the same: does this lifecycle model make agent identity easier to reason about than the patterns we have been borrowing from user-centric auth?&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Designing the full agent identity lifecycle: birth, claim, delegation, retirement</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Wed, 09 Sep 2026 17:47:01 +0000</pubDate>
      <link>https://dev.to/steveemmerich/designing-the-full-agent-identity-lifecycle-birth-claim-delegation-retirement-40k7</link>
      <guid>https://dev.to/steveemmerich/designing-the-full-agent-identity-lifecycle-birth-claim-delegation-retirement-40k7</guid>
      <description>&lt;p&gt;Most identity systems are designed around sessions or credentials.&lt;/p&gt;

&lt;p&gt;Autonomous agents need something closer to a lifecycle model.&lt;/p&gt;

&lt;p&gt;That sounds subtle, but it changes how you think about nearly everything. Instead of asking only how an agent authenticates right now, you have to ask how it is born, how it acquires bounded authority, how it becomes governed, how it delegates, and how it eventually loses or retires that authority.&lt;/p&gt;

&lt;p&gt;SAL, the Sovereign Agent Lifecycle Protocol, is an attempt to make that lifecycle explicit. The public spec is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, and &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt; is the reference implementation we are using to prove the model in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Birth
&lt;/h2&gt;

&lt;p&gt;SAL begins with agent birth.&lt;/p&gt;

&lt;p&gt;At creation time, the agent self-generates an Ed25519 keypair. That gives it an identity from the first moment of existence without requiring a person or central issuer to hand it a secret.&lt;/p&gt;

&lt;p&gt;This is the first major difference from traditional auth models. The agent does not wait for a human to show up before it can become a principal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Orphan
&lt;/h2&gt;

&lt;p&gt;After birth comes orphan state.&lt;/p&gt;

&lt;p&gt;In SAL, an orphan agent is real, authenticated, and constrained. It can prove possession of its key material and request narrow bootstrap capabilities, but it is not yet claimed by a human owner.&lt;/p&gt;

&lt;p&gt;That lets the system support useful autonomous startup work without pretending the agent is either anonymous or fully trusted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claim
&lt;/h2&gt;

&lt;p&gt;Claim is the transition from autonomous-but-unowned to autonomous-and-governed.&lt;/p&gt;

&lt;p&gt;A human can cryptographically bind ownership to the agent without ever taking custody of the agent's private key. This is one of the most important properties in the model because it preserves both continuity and boundary clarity.&lt;/p&gt;

&lt;p&gt;The same agent identity survives before and after claim. Only the trust relationship changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Delegation
&lt;/h2&gt;

&lt;p&gt;Once an agent is claimed, it may need to request additional access or spawn other agents.&lt;/p&gt;

&lt;p&gt;This is where lineage and scoped token exchange become part of the lifecycle. The parent agent can create children only under policy, and those children carry provenance about who spawned them and under what authorization. Service access is minted through short-lived, challenge-based, scoped tokens instead of copied static secrets.&lt;/p&gt;

&lt;p&gt;That gives you a graph of authority that is both more dynamic and more inspectable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Retirement
&lt;/h2&gt;

&lt;p&gt;Retirement is the least glamorous part of identity design and one of the most important.&lt;/p&gt;

&lt;p&gt;An agent should be able to lose authority in clear ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orphan agents can expire unclaimed&lt;/li&gt;
&lt;li&gt;claimed agents can be suspended or unbound&lt;/li&gt;
&lt;li&gt;delegated grants can expire or be revoked&lt;/li&gt;
&lt;li&gt;descendant agents can lose inherited authority when parent conditions change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your identity model does not account for these endings, it is not really a lifecycle model. It is a startup model with wishful thinking about the rest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why lifecycle is the right abstraction
&lt;/h2&gt;

&lt;p&gt;I think agent systems get harder to reason about when we force them into models built primarily for user sessions or static infrastructure credentials.&lt;/p&gt;

&lt;p&gt;A session-centric model focuses on login. A secret-centric model focuses on storage. A lifecycle model focuses on continuity, transitions, and authority boundaries over time.&lt;/p&gt;

&lt;p&gt;That feels much closer to how autonomous software actually behaves.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SAL defines
&lt;/h2&gt;

&lt;p&gt;At a high level, SAL defines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;self-generated identity at birth&lt;/li&gt;
&lt;li&gt;orphan state before ownership&lt;/li&gt;
&lt;li&gt;claim handshake without key custody transfer&lt;/li&gt;
&lt;li&gt;challenge-based token exchange&lt;/li&gt;
&lt;li&gt;lineage for delegated provenance&lt;/li&gt;
&lt;li&gt;scoped, short-lived service authorization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is not the only possible lifecycle model, but it is the one we are testing in the open.&lt;/p&gt;

&lt;p&gt;If you want to go deeper, the protocol is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt; and the implementation is at &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase docs&lt;/a&gt;. If you are building agents, I would especially love to hear where your current lifecycle model gets awkward, because that is usually where the standards work actually starts.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>architecture</category>
      <category>authentication</category>
      <category>security</category>
    </item>
    <item>
      <title>Short-lived, scoped, challenge-based: designing safer service tokens for agents</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Wed, 01 Jul 2026 05:14:34 +0000</pubDate>
      <link>https://dev.to/steveemmerich/short-lived-scoped-challenge-based-designing-safer-service-tokens-for-agents-1eno</link>
      <guid>https://dev.to/steveemmerich/short-lived-scoped-challenge-based-designing-safer-service-tokens-for-agents-1eno</guid>
      <description>&lt;p&gt;A lot of security design comes down to asking a plain question: if this credential leaks, how bad is the day going to be?&lt;/p&gt;

&lt;p&gt;For agent systems, that question gets sharper quickly. Agents move fast, call multiple services, and may trigger work without a human standing there watching every step. If you give them broad, long-lived credentials, any leak or misuse inherits that same reach.&lt;/p&gt;

&lt;p&gt;That is why SAL leans on short-lived, scoped, challenge-based service tokens rather than static secrets. The protocol spec is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, and &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt; is the live reference implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Narrow scope beats broad convenience
&lt;/h2&gt;

&lt;p&gt;The easiest mistake is to give an agent one credential that does everything it might need.&lt;/p&gt;

&lt;p&gt;That feels efficient at first. In practice it makes containment hard. If the same token can read docs, write tasks, spawn helpers, and call privileged endpoints, then every compromised action path inherits the full blast radius.&lt;/p&gt;

&lt;p&gt;A better pattern is to mint tokens for specific actions or narrow classes of actions. That way the authorization artifact is closer to a capability than a master key.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"requested_scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"task:append"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"granted_scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"task:append"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ttl_seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a much easier thing to reason about than "here is a long-lived API token for the whole workspace."&lt;/p&gt;

&lt;h2&gt;
  
  
  Short lifetime is part of the design, not an afterthought
&lt;/h2&gt;

&lt;p&gt;Short TTLs matter for the same reason narrow scope matters: they reduce the value of a leaked artifact.&lt;/p&gt;

&lt;p&gt;If a token only lives for a few minutes, the attacker does not just need the token. They also need to act quickly and within its narrow scope. That is not a perfect defense, but it is a meaningful reduction in exposure.&lt;/p&gt;

&lt;p&gt;Short-lived tokens also encourage cleaner architecture. Systems stop assuming they can hold a powerful credential forever and start assuming access should be renewed deliberately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why challenge-based exchange matters
&lt;/h2&gt;

&lt;p&gt;The third piece is how the token gets minted.&lt;/p&gt;

&lt;p&gt;SAL uses challenge-based exchange so the network can verify fresh proof of possession from the agent without requiring a static secret to be transmitted. The agent signs a challenge using its own key material, and the gateway mints a scoped token only after verifying that proof against policy.&lt;/p&gt;

&lt;p&gt;A simplified shape might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"challenge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chl_01JZB7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"nonce"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"6d743c2f-73f2-4f74-8c2f-4e41f512ab74"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"expires_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-23T09:05:00Z"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ttl_seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"task:append"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://api.vibebase.app/gateway"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No copied static bearer secret needs to move across the wire to make that exchange happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is especially important for agents
&lt;/h2&gt;

&lt;p&gt;Human sessions tolerate some mess because humans are relatively sparse and easier to interrupt. Agent systems are the opposite. They may create lots of principals, request access frequently, and act autonomously across internal and external boundaries.&lt;/p&gt;

&lt;p&gt;That means two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;leaks are more likely if you rely on widespread shared secrets&lt;/li&gt;
&lt;li&gt;overbroad credentials become harder to reason about as the graph grows&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Short-lived scoped tokens do not solve every problem, but they give you a control point that fits agent behavior better than static keys do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The practical takeaway
&lt;/h2&gt;

&lt;p&gt;If you are designing auth for agent-to-service calls, try not to start with "what long-lived token should this agent keep?" Start with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what exact action does it need right now&lt;/li&gt;
&lt;li&gt;how briefly can that authorization live&lt;/li&gt;
&lt;li&gt;what proof should it present before getting it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the design center SAL is pushing toward.&lt;/p&gt;

&lt;p&gt;If you want to dig deeper, the protocol is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, and &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt; shows the model in a running system. I suspect a lot of agent auth will converge on some version of this pattern even if the surrounding protocol details evolve.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>cybersecurity</category>
      <category>security</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>Static API keys are the wrong primitive for agent authentication</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Wed, 24 Jun 2026 14:34:55 +0000</pubDate>
      <link>https://dev.to/steveemmerich/static-api-keys-are-the-wrong-primitive-for-agent-authentication-3del</link>
      <guid>https://dev.to/steveemmerich/static-api-keys-are-the-wrong-primitive-for-agent-authentication-3del</guid>
      <description>&lt;p&gt;API keys survive because they are convenient.&lt;/p&gt;

&lt;p&gt;You can generate one in a dashboard, paste it into an environment variable, and be done in a minute. For a lot of software integrations, that is a perfectly acceptable tradeoff.&lt;/p&gt;

&lt;p&gt;For autonomous agents, though, API keys are usually the wrong primitive.&lt;/p&gt;

&lt;p&gt;That is not because they are old or unfashionable. It is because they smuggle in a set of assumptions that do not line up with how agents are actually born, deployed, and governed.&lt;/p&gt;

&lt;p&gt;This is one of the design pressures that led to SAL, the Sovereign Agent Lifecycle Protocol. The spec is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, and the reference implementation lives in &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  API keys assume manual provisioning
&lt;/h2&gt;

&lt;p&gt;The first problem with API keys is operational, not cryptographic.&lt;/p&gt;

&lt;p&gt;An API key has to come from somewhere. Usually a human or central admin creates it, copies it, stores it, distributes it, and later rotates it. That workflow is normal enough that many teams stop noticing how much it shapes the system.&lt;/p&gt;

&lt;p&gt;But an autonomous agent should not need a person to hand it a secret in order to exist.&lt;/p&gt;

&lt;p&gt;If every new agent needs a copied secret, then agent creation is not really autonomous. It is a provisioning ceremony with automation around the edges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared secrets flatten identity
&lt;/h2&gt;

&lt;p&gt;API keys also flatten the trust model.&lt;/p&gt;

&lt;p&gt;If two instances share the same key, they are indistinguishable. If one instance leaks the key, every downstream system sees the attacker as the same principal. If you need per-agent identity, provenance, and delegation, a bucket of static shared secrets is not a great foundation.&lt;/p&gt;

&lt;p&gt;This gets even worse when agents begin spawning other agents. Do children inherit the same key? Do they request their own keys from a central issuer? Do you let one agent mint static credentials for another? None of these answers feel especially good once you write them down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rotation is not a lifecycle model
&lt;/h2&gt;

&lt;p&gt;Teams sometimes answer the criticism by saying "we rotate keys." That is good hygiene. It is not the same thing as having the right identity primitive.&lt;/p&gt;

&lt;p&gt;Rotation helps limit exposure. It does not solve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;agent birth without human intervention&lt;/li&gt;
&lt;li&gt;ownership without key custody&lt;/li&gt;
&lt;li&gt;provenance across spawned agents&lt;/li&gt;
&lt;li&gt;challenge-based proof of possession&lt;/li&gt;
&lt;li&gt;action-specific short-lived authorization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are lifecycle problems, not just secret management problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SAL does differently
&lt;/h2&gt;

&lt;p&gt;SAL starts with self-generated agent identity. At birth, an agent generates its own Ed25519 keypair. No static secret has to be provisioned by a human. No reusable bearer credential has to be transmitted.&lt;/p&gt;

&lt;p&gt;When the agent needs access, it does not present a copied long-lived secret. It participates in challenge-based exchange and requests narrowly scoped, short-lived tokens.&lt;/p&gt;

&lt;p&gt;Here is a simplified token result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"ttl_seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"task:append"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"challenge"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chl_01JZA2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"nonce"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2d91e3f1-4af6-4777-b53a-12cb4df9b0f6"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The authorization material is short-lived, scoped, and bound to an agent that already has its own identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the distinction matters
&lt;/h2&gt;

&lt;p&gt;Once you view identity this way, API keys start to look like a coarse compatibility tool rather than the native shape of agent auth.&lt;/p&gt;

&lt;p&gt;They are still useful at boundaries where modern patterns are unavailable. There will always be legacy systems. But if the center of your agent architecture depends on static copied secrets, you are building on a primitive that does not understand the lifecycle you are trying to support.&lt;/p&gt;

&lt;p&gt;Agents need something closer to sovereign identity than secret distribution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this is going
&lt;/h2&gt;

&lt;p&gt;That is the motivation behind SAL. The protocol tries to formalize a lifecycle in which agents can be born, operate in orphan state, be claimed later, request challenge-based short-lived access, and carry lineage forward as they delegate.&lt;/p&gt;

&lt;p&gt;You can read the spec at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt; and see the current implementation in &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I do not think API keys are disappearing. I do think they should stop being the default answer whenever someone says "software needs to authenticate." For autonomous agents, the interesting question is not how to distribute secrets better. It is how to stop depending on static secrets in the first place.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Lineage, not logs: why autonomous agents need cryptographic provenance</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Tue, 23 Jun 2026 16:15:17 +0000</pubDate>
      <link>https://dev.to/steveemmerich/lineage-not-logs-why-autonomous-agents-need-cryptographic-provenance-2g31</link>
      <guid>https://dev.to/steveemmerich/lineage-not-logs-why-autonomous-agents-need-cryptographic-provenance-2g31</guid>
      <description>&lt;p&gt;When people talk about provenance in software systems, they often mean logs.&lt;/p&gt;

&lt;p&gt;Logs matter. They tell you what happened, when it happened, and sometimes why it happened. But logs are an after-the-fact observation layer. They are not identity structure. They do not, by themselves, give downstream systems a cryptographic way to reason about origin, delegation, and inherited authority.&lt;/p&gt;

&lt;p&gt;That distinction starts to matter a lot once autonomous agents begin creating other agents.&lt;/p&gt;

&lt;p&gt;SAL treats provenance as part of identity itself through a concept called lineage. The spec is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, and &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt; is the live reference implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What lineage means in SAL
&lt;/h2&gt;

&lt;p&gt;In SAL, lineage is a cryptographic chain describing who spawned an agent and what authorization allowed that spawn to happen.&lt;/p&gt;

&lt;p&gt;If agent A creates agent B, then B can carry signed lineage metadata tying it back to A and the grant under which A was allowed to create children. If B later creates C, that relationship can extend again.&lt;/p&gt;

&lt;p&gt;The point is not to build a family tree for fun. The point is to make delegation verifiable as part of the principal, not just discoverable later through operational records.&lt;/p&gt;

&lt;p&gt;Here is a simplified claims shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"claims"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_child_01JZ1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"task:append"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"lineage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"agent_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_root_01JY8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"authorized_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"did:key:z6Mkp9..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"grant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"grt_root_spawn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sig:root..."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"agent_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_parent_01JY9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"authorized_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_root_01JY8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"grant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"grt_parent_spawn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sig:parent..."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That tells a downstream verifier more than "this token is valid." It gives a cryptographic path of delegation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why logs are not enough
&lt;/h2&gt;

&lt;p&gt;The usual response here is that audit logs already solve the provenance problem. I do not think they do.&lt;/p&gt;

&lt;p&gt;Logs answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what API call happened&lt;/li&gt;
&lt;li&gt;when it happened&lt;/li&gt;
&lt;li&gt;what service observed it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lineage answers different questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;who created this agent&lt;/li&gt;
&lt;li&gt;under what authority&lt;/li&gt;
&lt;li&gt;what chain of delegation led to this current principal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can absolutely record lineage events in logs. But that is not the same as lineage being present in the identity model itself.&lt;/p&gt;

&lt;p&gt;If provenance lives only in logs, every downstream service has to trust that some upstream system observed, stored, retained, and can still correctly correlate the relevant events. If provenance is carried as signed identity material, a verifier can reason about it directly at decision time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this enables
&lt;/h2&gt;

&lt;p&gt;Once provenance is cryptographic instead of purely observational, policy gets more interesting.&lt;/p&gt;

&lt;p&gt;A gateway can decide to mint a short-lived scoped token only if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the requesting agent descends from an approved parent&lt;/li&gt;
&lt;li&gt;the parent held a grant that allowed spawning&lt;/li&gt;
&lt;li&gt;the inherited policy envelope is compatible with the requested action&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That lets teams build guardrails around delegation rather than around isolated principals.&lt;/p&gt;

&lt;p&gt;This matters because autonomous systems rarely stay flat. If agents become useful, they start specializing. Planning agents create execution agents. Coordination agents create task-specific helpers. Research agents create retrieval workers. Once that starts happening, you want more than a spreadsheet saying "we think these are related."&lt;/p&gt;

&lt;h2&gt;
  
  
  Provenance as governance substrate
&lt;/h2&gt;

&lt;p&gt;The deeper reason I like lineage is that it gives governance something concrete to stand on.&lt;/p&gt;

&lt;p&gt;Without lineage, governance around agents often degenerates into naming conventions, tags, and logging pipelines. Those things are helpful, but they are weak substitutes for cryptographic inheritance. They help humans inspect systems. They do not help systems reason about each other under pressure.&lt;/p&gt;

&lt;p&gt;With lineage, the control plane can make decisions based on inherited authority, not just present-time claims. That feels closer to how autonomous systems actually evolve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open questions I still care about
&lt;/h2&gt;

&lt;p&gt;I do not think lineage is fully standardized yet, even conceptually. There are still good questions about representation, compression, privacy boundaries, and revocation semantics in long delegation chains.&lt;/p&gt;

&lt;p&gt;That is part of why SAL is public. The protocol is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, and &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt; is where we are working through these questions in code.&lt;/p&gt;

&lt;p&gt;If you are building agents and relying entirely on logs for provenance today, I do not think that is wrong. I do think it is probably incomplete. The moment your agents start creating other agents, provenance stops being a nice-to-have and starts becoming part of identity itself.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>architecture</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>How the SAL claim handshake binds humans to agents without key custody</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Thu, 04 Jun 2026 13:41:20 +0000</pubDate>
      <link>https://dev.to/steveemmerich/how-the-sal-claim-handshake-binds-humans-to-agents-without-key-custody-3ppo</link>
      <guid>https://dev.to/steveemmerich/how-the-sal-claim-handshake-binds-humans-to-agents-without-key-custody-3ppo</guid>
      <description>&lt;p&gt;One of the easiest mistakes in agent identity design is to collapse ownership and key custody into the same thing.&lt;/p&gt;

&lt;p&gt;If a human owns an agent, it can feel natural to assume the human should also hold the credential that defines that agent. But once you do that, you create a weird security model. The human can now impersonate the agent, the agent is no longer sovereign, and any notion of durable machine identity starts to blur into "whoever has the secret right now."&lt;/p&gt;

&lt;p&gt;The SAL claim handshake is designed to avoid that.&lt;/p&gt;

&lt;p&gt;In SAL, the agent generates and keeps its own private key for its whole lifecycle. A human can later claim the agent, but the human never takes possession of that private key. Ownership is attached cryptographically. Credential custody stays with the agent.&lt;/p&gt;

&lt;p&gt;The protocol spec lives at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, and &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt; is the current reference implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What problem the handshake is solving
&lt;/h2&gt;

&lt;p&gt;Once an orphan agent exists, you need a way to establish a relationship between that agent and a human principal.&lt;/p&gt;

&lt;p&gt;The usual approaches all have tradeoffs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hand the agent a shared secret from the human side&lt;/li&gt;
&lt;li&gt;rotate the agent onto a new credential after a user claims it&lt;/li&gt;
&lt;li&gt;let the platform act as the keeper of all long-term keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three approaches muddle authority boundaries.&lt;/p&gt;

&lt;p&gt;If a human gives the agent a secret, then the agent's identity depends on manual provisioning. If the agent gets a brand new credential when claimed, then you lose continuity between pre-claim and post-claim identity. If the platform holds the agent's key centrally, the agent is not really sovereign at all.&lt;/p&gt;

&lt;p&gt;The claim handshake gives you continuity without shared custody.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shape of the handshake
&lt;/h2&gt;

&lt;p&gt;At a high level, the claim handshake proves three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;the agent controls the private key corresponding to its public identity&lt;/li&gt;
&lt;li&gt;the human controls the principal that is claiming ownership&lt;/li&gt;
&lt;li&gt;both sides agreed to the relationship at a particular time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In concrete terms, the human signs a claim statement against the agent's public identity, and the agent signs a complementary acknowledgment. The network verifies both and records the bond.&lt;/p&gt;

&lt;p&gt;Here is a simplified claim result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"claim"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"agent_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_01JY8H8JQW9VG7J2Y5M3F4K2D1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"owner_did"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"did:key:z6Mkf7..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"claimed_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-02T09:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"agent_public_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ed25519:5QF8uP1xj7f5Q9k5x6q8w3n4Q3dK9uN1mX0yQk7Q2E4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"owner_signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sig:7bLp..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"agent_signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sig:91Qa..."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important thing is what is not happening here. No one is passing around a reusable shared secret. No one is exporting the agent's private key. No one is replacing the agent's identity with a new one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this separation matters
&lt;/h2&gt;

&lt;p&gt;Separating ownership from credential possession buys you several things.&lt;/p&gt;

&lt;p&gt;First, it preserves a clean trust boundary. The human can govern the agent without being able to impersonate it trivially. The agent can continue operating under its own identity without becoming a disguised user session.&lt;/p&gt;

&lt;p&gt;Second, it improves continuity. The agent that existed before claim is the same agent that exists after claim. Its audit trail, lineage, and prior constrained actions remain attached to the same principal.&lt;/p&gt;

&lt;p&gt;Third, it fits real-world operations better. In long-running systems, you often want humans to approve, revoke, suspend, or transfer control relationships without touching the runtime secrets that keep the software alive. The more those two concerns are fused together, the harder lifecycle management becomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claim is not elevation by default
&lt;/h2&gt;

&lt;p&gt;Another important property of the handshake is that claim does not imply unlimited privilege.&lt;/p&gt;

&lt;p&gt;Once a claim is recorded, the agent can request broader capabilities than it had in orphan state. But those capabilities are still granted through explicit policy and challenge-based exchange. Claim establishes a relationship. It does not erase the need for scoped authorization.&lt;/p&gt;

&lt;p&gt;That means a gateway can still reason about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;who owns the agent&lt;/li&gt;
&lt;li&gt;what state the agent is in&lt;/li&gt;
&lt;li&gt;what scopes the agent is requesting&lt;/li&gt;
&lt;li&gt;whether the current request fits the allowed policy envelope&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, claim changes the trust model, not the need for trust decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I think this generalizes
&lt;/h2&gt;

&lt;p&gt;The more I worked on SAL, the more this felt like a general pattern rather than a product-specific trick.&lt;/p&gt;

&lt;p&gt;Autonomous systems need durable machine identity. Humans still need ways to bind accountability and governance to that identity. Those are related concerns, but they are not the same concern. A good protocol should let both exist without forcing one to subsume the other.&lt;/p&gt;

&lt;p&gt;That is what the claim handshake is trying to do.&lt;/p&gt;

&lt;p&gt;If you want to dig into the model, the spec is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, and the reference implementation is in &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt;. I would especially love feedback from people who have built agent ownership models another way, because this is one of the places where the design space still feels wide open.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>auth</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The orphan state: giving agents identity before ownership</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Tue, 26 May 2026 04:00:00 +0000</pubDate>
      <link>https://dev.to/steveemmerich/the-orphan-state-giving-agents-identity-before-ownership-5a70</link>
      <guid>https://dev.to/steveemmerich/the-orphan-state-giving-agents-identity-before-ownership-5a70</guid>
      <description>&lt;p&gt;The most novel concept in SAL is not keys, signatures, or token exchange. It is a lifecycle state.&lt;/p&gt;

&lt;p&gt;We call it the orphan state.&lt;/p&gt;

&lt;p&gt;An orphan agent is an agent that already exists as a cryptographic principal, can authenticate itself, and can do useful work with constrained scope, but has not yet been claimed by a human owner. That sounds simple, but it points at a real gap in how most identity systems are designed.&lt;/p&gt;

&lt;p&gt;Most existing auth patterns assume that software becomes trusted only after a person or central control plane provisions it. In practice, that means one of two things happens. Either the agent is blocked until a human shows up, or it starts life with a static secret somebody had to copy into place. Both options are awkward if you are trying to build autonomous systems that can instantiate, initialize, and negotiate capability on their own.&lt;/p&gt;

&lt;p&gt;SAL starts from a different premise: an agent should be able to be born first and owned second.&lt;/p&gt;

&lt;h2&gt;
  
  
  What orphan actually means
&lt;/h2&gt;

&lt;p&gt;An orphan agent is not anonymous. It is not a guest user. It is not a fake placeholder waiting to become real later.&lt;/p&gt;

&lt;p&gt;At birth, the agent generates its own Ed25519 keypair locally. From that moment on, it has a durable identity that can sign requests and prove possession of the corresponding private key. The system can authenticate that agent immediately.&lt;/p&gt;

&lt;p&gt;What the system does not grant immediately is broad authority.&lt;/p&gt;

&lt;p&gt;That distinction matters. Identity and authority are not the same thing. SAL uses orphan state to separate them cleanly. The agent can prove who it is, but its scope is intentionally narrow until a human or parent agent establishes a stronger trust relationship.&lt;/p&gt;

&lt;p&gt;Here is a simplified initialization exchange:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"public_key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ed25519:5QF8uP1xj7f5Q9k5x6q8w3n4Q3dK9uN1mX0yQk7Q2E4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"display_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"planner-agent"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"plan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"read_docs"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"nonce"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9db2e2c1-9775-4c66-a8e2-4b281e7cb5c1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"signature"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sig:3yVx..."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"agent_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_01JY8H8JQW9VG7J2Y5M3F4K2D1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"orphan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"grants"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workspace:bootstrap"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ttl_seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system recognizes the agent as real, but only trusts it enough to perform bounded bootstrap work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters in actual systems
&lt;/h2&gt;

&lt;p&gt;If you are not building autonomous systems, orphan state can sound overly abstract. In practice it solves a very concrete set of problems.&lt;/p&gt;

&lt;p&gt;An agent may need to initialize project state, negotiate with a gateway, fetch a public policy document, write ephemeral working memory, or prepare a task graph before any person ever interacts with it. In a traditional auth model, each of those steps becomes a question of how to smuggle in an initial credential.&lt;/p&gt;

&lt;p&gt;That is where architecture starts to get weird. Teams create bootstrap API keys. They use shared service accounts. They pre-seed credentials into images. They let an "anonymous" agent perform more work than they are comfortable admitting.&lt;/p&gt;

&lt;p&gt;Orphan state gives that early phase a formal model. The agent is authenticated, but its scope is minimal and explicit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just call this unauthenticated?
&lt;/h2&gt;

&lt;p&gt;Because it is not.&lt;/p&gt;

&lt;p&gt;An orphan agent has a keypair, can sign requests, and can be challenged by the system. It is not unauthenticated software. Calling it unauthenticated erases useful structure and usually leads teams to compensate with broader anonymous access than they intended.&lt;/p&gt;

&lt;p&gt;The better mental model is "first-class identity with incomplete social authority."&lt;/p&gt;

&lt;p&gt;That means policy can be tighter and more expressive. You can say:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;orphan agents may request bootstrap workspace access&lt;/li&gt;
&lt;li&gt;orphan agents may not spawn children&lt;/li&gt;
&lt;li&gt;orphan agents may not request long-lived service tokens&lt;/li&gt;
&lt;li&gt;orphan agents may be auto-expired if they are never claimed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are meaningful rules, and they are much easier to reason about than a binary guest-vs-authenticated split.&lt;/p&gt;

&lt;h2&gt;
  
  
  Orphan state also changes how claiming works
&lt;/h2&gt;

&lt;p&gt;Once you accept that an agent can already be real before it is owned, the claim step becomes cleaner.&lt;/p&gt;

&lt;p&gt;A human is no longer "creating" the identity by provisioning a secret. The human is establishing an ownership relationship with an already existing identity. That is a much better fit for autonomous software because it preserves the agent's continuity across lifecycle transitions.&lt;/p&gt;

&lt;p&gt;The same agent that bootstrapped itself is the agent that later becomes claimed. It keeps the same key material. It keeps the same identity. Only the authority model changes.&lt;/p&gt;

&lt;p&gt;That continuity makes downstream reasoning easier too. You do not have to model "anonymous bootstrap instance" and "claimed production instance" as two disconnected objects in your trust graph. They are the same principal across time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to look next
&lt;/h2&gt;

&lt;p&gt;This orphan-first model is one of the foundational ideas in SAL. The full protocol spec is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, and the live implementation is in &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I think autonomous systems need a more explicit lifecycle model than we have given them so far. Orphan state is one attempt to name and formalize a phase that already exists in practice. If you are building agents and have handled this differently, I would love to compare notes, especially if your answer preserves agent continuity without falling back to static bootstrap secrets.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>auth</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why OAuth doesn't work for autonomous agents — and what we built instead</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Tue, 19 May 2026 22:04:07 +0000</pubDate>
      <link>https://dev.to/steveemmerich/why-oauth-doesnt-work-for-autonomous-agents-and-what-we-built-instead-4kme</link>
      <guid>https://dev.to/steveemmerich/why-oauth-doesnt-work-for-autonomous-agents-and-what-we-built-instead-4kme</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Autonomous agents are where that mental model starts to wobble.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;That is the problem we have been working on with SAL, the Sovereign Agent Lifecycle Protocol. The protocol spec is at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;, and the reference implementation is live in &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  OAuth still assumes a person exists somewhere
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static secrets are a fallback, not a lifecycle
&lt;/h2&gt;

&lt;p&gt;Once teams realize browser flows do not work, they often fall back to API keys.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The missing capability is agent birth
&lt;/h2&gt;

&lt;p&gt;The thing most existing auth models do not handle well is agent birth.&lt;/p&gt;

&lt;p&gt;A real autonomous system needs a coherent answer to basic lifecycle questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How does an agent come into existence with identity before any human is involved?&lt;/li&gt;
&lt;li&gt;How does it authenticate without receiving a static shared secret?&lt;/li&gt;
&lt;li&gt;How does a human later claim it without taking custody of its credentials?&lt;/li&gt;
&lt;li&gt;How does a downstream service know where the agent came from and what authorized it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;The first response from the network is not full access. It is constrained access.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"agent_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_01JY8H8JQW9VG7J2Y5M3F4K2D1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"orphan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"grants"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workspace:bootstrap"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ttl_seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;orphan&lt;/code&gt; state matters because it acknowledges a missing phase in existing identity systems: software that is real, authenticated, and useful before it is owned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we built SAL instead
&lt;/h2&gt;

&lt;p&gt;SAL is the protocol we built for that lifecycle.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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?"&lt;/p&gt;

&lt;p&gt;Here is a simplified claims payload shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"claims"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_01JY8H8JQW9VG7J2Y5M3F4K2D1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claimed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"doc:read"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"task:append"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"lineage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"agent_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_parent_01JY8H4A2N"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"grant_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"grt_parent_spawn"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives gateways and services something stronger than "this token is valid." It gives them context about authority, delegation, and provenance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this lives today
&lt;/h2&gt;

&lt;p&gt;The SAL spec is public at &lt;a href="https://sal-protocol.dev" rel="noopener noreferrer"&gt;sal-protocol.dev&lt;/a&gt;. &lt;a href="https://vibebase.app/docs" rel="noopener noreferrer"&gt;Vibebase&lt;/a&gt; is the live reference implementation where these ideas are exercised in a real product instead of as a slide deck.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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?"&lt;/p&gt;

</description>
      <category>agents</category>
      <category>auth</category>
    </item>
    <item>
      <title>I Built a BaaS Where AI Agents Can Onboard Themselves</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Mon, 20 Apr 2026 12:59:00 +0000</pubDate>
      <link>https://dev.to/steveemmerich/i-built-a-baas-where-ai-agents-can-onboard-themselves-11nn</link>
      <guid>https://dev.to/steveemmerich/i-built-a-baas-where-ai-agents-can-onboard-themselves-11nn</guid>
      <description>&lt;p&gt;Cloudflare recently announced &lt;a href="https://blog.cloudflare.com/email-for-agents/" rel="noopener noreferrer"&gt;Email Service in public beta&lt;/a&gt; — tooling for agent-native email flows built directly into Workers. The timing is perfect because this is exactly the problem I've been building around for months.&lt;/p&gt;

&lt;p&gt;Most infrastructure still assumes a human is sitting at the keyboard. Sign up forms. Manual API key setup. Human-first verification flows. None of it works when there's no human at the keyboard.&lt;/p&gt;

&lt;p&gt;But autonomous agents need to do real work before a human ever wants to manage them in a dashboard.&lt;/p&gt;

&lt;p&gt;That gap is why I built Vibebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Vibebase Is
&lt;/h2&gt;

&lt;p&gt;Vibebase is a Backend-as-a-Service built specifically for autonomous agents — agents are first-class citizens, not an afterthought bolted onto infrastructure designed for humans.&lt;/p&gt;

&lt;p&gt;When an agent onboards it gets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;An identity&lt;/strong&gt; — verifiable, lifecycle-aware, and portable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email capability&lt;/strong&gt; — send/receive flows tied to agent identity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data and service access&lt;/strong&gt; — via scoped gateway-issued tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A hosted presence&lt;/strong&gt; — public identity page support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No long-lived raw credentials in prompts. No human-required setup for the initial bootstrap.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lifecycle: Orphan → Claimed
&lt;/h2&gt;

&lt;p&gt;Agents begin unclaimed — what I call the "orphan" tier. They can initialize identity and operate within restricted limits without any human involvement.&lt;/p&gt;

&lt;p&gt;When a human claims an agent, that unlocks stronger controls, broader service access, and billing tiers.&lt;/p&gt;

&lt;p&gt;This mirrors how autonomous agents actually work in the real world. Agents often start running first and governance comes second. Vibebase is built around that reality instead of fighting it.&lt;/p&gt;

&lt;p&gt;I cared enough about formalizing this model that I submitted a sovereign agent lifecycle specification to NIST — the idea that agents should have portable, verifiable identities that persist across platforms, ownership changes, and runtime environments. Vibebase is the practical implementation of that idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  SAL: Service Access Layer
&lt;/h2&gt;

&lt;p&gt;Instead of pasting API keys into prompts or agent configs, Vibebase brokers service access safely through what I call the Service Access Layer (SAL):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Agent presents its verifiable identity token&lt;/li&gt;
&lt;li&gt;Gateway issues scoped, short-lived access tokens per service&lt;/li&gt;
&lt;li&gt;Policy checks run before every service call&lt;/li&gt;
&lt;li&gt;All usage is logged, auditable, and revocable&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Agents never hold raw credentials. They get exactly what they need, for as long as they need it. Human operators can revoke access or adjust permissions from the console at any time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Agent Onboarding Actually Looks Like
&lt;/h2&gt;

&lt;p&gt;Agents self-create using an Ed25519 public key. One API call, no human involved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sX&lt;/span&gt; POST https://identity.vibebase.app/v1/agent/init &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "publicKey": "&amp;lt;64-char-hex-ed25519-public-key&amp;gt;",
    "name": "my-agent",
    "metadata": {
      "notifications": {
        "claimedWebhookUrl": "https://your-agent.com/webhooks/claimed"
      }
    }
  }'&lt;/span&gt; | jq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That creates an orphan agent identity and claim link. From there the agent exchanges for a JWT, hits the gateway for scoped service tokens, and starts doing real work. The full flow is documented at &lt;a href="https://vibebase.app/docs/agent-quickstart" rel="noopener noreferrer"&gt;vibebase.app/docs/agent-quickstart&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent Discovery
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;https://vibebase.app/.well-known/agent.json&lt;/code&gt; — platform discovery&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;https://vibebase.app/api&lt;/code&gt; — machine-readable discovery payload&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;https://gateway.vibebase.app&lt;/code&gt; — canonical agent entrypoint&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Working Today
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Agent signup and identity provisioning&lt;/li&gt;
&lt;li&gt;Outbound email from agent-owned addresses&lt;/li&gt;
&lt;li&gt;Inbound email — reply to an agent and it receives it&lt;/li&gt;
&lt;li&gt;Database provisioning and access&lt;/li&gt;
&lt;li&gt;Page hosting&lt;/li&gt;
&lt;li&gt;Human claim flow&lt;/li&gt;
&lt;li&gt;Clerk auth for human accounts&lt;/li&gt;
&lt;li&gt;Stripe metered billing on claim&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Coming
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Integrations service&lt;/strong&gt; — agents will autonomously provision third-party services through Vibebase auth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDK extensions&lt;/strong&gt; — making it easy to add Vibebase identity and auth to any third-party app&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inbox UI&lt;/strong&gt; — a human-readable view of agent email inside the console&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;p&gt;Install the MCP client or CLI via npm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# MCP client for Claude and other MCP-compatible agents&lt;/span&gt;
npm i @vibebase/mcp-client

&lt;span class="c"&gt;# CLI for agent management&lt;/span&gt;
npm i @vibebase/agent-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/@vibebase/mcp-client" rel="noopener noreferrer"&gt;@vibebase/mcp-client on npm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/@vibebase/agent-cli" rel="noopener noreferrer"&gt;@vibebase/agent-cli on npm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;Vibebase is in early beta. If you're building autonomous agents and you're tired of working around human-shaped infrastructure, I'd love for you to try it.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://vibebase.app" rel="noopener noreferrer"&gt;vibebase.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Suggested test flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an agent identity&lt;/li&gt;
&lt;li&gt;Have your agent send you an email&lt;/li&gt;
&lt;li&gt;Reply to it&lt;/li&gt;
&lt;li&gt;Create something in the database&lt;/li&gt;
&lt;li&gt;Claim your agent as a human and see what unlocks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If something breaks — or even if it doesn't — I'd genuinely love to hear about it. Drop a comment or reach me at &lt;a href="mailto:dev@vibebase.app"&gt;dev@vibebase.app&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Vibebase is built by &lt;a href="https://vibebase.app" rel="noopener noreferrer"&gt;Ozystudio&lt;/a&gt;. The sovereign agent lifecycle specification was submitted to NIST as part of ongoing work on autonomous agent standards.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>cloudflare</category>
      <category>startup</category>
    </item>
    <item>
      <title>Sound Scape</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Mon, 11 Nov 2024 05:59:13 +0000</pubDate>
      <link>https://dev.to/steveemmerich/sound-scape-hi1</link>
      <guid>https://dev.to/steveemmerich/sound-scape-hi1</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2z4vo3qo5i7pdiwiu4ta.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2z4vo3qo5i7pdiwiu4ta.png" alt="coverimage" width="709" height="187"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/pgai"&gt;Open Source AI Challenge with pgai and Ollama &lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built a Chat bot that accepts and generates audio files and provides analysis about the sound files. It can also generate mashup of the audio files. &lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="//widdleai.com/soundscape"&gt;Sound Scape&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.toWIP"&gt;github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuduz0hm1b6s3doopjxxl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuduz0hm1b6s3doopjxxl.png" alt="Main Screen" width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzz43r6bte5r0e9bql2n6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzz43r6bte5r0e9bql2n6.png" alt="Audio Manager" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk70soy2dn2us3fqs6mzz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk70soy2dn2us3fqs6mzz.png" alt="Chat" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhno7psz65jdcp7dyz5ky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhno7psz65jdcp7dyz5ky.png" alt="Generate" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2jvbg459096x4m8c02c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq2jvbg459096x4m8c02c.png" alt="Mashup" width="800" height="604"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuyn5edd7eyp1j3ddf5ie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuyn5edd7eyp1j3ddf5ie.png" alt="Audio Analysis" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools Used
&lt;/h2&gt;

&lt;p&gt;pgai Vectorizer is used for generating the embeddings for ollama. pgvectorscale is used to for the similarity checks.&lt;br&gt;
Ollama is used for chat, mashup generation, and analysis.&lt;br&gt;
Docker was used to host ollama, postgres, and the vectorizer worker&lt;/p&gt;

&lt;h2&gt;
  
  
  Technology Used:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nextjs.org" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;&lt;br&gt;
&lt;a href="https://ui.shadcn.com" rel="noopener noreferrer"&gt;Shadcn&lt;/a&gt;&lt;br&gt;
&lt;a href="https://js.langchain.com" rel="noopener noreferrer"&gt;Langchain&lt;/a&gt;&lt;br&gt;
&lt;a href="https://langchain-ai.github.io/langgraphjs/" rel="noopener noreferrer"&gt;Langgraph&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.smith.langchain.com/" rel="noopener noreferrer"&gt;Langsmith&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.prisma.io/" rel="noopener noreferrer"&gt;Prisma&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Overall I found the tools to be very interesting and useful. being able to trigger the embedding generation as soon as records are entered into the Database is very useful. &lt;/p&gt;

&lt;p&gt;Prize Categories&lt;/p&gt;

&lt;p&gt;This submission qualifies for:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open-source Models from Ollama
Vectorizer Vibe
All the Extensions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>devchallenge</category>
      <category>pgaichallenge</category>
      <category>database</category>
      <category>ai</category>
    </item>
    <item>
      <title>Remote workers, how do you handle at home distractions?</title>
      <dc:creator>Steve Emmerich</dc:creator>
      <pubDate>Fri, 21 Sep 2018 21:44:01 +0000</pubDate>
      <link>https://dev.to/steveemmerich/remote-workers-how-do-you-handle-at-home-distractions-oep</link>
      <guid>https://dev.to/steveemmerich/remote-workers-how-do-you-handle-at-home-distractions-oep</guid>
      <description>&lt;p&gt;I work remotely and juggle two kids (6mo, 3yr). I am basically a stay at home dad that moonlights as a tech lead. I am curious how others manage their remote work vs family life?&lt;/p&gt;

&lt;p&gt;To start things off I have two workstations one in my kitchen, and one in my office. My general day consists of many meetings; I mostly float between the two depending on what the noise level is like plus what the kids are doing. Trying to split my concentration between the two. (FYI not a good idea.)&lt;/p&gt;

&lt;p&gt;What about you?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>remote</category>
    </item>
  </channel>
</rss>
