HWT — Hash Web Token

Verifizierbare Auth-Tokens zwischen beliebigen zwei Services. Kein zentraler Anbieter erforderlich.


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"] }
}

Spezifikation lesen - Demos ansehen - Bibliothek herunterladen


Token-Format

hwt.signature.key-id.expires.format.payload

Sechs durch Punkte getrennte Felder. Die Signatur deckt Ablaufzeit, Format und payload in einem einzigen kanonischen Durchlauf ab. Die Verifizierung rekonstruiert diese Eingabe aus dem Token und prüft sie gegen den veröffentlichten Schlüssel des Issuers (Aussteller).

Dekodierter payload – delegierter Agenten-Token, Zwei-Hop-Kette:

{
  "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" }
  ]
}

Der Verifier (Prüfer) sieht die vollständige Kette: Benutzer hat an agent-a delegiert, agent-a hat an agent-b delegiert. Das del-Array ist durch die äußere Signatur abgedeckt – es kann nach der Ausstellung nicht manipuliert werden. Zustandsprüfungen auf Anwendungsebene (Revocation (Widerruf), Session-Validität) liegen in der Verantwortung der verbrauchenden Anwendung bei jedem Issuer.


Verifizierung

Vorab registrierte Issuer – für Produktion empfohlen:

Vertrauenswürdige Issuer-Schlüssel beim Start laden. Nachfolgende Verifizierung ist lokal – kein Netzwerkaufruf pro Token.

import Hwtr from 'jsr:@hwt/hwtr-js'

// beim Start: Instanz mit vertrauenswürdigen Issuer-Schlüsseln erstellen
const hwtr = await Hwtr.factory({}, {
  type: 'Ed25519',
  keys: [],
  publicKeys: {
    'auth-key':    'BASE64URL_SPKI',   // von auth.example.com
    'partner-key': 'BASE64URL_SPKI'    // von partner.example.com
  }
})

// im Request-Handler – kein Netzwerkaufruf
const result = await hwtr.verify(token)
if (result.ok) {
    console.log(result.data)
    // sub "user:4503" authz { scheme: "RBAC/1.0.2", roles: ["editor"] }
}

Signing und vollständiger Round-Trip:

// Schlüssel einmalig generieren, sicher speichern
const keyConfig = await Hwtr.generateKeys({ type: 'Ed25519' })

const hwtr = await Hwtr.factory({ expiresInSeconds: 3600 }, keyConfig)

// Signieren
const token = await hwtr.create({
  sub: 'user:4503',
  authz: { scheme: 'RBAC/1.0.2', roles: ['editor'] }
})

// Verifizieren
const result = await hwtr.verify(token)
// result.ok, result.data, result.expires, result.error

Die Delegation Chain

DELEGATION-CHAIN-FLUSSDIAGRAMM
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ┌────────────────────────────────────┐
  │  user:4503                         │──────────────► auth.example.com
  │  iss: auth.example.com             │                 Schlüsselveröffentlichung
  │  tid: tok-a1b2                     │
  └────────────────────────────────────┘
                    │ delegiert an
                    ▼
  ┌────────────────────────────────────┐
  │  svc:agent-a                       │──────────────► agent-a.example.com
  │  iss: agent-a.example.com          │                 Schlüsselveröffentlichung
  │  tid: tok-c3d4                     │
  └────────────────────────────────────┘
                    │ delegiert an
                    ▼
  ┌────────────────────────────────────┐
  │  svc:agent-b                       │──────────────► agent-b.example.com
  │  iss: agent-b.example.com          │                 Schlüsselabruf + Sig-Prüfung
  │  tid: tok-7c8d  (äußerer Token)    │
  └────────────────────────────────────┘
                    │ übergibt Token
                    ▼
          api.target.com

  Protokollverifizierung (Spec §12):
    1. agent-b-Signatur gegen agent-b.example.com-Schlüssel verifizieren
    2. Strukturelle Integrität von del[] bestätigen – durch äußere Signatur abgedeckt
    3. Verifizierten payload an Anwendung übergeben

  Anwendungsebene (Implementierungsentscheidung):
    4. Zustand von tok-c3d4 bei agent-a.example.com prüfen
    5. Zustand von tok-a1b2 bei auth.example.com prüfen

  Kein Schritt kontaktiert einen zentralen Server.
  Das del-Array ist durch agent-b's Signatur abgedeckt –
  es kann nach der Ausstellung nicht manipuliert werden.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Was HWT nicht adressiert

Explizite Grenzen sind für Sicherheitsprotokolle wichtig. Diese liegen bewusst außerhalb des HWT-Geltungsbereichs.

Token-Zustand und Revocation. Ob ein Token nach der Ausstellung ungültig gemacht wurde, ist keine Eigenschaft des signierten Byte-Strings. HWT definiert, was ein Token strukturell garantiert; es definiert keine Session-Lebensdauer oder Revocation-Infrastruktur. Anwendungen, die eine sofortige Invalidierung benötigen, pflegen ihren eigenen Zustandsspeicher und prüfen ihn auf Anwendungsebene. Kurze Token-Lebensdauern sind der primäre Mechanismus zur Risikobegrenzung.

Token-Ausstellung. Wie ein Principal einen Token erhält, ist Sache des Principals und des ausstellenden Service. WebAuthn/FIDO2 ist eine natürliche Ergänzung für den Authentifizierungsschritt vor der Ausstellung – ebenfalls domänensouverän, kein zentraler Anbieter.

Autorisierungsauswertung. HWT trägt den Anspruch (roles: ["editor"]). Ob editor eine bestimmte Aktion erlaubt, entscheidet die verbrauchende Anwendung. OPA und Casbin sind natürliche Ergänzungen.

Session-Bindung. HWT-Tokens sind Bearer Credentials (Inhabernachweise). Für Deployments, in denen Token-Diebstahl eine primäre Bedrohung darstellt, ist DPoP (RFC 9449) eine kompatible proof-of-possession-Erweiterung – keine HWT-Formatänderungen erforderlich.

Air-Gapped-Systeme. HWT setzt Netzwerkverfügbarkeit für Key Discovery voraus. Abgelaufene Tokens funktionieren offline nicht. Dies ist das korrekte Verhalten.

Die Begründung: Engere Protokollzusagen erzeugen präzisere Sicherheitsansprüche und klarere Integrator-Verantwortung. Wenn die Grenze explizit ist, weiß die Anwendung genau, was ihr gehört.


Algorithmen · Codecs

Algorithmus Hinweise
Ed25519 Empfohlener Standard. Schnell, kleine Signaturen.
ECDSA P-256 Breite Hardware- und HSM-Unterstützung.
ECDSA P-384 Höhere Sicherheitsmarge, wo erforderlich.
HMAC Nur für Single-Service. Nicht konform für domänenübergreifenden Einsatz.
Codec Bezeichner Hinweise
JSON j Erforderliche Baseline. Alle Implementierungen.
JSON Extended jx Dates, BigInt, typisierte Arrays, Maps, Sets. Optionaler experimenteller Import.
CBOR, MessagePack community Binäre Codecs. Siehe CONVENTIONS.md.

Status

Draft v0.7. Protokollstruktur stabil seit 2026-04.

Offen: IANA well-known URI-Registrierung · Token-Exchange-Scope-Semantik

Quellcode auf GitHub →


Erste Schritte

JS-Bibliothek installieren:

import Hwtr from 'jsr:@hwt/hwtr-js'

Funktionierende Beispiele (Deno, Node, Cloudflare Workers): hwt-demo →

Spezifikation lesen:

SPEC.md →

Implementierungen in anderen Sprachen:

IMPLEMENTATIONS.md →

Beitragen:

CONTRIBUTING.md →


Apache License 2.0 · Copyright 2026 Jim Montgomery and HWT Contributors · github.com/hwt-protocol