Relay · 身分驗證
驗證 Relay request
Host 驗證自己的 user,再簽發 Relay token。Relay 驗證 token,並透過其中的 claims 決定 tenant 與 user。Relay 不提供 login flow。
Production flow
Relay admin creates tenant
→ host stores the host-sync credential
→ host fetches the tenant signing secret
→ host signs a short-lived user token
→ client uses the token with REST or WebSocket 建立 tenant 後會取得 tenant_id、host_sync_client_id 與 host_sync_client_secret。Host-sync credential 必須留在受信任的 server,不得送到 browser 或 mobile client。
Host 使用 HTTP Basic authentication 取得有效的 signing secret:
POST /api/host/tenants/{tenant_id}/jwt_secret/fetch
Authorization: Basic base64(<host_sync_client_id>:<host_sync_client_secret>) 成功回應包含目前的 kid、algorithm、issuer、audience 與 jwt_secret_primary,並帶有 Cache-Control: no-store, private 和 Pragma: no-cache。
Token contract
Relay 接受使用 HS256 的 JWT。Protected header 如下:
{
"alg": "HS256",
"typ": "JWT",
"kid": "019d4900-0000-7000-8000-000000000001"
} Payload 必須包含 iss、aud、exp、tenant_id 與 user_id:
{
"iss": "tonetify-relay",
"aud": "tonetify-relay",
"exp": 1910000000,
"tenant_id": "019d4900-0000-7000-8000-000000000001",
"user_id": "019d4900-0000-7000-8000-000000000002"
} Relay 會檢查以下條件:
- Algorithm 必須是 HS256。
iss與aud必須是tonetify-relay。exp尚未到期。- Protected header 必須包含
kid。 kid必須等於 payload 的tenant_id。- Tenant 必須存在且未停用。
- Signature 必須符合該 tenant 目前的 primary 或 previous secret。
nbf 不在目前的 validation contract 內。
使用 token
每個 tenant REST request 都要把 token 放進 bearer credential:
Authorization: Bearer <jwt> WebSocket connection 使用相同的 token contract。Topic 仍包含 tenant 與 channel identifier,但這些值不能覆蓋已簽章的 tenant identity。
失敗行為
Bearer token 無效或缺少時,回應如下:
{ "errors": ["invalid_or_missing_token"] } Tenant 不存在、host-sync client ID 錯誤,或 host-sync secret 錯誤時,都會收到相同的 host-sync response:
401 Unauthorized { "errors": ["invalid_host_sync_credentials"] } Relay 不會透露 tenant 或 credential 是否存在。
Rotation 與 revocation
每個 tenant 可以同時保留 primary 與 optional previous JWT secret。正常 rotation 期間,新 token 使用 primary secret;尚未到期的既有 token 可以繼續由 previous secret 驗證。
計畫性 rotation 使用 rotate,完成後執行 expire_previous。事故處理使用 revoke_all。停用 tenant 後,JWT verification 與 host-sync secret fetch 都會被拒絕。
下一步:傳送可安全重試的訊息。