開始使用 Signet
這份指南是寫給串接方開發者的:您要將既有的應用程式接上已經部署好的 Signet。若您要找伺服器營運與部署文件(啟動伺服器、環境變數、金鑰產生等),請參考專案 README。
稽核頁面(/admin/audit 與 /account/audit)一律使用游標式「上一頁/下一頁」導覽,不顯示總筆數或頁碼。僅含舊式 ?page=N 的網址會開啟第一個游標頁面;既有游標連結仍可使用。已移除的 AUDIT_CURSOR_PAGINATION_ENABLED 環境變數不再生效。JSON API 保留 offset 分頁與總筆數。營運文件請參考專案 README。
Signet 是一個 OAuth 2.0 + OpenID Connect 授權伺服器,會簽發權杖(token)給您的應用程式,用於認證使用者與呼叫受保護的 API。
選擇流程
| 您的應用程式型態 | 建議流程 |
|---|---|
| 伺服器端網頁應用(有後端) | Authorization Code + PKCE(機密客戶端) |
| 單頁應用(React / Vue / Svelte 等) | Authorization Code + PKCE(公開客戶端) |
| 行動或桌面應用 | Authorization Code + PKCE(公開客戶端) |
| CLI 工具、IoT 裝置、無頭環境(SSH、容器) | Device Authorization Grant |
| 後端服務呼叫另一個服務(無使用者) | Client Credentials |
| 跑不了任何流程的 script、CI job、cron | 個人 API 金鑰(sgk_) |
還沒頭緒?任何「有使用者」的情境請用 Authorization Code + PKCE,「服務對服務」請用 Client Credentials。個人 API 金鑰 是最後手段,給完全跑不了任何流程的呼叫端 — 它拿短命 token 與離線驗證換來「一行 curl 就能跑」。
串接之前
向 Signet 管理員索取:
- Base URL — 例如
https://your-signet。其他資訊都可以從BASE_URL/.well-known/openid-configuration發現(見下節)。
client_id— 識別您的應用程式。
client_secret— 只有 機密 客戶端才會拿到(伺服器端網頁應用、Client Credentials 服務)。公開客戶端(SPA、行動、CLI)沒有 secret。
- 允許的 redirect URI — Authorization Code Flow 會用到。Signet 做 完全字串比對:
https://yourapp.example/cb與https://yourapp.example/cb/是不同的。
- 允許的 scope — 此客戶端可要求的 scope 子集(例如
openid、profile、email、offline_access)。管理員也可能註冊了自訂的 API scope,請向管理員詢問。
- 啟用的 grant type — 此客戶端開啟了 Device Flow / Auth Code Flow / Client Credentials 中的哪幾種。
- Resource 識別字 — _除非您在整合 MCP server 或多 RS 部署且需要 audience binding(RFC 8707),否則略過此項_。要帶入
resource=的絕對 http(s) URI,這樣簽發的 access token 的aud才會等於您的 resource server。每個值都必須由管理員加入您客戶端的 允許資源清單 — 它 預設全部拒絕,因此允許清單為空的客戶端,送出任何resource=都會拿到invalid_target。
從這裡開始:OIDC Discovery
不要把端點 URL 寫死,改成抓取 OIDC Discovery 文件:
curl https://your-signet/.well-known/openid-configuration
{
"issuer": "https://your-signet",
"authorization_endpoint": "https://your-signet/oauth/authorize",
"token_endpoint": "https://your-signet/oauth/token",
"userinfo_endpoint": "https://your-signet/oauth/userinfo",
"revocation_endpoint": "https://your-signet/oauth/revoke",
"jwks_uri": "https://your-signet/.well-known/jwks.json",
"response_types_supported": ["code"],
"subject_types_supported": ["public"],
"id_token_signing_alg_values_supported": ["RS256"],
"scopes_supported": ["openid", "profile", "email"],
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post",
"none"
],
"grant_types_supported": [
"authorization_code",
"urn:ietf:params:oauth:grant-type:device_code",
"refresh_token",
"client_credentials"
],
"claims_supported": [
"sub",
"iss",
"aud",
"exp",
"iat",
"jti",
"auth_time",
"nonce",
"at_hash",
"name",
"preferred_username",
"email",
"email_verified",
"picture",
"updated_at"
],
"code_challenge_methods_supported": ["S256"],
"authorization_response_iss_parameter_supported": true
}
多數成熟的 OAuth / OIDC 函式庫可以直接吃這份文件並自動把流程接起來。
幾個需要注意的眉角:
jwks_uri與id_token_signing_alg_values_supported只在 Signet 設定為 RS256/ES256(非對稱簽章)時才會出現。HS256 部署會省略這兩個欄位。
/oauth/introspect與/oauth/device/code有支援,但 未在 Discovery 宣告,請直接使用本指南列出的路徑。
scopes_supported只列出內建的 OIDC scope(openid、profile、email)。offline_access以及管理員為某客戶端註冊的任何 自訂 API scope,即使沒列在這裡,被要求時仍會被接受 — 請向管理員詢問哪些適用。
非 OIDC / MCP 客戶端:Signet 也在
/.well-known/oauth-authorization-server發布一份 RFC 8414 授權伺服器 metadata,會宣告resource_indicators_supported: true與device_authorization_endpoint,是 MCP 與純 OAuth 2.1 客戶端慣用的版本。兩份文件重疊欄位內容相同;依您函式庫的需求挑一份即可。
支援的 scope
| Scope | 用途 |
|---|---|
openid |
要拿到 ID token 與使用 /oauth/userinfo 的必要條件 |
profile |
在 UserInfo / ID token 中解鎖 name、preferred_username、picture、updated_at |
email |
在 UserInfo / ID token 中解鎖 email、email_verified |
offline_access |
表示您想拿到 refresh token(OIDC Core §11) |
注意事項:
openid與offline_access在 Client Credentials 流程中 不合法,會被拒絕。
- 客戶端只能索取管理員為其註冊過的 scope。
- scope 以空白分隔字串傳送(
scope=openid profile email)。
權杖速覽
流程成功後,Signet 會簽發:
- Access token — JWT;短效;帶在 API 呼叫的
Authorization: Bearer <token>中。
- Refresh token — 不透明;較長效;拿到
/oauth/token換取新的 access token。
- ID token — 關於使用者的 JWT(只有
scope包含openid時才會有)。詳見 OpenID Connect。
Access token 的生命週期會依每個客戶端的設定而異(short ≈ 15 分鐘、standard ≈ 10 小時、long ≈ 24 小時)。請一律看 token response 的 expires_in 欄位,絕對不要寫死時間。
在 token 請求帶 resource=<URL> 時,access token 的 aud claim 會綁到該 resource(RFC 8707)— 前提是該值在您客戶端的允許清單上(預設全部拒絕)。Resource server 應對自己的識別字驗 aud — 見 JWT 驗證 §Audience Binding。
速率限制、撤銷、反查、refresh rotation:請見 Token 與撤銷。
最小串接檢查清單
- [ ] 與管理員確認
BASE_URL、client_id、(必要時)client_secret、redirect URI、scope。
- [ ] 啟動時抓一次
/.well-known/openid-configuration並快取。
- [ ] 選一個流程並實作(見下方各流程文件)。
- [ ] 在 resource server 以 JWKS 驗證 token(JWT 驗證)。
- [ ] 處理常見的 OAuth 錯誤(錯誤處理)。
- [ ] 實作登出:以 refresh token 呼叫
/oauth/revoke(Token 與撤銷)。
- [ ] 如果是公開且長效的客戶端,使用 PKCE(Signet 只接受
S256)。
下一步
- Authorization Code Flow + PKCE — 網頁、SPA、行動應用
- Device Authorization Flow — CLI 與無頭客戶端
- Client Credentials Flow — 服務對服務
- API 金鑰 — 給跑不了流程的 script 與 CI 用的不透明
sgk_金鑰
- OpenID Connect — ID token 與 UserInfo
- JWT 驗證 — 在 resource server 驗證 access token
- Token 與撤銷 — 刷新、撤銷、反查
- 錯誤處理 — OAuth 錯誤碼與對應做法