Obexal Docs

Docs/Agents IA/Enregistrer un agent

Enregistrer un agent

Créer le client OAuth de l'agent, lui affecter un propriétaire humain et une date d'expiration, émettre un premier jeton et vérifier le résultat dans l'inventaire.

Ce pas à pas enregistre une identité d'agent complète : le client OAuth, son propriétaire humain, son expiration, un premier jeton, et la vérification dans l'inventaire. Lisez d'abord le modèle d'identité d'agent si ce n'est pas fait.

Prérequis

Les exemples utilisent un jeton d'API admin (préfixe obx_) portant la permission apps:manage, passé en Authorization: Bearer. Tout peut aussi se faire depuis la console d'administration (la page Applications propose une option Agent IA), où les mutations d'agent exigent en plus une vérification MFA récente (step-up).

Note

Tous les exemples utilisent accounts.obexal.com, le domaine par défaut. Si votre organisation utilise un domaine personnalisé, remplacez-le.

Créer le client agent

Dans la console, créez une application et cochez Agent IA (délégation Token Exchange) : le type de client est forcé à confidential et les grants machine sont posés automatiquement. Par l'API, créez le client explicitement :

curl -sS -X POST https://accounts.obexal.com/v1/applications \
  -H "Authorization: Bearer $OBEXAL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support triage bot",
    "clientType": "confidential",
    "redirectUris": ["https://agents.example.eu/unused-callback"],
    "scopes": ["openid", "tickets:read", "tickets:write"],
    "grantTypes": ["client_credentials", "urn:ietf:params:oauth:grant-type:token-exchange"],
    "requireConsent": true
  }'
{
  "application": {
    "clientId": "8Zl2vQx0T9hK3mW1s5nDgA",
    "name": "Support triage bot",
    "clientType": "confidential",
    "grantTypes": ["client_credentials", "urn:ietf:params:oauth:grant-type:token-exchange"],
    "scopes": ["openid", "tickets:read", "tickets:write"],
    "tokenEndpointAuthMethod": "client_secret_basic",
    "requireConsent": true
  },
  "clientSecret": "kq2Vt7...montre-une-seule-fois"
}

Trois champs méritent attention :

  • scopes est le périmètre maximal de l'agent : aucun jeton émis à cet agent ne le dépassera jamais. La liste doit inclure openid (validation des clients), placez donc les permissions réelles de l'agent à côté.
  • grantTypes : client_credentials permet à l'agent d'agir en son nom propre, l'URN de token-exchange lui permet d'agir au nom d'un utilisateur. N'incluez que ce dont l'agent a besoin.
  • requireConsent: true rend l'agent gouverné : chaque utilisateur doit l'autoriser explicitement avant qu'il puisse agir en son nom. Ne l'omettez que pour des agents internes de confiance.
Note

La validation des clients exige au moins une entrée redirectUris absolue en http(s), même pour un agent purement machine qui ne lance jamais de flux interactif. Utilisez une URL de convenance sur un domaine que vous possédez.

Attention

Le clientSecret est renvoyé une seule fois et jamais plus (seul son SHA-256 est stocké). Placez-le immédiatement dans votre gestionnaire de secrets. S'il est perdu, renouvelez-le.

Poser le propriétaire et l'expiration

curl -sS -X PUT https://accounts.obexal.com/v1/admin/agents/8Zl2vQx0T9hK3mW1s5nDgA/identity \
  -H "Authorization: Bearer $OBEXAL_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"owner": "alice@example.eu", "expiresAt": "2026-12-31T23:59:59Z"}'
# 204 No Content

owner doit être l'e-mail d'un utilisateur existant de votre organisation : il est stocké comme une référence d'annuaire, si bien que l'inventaire peut marquer l'agent orphan si cette personne part. expiresAt est appliqué fail-closed à l'émission : passé cette date, toute demande de jeton est refusée. Une chaîne vide efface l'un ou l'autre champ. Un client qui n'est pas un agent ou un e-mail de propriétaire inconnu renvoie 400 invalid_request ; un clientId inconnu renvoie 404.

Émettre le premier jeton

L'agent s'authentifie en HTTP Basic sur le token endpoint et utilise le grant client_credentials :

curl -sS -X POST https://accounts.obexal.com/oauth/token \
  -u "8Zl2vQx0T9hK3mW1s5nDgA:$AGENT_CLIENT_SECRET" \
  -d grant_type=client_credentials \
  -d scope="tickets:read"
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6ImF0K2p3dCIsImtpZCI6IjIwMjYtMDYifQ...",
  "token_type": "Bearer",
  "expires_in": 600,
  "scope": "tickets:read"
}

L'access token est un JWT (typ: at+jwt) dont le sub vaut le client_id : une identité machine, aucun utilisateur impliqué. Ni id_token ni refresh_token ne sont émis pour ce grant. scope est optionnel et doit être un sous-ensemble des scopes du client ; les plafonds de la politique de gouvernance s'appliquent par-dessus. Cette émission met aussi à jour lastUsedAt.

Vérifier dans l'inventaire

curl -sS https://accounts.obexal.com/v1/admin/agents \
  -H "Authorization: Bearer $OBEXAL_API_TOKEN"
{
  "agents": [
    {
      "clientId": "8Zl2vQx0T9hK3mW1s5nDgA",
      "name": "Support triage bot",
      "ownerEmail": "alice@example.eu",
      "expiresAt": "2026-12-31T23:59:59Z",
      "lastUsedAt": "2026-07-02T09:14:07Z",
      "status": "active",
      "governed": true,
      "enabled": true,
      "needsReview": true,
      "openAnomalies": 0
    }
  ]
}

needsReview reste vrai jusqu'à une première attestation : POST /v1/admin/agents/8Zl2vQx0T9hK3mW1s5nDgA/review l'enregistre et renvoie 204.

Étapes suivantes

  1. La délégation par Token Exchange : faire agir l'agent au nom d'un utilisateur.
  2. La politique de gouvernance par agent : plafonner TTL, scopes et audiences avant la production.
  3. La rotation des secrets : donner une expiration au secret et le renouveler à échéance.