8.1 KiB
8.1 KiB
API Spec
本文件定義 File Access Agent 對外 API 邊界,以及它依賴的 Member Center File Access 授權契約。
目前狀態:
- File Access Agent API:本文件定義為本專案目標契約。
- Member Center File Access API:依
../member_center/docs/openapi.yaml與相關文件整理,作為本專案整合依據。
0. 部署與資料假設
- Single-tenant instance:一個 File Access Agent instance 只服務一個 tenant。
- 服務啟動時需設定固定
INSTANCE_TENANT_ID;所有請求中的tenant_id(token 或 validation 結果)都必須與此值一致。 - 預設無 DB,服務維持 stateless。
- Metadata 讀取以 bucket provider 為主,不以本地 DB 作為權威來源。
- 若未來出現審計、replay 防護或特殊索引需求,可再加可選持久化層。
1. 角色分工
File Access Agent
負責:
- 驗證 upload 用的 Member Center JWT access token
- 接收檔案上傳、下載、metadata 查詢、刪除
- 對 delegated download token 向 Member Center 做線上驗證
- 控制實際 bucket / file space 存取
不負責:
- OAuth client 管理
- access token 簽發
- delegated download token 簽發
- 商業規則判斷與版本管理
- 結構化查詢或 metadata 主資料治理
Member Center
負責:
- 簽發 upload 用的 S2S JWT access token
- 簽發 delegated short-lived opaque download token
- 提供 delegated token validation endpoint
2. 授權模型
2.1 Upload
- token 來源:Member Center
client_credentials - audience:
file_access_api - 必要 scope:
files:upload.write - 必要 claim:
tenant_id - 驗證方式:File Access Agent 以 Member Center JWKS 驗簽 JWT
2.2 Download
- token 來源:業務服務以
files:download.delegate呼叫 Member Center 申請 - token 類型:delegated short-lived opaque token
- token 需綁定:
tenant_iduser_idfile_id或object_keymethod=GET- 短效
exp
- 驗證方式:File Access Agent 呼叫 Member Center validation endpoint 線上驗證
2.3 Metadata
建議沿用 upload 類型的 S2S JWT:
- audience:
file_access_api - 必要 scope:
files:metadata.read - 必要 claim:
tenant_id
2.4 Delete
建議沿用 upload 類型的 S2S JWT:
- audience:
file_access_api - 必要 scope:
files:delete - 必要 claim:
tenant_id
3. File Access Agent API
Base path 暫定:/
3.1 Upload File
- Method:
PUT - Path:
/files/{objectKey} - Auth:
BearerJWT - Required scope:
files:upload.write
用途:
- 由業務服務上傳檔案到 File Access Agent
Path parameters:
objectKey:URL-encoded object key
Headers:
Authorization: Bearer <access_token>Content-Type: <mime-type>
Optional headers:
X-File-Id: <string>
Request body:
- binary stream
Validation:
- JWT signature /
iss/aud=file_access_api/exp - token
tenant_id scope=files:upload.write- request
objectKey是否符合允許的 tenant 邊界策略
Object key 命名建議(介接規範):
- Agent 不做複雜命名治理,
objectKey由介接服務自行決定。 - 建議 key 結構:
{domain}/{entity}/{yyyy}/{MM}/{dd}/{id-or-uuid}/{sanitized-filename} - 建議至少包含一個高唯一性段(例如
uuid或資料庫主鍵),避免只用原始檔名。 - 建議避免使用空白、反斜線與
..;上傳前先做檔名 sanitize(保留副檔名)。 - 建議全部使用小寫與固定分隔字元(
/、-),便於跨服務對齊。
避免重複檔名與版本策略(責任邊界):
- 若上傳相同
objectKey,Agent 視為覆蓋(overwrite),不自動做版本保留。 - Agent 不負責「同名檔案改名」或「自動遞增版本號」。
- 若要避免覆蓋,介接服務應在上傳前自行產生新 key(例如
timestamp + uuid)。 - 若要做版本管理,請由介接服務把每個版本寫成不同
objectKey(例如.../v0001/...、.../v0002/...)。 - 若要保留「原始檔名查詢」能力,請在介接服務自己的資料表維護
display_name -> objectKey對照。
Responses:
201 Created400 Bad Request401 Unauthorized403 Forbidden409 Conflict413 Payload Too Large
Success body:
{
"tenant_id": "uuid",
"file_id": "optional-string",
"object_key": "reports/2026/04/file.pdf",
"content_type": "application/pdf",
"size": 12345,
"etag": "optional-string",
"last_modified_at": "2026-04-24T03:10:00Z"
}
3.2 Download File
- Method:
GET - Path:
/files/{objectKey} - Auth: delegated download token
用途:
- 由 client 使用 delegated token 下載檔案
Path parameters:
objectKey:URL-encoded object key
Headers:
Authorization: Bearer <delegated_download_token>
Validation:
- 將 token 與實際
tenant_id + file_id/object_key + method=GET邊界送到 Member Center validation endpoint - validation 成功後才允許下載
Responses:
200 OKwith file stream401 Unauthorized403 Forbidden404 Not Found
3.3 Get File Metadata
- Method:
GET - Path:
/files/metadata/{objectKey} - Auth:
BearerJWT - Required scope:
files:metadata.read
用途:
- 由業務服務讀取檔案 metadata,不回傳檔案內容
Responses:
200 OK401 Unauthorized403 Forbidden404 Not Found
Success body:
{
"tenant_id": "uuid",
"file_id": "optional-string",
"object_key": "reports/2026/04/file.pdf",
"content_type": "application/pdf",
"size": 12345,
"etag": "optional-string",
"last_modified_at": "2026-04-24T03:10:00Z"
}
3.4 Head File
- Method:
HEAD - Path:
/files/{objectKey} - Auth:
BearerJWT - Required scope:
files:metadata.read
用途:
- 提供較輕量的 existence / metadata header 檢查
Responses:
200 OK401 Unauthorized403 Forbidden404 Not Found
3.5 Delete File
- Method:
DELETE - Path:
/files/{objectKey} - Auth:
BearerJWT - Required scope:
files:delete
用途:
- 由業務服務刪除檔案
Responses:
204 No Content401 Unauthorized403 Forbidden404 Not Found
3.6 Health
- Method:
GET - Path:
/health - Auth: none
用途:
- liveness / readiness 的最小檢查
Responses:
200 OK
Success body:
{
"status": "ok"
}
4. 與 Member Center 的整合 API
以下端點不屬於本專案提供,但 File Access Agent 需要依賴。
4.1 Issue Delegated Download Token
- Provider: Member Center
- Method:
POST - Path:
/file-access/download-tokens - Required scope:
files:download.delegate
Request body:
{
"tenant_id": "uuid",
"user_id": "uuid",
"file_id": "optional-string",
"object_key": "reports/2026/04/file.pdf",
"method": "GET",
"expires_in_seconds": 300
}
Response body:
- 由 Member Center 定義;目前至少會回傳 delegated download token 與到期資訊
4.2 Validate Delegated Download Token
- Provider: Member Center
- Method:
POST - Path:
/file-access/download-tokens/validate - Required scope:
files:download.read
Request body:
{
"token": "opaque-token",
"tenant_id": "uuid",
"file_id": "optional-string",
"object_key": "reports/2026/04/file.pdf",
"method": "GET"
}
Response body:
- 由 Member Center 定義;目前至少需包含 validation success / active 狀態與對應邊界資訊
5. 共通錯誤格式
建議本專案統一採用:
{
"error": "string_code",
"message": "human readable message",
"request_id": "uuid"
}
建議錯誤碼:
invalid_tokeninsufficient_scopetenant_mismatchobject_key_mismatchmethod_mismatchfile_not_foundpayload_too_largeunsupported_media_typestorage_unavailable
6. 待補細節
tenant_id從 request path、header 或 object key prefix 如何對齊file_id是否作為正式主 key,或僅保留object_keyHEAD /files/{objectKey}是否保留,或改以GET /files/metadata/{objectKey}- upload 是否需要支援 overwrite 策略 header
- 下載是否要支援
Rangerequest - metadata / delete 是否允許 delegated token,或只接受 S2S JWT
- 可選持久化是否需要最小 audit / jti 表(預設不啟用)