HWT — Hash Web Token
Tokens d'authentification vérifiables entre deux services quelconques. Aucun fournisseur central requis.
import Hwtr from 'jsr:@hwt/hwtr-js'
const hwtr = await Hwtr.factory({}, keyConfig)
const result = await hwtr.verify(token)
if (result.ok) {
console.log(result.data)
// sub "user:4503", authz { scheme: "RBAC/1.0.2", roles: ["editor"] }
}
Lire la spécification - Voir les démos - Obtenir la bibliothèque
Format du token
hwt.signature.key-id.expires.format.payload
Six champs séparés par des points. La signature couvre l'expiration, le format et le payload en une seule passe canonique. La vérification reconstruit cette entrée à partir du token et la vérifie contre la clé publiée de l'émetteur (issuer).
Payload décodé — token d'agent délégué, chaîne de délégation (delegation chain) à deux sauts :
{
"iss": "https://agent-b.example.com",
"sub": "svc:agent-b",
"aud": "https://api.target.com",
"tid": "tok-7c8d",
"authz": { "scheme": "RBAC/1.0.2", "roles": ["editor"] },
"del": [
{ "iss": "https://auth.example.com", "sub": "user:4503", "tid": "tok-a1b2" },
{ "iss": "https://agent-a.example.com", "sub": "svc:agent-a", "tid": "tok-c3d4" }
]
}
Le vérificateur (verifier) voit la chaîne complète : l'utilisateur a délégué à agent-a, agent-a a délégué à agent-b. Le tableau del est couvert par la signature externe — il ne peut pas être altéré après émission. Les vérifications d'état en couche applicative (révocation (revocation), validité de session) relèvent de la responsabilité de l'application consommatrice auprès de chaque émetteur.
Vérification
Émetteurs pré-enregistrés — recommandé pour la production :
Charger les clés publiques des émetteurs de confiance au démarrage. La vérification ultérieure est locale — aucun appel réseau par token.
import Hwtr from 'jsr:@hwt/hwtr-js'
// au démarrage : créer une instance avec les clés publiques des émetteurs de confiance
const hwtr = await Hwtr.factory({}, {
type: 'Ed25519',
keys: [],
publicKeys: {
'auth-key': 'BASE64URL_SPKI', // de auth.example.com
'partner-key': 'BASE64URL_SPKI' // de partner.example.com
}
})
// dans le gestionnaire de requête — aucun appel réseau
const result = await hwtr.verify(token)
if (result.ok) {
console.log(result.data)
// sub "user:4503" authz { scheme: "RBAC/1.0.2", roles: ["editor"] }
}
Signature et aller-retour complet :
// Générer les clés une fois, les stocker de façon sécurisée
const keyConfig = await Hwtr.generateKeys({ type: 'Ed25519' })
const hwtr = await Hwtr.factory({ expiresInSeconds: 3600 }, keyConfig)
// Signer
const token = await hwtr.create({
sub: 'user:4503',
authz: { scheme: 'RBAC/1.0.2', roles: ['editor'] }
})
// Vérifier
const result = await hwtr.verify(token)
// result.ok, result.data, result.expires, result.error
La chaîne de délégation
SCHÉMA DE FLUX DE LA CHAÎNE DE DÉLÉGATION
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
┌────────────────────────────────────┐
│ user:4503 │──────────────► auth.example.com
│ iss: auth.example.com │ publication de clé
│ tid: tok-a1b2 │
└────────────────────────────────────┘
│ délégué à
▼
┌────────────────────────────────────┐
│ svc:agent-a │──────────────► agent-a.example.com
│ iss: agent-a.example.com │ publication de clé
│ tid: tok-c3d4 │
└────────────────────────────────────┘
│ délégué à
▼
┌────────────────────────────────────┐
│ svc:agent-b │──────────────► agent-b.example.com
│ iss: agent-b.example.com │ récupération de clé + vérif. sig
│ tid: tok-7c8d (token externe) │
└────────────────────────────────────┘
│ présente le token
▼
api.target.com
Vérification protocolaire (spec §12) :
1. Vérifier la signature d'agent-b contre les clés d'agent-b.example.com
2. Confirmer l'intégrité structurelle de del[] — couverte par la signature externe
3. Transmettre le payload vérifié à l'application
Couche applicative (choix d'implémentation) :
4. Vérifier l'état de tok-c3d4 auprès d'agent-a.example.com
5. Vérifier l'état de tok-a1b2 auprès d'auth.example.com
Aucune étape ne contacte un serveur central.
Le tableau del est couvert par la signature d'agent-b —
il ne peut pas être altéré après émission.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Ce que HWT ne couvre pas
Des frontières explicites sont importantes pour les protocoles de sécurité. Les éléments suivants sont hors du périmètre de HWT par conception.
État du token et révocation (revocation). Le fait qu'un token ait été invalidé après émission n'est pas une propriété de la chaîne d'octets signée. HWT définit ce qu'un token garantit structurellement ; il ne définit pas le cycle de vie de session ni l'infrastructure de révocation. Les applications nécessitant une invalidation immédiate maintiennent leur propre dépôt d'état et le vérifient en couche applicative. La courte durée de vie des tokens est le mécanisme principal de limitation de l'exposition.
Émission de tokens. La manière dont un principal obtient un token relève du principal et du service émetteur. WebAuthn/FIDO2 est un complément naturel pour l'étape d'authentification qui précède l'émission — également souverain par domaine, sans fournisseur central.
Évaluation des autorisations. HWT transporte la déclaration (roles: ["editor"]). La question de savoir si editor autorise une action spécifique relève de la décision de l'application consommatrice. OPA et Casbin sont des compléments naturels.
Liaison de session. Les tokens HWT sont des credentials au porteur (bearer credential). Pour les déploiements où le vol de token est une menace principale, DPoP (RFC 9449) est une extension proof-of-possession compatible — aucune modification du format HWT n'est requise.
Systèmes déconnectés. HWT suppose la disponibilité du réseau pour la découverte de clé (key discovery). Les tokens expirés ne fonctionnent pas hors ligne. C'est le comportement attendu.
La justification : des engagements protocolaires plus restreints produisent des affirmations de sécurité plus précises et une responsabilité de l'intégrateur plus claire. Lorsque la frontière est explicite, l'application sait exactement ce qui lui appartient.
Algorithmes · Codecs
| Algorithme | Notes |
|---|---|
| Ed25519 | Par défaut recommandé. Signatures rapides et compactes. |
| ECDSA P-256 | Large support matériel et HSM. |
| ECDSA P-384 | Marge de sécurité accrue si nécessaire. |
| HMAC | Usage mono-service uniquement. Non conforme pour l'usage inter-domaines. |
| Codec | Identifiant | Notes |
|---|---|---|
| JSON | j |
Référence obligatoire. Toutes les implémentations. |
| JSON Extended | jx |
Dates, BigInt, tableaux typés, Maps, Sets. Import expérimental optionnel. |
| CBOR, MessagePack | community | Codecs binaires. Voir CONVENTIONS.md. |
Statut
Brouillon v0.7. Structure du protocole stable depuis 2026-04.
En suspens : enregistrement IANA des URI well-known · sémantique des portées d'échange de token
Démarrage
Installer la bibliothèque JS :
import Hwtr from 'jsr:@hwt/hwtr-js'
Exemples fonctionnels (Deno, Node, Cloudflare Workers) : hwt-demo →
Lire la spécification :
Implémentations dans d'autres langages :
Contribuer :
Licence Apache 2.0 · Copyright 2026 Jim Montgomery and HWT Contributors · github.com/hwt-protocol