HWT — Hash Web Token

任意の2サービス間で検証可能な認証トークン。中央プロバイダー不要。


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

仕様書を読む - デモを見る - ライブラリを入手する


トークンフォーマット

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

6つのドット区切りフィールド。署名は有効期限・フォーマット・payloadを単一の正規パスでカバーする。検証時はトークンからそのinputを再構築し、issuer(発行者)の公開鍵と照合する。

デコードされたpayload — 2ホップdelegation chain(委任チェーン)を持つエージェントトークン:

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

verifier(検証者)はチェーン全体を確認できる:ユーザーがagent-aに委任し、agent-aがagent-bに委任している。del配列は外側の署名でカバーされているため、発行後に改ざんすることはできない。アプリケーション層での状態確認(revocation(失効)、セッション有効性)は、各issuerにおける利用側アプリケーションの責務である。


検証

事前登録済みissuer — 本番環境での推奨構成:

起動時に信頼済みissuerの公開鍵を読み込む。以降の検証はローカルで完結し、トークンごとのネットワーク呼び出しは不要。

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

// 起動時:信頼済みissuerの公開鍵を持つインスタンスを生成
const hwtr = await Hwtr.factory({}, {
  type: 'Ed25519',
  keys: [],
  publicKeys: {
    'auth-key':    'BASE64URL_SPKI',   // auth.example.comの鍵
    'partner-key': 'BASE64URL_SPKI'    // partner.example.comの鍵
  }
})

// リクエストハンドラ内 — ネットワーク呼び出しなし
const result = await hwtr.verify(token)
if (result.ok) {
    console.log(result.data)
    // sub "user:4503" authz { scheme: "RBAC/1.0.2", roles: ["editor"] }
}

署名と完全なラウンドトリップ:

// 鍵を一度生成し、安全に保管する
const keyConfig = await Hwtr.generateKeys({ type: 'Ed25519' })

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

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

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

Delegation chain

DELEGATION CHAIN フロー図
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ┌────────────────────────────────────┐
  │  user:4503                         │──────────────► auth.example.com
  │  iss: auth.example.com             │                 鍵公開
  │  tid: tok-a1b2                     │
  └────────────────────────────────────┘
                    │ 委任先
                    ▼
  ┌────────────────────────────────────┐
  │  svc:agent-a                       │──────────────► agent-a.example.com
  │  iss: agent-a.example.com          │                 鍵公開
  │  tid: tok-c3d4                     │
  └────────────────────────────────────┘
                    │ 委任先
                    ▼
  ┌────────────────────────────────────┐
  │  svc:agent-b                       │──────────────► agent-b.example.com
  │  iss: agent-b.example.com          │                 鍵取得 + 署名検証
  │  tid: tok-7c8d  (outer token)      │
  └────────────────────────────────────┘
                    │ トークン提示
                    ▼
          api.target.com

  プロトコル検証(spec §12):
    1. agent-b.example.comの鍵に対しagent-bの署名を検証する
    2. del[]の構造的整合性を確認する — 外側の署名でカバーされている
    3. 検証済みpayloadをアプリケーションに渡す

  アプリケーション層(実装者の選択):
    4. agent-a.example.comでtok-c3d4の状態を確認する
    5. auth.example.comでtok-a1b2の状態を確認する

  どのステップも中央サーバーに接続しない。
  del配列はagent-bの署名でカバーされている —
  発行後に改ざんすることはできない。

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

HWTがカバーしない領域

セキュリティプロトコルにおいて明示的な境界は重要である。以下はHWTが意図的にスコープ外としている領域だ。

トークンの状態とrevocation。 発行後にトークンが無効化されたかどうかは、署名済みバイト列の属性ではない。HWTはトークンが構造的に何を保証するかを定義するものであり、セッションライフサイクルやrevocationインフラを定義するものではない。即時無効化が必要なアプリケーションは、独自の状態ストアを持ちアプリケーション層でこれを確認する。トークンのライフタイムを短くすることが、露出リスクを抑える主要なメカニズムである。

トークン発行。 プリンシパルがトークンを取得する方法は、プリンシパルと発行サービス間の問題である。WebAuthn/FIDO2は発行前の認証ステップとして自然な補完手段であり、こちらもドメイン主権型で中央プロバイダーを必要としない。

認可評価。 HWTはクレーム(roles: ["editor"])を運ぶ。editorが特定のアクションを許可するかどうかは、利用側アプリケーションの判断である。OPAやCasbinは自然な補完ツールとなる。

セッションバインディング。 HWTトークンはbearer credential(所持者認証情報)である。トークン盗用が主要な脅威となるデプロイメントでは、DPoP(RFC 9449)が互換性のあるproof-of-possession拡張として使用できる — HWTフォーマットの変更は不要。

エアギャップ環境。 HWTはkey discovery(鍵探索)にネットワークの可用性を前提としている。有効期限切れのトークンはオフラインでは動作しない。これは意図した動作である。

設計意図:プロトコルのコミットメントを絞り込むほど、セキュリティ上の主張が精密になり、インテグレーター側の責務が明確になる。境界が明示されていれば、アプリケーションは自分が何を担うかを正確に把握できる。


アルゴリズム · Codec

アルゴリズム 備考
Ed25519 推奨デフォルト。高速、署名サイズが小さい。
ECDSA P-256 ハードウェアおよびHSMのサポートが広い。
ECDSA P-384 必要な場合により高いセキュリティマージン。
HMAC 単一サービス専用。クロスドメイン利用には非準拠。
Codec 識別子 備考
JSON j 必須ベースライン。全実装対象。
JSON Extended jx Date、BigInt、typed array、Map、Set対応。オプションの実験的インポート。
CBOR、MessagePack コミュニティ バイナリcodec。CONVENTIONSを参照。

ステータス

Draft v0.7。プロトコル構造は2026-04時点で安定。

未解決:IANA well-known URI登録 · トークン交換スコープのセマンティクス

GitHubのソース →


はじめる

JSライブラリのインストール:

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

動作サンプル(Deno、Node、Cloudflare Workers):hwt-demo →

仕様書を読む:

SPEC.md →

他言語の実装:

IMPLEMENTATIONS.md →

貢献する:

CONTRIBUTING.md →


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