client_access line
client_access 是 chatroom、department 與 company 三種 scope 上每張 table 的 singleton resource。它不使用 authored ref,而是固定成 {table}.client_access;passphrase 是 write-only secret,其他設定仍可 plan 與 state 管理。對應的 REST clientAccess 介面使用同一個三-scope matrix。
JSONL Line
{"kind":"client_access","table":"orders","spec":{"passphrase_enabled":true,"passphrase":"correct-horse-battery-staple","passphrase_permissions":{"can_read":"all","can_insert":false,"can_edit":"none"}}}欄位契約
頂層 IacClientAccessLine 只接受三個欄位,且全部必填:kind: "client_access"、table ref、typed spec。沒有 ref、renamed_from 或 state。
IacClientAccessSpec:
| 欄位 | 必填 | 精確契約 |
|---|---|---|
passphrase_enabled | 是 | Pydantic boolean;JSON boolean 最清楚,"false" 等可辨識 token 會被 coercion |
passphrase | 否 | string/null,最多 256 字元;plaintext write-only;"<REDACTED>" 表示保留 live secret |
passphrase_permissions | 否 | DefaultPermissionsPayload object/null |
passphrase_permissions 支援 can_read(預設 all)、can_insert(預設 false)、can_edit(預設 none)、read_filter、edit_filter;access level 集合是 none|own|all|filtered。省略整個 permissions 時,apply 使用 read-only defaults。Client-access spec 的未知欄位會以 extra_forbidden 拒絕。
Ref 與身分規則
table: "orders" 產生固定 identity orders.client_access。它加入同一 per-table child-ref namespace,因此若 column、rule、trigger、view 或 public_read 的 authored ref 也叫 client_access,會碰撞:
duplicate ref 'orders.client_access' (already declared in this document)passphrase_permissions 直接重用 REST DefaultPermissionsPayload。其中 row-policy predicate 的 column 是 live col_<hex> internal key,不是 IaC column ref;client_access path 不做 grant line 的 ref translation。Filtered client access 因此必須以目的 scope 的 internal keys 重新核對,不能把來源 scope 的 policy 當成可攜 ref。Passphrase 本身不是 ref,也不應被拿來形成 identity。
生命週期與規劃
Client access 沒有 state 欄位,因此也沒有 absent/delete lifecycle——這一點它只和 header 與 record 相同,其他 kind 都不是這樣。要停用 passphrase access,宣告 passphrase_enabled: false。初次設定提供真實 passphrase;export 永遠輸出 "<REDACTED>"。在同一 scope apply redacted value會保留既有 hash;在新 scope 啟用時若沒有 live hash,必須替換為真實 passphrase,否則 plan error:
passphrase_enabled with '<REDACTED>' requires an existing live passphrase hashPlan 對 secret 只顯示 <REDACTED>,不回傳 plaintext/hash。Spec omitted fields 不接管 live value;state 也會移除 secret。
驗證錯誤
缺少 spec:
[{"type": "missing", "loc": ["client_access", "spec"], "msg": "Field required", "url": "https://errors.pydantic.dev/2.12/v/missing"}]passphrase_enabled: "maybe":
[{"type": "bool_parsing", "loc": ["client_access", "spec", "passphrase_enabled"], "msg": "Input should be a valid boolean, unable to interpret input", "url": "https://errors.pydantic.dev/2.12/v/bool_parsing"}]Parent 與 singleton collision:
unknown table ref 'orders'
duplicate ref 'orders.client_access' (already declared in this document)精確本機 detail 來源:components/iac/parse.ts:694-759,1209-1225;secret/live-hash 與 row-policy internal-key 檢查只會在 server plan 出現。REST 欄位契約見 client access 參考。
動手試試
在 IaC 工作台用 passphrase_enabled: "maybe" 觀察 parse error,再改成 JSON boolean。Export 一份測試設定並確認 secret 已遮罩;跨 scope apply 前替換 redacted passphrase。