114 lines
6.3 KiB
Markdown
114 lines
6.3 KiB
Markdown
# OAuth Scope 現況
|
||
|
||
本文只記錄目前程式已註冊與 seed 的 scope。Client Credentials 與 Authorization Code 實際核發的 scope 由 OAuth application `usage` 對應的 DB mapping 決定,不接受呼叫端自行擴權。修改預設 mapping 後,既有環境需執行 `sync-oauth-clients`。
|
||
|
||
## 授權邊界
|
||
|
||
- `profile:*` 是 current-user scope,資料主體固定為 access token 的 `sub`,不能查詢其他會員。
|
||
- Email 不是跨會員 lookup key;目前沒有 by-email service API。
|
||
- Tenant scope 必須帶有效 `tenant_id`,且與 request/list tenant 相符;缺少或不符時 fail-closed。
|
||
- `.global` scope 不依賴 tenant claim,只應授予平台級 confidential client。
|
||
- Superuser/Admin 後台權限不使用 OAuth scopes,而使用 Web role + Admin Permission。
|
||
|
||
## Resource / Audience
|
||
|
||
| Resource | 預設 audience | Tenant | Scopes |
|
||
|---|---|---|---|
|
||
| `member_center_api` | `member_center_api` | scope 個別判定 | OIDC、`profile:*`、`newsletter:list.*`、`newsletter:subscriptions.*`、`newsletter:events.*` |
|
||
| `send_engine_api` | `send_engine_api` | 必須 | `newsletter:send.read`、`newsletter:send.write` |
|
||
| `file_access_api` | `file_access_api` | 必須 | `files:*` |
|
||
|
||
Token audience 由 scope → resource registry 計算。
|
||
|
||
## Scope Catalog
|
||
|
||
### OIDC
|
||
|
||
| Scope | 能力 |
|
||
|---|---|
|
||
| `openid` | OpenID Connect subject / ID token。 |
|
||
| `email` | Email claim。 |
|
||
| `profile` | 標準 OIDC profile scope;實際會員 API 仍需細分的 `profile:*`。 |
|
||
|
||
### Current-user Profile
|
||
|
||
| Scope | 能力 |
|
||
|---|---|
|
||
| `profile:basic.read` | 讀取目前登入會員基本資料。 |
|
||
| `profile:basic.write` | 修改目前登入會員基本資料。 |
|
||
| `profile:addresses.read` | 讀取目前會員地址簿。 |
|
||
| `profile:addresses.write` | 新增、修改、刪除目前會員地址。 |
|
||
| `profile:subscriptions.read` | 讀取目前會員的電子報訂閱。 |
|
||
| `profile:subscriptions.write` | 取消目前會員自己的訂閱。 |
|
||
|
||
### Newsletter / Member Center
|
||
|
||
| Scope | Tenant 規則 | 能力 |
|
||
|---|---|---|
|
||
| `newsletter:list.read` | token tenant 必須擁有 list | 依 list 讀取訂閱名單。 |
|
||
| `newsletter:list.read.global` | 平台級 | 跨 tenant 讀取訂閱名單。 |
|
||
| `newsletter:subscriptions.read` | token tenant 必須擁有 list | 依 list + email 讀取訂閱偏好。 |
|
||
| `newsletter:subscriptions.write` | token tenant 必須擁有 list | 建立訂閱、簽發一般退訂 token、更新偏好。 |
|
||
| `newsletter:events.read` | 依 resource service 規則 | 讀取電子報事件;目前 Member Center 無直接 endpoint。 |
|
||
| `newsletter:events.write` | `tenant_id` 必須匹配 | Tenant 事件回寫、one-click token、disable subscription。 |
|
||
| `newsletter:events.write.global` | 平台級 | 跨 tenant 事件回寫、one-click token、disable subscription、webhook client mapping。 |
|
||
|
||
### Send Engine
|
||
|
||
| Scope | 能力 |
|
||
|---|---|
|
||
| `newsletter:send.write` | 在 Send Engine 建立/執行發送工作。 |
|
||
| `newsletter:send.read` | 在 Send Engine 讀取發送狀態。 |
|
||
|
||
上述 scope 的資源是 Send Engine,不是 Member Center controller。
|
||
|
||
### File Access
|
||
|
||
| Scope | 能力 |
|
||
|---|---|
|
||
| `files:upload.write` | File Access service 上傳檔案。 |
|
||
| `files:download.read` | Access agent 呼叫 Member Center 驗證 delegated download token。 |
|
||
| `files:download.delegate` | 業務服務向 Member Center 簽發短效 download token。 |
|
||
| `files:metadata.read` | File Access service 讀取檔案 metadata。 |
|
||
| `files:delete` | File Access service 刪除檔案。 |
|
||
|
||
`files:upload.write`、`files:metadata.read`、`files:delete` 由 File Access service 驗證;Member Center 目前只提供 delegated token issuing / validation。
|
||
|
||
## Client Usage 預設 Mapping
|
||
|
||
| Usage | Client 型態 / Tenant | 預設 scopes |
|
||
|---|---|---|
|
||
| `web_login` | public 或 confidential;互動式登入 | `openid`、`email`、`profile`、`profile:basic.read` |
|
||
| `tenant_api` | confidential;必須綁 tenant | `newsletter:events.write`、`newsletter:list.read`、`newsletter:subscriptions.read/write`、全部 `profile:*` |
|
||
| `platform_service` | confidential;可不綁 tenant | `newsletter:events.write.global`、`newsletter:list.read.global`、全部 `profile:*` |
|
||
| `send_api` | confidential;必須綁 tenant | `newsletter:send.read/write` |
|
||
| `file_api` | confidential;必須綁 tenant | 全部 `files:*` |
|
||
| `webhook_outbound` | 現有 webhook credential usage | `openid`、`email`、`profile`、`newsletter:events.write` |
|
||
|
||
Mapping seed 採完整集合同步:從預設 mapping 移除的 scope 會在 DB mapping 停用。個別 OAuth application permissions 由 Installer `sync-oauth-clients` 更新。
|
||
|
||
現有 `tenant_api` / `platform_service` mapping 雖包含 `profile:*`,但 current-user endpoint 仍要求 `sub` 對應實際會員;Client Credentials principal 不能用這些 endpoint 查詢其他會員。目前沒有 S2S 會員資料 endpoint。
|
||
|
||
## Member Center Endpoint 對照
|
||
|
||
| Endpoint | Scope |
|
||
|---|---|
|
||
| `GET /user/profile` | `profile:basic.read` |
|
||
| `POST /user/profile` | `profile:basic.write` |
|
||
| `GET /user/addresses` | `profile:addresses.read` |
|
||
| `POST /user/addresses`、`DELETE /user/addresses/{id}` | `profile:addresses.write` |
|
||
| `GET /user/subscriptions` | `profile:subscriptions.read` |
|
||
| `POST /user/subscriptions/{id}/unsubscribe` | `profile:subscriptions.write` |
|
||
| `POST /newsletter/subscribe` | `newsletter:subscriptions.write` |
|
||
| `POST /newsletter/unsubscribe-token` | `newsletter:subscriptions.write` |
|
||
| `GET /newsletter/preferences` | `newsletter:subscriptions.read` |
|
||
| `POST /newsletter/preferences` | `newsletter:subscriptions.write` |
|
||
| `GET /newsletter/subscriptions` | `newsletter:list.read` 或 `.global` |
|
||
| `POST /newsletter/one-click-unsubscribe-token(s)` | `newsletter:events.write` 或 `.global` |
|
||
| `POST /subscriptions/disable` | `newsletter:events.write` 或 `.global` |
|
||
| `POST /integrations/send-engine/webhook-clients/upsert` | `newsletter:events.write.global` |
|
||
| `POST /file-access/download-tokens` | `files:download.delegate` |
|
||
| `POST /file-access/download-tokens/validate` | `files:download.read` |
|
||
|
||
以下端點依一次性 token 操作,不要求 OAuth scope:`GET /newsletter/confirm`、`POST /newsletter/unsubscribe`。公開 auth endpoint(register、forgot/reset、email verify)亦不屬於 scope 授權模型。
|