feat(cli): vault_get + deploy-time vault resolution
Some checks failed
CI / Lint (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Broker tests (Postgres) (push) Has been cancelled
CI / Docker build (linux/amd64) (push) Has been cancelled

- Add vault_get wire message to fetch encrypted entries for client-side
  decryption
- Deploy handler resolves $vault: refs: fetches encrypted entries from
  broker, decrypts with mesh keypair locally, sends resolved env over TLS
- File-type vault entries encoded as __vault_file__:path:base64 for
  runner-side extraction

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-04-08 12:16:46 +01:00
parent a90046a8e3
commit 75ca892ea7
5 changed files with 97 additions and 4 deletions

View File

@@ -72,6 +72,7 @@ import {
vaultSet,
vaultList,
vaultDelete,
vaultGetEntries,
upsertService,
updateServiceStatus,
updateServiceScope,
@@ -3153,6 +3154,15 @@ function handleConnection(ws: WebSocket): void {
break;
}
case "vault_get": {
const vg = msg as any;
try {
const entries = await vaultGetEntries(conn.meshId, conn.memberId, vg.keys ?? []);
sendToPeer(presenceId, { type: "vault_get_result", entries: entries.map((e: any) => ({ key: e.key, ciphertext: e.ciphertext, nonce: e.nonce, sealed_key: e.sealedKey, entry_type: e.entryType, mount_path: e.mountPath })), _reqId: vg._reqId } as any);
} catch (e) { sendError(ws, "vault_error", e instanceof Error ? e.message : String(e), undefined, vg._reqId); }
break;
}
// --- MCP Deploy/Undeploy ---
case "mcp_deploy": {
const md = msg as any;

View File

@@ -1101,6 +1101,8 @@ export interface WSVaultSetMessage { type: "vault_set"; key: string; ciphertext:
export interface WSVaultListMessage { type: "vault_list"; _reqId?: string; }
/** Client → broker: delete vault entry. */
export interface WSVaultDeleteMessage { type: "vault_delete"; key: string; _reqId?: string; }
/** Client → broker: fetch encrypted vault entries for local decryption. */
export interface WSVaultGetMessage { type: "vault_get"; keys: string[]; _reqId?: string; }
export type WSClientMessage =
| WSHelloMessage
@@ -1182,7 +1184,8 @@ export type WSClientMessage =
| WSSkillDeployMessage
| WSVaultSetMessage
| WSVaultListMessage
| WSVaultDeleteMessage;
| WSVaultDeleteMessage
| WSVaultGetMessage;
// --- Skill messages ---
@@ -1268,6 +1271,8 @@ export interface WSSkillDeployAckMessage { type: "skill_deploy_ack"; name: strin
export interface WSVaultAckMessage { type: "vault_ack"; key: string; action: "stored" | "deleted" | "not_found"; _reqId?: string; }
/** Broker → client: vault entry listing. */
export interface WSVaultListResultMessage { type: "vault_list_result"; entries: Array<{ key: string; entry_type: "env" | "file"; mount_path?: string; description?: string; updated_at: string }>; _reqId?: string; }
/** Broker → client: encrypted vault entries for local decryption. */
export interface WSVaultGetResultMessage { type: "vault_get_result"; entries: Array<{ key: string; ciphertext: string; nonce: string; sealed_key: string; entry_type: string; mount_path?: string }>; _reqId?: string; }
export type WSServerMessage =
| WSHelloAckMessage
@@ -1327,4 +1332,5 @@ export type WSServerMessage =
| WSSkillDeployAckMessage
| WSVaultAckMessage
| WSVaultListResultMessage
| WSVaultGetResultMessage
| WSErrorMessage;