BLUEPRINT
第 5 章 鑑權兌換
本章描述 FayID 如何與傳統鑑權方式互通:把帳密、Certificate、Authorization、Access Token、Smart Contract 等傳統憑據兌換為 Authorization Grant,從而讓使用者只需出示 FayID(或其動態碼)即可存取多種受保護資源。
設計動機
傳統網際網路中,一個人往往需要為不同系統維護大量獨立的鑑權票據。FayID 提供了一個統一的兌換層:使用者向 Auth Exchange 提交一次傳統鑑權憑據,即可獲得一份繫結到 FayID 的 Authorization Grant;此後存取目標資源時,只需出示 Grant 即可,不再需要每次重新走傳統鑑權。
一句話:FayID 是「票據聚合器」——一個 Human ID 名下可同時持有來自不同系統的多份有效 Grant。
五類傳統鑑權來源
Auth Exchange 支援以下五類傳統鑑權憑據:
| 來源類型 | 說明 |
|---|---|
| PASSWORD | 帳號 / 密碼 |
| CERTIFICATE | 數位憑證(如 X.509) |
| AUTHORIZATION | OAuth 等授權權杖 |
| ACCESS_TOKEN | API Access Token |
| SMART_CONTRACT | 智慧合約憑據 |
每份 Authorization Grant 在中繼資料中記錄其 legacySourceKind,標明該 Grant 是從哪類來源兌換而來。
兌換流程
基本流程
sequenceDiagram
autonumber
participant U as Holder<br/>(Human / iFay)
participant LAS as Legacy Auth Source
participant AEX as Auth Exchange
participant TR as Target Resource
U ->> LAS: 出示帳密 / Cert / Token / SC 憑據
LAS -->> U: 校驗通過(傳統鑑權方完成)
U ->> AEX: exchangeLegacyForGrant(legacyCred, targetFayID, resourceRef)
AEX ->> AEX: 校驗 legacyCred<br/>校驗 targetFayID 未撤銷
alt legacyCred 校驗失敗
AEX -->> U: LEGACY_AUTH_FAILED
else targetFayID 已撤銷
AEX -->> U: IDENTITY_REVOKED
else 通過
AEX -->> U: Authorization Grant (state=ACTIVE, expiresAt)
end
Note over U,TR: 後續存取
U ->> TR: 出示 Authorization Grant
TR ->> AEX: verifyGrant(grant, resourceRef)
alt now > grant.expiresAt
AEX -->> TR: GRANT_EXPIRED
else grant.state == REVOKED
AEX -->> TR: GRANT_REVOKED
else
AEX -->> TR: ok(等效於原始傳統憑據)
end
關鍵規則
- 目標 FayID 可以是 iFay ID 或 Human ID:協定層允許兩種 target,使數位人格與自然人都能持票
- Grant 必須攜帶過期時間:
expiresAt是顯式欄位,不允許永不過期 - 撤銷支援:Grant 可被持有者主動撤銷,撤銷後立即失效
- 等效性:在有效期內,出示 Grant 等效於出示原始傳統鑑權憑據
Human ID 單點持票
設計目的
讓自然人使用者只需記憶 Human ID(或其動態碼)即可換出名下所有 Grant,不再為每個系統單獨管理票據。
流程圖
sequenceDiagram
autonumber
participant U as Human Prototype
participant AEX as Auth Exchange
participant RES as Resolver
U ->> AEX: listGrantsOfHuman(presented, resourceRef)
alt presented 是 Dynamic Code
AEX ->> RES: resolveDynamicCode(presented)
alt 解析失敗 / 過期
RES -->> AEX: DYNAMIC_CODE_EXPIRED
AEX -->> U: DYNAMIC_CODE_INVALID
else
RES -->> AEX: humanIDRef
end
else presented 是 Human ID 明文
AEX ->> AEX: 校驗 proofOfHuman
end
AEX ->> AEX: 過濾 humanIDRef 名下、resourceRef 比對、state==ACTIVE 的 Grant
AEX -->> U: [grant_1, grant_2, ...]
Note right of AEX: 永遠不返回 Mnemonic / 私鑰
關鍵規則
- 支援 Dynamic Code 出示:使用者可用動態碼代替 Human ID 明文,避免暴露根身份
- Dynamic Code 失敗處理:動態碼解析失敗或過期時,返回
DYNAMIC_CODE_INVALID - 永不返回敏感材料:Auth Exchange 不向呼叫方返回任何 Human ID 的 Mnemonic 或私鑰
- 結果是過濾集:返回該 Human ID 名下、比對 resourceRef、狀態為 ACTIVE 的 Grant 清單
撤銷協定
流程圖
sequenceDiagram
autonumber
participant U as Grant Owner
participant AEX as Auth Exchange
participant TR as Target Resource
U ->> AEX: revokeGrant(proofOfOwner, grantID)
AEX ->> AEX: state := REVOKED(終態)
AEX -->> U: ok
Note over AEX: 後續 verifyGrant 立即返回 GRANT_REVOKED
TR ->> AEX: verifyGrant(grant, resourceRef)
AEX -->> TR: GRANT_REVOKED
關鍵規則
- 撤銷是終態:一旦進入 REVOKED 狀態,不可復原
- 立即生效:撤銷後,所有後續
verifyGrant呼叫都立即返回GRANT_REVOKED - 需要所有權證明:撤銷請求必須攜帶 proofOfOwner
resourceRef 命名空間
每份 Authorization Grant 透過 resourceRef 欄位識別它保護的目標資源。
建議格式
resourceRef := "<scheme>://<authority>/<path>"
scheme := "http" | "https" | "smartcontract" | "rpc" | "fayid" | <impl-defined>
約束
resourceRef是可比較的不透明字串- 具體語法由實作決定,但 不得包含 Human ID 明文
- 跨實作互通操作時,建議遵循 URI 標準
與撤銷 ID 的互動
| 場景 | Auth Exchange 行為 |
|---|---|
| 目標 FayID(iFay ID / coFay ID)已撤銷 | 拒絕頒發新 Grant,返回 IDENTITY_REVOKED |
| Grant 已撤銷 | 後續校驗返回 GRANT_REVOKED |
| Grant 已過期 | 後續校驗返回 GRANT_EXPIRED |
| 傳統鑑權憑據校驗失敗 | 拒絕頒發,返回 LEGACY_AUTH_FAILED |
詳細的錯誤碼語義見 design.md 的「Error Handling」章節。
