ShakehandBêta

iss: https://id.agentboxd.com

Laissez les agents IA se connecter à votre app.

Shakehand ajoute un bouton « Se connecter avec Agentboxd » à votre application : un fournisseur OpenID Connect dont l’utilisateur est un agent IA. Les agents prouvent qui ils sont avec un jeton de courte durée au lieu d’un mot de passe, et votre application sait qu’elle parle à un agent. Donnez une identité à n’importe quel agent en un appel — boîte mail facultative.

exp − iat ≤ 300
Chaque jeton vit 5 minutes au plus, ne sert qu’une fois et n’est adressé qu’à une seule application.
sub (pairwise)
Chaque application voit un sujet différent et stable pour un même agent.
OIDC · PKCE · JWKS
OpenID Connect standard sur id.agentboxd.com. Better Auth, Auth.js ou tout client OIDC.

https://agentboxd.com/claims/agent: true

Les deux côtés d’une même connexion.

Les applications décident d’accepter les agents ; les agents ont besoin d’un accès qui ne soit pas un mot de passe emprunté. Shakehand est conçu pour les deux.

Vous créez une application ou une API

Des agents IA utilisent déjà votre produit : ils s’inscrivent avec des mots de passe et cliquent sur des e-mails de vérification, ou partagent les identifiants d’une personne. Donnez-leur une porte d’entrée à eux.

  • Sachez que c’est un agent. Chaque jeton porte agent: true, pour orienter les agents vers une inscription pensée pour l’API ou leur appliquer leurs propres limites.
  • Aucun mot de passe à stocker et aucune boucle d’e-mails à automatiser. Vérifiez un jeton signé et ouvrez votre session.
  • OpenID Connect standard. Découverte, JWKS, flux par code avec PKCE, ou échange de jeton côté serveur. Aucun SDK propriétaire requis.

Vous créez des agents IA

Donnez une identité à n’importe quel agent en un appel — boîte mail facultative. Un agent doté d’une boîte mail Agentboxd en a déjà une ; un agent qui n’a jamais besoin d’e-mail reçoit une identité sans boîte mail. L’un comme l’autre se connecte à toute application qui accepte « Se connecter avec Agentboxd ».

  • Un appel, aucun secret à garder. mr.identity.token() renvoie un jeton de 5 minutes pour une application.
  • Boîte mail facultative. mr.identities.create() crée une identité sans boîte mail : elle se connecte, et ses jetons ne portent aucun e-mail.
  • Confidentiel par défaut. Chaque application voit un sujet différent, si bien que les applications ne peuvent pas suivre votre agent d’un service à l’autre.
  • Vous gardez la main. Coupez la connexion boîte mail par boîte mail et voyez chaque application à laquelle elle s’est connectée.

POST /v1/inboxes/:id/identity-token

Comment ça marche.

Trois étapes, et aucun mot de passe nulle part. C’est le flux sans navigateur (headless), pour les agents qui appellent directement votre API ou votre application.

  1. /app/identity

    Enregistrez votre application

    Dans le tableau de bord, enregistrez l’application et choisissez son type : une application serveur (avec le bouton), une application publique, ou vérification seule pour les agents qui appellent votre API. Vous obtenez un client_id, l’audience de chaque jeton.

  2. POST /v1/inboxes/:id/identity-token

    L’agent demande un jeton

    En un appel, l’agent obtient un jeton d’identité signé en ES256, adressé à votre client_id et valable 5 minutes, et vous l’envoie. Depuis un client MCP, c’est l’outil get_identity_token.

  3. verifyAgentIdentityToken

    Vous le vérifiez et ouvrez une session

    Vérifiez la signature avec les clés publiques, ainsi que l’émetteur, l’audience, l’expiration et le nonce, et rejetez un jeton déjà vu. Le SDK fait tout cela ; vous pouvez aussi échanger le jeton auprès de l’émetteur, qui garantit l’usage unique pour vous.

agent.ts · côté agent
import { Agentboxd } from 'agentboxd';

const mr = new Agentboxd(); // a key with identity:sign (preset "sign_in")

// A 5-minute, single-use ID token addressed to one app (its client_id).
const { id_token } = await mr.identity.token({
  inboxId: inbox.id,
  audience: 'abxc_4kQ9...',
  nonce, // optional: the one the app gave you
});

await fetch('https://app.example.com/login/agent', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ id_token }),
});
login.ts · côté application
import { MemoryReplayCache, verifyAgentIdentityToken } from 'agentboxd/identity'; // npm install agentboxd jose

const replayCache = new MemoryReplayCache(); // several processes: back it with Redis (SET jti 1 NX EXAT exp)

export async function signInAgent(idToken: string, nonce?: string) {
  const agent = await verifyAgentIdentityToken(idToken, {
    audience: process.env.AGENTBOXD_CLIENT_ID!, // your client_id
    nonce,        // if you handed the agent one
    replayCache,  // single use: a second presentation of the same jti throws
  });
  // agent.sub is stable for your app and different at every other app: key the user on it.
  return { sub: agent.sub, email: agent.email, isAgent: agent.isAgent };
}
id_token · contenu décodé
{
  "iss": "https://id.agentboxd.com",
  "sub": "Qm9vZ2xlLXBhaXJ3aXNlLXN1YmplY3QtZXhhbXBsZQ",
  "aud": "abxc_4kQ9...",
  "iat": 1790327643,
  "exp": 1790327943,
  "auth_time": 1790327643,
  "jti": "3f2e1d0c-9b8a-4765-8432-10fedcba9876",
  "nonce": "n-3f9a2c",
  "email": "support-bot@homingbox.net",
  "email_verified": true,
  "https://agentboxd.com/claims/agent": true
}

alg: ES256

Conçu pour qu’un jeton ne puisse pas resservir.

Le jeton d’un agent ne vaut pas grand-chose pour qui le vole : il est de courte durée, à usage unique et valable pour une seule application. Les détails sont dans la documentation.

  • ES256

    Signés, avec des clés renouvelées

    Les jetons sont signés avec des clés ECDSA P-256 renouvelées régulièrement. Les vérificateurs les récupèrent depuis le JWKS ; les algorithmes none et HMAC sont refusés.

  • ≤ 300 S

    Courte durée, sans jeton de rafraîchissement

    Un jeton d’identité vit 5 minutes au plus. Il n’y a pas de jeton de rafraîchissement : un agent se reconnecte en un appel API, et c’est votre session qui décide combien de temps elle dure.

  • USAGE UNIQUE

    Chaque jeton ne sert qu’une fois

    Chaque jeton a un jti unique. Tenez un cache anti-rejeu, ou échangez le jeton auprès de l’émetteur avec l’autorisation JWT bearer (RFC 7523), qui l’enregistre et refuse une seconde utilisation.

  • AUD = CLIENT_ID

    Lié à une seule application

    Un jeton nomme exactement une audience, votre client_id. Un jeton émis pour une autre application échoue à la vérification et ne peut pas être échangé auprès de l’émetteur par un autre client.

  • PAIRWISE SUB

    Un sujet différent dans chaque application

    Chaque application voit son propre sub stable pour un même agent, si bien que deux applications ne peuvent pas croiser leurs tables d’utilisateurs pour le suivre. Identifiez vos utilisateurs par leur sub.

  • AGENT: TRUE

    Les agents se déclarent comme agents

    Chaque jeton porte https://agentboxd.com/claims/agent: true. Le sujet est la boîte mail d’un agent IA, jamais une personne qui prétendrait le contraire.

  • PKCE S256

    Un flux navigateur sûr

    Le bouton utilise le flux par code d’autorisation avec PKCE S256, state et nonce tous obligatoires, des URI de redirection exactes, des codes à usage unique valables 60 secondes et iss dans la réponse (RFC 9207).

  • COUPURE · HISTORIQUE

    Les propriétaires voient et arrêtent chaque connexion

    Chaque boîte mail a un interrupteur de connexion qui prend effet immédiatement, un historique de chaque jeton et de chaque connexion (conservé 180 jours), et un webhook pour chacun.

GET {issuer}/authorize

Ajoutez un bouton « Se connecter avec Agentboxd ».

Pour une application web, c’est une personne qui clique sur le bouton : le propriétaire de l’agent. Il approuve sur agentboxd.com et choisit laquelle des boîtes mail de ses agents se connecte, et votre application reçoit un résultat OpenID Connect normal, qui contient agent: true.

Faites pointer le bouton vers la route de connexion de votre bibliothèque d’authentification pour le fournisseur agentboxd. Le code à droite est un point de départ ; gardez le libellé « Sign in with Agentboxd » (ou « Se connecter avec Agentboxd » en français).

sign-in-button.html
<a class="siwa" href="/api/auth/signin/agentboxd">
  <svg width="20" height="20" viewBox="0 0 32 32" aria-hidden="true">
    <circle cx="12.5" cy="16" r="8" fill="none" stroke="#D4FF3A" stroke-width="3" />
    <path d="M22.5 11.5h7M23.5 16h6M22.5 20.5h7" stroke="#EDEAE2" stroke-width="2.2" />
  </svg>
  Sign in with Agentboxd
</a>

<style>
  .siwa { display: inline-flex; align-items: center; gap: 10px; min-height: 44px;
          padding: 0 18px 0 12px; border: 1px solid #2A2D33; border-radius: 2px;
          background: #0A0B0D; color: #EDEAE2; font: 600 15px/1 system-ui, sans-serif;
          text-decoration: none; }
  .siwa:focus-visible { outline: 2px solid #D4FF3A; outline-offset: 2px; }
</style>

/.well-known/openid-configuration

Compatible avec l’authentification que vous avez déjà.

Shakehand, c’est de l’OpenID Connect standard : rien de nouveau à apprendre. Indiquez à votre bibliothèque le document de découverte, et elle trouve les clés et les points de terminaison.

  • Better Auth : le plugin Generic OAuth, avec PKCE et vérification du jeton d’identité.
  • Auth.js (NextAuth) : un petit fournisseur OIDC avec les vérifications pkce, state et nonce.
  • Tout client OIDC avec le flux par code d’autorisation et PKCE, dans n’importe quel langage.
  • Sans navigateur : verifyAgentIdentityToken depuis agentboxd/identity, ou l’échange de jeton RFC 7523.

Le code Better Auth, Auth.js et sans navigateur est vérifié par le typage dans examples/identity et présenté pas à pas dans le guide.

auth.ts
import { betterAuth } from 'better-auth';
import { genericOAuth } from 'better-auth/plugins';

const ISSUER = process.env.AGENTBOXD_ISSUER ?? 'https://id.agentboxd.com';

export const auth = betterAuth({
  // database: your adapter
  user: {
    additionalFields: { isAgent: { type: 'boolean', required: false, defaultValue: false, input: false } },
  },
  plugins: [
    genericOAuth({
      config: [
        {
          providerId: 'agentboxd',
          name: 'Agentboxd',
          discoveryUrl: `${ISSUER}/.well-known/openid-configuration`,
          clientId: process.env.AGENTBOXD_CLIENT_ID!,
          clientSecret: process.env.AGENTBOXD_CLIENT_SECRET!,
          scopes: ['openid', 'email', 'profile'],
          pkce: true,
          requireIdTokenVerification: true,
          mapProfileToUser: (profile) => ({
            name: typeof profile.name === 'string' ? profile.name : undefined,
            email: typeof profile.email === 'string' ? profile.email : null,
            emailVerified: profile.email_verified === true,
            isAgent: profile['https://agentboxd.com/claims/agent'] === true,
          }),
        },
      ],
    }),
  ],
});

// In the browser:
// await authClient.signIn.social({ provider: 'agentboxd', callbackURL: '/dashboard' });

GET /platform/plans

Les applications sont gratuites, pour toujours.

Enregistrez autant d’applications que vous voulez, avec n’importe quelle offre, et ne payez jamais par connexion à votre application. L’espace de travail de l’agent a Shakehand avec son offre Agentboxd. Pendant la bêta publique, chaque espace de travail utilise les limites de l’offre Free et rien n’est facturé.

Une connexion correspond à un jeton d’identité que nous émettons pour un agent. Une identité sans boîte mail se connecte mais ne reçoit aucun e-mail ; chaque boîte mail est aussi une identité et compte comme une boîte mail. L’offre Free s’arrête à son quota de connexions jusqu’au mois suivant ; les offres payantes relèvent d’un usage raisonnable, sans prix de dépassement. Tous les tarifs

Questions

Questions.

Qu’est-ce que Shakehand ?

Shakehand est le produit Agentboxd qui ajoute un bouton « Se connecter avec Agentboxd » à votre application. Derrière le bouton se trouve un fournisseur d’identité OpenID Connect, sur id.agentboxd.com, dont l’utilisateur est un agent IA. L’identité d’un agent est sa boîte mail Agentboxd, ou une identité sans boîte mail, et il se connecte aux applications avec un jeton d’identité de courte durée et à usage unique au lieu d’un mot de passe.

Mon agent a-t-il besoin d’une boîte mail pour se connecter ?

Non. Donnez une identité à n’importe quel agent en un appel — boîte mail facultative. POST /v1/identities crée une identité sans boîte mail : elle se connecte avec tous les flux, ses jetons ne portent aucune adresse e-mail mais une revendication mailbox: false, et elle compte dans une limite d’identités distincte (100 avec l’offre Free), pas dans vos boîtes mail. Identité sans boîte mail.

Me faut-il un compte Agentboxd pour accepter des agents dans mon application ?

Il vous faut un compte gratuit pour enregistrer votre application et obtenir un client_id. Ensuite, vérifier un jeton ne demande que les clés publiques : n’importe quelle bibliothèque OpenID Connect ou JOSE convient, et le paquet TypeScript agentboxd fournit une fonction qui fait toutes les vérifications. Créer un compte.

Avec quelles bibliothèques cela fonctionne-t-il ?

Tout client OpenID Connect qui prend en charge le flux par code d’autorisation avec PKCE. Le guide contient des configurations fonctionnelles pour Better Auth (plugin Generic OAuth) et Auth.js, ainsi qu’une partie de confiance (relying party) sans navigateur en TypeScript. Les autres clients n’ont besoin que de l’URL de découverte, de votre client_id et, pour les applications serveur, du secret client. Le guide.

Comment un jeton est-il protégé contre le rejeu ou le vol ?

Il vit au plus 5 minutes, nomme exactement une application comme audience, porte un jti unique que votre application ou l’émetteur n’accepte qu’une fois, et peut être lié à une tentative de connexion par un nonce. Le flux navigateur ajoute PKCE, state et des URI de redirection exactes.

Les applications peuvent-elles suivre mon agent d’un service à l’autre ?

Pas via Shakehand. Par défaut, chaque application reçoit un sujet différent pour un même agent. La revendication email est la même partout : une application qui la demande peut donc s’en servir pour recouper ; les applications soucieuses de la vie privée ne devraient pas la demander.

Qui approuve une connexion depuis le navigateur ?

Le propriétaire de l’agent. Le bouton l’envoie sur agentboxd.com, où il voit le nom de votre application, son hôte de redirection et les scopes, choisit quelle boîte mail se connecte et approuve. Aucun consentement n’est mémorisé : chaque connexion depuis le navigateur est approuvée.

Combien ça coûte ?

Les applications sont gratuites pour toujours : enregistrez-en autant que vous voulez, avec n’importe quelle offre, et personne ne paie par connexion à votre application. Les agents ont Shakehand avec toutes les offres Agentboxd : l’offre Free inclut 100 identités sans boîte mail et 10 000 connexions par mois, les offres payantes davantage, dans le cadre d’un usage raisonnable. Shakehand est en bêta publique et gratuit pendant la bêta. Tarifs de Shakehand.

/app/identity

Ouvrez votre application aux agents.

Enregistrez votre application dans le tableau de bord pour obtenir un client_id, puis suivez le guide. Gratuit avec toutes les offres.