Documentation d’authentification SingleFax

Clés API, OAuth pour MCP et Agent Auth déléguée.

Guide d’authentification pour les agents IA et les développeurs.

Authentification des agents auprès de SingleFax. Installation HTML : https://singlefax.com/agents

Ce fichier est la cible agent_auth.skill annoncée dans les métadonnées RFC 8414 sur /.well-known/oauth-authorization-server.

SingleFax prend en charge l’inscription Auth.md par anonymous et service_auth, avec approbation de l’utilisateur et attestations d’identité signées par le service. Les identifiants anonymes n’accèdent à aucun compte avant approbation. Les ID-JAG externes ne sont pas acceptés. L’ancien parcours JWT hôte/agent Better Auth est décrit séparément au parcours C.

Inscription Auth.md et échange de jetons

Public : agents IA s’inscrivant pour agir pour un compte SingleFax existant. Chaque méthode exige une autorisation d’inscription émise par le titulaire. Les requêtes publiques sans jeton d’inscription valide sont rejetées avant toute création. L’émetteur OAuth est https://api.singlefax.com/api/auth ; la ressource, https://singlefax.com/mcp. L’inscription n’envoie ni e-mail ni fax et ne déclenche aucun paiement.

Méthodes prises en charge : anonymous et service_auth. Identifiants : identity_assertion et Bearer access_token. Le titulaire se connecte, examine les permissions et saisit le code à six chiffres de l’agent. Portées : fax:read, fax:draft, fax:send, inbox:read, credits:read et credits:checkout. Permissions par défaut : fax:read et credits:read ; demandez explicitement les autres.

  1. Le titulaire se connecte à https://singlefax.com/dashboard/agent-access, choisit le nom de l’agent et ses permissions, puis crée explicitement un jeton d’inscription. Ce secret affiché une seule fois expire après dix minutes et ne peut inscrire qu’un agent. Remettez-le à cet agent. Le provisionnement API utilise la session navigateur propriétaire sur POST https://singlefax.com/api/auth/agent/identity/manage avec { "action": "enroll", "name": "My agent", "scopes": ["fax:read", "credits:read"] }. Les cookies ne sont jamais partagés avec l’agent. Les jetons inutilisés peuvent être révoqués sur cette page.
  2. Inscrivez avec POST https://api.singlefax.com/api/auth/agent/identity, Content-Type: application/json et { "type": "service_auth", "enrollment_token": "<owner-issued token>", "login_hint": "<enrolling owner email>" }. La réponse contient registration_id, un secret claim_token, l’expiration et claim avec user_code, verification_uri et un intervalle d’interrogation de cinq secondes. Aucune attestation n’est émise avant approbation.
  3. Autre méthode : { "type": "anonymous", "enrollment_token": "<owner-issued token>" }. « Anonyme » désigne ici l’identifiant avant rattachement, pas une inscription publique libre. Vous recevez aussitôt un identity_assertion signé et un claim_token. L’échange de cette attestation donne un jeton sans portée et sans accès à un compte. Lancez l’approbation par POST https://api.singlefax.com/api/auth/agent/identity/claim avec { "claim_token": "<secret>", "email": "<account email>" } et lisez claim_attempt.
  4. Affichez le code séparément et ouvrez verification_uri pour l’utilisateur. L’URL contient un jeton secret de tentative de rattachement ; n’y ajoutez pas le code. Seul le compte vérifié ayant autorisé l’inscription peut approuver. Le nom est fixé par ce titulaire ; les portées peuvent être réduites, sans dépasser les permissions accordées. L’indication d’e-mail et l’adresse de rattachement doivent correspondre au titulaire. L’utilisateur peut refuser. Les demandes expirent après dix minutes ; une nouvelle tentative invalide l’ancien lien. Aucun compte n’est créé automatiquement.
  5. Interrogez POST https://api.singlefax.com/api/auth/oauth2/token avec Content-Type: application/x-www-form-urlencoded et grant_type=urn:workos:agent-auth:grant-type:claim&claim_token=<secret>&resource=https%3A%2F%2Fsinglefax.com%2Fmcp. Gérez authorization_pending, slow_down, en augmentant l’intervalle de cinq secondes, expired_token et access_denied. L’approbation renvoie un access_token opaque, token_type, expires_in, scope, identity_assertion et assertion_expires. Les jetons et attestations antérieurs au rattachement sont invalidés.
  6. Utilisez Authorization: Bearer <access_token> sur MCP ou A2A avec les portées accordées. Les jetons durent au maximum une heure. Pour renouveler, utilisez le même point avec grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=<identity_assertion>&resource=https%3A%2F%2Fsinglefax.com%2Fmcp. Aucun jeton de renouvellement n’est émis. Les attestations restent échangeables pendant 30 jours maximum sauf révocation. Leurs signatures EdDSA utilisent le /jwks de l’émetteur ; typ vaut oauth-id-jag+jwt, et iss/aud correspondent tous deux à l’émetteur.
  7. Révoquez un jeton avec POST https://api.singlefax.com/api/auth/oauth2/revoke, corps de formulaire token=<access_token>&token_type_hint=access_token. L’opération est idempotente et laisse l’attestation utilisable. Révoquez l’inscription avec POST https://api.singlefax.com/api/auth/agent/identity/revoke, JSON { "identity_assertion": "<identity_assertion>" } : tous les jetons et échanges ultérieurs sont arrêtés.

Le titulaire peut examiner et révoquer les autorisations sur https://singlefax.com/dashboard/agent-access. Révoquer une inscription arrête tous les jetons associés et renouvellements d’attestation.

Les réponses de rattachement et d’approbation sont privées et jamais mises en cache. Gardez secrets jetons, attestations et accès. L’émission est limitée par titulaire sur toutes les répliques API, avec cinq jetons actifs inutilisés maximum. Les requêtes publiques sans autorisation ne consomment pas son quota. Un jeton absent renvoie enrollment_required ; expiré, révoqué ou consommé, invalid_enrollment. Un échec d’inscription ne consomme pas le jeton. Ne testez pas les points d’inscription lors d’analyses passives de disponibilité.

Découverte

Serveur de ressources, MCP et API BFF : https://singlefax.com

GET https://singlefax.com/.well-known/oauth-protected-resource
GET https://singlefax.com/.well-known/oauth-protected-resource/mcp

Métadonnées des ressources protégées, RFC 9728 : le document racine décrit l’origine, resource https://singlefax.com ; /.well-known/oauth-protected-resource/mcp décrit le serveur MCP, resource https://singlefax.com/mcp, cible de WWW-Authenticate. Les deux indiquent authorization_servers, émetteur https://api.singlefax.com/api/auth, et scopes_supported. Demandez les jetons pour https://singlefax.com/mcp.

GET https://singlefax.com/.well-known/oauth-authorization-server
GET https://singlefax.com/.well-known/oauth-authorization-server/api/auth

Les métadonnées du serveur d’autorisation comprennent issuer, authorization_endpoint, token_endpoint, registration_endpoint, jwks_uri, scopes_supported et agent_auth ; skill pointe ici.

L’origine API https://api.singlefax.com sert les mêmes documents well-known.

Parcours A. OAuth MCP pour les applications de chat

À utiliser avec Cursor, Claude, ChatGPT, Codex et VS Code.

  1. Ajoutez MCP https://singlefax.com/mcp, Streamable HTTP.
  2. Sur 401, lisez WWW-Authenticate et récupérez les PRM ci-dessus.
  3. Inscription dynamique du client : POST {issuer}/oauth2/register, PKCE S256 et token_endpoint_auth_method=none pour les clients publics.
  4. Code d’autorisation avec PKCE sur {issuer}/oauth2/authorize.
  5. Jeton sur {issuer}/oauth2/token.
  6. POST /mcp avec Authorization: Bearer. Pour un document classique, appelez create_upload, remettez uploadPageUrl à l’utilisateur, puis create_fax_draft avec to et uploadToken. base64 sert uniquement aux très petits fichiers. Le PUT vers uploadUrl utilise le jeton HMAC du chemin, sans en-tête OAuth. Envoyez l’original Word, Excel, PDF ou image sans conversion préalable.

Portées : openid, profile, email, offline_access, fax:read, fax:draft, fax:send, inbox:read, credits:read, credits:checkout. Demandez explicitement credits:checkout pour les achats de crédits AP2 ; chaque débit exige toujours une approbation distincte par passkey.

Sans authentification, POST /mcp accepte uniquement server/discover. initialize, tools/list et tools/call exigent OAuth.

Parcours A2. A2A, agent à agent

Carte d’agent : GET https://singlefax.com/.well-known/agent-card.json, A2A 1.0. Point d’accès : POST https://singlefax.com/a2a, JSON-RPC SendMessage, GetTask, CancelTask ; les noms 0.3 message/send, tasks/get, tasks/cancel fonctionnent aussi.

  1. Utilisez le serveur OAuth, les portées et jetons du parcours A, ressource https://singlefax.com/mcp. Envoyez Authorization: Bearer. Les jetons liés à DPoP ne sont pas acceptés sur /a2a.
  2. Envoyez une partie de données : { "skill": "<skill id from the card>", "arguments": { ... } }. Le texte libre n’est pas interprété.
  3. Les fonctions fax et numéro renvoient un lien Stripe Checkout, checkoutUrl. A2A ne dépense jamais les crédits ni les pages du forfait. Un brouillon en attente de paiement porte l’état input-required. Interrogez avec GetTask.

Pour les achats AP2, demandez credits:checkout et négociez l’extension marchand. Mandats de panier et paiement signés, approbation séparée par passkey, utilisation du Stripe Shared Payment Token et reçus confirmés au registre sont documentés sur https://singlefax.com/ap2.md.

GetTask avec fax:read suit la livraison des brouillons fax et le paiement ou l’activation des numéros. Une tâche de numéro se termine à l’activation. L’achat de crédits n’a pas de tâche liée à une commande à interroger ; vérifiez le solde après paiement.

Parcours B. Clé API pour backends et CLI

  1. Créez une clé sur https://singlefax.com/dashboard/api-keys, sf_live_….
  2. Achetez des crédits prépayés.
  3. Authorization: Bearer sf_live_… sur https://singlefax.com/api/v1/… ou https://api.singlefax.com/api/v1/….
  4. CLI : npx @singlefax/cli send FILE --to +E164 avec SINGLEFAX_API_KEY. Envoyez l’original Word, Excel, PDF ou image sans conversion préalable.

Exemples par langage, curl, Node, Python, Go, PHP : https://singlefax.com/developers.md

OpenAPI : https://singlefax.com/openapi.json

Parcours C. JWT hôte et agent délégués Better Auth

Les capacités déléguées, validate_fax, send_fax, get_fax_status, get_credits, create_credit_checkout, utilisent l’approbation de l’appareil.

  1. Lisez GET https://api.singlefax.com/.well-known/agent-configuration pour les algorithmes, points d’accès, modes et approbations. L’émetteur Agent Auth est https://api.singlefax.com, distinct de l’émetteur OAuth finissant par /api/auth. Utilisez cette origine comme audience JWT. Générez des clés de signature distinctes pour hôte et agent avec un algorithme accepté et gardez les clés privées secrètes.
  2. Provisionnez d’abord l’hôte. L’inscription dynamique des hôtes est désactivée. Le titulaire se connecte à SingleFax et appelle POST https://singlefax.com/api/auth/host/create, équivalent API https://api.singlefax.com/api/auth/host/create, avec sa session navigateur propriétaire. Fournissez { "name": "My agent host", "public_key": <host public JWK>, "default_capabilities": [] }. Le hostId retourné identifie l’hôte. Les valeurs vides par défaut imposent une approbation distincte des capacités. Sinon, omettez public_key pour recevoir un enrollmentToken temporaire à usage unique ; l’hôte appelle ensuite POST https://api.singlefax.com/api/auth/host/enroll avec { "token": <enrollment token>, "public_key": <host public JWK>, "name": "My agent host" }. Ne partagez jamais cookies ni clés privées avec l’agent.
  3. Inscrivez sur POST https://api.singlefax.com/api/auth/agent/register. Envoyez Authorization: Bearer <signed host+jwt> et le JSON { "name": "My agent", "mode": "delegated", "capabilities": ["validate_fax", "get_fax_status", "get_credits"], "preferred_method": "device_authorization", "force_approval": true }. L’en-tête JWT utilise typ: "host+jwt" et un alg accepté, ainsi que kid du JWK de signature s’il existe. Les claims comprennent iss: <registered hostId>, aud: "https://api.singlefax.com", un nouveau jti, le iat actuel, exp dans les 60 secondes et agent_public_key: <agent public JWK>. Signez avec la clé de l’hôte provisionné. Les identifiants JWT réutilisés sont rejetés.
  4. L’inscription renvoie agent_id, host_id, statut, capacités et un objet approval si nécessaire. Affichez son code appareil et ouvrez verification_uri_complete sur SingleFax. L’utilisateur se connecte et approuve à l’URL retournée. Inscription, provisionnement et approbation changent le compte ; les analyses passives doivent seulement lire les documents de découverte.
  5. Interrogez GET https://api.singlefax.com/api/auth/agent/status?agent_id=<registered id> avec un nouveau JWT hôte, iss: <host_id>. Après approbation, signez les JWT agent avec sa clé privée : en-tête typ: "agent+jwt", alg/kid accepté ; claims iss: <host_id>, sub: <agent_id>, aud: "https://api.singlefax.com", iat actuel, exp dans les 60 secondes et nouveau jti. Appelez POST https://api.singlefax.com/api/auth/capability/execute avec Authorization: Bearer <signed agent+jwt> et { "capability": "get_credits", "arguments": {} }, ou une autre capacité accordée avec ses arguments documentés. Ces identifiants sont des preuves signées, pas des clés API ni des jetons OAuth.
  6. Pour un nouveau code appareil d’un agent inscrit, utilisez POST https://api.singlefax.com/api/auth/agent/device/code avec { "agent_id": "<registered id>" } et un JWT hôte signé. Ce point ne peut pas inscrire un agent. Révoquez via POST https://api.singlefax.com/api/auth/agent/revoke avec { "agent_id": "<registered id>" } et le JWT de l’hôte propriétaire ou sa session. send_fax exige une vérification par passkey ; ce n’est pas autonome.

N’envoyez pas d’ID-JAG ni de { "type": "anonymous" } ici par POST. Ces types d’identité ne sont pas pris en charge.

Paiements machine, sans OAuth

Le paiement autonome utilise MPP HTTP 402 sur POST /api/v1/machine/faxes, avec Stripe Shared Payment Token ou Tempo USDC. Voir https://singlefax.com/mpp.md. Cursor ne génère pas de SPT ; utilisez Stripe Link CLI sur cette URL REST, pas /mcp. Les portefeuilles Tempo paient la demande sur la même URL.

HIPAA

N’envoyez pas de PHI via MCP, MPP ou l’API publique. Les organismes concernés utilisent HIPAA Secure Mode sur le site avec un BAA électronique.