Memories / 文件

本頁目錄

保管庫授權

本文件說明本機常駐程式的授權服務,以及 SaaS Center 的授權 HTTP 介面。下列本機 RPC 操作可透過共用核心、CLI 與 MCP 授權工具使用。 現有的 memories mcp grant、memories mcp revoke、Center 票證匯入與保管庫稽核命令,皆使用更新後的核心檢查。

角色與範圍上限

保管庫角色 最大授權範圍 可核發或委派?
讀者(Reader) read 否
編輯者(Editor) read_write 否
管理員(Admin) read_write_delete 是
擁有者(Owner) allow_all 是

省略範圍代表 read,而非 allow_all。這適用於本機授權、Center 票證核發、靜態託管授權與成員建立。明確指定舊版的 write: true 仍會選用 read_write;write: false 則選用 read。 write 仍是僅限寫入的範圍。allow_all 必須明確選取,且核發者必須是擁有者,即使目前它涵蓋的一般資產內容操作與 read_write_delete 相同。

核發時會同時檢查核發者目前的保管庫角色,以及使用 bearer 憑證呼叫時,核發授權的範圍。授權不能授予另一個保管庫的權限、超過任一上限,或比其父授權更晚到期。有效期間為 1–60 分鐘。要求更廣或更長的權限會失敗,不會默默縮小要求的範圍。 接收者必須已是所選保管庫的成員。內容授權可為成員提供額外的內容存取權,但不會改變其角色:持有廣泛授權的編輯者或讀者,仍無法委派或核准請求。

授權記錄會揭露 id、vault、scope、issued_by(成員 ID)、grantee、parent(核發授權 ID,或 null)、depth,以及以 Unix 秒表示的 expiry。授權 ID 是隨機的不透明識別碼,與其 bearer 權杖無關。核發時只回傳一次權杖;存取/授權清單絕不包含權杖。授權、請求與主體 ID 都是不透明的標準識別碼;面向用戶端的保管庫 ID 保留一般的短 ID 投影。

本機管理員/擁有者核發授權需要已解鎖的保管庫,不需要終端機提權。撤銷同樣不需要提權,但僅允許授權的核發者,或該保管庫目前的管理員/擁有者執行。撤銷具有遞移性。 移除核發者或被授權者,或將核發者的角色降至其核發範圍以下,會在提交政策時使受影響的授權及其後代失效;這也包含透過同步匯入的政策變更,以及重新啟動後所做的變更。 授權保存在裝置本機的加密 Store 中,僅儲存 SHA-256 bearer 雜湊與授權中繼資料;驗證採用固定時間比較雜湊。 撤銷與後代移除會隨加密狀態一併提交。鎖定會清除記憶體中的授權與 Store 金鑰,使所有授權在解鎖前無法使用;尚未到期的授權會在解鎖或常駐程式重新啟動後恢復。絕對到期時間會持久保存,載入與常駐程式定期執行時會清除已到期的授權及其後代。授權不會透過保管庫同步或復原備份匯出。

成員資格變更與裝置核准,除了新增的管理員/擁有者要求外,仍保留現有的提權檢查。建立邀請現在要求呼叫者至少在一個本機保管庫具有管理員/擁有者資格。沒有保管庫的呼叫者,以及僅具編輯者/讀者資格的呼叫者,皆採拒絕優先原則。管理員可管理管理員資格,但不能新增、移除或變更擁有者。擁有權變更使用簽署的擁有權移轉操作,並維持恰好一位擁有者。

權限請求

指定被授權者與委派深度

即使要求的內容範圍僅為 read,常駐程式與託管 Center 都會拒絕向角色高於核發者有效角色的被授權者核發授權。Center 也會拒絕保留的 center-admin 被授權者,包含先前已持久保存且具有該主體的授權。

授權呼叫者使用的授權,其主體與真正核發者不同(subject != issued_by)。此類呼叫者可建立請求,但無法核准、拒絕、取消或領取任何權限請求,包括自己的請求。常駐程式回傳 Unauthorized;Center 回傳 HTTP 403。這些呼叫者不具核准資格。自行核發的授權保留既有請求規則;Center 領取仍需要請求者的持久成員憑證。持久的 Center 成員 bearer 屬於成員權限,而非委派授權權限。

常駐程式保留嚴格的請求者憑證綁定:使用指定被授權者 bearer 建立的請求,之後不能以不同的成員憑證領取。請以將用於領取的成員或自行核發憑證重新建立此類請求。Center 則將領取綁定至請求者的持久成員 bearer。

兩種實作皆定義 pub const MAX_DELEGATION_DEPTH: u32 = 2。 由成員直接核發的授權深度為 1。使用授權權限核發時,包括領取延後核准時所使用的父授權,深度為 parent.depth + 1;深度 3 會遭拒絕。depth 會持久保存,並包含於授權摘要、核發回應、存取檢視與已核發授權清單中。沒有 depth 的舊版記錄會根據父授權鏈重建(無父授權的授權深度為 1)。遺失、循環或超過限制的授權祖先鏈採拒絕優先原則,並在載入時清除。Center 內部的持久成員憑證深度為 0,不屬於委派授權。

委派核發會透過父授權鏈保留真正核發者,而不會將指定被授權者變成自行核發的主體。判定呼叫者的真正核發者時,也會檢查既有舊版鏈。

使用指定被授權者授權記錄的舊版延後核准,在領取時也採拒絕優先原則;請從具資格的成員權限取得新的核准。

不相容變更:角色較高的接收者與 center-admin 接收者無法再取得授權;指定被授權者 bearer 無法再參與權限決策、取消或領取;深度超過兩個授權的鏈無法再使用。請使用成員憑證進行權限決策與領取;若額外委派會超過限制,請核發新的根授權。

任何目前的成員都可針對自己在保管庫中的存取權提交請求:

{
  "op": "request_create",
  "vault": "VAULT",
  "target": {"type": "scope", "scope": "read_write"},
  "reason": "Update the shared project notes",
  "duration_minutes": 15,
  "approvers": []
}

target 為 {"type":"scope","scope":"..."}(範圍預設為 read)或 {"type":"role","role":"editor"}。原因、有效期間與核准者皆為選填。若省略有效期間,範圍核准預設為 30 分鐘。角色變更是永久的:角色請求若包含有效期間會遭拒絕,且有時限的授權呼叫者不能核准永久角色變更。核准角色請求需要與直接變更成員角色相同、綁定呼叫者的提權。擁有者核准擁有者角色請求時,會執行簽署的擁有權移轉。

空的核准者清單會廣播給該保管庫所有目前的管理員/擁有者成員。否則只有列出的成員 ID 可做決定;每個列出的 ID 在建立時都必須是管理員/擁有者成員,決策時也會重新檢查資格。讀者與編輯者不能列為核准者。請求者不能核准或拒絕自己的請求,即使其為管理員/擁有者或具名核准者;但仍可取消請求。範圍/角色核准必須符合核准者的角色與 bearer 範圍,而範圍的到期時間也必須符合父授權。超出上限的核准會讓請求維持待處理狀態。

請求只會從 pending 轉換一次至 approved、rejected 或 cancelled。只有請求者能取消待處理請求。範圍核准會記錄授權參數,不會產生 bearer。請求者使用 request_claim 一次,以產生並接收權杖;request_list 只回傳中繼資料。建立/世代與授權有效期間從領取時開始,並受記錄的父授權到期時間限制。核准與領取狀態可跨鎖定/重新啟動保留,但已撤銷/到期的核准權限無法授權領取。請求狀態或持久保存的 Store 狀態皆不保留明文權杖。已領取的授權以雜湊與中繼資料形式跨鎖定/重新啟動保留。請求與權杖不會透過保管庫同步匯出。

request_list 回傳呼叫者的請求(包含已決定的請求),以及其有資格決定的待處理請求。其他成員無法檢視指定核准者的請求。每個保管庫最多儲存 1,000 個請求;原因最多 4,096 位元組。本機常駐程式與託管 Center 同時最多可有 10,000 個有效授權。

待處理限制:每位請求者在每個保管庫最多可有 20 個待處理請求,每個保管庫最多可有 200 個待處理請求;超過限制的建立操作會因限制錯誤失敗(託管 Center 回傳 HTTP 429)。待處理與已核准但未領取的請求會在 7 天後到期(稽核為 request.expire,操作者為 system);已決定的請求會在最後一次狀態轉換 30 天後清除。

RPC 操作與介面

常駐程式 JSON 的 op 名稱如下:

操作 欄位 權限
access_list vault 管理員/擁有者
grant_list vault 管理員/擁有者可查看全部;其他目前成員只能查看自己核發的授權
grant_issue vault、minutes、選填的 scope、grantee 管理員/擁有者
grant_revoke vault、id 核發者或管理員/擁有者
request_create vault、target、選填的 reason、duration_minutes、approvers 任何成員
request_list vault 自己的請求或具決策資格的待處理請求
request_approve vault、id 具資格的管理員/擁有者
request_claim vault、id 已核准範圍請求的原始請求者憑證;僅限一次
request_reject vault、id、選填的 reason 具資格的管理員/擁有者
request_cancel vault、id 待處理請求的請求者
audit vault、verify_only 管理員/擁有者

舊版 mcp_grant 與 mcp_revoke 仍受支援。Bearer 呼叫者只能針對其授權所屬的保管庫使用這些授權 RPC;這不允許 MCP 繼承終端機提權或存取已儲存的憑證。行動裝置 FFI 繼續拒絕授權管理與新的權限請求操作;不需要變更原生 ABI。

access_list 回傳依 owner、admin、editor 與 reader 分組的 principals,以及有效的 grants、devices(保管庫政策中已授權且未撤銷的裝置:device、所屬 member、name;政策不記錄建立時間)、pending_requests 與 approved_unclaimed_requests(各自包含 id、requester、範圍/角色 target、approvers 清單或 "broadcast",以及以 Unix 秒表示的 created 和 expires)。可見性仍限於管理員/擁有者。grant_list 回傳 {"vault":"VAULT","grants":[...]},不含主體分組。每個已核發授權包含 id、parent(根授權為 null)、issued_by、grantee、scope、vault、以 Unix 秒表示的 expiry、generation、depth,以及可取得時以 Unix 秒表示的 created。本機世代是核發時已提交狀態的世代,而非列出時的目前世代。已到期/撤銷的授權不會列入。 管理員/擁有者可列出保管庫內全部授權;其他目前成員只能列出自己核發的授權,不能列出僅接收的授權。Bearer 呼叫者仍綁定至其授權所屬的保管庫。兩種回應都不包含權杖、bearer 雜湊或資產本文。常駐程式 RPC、MCP grant_list 與 memories grant list VAULT 共用此服務回應。

CLI 包裝介面實作為下列確切命令(ID 為不透明識別碼):

memories access list VAULT
memories grant issue VAULT --minutes N [--scope S] [--grantee ID]
memories grant list VAULT
memories grant revoke VAULT ID
memories request create VAULT [--scope S | --role R] [--reason T] [--duration M] [--approver ID]...
memories request list VAULT
memories request approve VAULT ID
memories request claim VAULT ID
memories request reject VAULT ID [--reason T]
memories request cancel VAULT ID
memories audit list VAULT [--verify-only]

舊版 memories audit VAULT [--verify] 語法仍受支援。範圍預設為 read;未指定有效期間的本機範圍請求,保留常駐程式的 30 分鐘核准預設值。角色請求不能包含有效期間。輸出使用一般 CLI 封套中的 JSON。

託管 Center 的對應命令使用 HTTP 授權路由:

memories center access VAULT
memories center grant issue VAULT --minutes N [--scope S] [--grantee ID]
memories center grant list [VAULT]
memories center grant revoke ID
memories center request create VAULT [--scope S] [--reason T] [--duration M] [--approver ID]...
memories center request list [VAULT]
memories center request approve ID
memories center request claim ID
memories center request reject ID [--reason T]
memories center request cancel ID
memories center audit [--vault V] [--format json|jsonl]

這些命令接受 --center-url,否則使用 MEMORIES_CENTER_URL 或設定的 SaaS Center。若已設定 MEMORIES_CENTER_TOKEN,便使用該值,否則使用 MEMORIES_CENTER_ADMIN_TOKEN;權限失敗不會改用另一個 bearer 重試。託管請求支援範圍,不支援本機角色變更。範圍預設為 read,請求有效期間預設為 30 分鐘。JSONL 稽核匯出每行印出一筆 JSON 項目,不含 CLI 封套;其他輸出使用 JSON 封套。

常駐程式的 MCP 工具為 access_list、grant_issue、grant_list、grant_revoke、request_create、request_list、request_approve、request_claim、request_reject、request_cancel 與 audit_list。其參數遵循上方 RPC 欄位(授權核發使用 minutes,請求建立使用 target 與 duration_minutes,稽核使用 verify_only)。省略授權範圍或請求目標時,預設為 read。每次呼叫皆使用既有 MCP 能力憑證,絕不使用終端機提權或託管 Center bearer。

SaaS Center 實作 GET /v1/access/{vault}、POST/GET /v1/grants、DELETE /v1/grants/{id}、POST/GET /v1/requests、POST /v1/requests/{id}/approve|claim|reject|cancel,以及僅供管理員/擁有者使用的 GET /v1/audit。這些路由需要託管模式(--data)。確切的 HTTP 本文、查詢參數、回應與持久保存檔案,請參閱 Center 文件。

SaaS Center 授權

託管成員可具有選填的明確 role(reader、editor、admin、owner),與其內容 scope 獨立。省略 role 時,既有範圍層級對應為讀者(read)、編輯者(write/read_write)、管理員(read_write_delete)或擁有者(allow_all)。操作員 bearer 以 center-admin 擁有者身分作用於所有託管保管庫。靜態 bearer 主體使用 static:OPAQUE_ID ID,以及相同的範圍至角色對應。成員 ID 不能使用保留名稱 center-admin。內容範圍不會將讀者/編輯者接收者提升為管理角色。

POST /v1/grants 的 scope 預設為 read,duration_minutes 預設為 30;minutes 是有效期間的別名。核發需要管理員/擁有者角色,且遵循與本機核發相同的角色/範圍/保管庫/到期限制。回應使用 subject 表示接收者,並包含 parent、issued_by、expiry、generation 與 depth。授權權杖只出現在核發/領取回應,絕不出現在核准、清單或稽核中。 對成員呼叫者而言,接收者預設為核發者;明確指定的 grantee 必須識別所選保管庫中既有的主體。操作員未指定 grantee 核發時,會建立以授權 ID 識別的匿名授權主體,絕不建立 center-admin 主體。這也適用於託管票證核發。

每位託管成員都有持久保存的世代計數器。產生的授權會在核發時凍結核發者與接收者的世代;驗證絕不更新這些值。變更成員的範圍、角色或保管庫,或移除成員時,只會增加該成員的世代。被移除成員的計數器仍會保留,因此重新建立同一 ID 不會重設其世代。 移除或更新會撤銷該成員核發或接收的授權及所有後代,並留下稽核記錄;不相關的授權仍可運作。公開的 generation 欄位是接收者在核發時的世代。靜態與操作員主體具有固定世代。持久成員憑證只會在明確的政策轉換時重新建立,不會在驗證時重建。

託管產生的授權會保存在僅擁有者可存取的 DIR/grants.json,跨重新啟動保留;內容只有 SHA-256 bearer 雜湊、凍結的世代、到期/父授權中繼資料與撤銷資訊。雜湊比較採固定時間。已到期的授權與後代會在載入時、定期處理時,以及驗證/核發時清除。鎖定會清除 Store 金鑰並暫停授權,但不撤銷它們;尚未到期的授權與靜態/持久憑證會在解鎖後恢復。持久保存失敗會鎖定服務,並要求操作員修復/重新啟動,以避免已失效授權復活的風險。

POST /v1/requests 接受 vault,以及選填的 scope、reason、duration_minutes(別名為 duration)與 approvers。空的/省略的 approvers 會透過具資格管理員/擁有者的待處理請求清單廣播;提供 ID 則將請求指定給這些核准者。GET /v1/requests 回傳呼叫者擁有或位於其核准權限內的待處理請求,以及請求者已核准但未領取的請求,可選擇依 vault 篩選。核准與拒絕都需要所選核准者的角色/範圍/保管庫/到期權限。 請求者不能核准或拒絕自己的請求,即使其為管理員/擁有者或具名核准者;只有請求者可取消。一個決定會序列化並持久保存;重複操作回傳 409。核准只回傳 request 中繼資料,包含 status: approved、claimed: false,以及已驗證的範圍/有效期間/核發者限制;不會產生授權或回傳權杖。請求者接著以其持久成員 bearer 呼叫 POST /v1/requests/{id}/claim,取得 request 加上一次性的 grant 回應。核准者、其他成員與同一主體的其他授權,都不能使用那些憑證領取。第二次領取回傳 409。世代、建立時間與有效期間從領取時開始,到期時間受核准權限記錄的到期時間限制。已撤銷/到期的核准憑證或已變更的成員世代,不能用於領取。

常駐程式對範圍請求使用相同的延後產生流程:request_approve 儲存核准限制,request_claim 則回傳授權中繼資料,並只回傳一次 token。通過本機作業系統驗證的呼叫者仍必須是提出請求的成員;MCP 必須提供建立請求時的確切能力憑證,不能使用同一主體的不同授權。清單絕不回傳權杖。角色核准仍是立即的政策變更,沒有可領取的授權。加密 Store 狀態與 DIR/requests.json 只包含請求中繼資料;授權僅持久保存 bearer 雜湊。啟動時會依已驗證稽核核對 Center 決定與領取狀態,以避免中斷的中繼資料儲存重新開放已決定或已領取的請求。若成功領取的回應遺失,無法再次取回權杖;請改為要求新的核准。

稽核格式與驗證

本機稽核項目保留 vault、previous、sequence、timestamp、action、object、result、簽署憑證與簽章。新增的選填最上層欄位為 actor、subject(被授權者)、scope、expiry、parent、reason、issued_by、via_grant 與 request_id。Actor 識別執行操作的成員;簽署者識別記錄事件的常駐程式裝置。因此,委派操作的操作者與簽署使用者可能不同。稽核項目不包含密碼、已儲存的憑證或 bearer 權杖。

使用授權權限建立的項目包含 issued_by(真正核發者)與 via_grant(呼叫者的授權 ID);actor 仍是授權主體。核發事件的例外(mcp.grant/Center grant.issue)將真正核發者記錄為 actor,被授權者記錄為 subject,包含委派核發。這兩個選填欄位使用 serde 預設值,缺少時會省略,以保留舊版簽署稽核與 Center JSONL 記錄的序列化和驗證方式。託管內容稽核在共用 Store 中帶有相同的歸屬資訊。

稽核是每部裝置各自簽署的雜湊鏈。previous 指向前一個已序列化簽署項目的 SHA-256 雜湊,稽核映射以這些雜湊為鍵。Vault::verify 驗證簽章、雜湊、序號連續性,以及既有的保管庫歷程不變條件。舊記錄省略所有新欄位,並保留完全相同的舊版簽署位元組與雜湊。新欄位使用 serde 預設值,缺少時會省略;已填入的詳細資訊受簽章涵蓋。

事件包含 device.authorize、mcp.grant、mcp.grant.center、mcp.revoke、session.lock、session.unlock 與 request.create|request.approve|request.claim|request.reject|request.cancel,以及既有的成員資格與裝置事件。明確鎖定會傳遞稽核持久保存錯誤,但仍會清除已解鎖狀態。生命週期/閒置鎖定會嘗試稽核,即使持久保存失敗也一定清除狀態;不能為了保留稽核記錄而讓機密維持解鎖。鎖定狀態下的失敗無法簽署稽核。

SaaS Center 有獨立、僅能附加、模式為 0600 的 DIR/audit.jsonl SHA-256 鏈,並非本機簽署稽核格式。GET /v1/audit 需要管理員/擁有者,接受 vault 與 format=json|jsonl,且在篩選/匯出前會驗證完整鏈。綁定保管庫的管理員不能讀取另一個保管庫的事件;操作員也可查看全域鎖定/解鎖/註冊事件。項目包含 sequence、timestamp、prev_hash、hash、action、actor、subject、scope、vault、expiry、parent、reason、request_id 與 object;選填詳細資訊為 null。雜湊涵蓋序列化的元組 (sequence, timestamp, prev_hash, event_fields);第一筆項目的 prev_hash 為 null,之後則為前一筆項目的雜湊。

crates/center/src/saas/audit.rs 中的 verify_audit_chain(path) 檢查雜湊、序號連續性、前一個雜湊,以及完整 JSONL 行。啟動時會驗證既有檔案;附加/讀取時也會將其鏈首與執行中程序已知的鏈首比較。事件包含 device.authorize、grant.issue、grant.revoke、member.add|member.set|member.remove、session.lock|session.unlock 與 request.create|request.approve|request.claim|request.reject|request.cancel。領取事件將請求者記錄為操作者,產生的授權 ID 記錄為物件,絕不記錄權杖。稽核附加或請求/成員持久保存失敗會鎖定託管服務、設定 restart_required,並在操作員修復及重新啟動前阻止遠端解鎖。設定 restart_required 期間,授權變更與權限決策也會停止;操作員仍可進行唯讀檢視。這些未使用金鑰的鏈,無法證明操作員未重寫整份記錄或回復所有檔案;更強的保證需要外部鏈首錨點。

威脅模型與行為變更

  • 通過本機作業系統驗證的呼叫者,以已解鎖裝置所屬成員的身分操作。同一使用者的惡意程序仍位於既有端點信任邊界內。
  • 能力 bearer 是機密;任何持有者都可在撤銷、鎖定或到期前使用其受限權限。Bearer 不能擴大自己的範圍、離開所屬保管庫、延長到期時間,或繞過其主體的委派角色。
  • 撤銷不會清除先前已複製的明文或金鑰,也不能立即觸及離線對等端。政策與授權失效會在已提交更新政策的常駐程式上生效。
  • 雜湊鏈可相對於已知狀態偵測變造,不能偵測資料庫的完整回復,或遭入侵裝置省略的事件。更強的保證仍需要外部錨點與獨立安全稽核。
  • 不相容變更:未指定範圍的核發為唯讀;編輯者/讀者不能產生授權或邀請;稽核存取要求管理員/擁有者,而非提權;成員變更會使委派授權失效。新的管理員/擁有者授權核發,以及核發者/管理員撤銷,不再需要提權。沒有保管庫時建立邀請會遭拒絕,不會默默將呼叫者視為管理員。
  • 不相容變更:核准不再產生或交付 bearer,請求清單也不再交付已核准的 bearer。請求者必須明確領取一次。先前已核准但未記錄延後核准限制的請求無法領取;請建立新請求。既有、獨立核發的授權仍遵循其正常到期/撤銷規則。

限制請參閱 安全政策;獨立的僅票證 Center 與使用操作員金鑰的託管 Center 信任邊界,請參閱 Center 文件。

權限請求限制、到期與保留

適用於常駐程式(請求位於加密 Store)與 Center(requests.json):

  • MAX_PENDING_PER_REQUESTER_PER_VAULT = 20 與 MAX_PENDING_PER_VAULT = 200 只計算待處理請求。已決定、已取消、已到期,以及已核准但未領取的請求,不計入這些限制。(這取代了舊有全域 1000 個請求上限,舊限制會計算所有曾建立的請求。)超過限制時,常駐程式回傳限制錯誤,Center 回傳 HTTP 429。
  • PENDING_REQUEST_TTL = 7 days:待處理請求超過此時間後,狀態會變為 expired。稽核記錄為 request.expire,操作者為 system,之後無法再核准。已核准的範圍請求,若在核准後 7 天內未領取,也會以相同方式到期,之後無法領取。
  • REQUEST_RETENTION = 30 days:已拒絕、已取消、已到期或已領取的請求,會在最後一次狀態轉換(decided 時間戳記,或對沒有該欄位的舊記錄使用 created)經過此時間後刪除。
  • 到期與清除採延遲執行:常駐程式會在任何授權請求開始時執行,Center 則會在建立、列出、決定與領取請求時執行。啟動時不會執行。
  • Center 啟動核對會忽略已清除請求的稽核項目,並接受 request.expire 項目。expired 請求必須有到期稽核記錄。請求 ID 是永不重複使用的隨機 128 位元值,因此已清除的請求(包含已領取的請求)已不存在,無法再領取。基於這個原因,Center 不保留獨立的墓碑集合。