@vellumai/assistant 0.5.6 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +16 -2
- package/ARCHITECTURE.md +6 -75
- package/Dockerfile +1 -1
- package/README.md +0 -2
- package/bun.lock +0 -414
- package/docs/architecture/keychain-broker.md +45 -240
- package/docs/architecture/security.md +0 -17
- package/docs/credential-execution-service.md +2 -2
- package/node_modules/@vellumai/ces-contracts/package.json +1 -0
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +119 -0
- package/node_modules/@vellumai/credential-storage/package.json +1 -0
- package/node_modules/@vellumai/egress-proxy/package.json +1 -0
- package/package.json +2 -3
- package/src/__tests__/actor-token-service.test.ts +0 -114
- package/src/__tests__/assistant-feature-flags-integration.test.ts +30 -29
- package/src/__tests__/browser-skill-endstate.test.ts +6 -5
- package/src/__tests__/btw-routes.test.ts +0 -39
- package/src/__tests__/call-domain.test.ts +0 -128
- package/src/__tests__/ces-rpc-credential-backend.test.ts +199 -0
- package/src/__tests__/channel-approval-routes.test.ts +0 -5
- package/src/__tests__/channel-readiness-service.test.ts +1 -60
- package/src/__tests__/checker.test.ts +4 -2
- package/src/__tests__/cli-command-risk-guard.test.ts +112 -0
- package/src/__tests__/config-schema-cmd.test.ts +0 -1
- package/src/__tests__/config-schema.test.ts +1 -1
- package/src/__tests__/conversation-attention-telegram.test.ts +0 -5
- package/src/__tests__/conversation-init.benchmark.test.ts +0 -2
- package/src/__tests__/conversation-skill-tools.test.ts +0 -54
- package/src/__tests__/conversation-title-service.test.ts +87 -0
- package/src/__tests__/credential-execution-feature-gates.test.ts +28 -14
- package/src/__tests__/credential-execution-managed-contract.test.ts +33 -18
- package/src/__tests__/credential-security-e2e.test.ts +0 -66
- package/src/__tests__/credential-security-invariants.test.ts +4 -45
- package/src/__tests__/credentials-cli.test.ts +78 -0
- package/src/__tests__/db-migration-rollback.test.ts +2015 -1
- package/src/__tests__/docker-signing-key-bootstrap.test.ts +34 -143
- package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +6 -4
- package/src/__tests__/guardian-routing-state.test.ts +0 -5
- package/src/__tests__/host-shell-tool.test.ts +6 -7
- package/src/__tests__/http-user-message-parity.test.ts +3 -103
- package/src/__tests__/inbound-invite-redemption.test.ts +0 -4
- package/src/__tests__/inline-skill-load-permissions.test.ts +6 -8
- package/src/__tests__/intent-routing.test.ts +0 -13
- package/src/__tests__/jobs-store-qdrant-breaker.test.ts +178 -0
- package/src/__tests__/keychain-broker-client.test.ts +161 -22
- package/src/__tests__/memory-jobs-worker-backoff.test.ts +150 -0
- package/src/__tests__/migration-export-http.test.ts +2 -2
- package/src/__tests__/migration-import-commit-http.test.ts +2 -2
- package/src/__tests__/migration-import-preflight-http.test.ts +2 -2
- package/src/__tests__/migration-validate-http.test.ts +2 -2
- package/src/__tests__/non-member-access-request.test.ts +0 -5
- package/src/__tests__/notification-decision-fallback.test.ts +4 -0
- package/src/__tests__/notification-decision-identity.test.ts +4 -0
- package/src/__tests__/permission-types.test.ts +1 -0
- package/src/__tests__/provider-managed-proxy-integration.test.ts +5 -6
- package/src/__tests__/qdrant-manager.test.ts +28 -2
- package/src/__tests__/registry.test.ts +0 -6
- package/src/__tests__/runtime-attachment-metadata.test.ts +0 -4
- package/src/__tests__/secret-routes-managed-proxy.test.ts +0 -4
- package/src/__tests__/secure-keys.test.ts +83 -263
- package/src/__tests__/shell-identity.test.ts +96 -6
- package/src/__tests__/skill-feature-flags-integration.test.ts +22 -14
- package/src/__tests__/skill-feature-flags.test.ts +46 -45
- package/src/__tests__/skill-load-feature-flag.test.ts +7 -10
- package/src/__tests__/skill-load-inline-command.test.ts +8 -12
- package/src/__tests__/skill-load-inline-includes.test.ts +6 -10
- package/src/__tests__/skill-load-tool.test.ts +0 -2
- package/src/__tests__/skill-projection-feature-flag.test.ts +33 -29
- package/src/__tests__/skills.test.ts +0 -2
- package/src/__tests__/slack-inbound-verification.test.ts +0 -4
- package/src/__tests__/suggestion-routes.test.ts +1 -32
- package/src/__tests__/system-prompt.test.ts +0 -1
- package/src/__tests__/tool-executor-shell-integration.test.ts +5 -3
- package/src/__tests__/trusted-contact-lifecycle-notifications.test.ts +0 -5
- package/src/__tests__/trusted-contact-multichannel.test.ts +0 -4
- package/src/__tests__/update-bulletin.test.ts +0 -2
- package/src/__tests__/vellum-self-knowledge-inline-command.test.ts +6 -9
- package/src/__tests__/voice-scoped-grant-consumer.test.ts +0 -6
- package/src/__tests__/workspace-migration-015-migrate-credentials-to-keychain.test.ts +252 -0
- package/src/__tests__/workspace-migration-016-migrate-credentials-from-keychain.test.ts +218 -0
- package/src/__tests__/workspace-migration-down-functions.test.ts +1009 -0
- package/src/__tests__/workspace-migrations-runner.test.ts +114 -0
- package/src/calls/audio-store.test.ts +97 -0
- package/src/calls/audio-store.ts +205 -0
- package/src/calls/call-controller.ts +85 -7
- package/src/calls/call-domain.ts +3 -0
- package/src/calls/call-store.ts +10 -3
- package/src/calls/fish-audio-client.ts +117 -0
- package/src/calls/relay-server.ts +27 -0
- package/src/calls/twilio-routes.ts +2 -1
- package/src/calls/types.ts +1 -0
- package/src/calls/voice-ingress-preflight.ts +0 -42
- package/src/calls/voice-quality.ts +26 -5
- package/src/calls/voice-session-bridge.ts +6 -12
- package/src/cli/commands/config.ts +1 -4
- package/src/cli/commands/credentials.ts +34 -4
- package/src/cli/commands/oauth/index.ts +7 -0
- package/src/cli/commands/oauth/platform.ts +179 -0
- package/src/cli/commands/platform.ts +3 -3
- package/src/config/assistant-feature-flags.ts +186 -5
- package/src/config/bundled-skills/messaging/SKILL.md +5 -5
- package/src/config/bundled-skills/phone-calls/TOOLS.json +4 -0
- package/src/config/bundled-skills/settings/TOOLS.json +2 -2
- package/src/config/bundled-skills/settings/tools/voice-config-update.ts +42 -0
- package/src/config/bundled-tool-registry.ts +1 -11
- package/src/config/env-registry.ts +1 -1
- package/src/config/env.ts +8 -14
- package/src/config/feature-flag-registry.json +48 -8
- package/src/config/loader.ts +98 -31
- package/src/config/schema.ts +4 -13
- package/src/config/schemas/calls.ts +13 -0
- package/src/config/schemas/fish-audio.ts +39 -0
- package/src/config/schemas/security.ts +0 -4
- package/src/config/types.ts +0 -1
- package/src/contacts/contact-store.ts +39 -0
- package/src/contacts/types.ts +2 -0
- package/src/credential-execution/approval-bridge.ts +1 -0
- package/src/credential-execution/executable-discovery.ts +28 -4
- package/src/credential-execution/feature-gates.ts +16 -0
- package/src/credential-execution/process-manager.ts +38 -0
- package/src/daemon/assistant-attachments.ts +9 -0
- package/src/daemon/config-watcher.ts +5 -0
- package/src/daemon/conversation-tool-setup.ts +0 -105
- package/src/daemon/conversation.ts +10 -1
- package/src/daemon/handlers/config-vercel.ts +92 -0
- package/src/daemon/handlers/skills.ts +2 -15
- package/src/daemon/install-symlink.ts +195 -0
- package/src/daemon/lifecycle.ts +227 -51
- package/src/daemon/message-types/conversations.ts +3 -4
- package/src/daemon/message-types/diagnostics.ts +3 -22
- package/src/daemon/message-types/messages.ts +0 -2
- package/src/daemon/message-types/upgrades.ts +8 -0
- package/src/daemon/server.ts +30 -92
- package/src/events/domain-events.ts +2 -1
- package/src/inbound/platform-callback-registration.ts +3 -3
- package/src/instrument.ts +8 -5
- package/src/memory/conversation-title-service.ts +50 -1
- package/src/memory/db-init.ts +12 -0
- package/src/memory/items-extractor.ts +15 -1
- package/src/memory/job-handlers/conversation-starters.ts +4 -1
- package/src/memory/jobs-store.ts +30 -5
- package/src/memory/jobs-worker.ts +31 -7
- package/src/memory/migrations/001-job-deferrals.ts +19 -0
- package/src/memory/migrations/004-entity-relation-dedup.ts +10 -0
- package/src/memory/migrations/005-fingerprint-scope-unique.ts +76 -0
- package/src/memory/migrations/006-scope-salted-fingerprints.ts +50 -0
- package/src/memory/migrations/007-assistant-id-to-self.ts +10 -0
- package/src/memory/migrations/008-remove-assistant-id-columns.ts +34 -0
- package/src/memory/migrations/009-llm-usage-events-drop-assistant-id.ts +26 -0
- package/src/memory/migrations/014-backfill-inbox-thread-state.ts +10 -0
- package/src/memory/migrations/015-drop-active-search-index.ts +17 -0
- package/src/memory/migrations/019-notification-tables-schema-migration.ts +12 -0
- package/src/memory/migrations/020-rename-macos-ios-channel-to-vellum.ts +121 -0
- package/src/memory/migrations/024-embedding-vector-blob.ts +74 -0
- package/src/memory/migrations/026a-embeddings-nullable-vector-json.ts +82 -0
- package/src/memory/migrations/036-normalize-phone-identities.ts +11 -0
- package/src/memory/migrations/116-messages-fts.ts +106 -1
- package/src/memory/migrations/126-backfill-guardian-principal-id.ts +52 -0
- package/src/memory/migrations/127-guardian-principal-id-not-null.ts +77 -0
- package/src/memory/migrations/134-contacts-notes-column.ts +13 -0
- package/src/memory/migrations/135-backfill-contact-interaction-stats.ts +20 -0
- package/src/memory/migrations/136-drop-assistant-id-columns.ts +52 -0
- package/src/memory/migrations/140-backfill-usage-cache-accounting.ts +13 -0
- package/src/memory/migrations/141-rename-verification-table.ts +54 -0
- package/src/memory/migrations/142-rename-verification-session-id-column.ts +25 -0
- package/src/memory/migrations/143-rename-guardian-verification-values.ts +35 -0
- package/src/memory/migrations/144-rename-voice-to-phone.ts +136 -0
- package/src/memory/migrations/145-drop-accounts-table.ts +32 -0
- package/src/memory/migrations/147-migrate-reminders-to-schedules.ts +14 -1
- package/src/memory/migrations/148-drop-reminders-table.ts +35 -1
- package/src/memory/migrations/150-oauth-apps-client-secret-path.ts +69 -1
- package/src/memory/migrations/162-guardian-timestamps-epoch-ms.ts +290 -0
- package/src/memory/migrations/169-rename-gmail-provider-key-to-google.ts +51 -1
- package/src/memory/migrations/174-rename-thread-starters-table.ts +47 -1
- package/src/memory/migrations/176-drop-capability-card-state.ts +13 -0
- package/src/memory/migrations/180-backfill-inline-attachments-to-disk.ts +16 -0
- package/src/memory/migrations/181-rename-thread-starters-checkpoints.ts +28 -1
- package/src/memory/migrations/190-call-session-skip-disclosure.ts +15 -0
- package/src/memory/migrations/191-backfill-audio-attachment-mime-types.ts +64 -0
- package/src/memory/migrations/192-contacts-user-file-column.ts +15 -0
- package/src/memory/migrations/index.ts +4 -0
- package/src/memory/migrations/registry.ts +90 -0
- package/src/memory/migrations/validate-migration-state.ts +137 -11
- package/src/memory/qdrant-circuit-breaker.ts +9 -0
- package/src/memory/qdrant-manager.ts +64 -7
- package/src/memory/schema/calls.ts +1 -0
- package/src/memory/schema/contacts.ts +1 -0
- package/src/notifications/decision-engine.ts +4 -1
- package/src/oauth/connection-resolver.ts +6 -4
- package/src/permissions/checker.ts +0 -38
- package/src/permissions/shell-identity.ts +76 -22
- package/src/permissions/types.ts +4 -2
- package/src/platform/client.ts +35 -7
- package/src/prompts/persona-resolver.ts +138 -0
- package/src/prompts/system-prompt.ts +36 -4
- package/src/prompts/templates/users/default.md +1 -0
- package/src/providers/registry.ts +27 -40
- package/src/runtime/auth/__tests__/credential-service.test.ts +0 -1
- package/src/runtime/auth/__tests__/external-assistant-id.test.ts +13 -68
- package/src/runtime/auth/external-assistant-id.ts +13 -59
- package/src/runtime/auth/route-policy.ts +15 -1
- package/src/runtime/auth/token-service.ts +43 -138
- package/src/runtime/channel-readiness-service.ts +1 -16
- package/src/runtime/http-server.ts +27 -2
- package/src/runtime/middleware/error-handler.ts +1 -9
- package/src/runtime/routes/audio-routes.ts +40 -0
- package/src/runtime/routes/btw-routes.ts +0 -17
- package/src/runtime/routes/conversation-query-routes.ts +63 -1
- package/src/runtime/routes/conversation-routes.ts +4 -44
- package/src/runtime/routes/diagnostics-routes.ts +1 -477
- package/src/runtime/routes/identity-routes.ts +18 -29
- package/src/runtime/routes/inbound-stages/secret-ingress-check.ts +4 -33
- package/src/runtime/routes/inbound-stages/transcribe-audio.test.ts +1 -1
- package/src/runtime/routes/integrations/vercel.ts +89 -0
- package/src/runtime/routes/log-export-routes.ts +5 -0
- package/src/runtime/routes/memory-item-routes.ts +24 -6
- package/src/runtime/routes/migration-rollback-routes.ts +209 -0
- package/src/runtime/routes/migration-routes.ts +17 -1
- package/src/runtime/routes/notification-routes.ts +58 -0
- package/src/runtime/routes/schedule-routes.ts +65 -0
- package/src/runtime/routes/settings-routes.ts +41 -1
- package/src/runtime/routes/tts-routes.ts +86 -0
- package/src/runtime/routes/upgrade-broadcast-routes.ts +26 -2
- package/src/runtime/routes/workspace-commit-routes.ts +62 -0
- package/src/runtime/routes/workspace-routes.test.ts +22 -1
- package/src/runtime/routes/workspace-routes.ts +1 -1
- package/src/runtime/routes/workspace-utils.ts +86 -2
- package/src/security/ces-credential-client.ts +59 -22
- package/src/security/ces-rpc-credential-backend.ts +85 -0
- package/src/security/credential-backend.ts +12 -88
- package/src/security/keychain-broker-client.ts +10 -2
- package/src/security/secure-keys.ts +94 -113
- package/src/skills/catalog-install.ts +13 -7
- package/src/telemetry/usage-telemetry-reporter.ts +4 -2
- package/src/tools/calls/call-start.ts +1 -0
- package/src/tools/executor.ts +0 -4
- package/src/tools/network/script-proxy/session-manager.ts +19 -4
- package/src/tools/network/web-fetch.ts +3 -1
- package/src/tools/skills/execute.ts +1 -1
- package/src/tools/types.ts +0 -8
- package/src/util/errors.ts +0 -12
- package/src/util/platform.ts +3 -50
- package/src/workspace/git-service.ts +5 -2
- package/src/workspace/migrations/001-avatar-rename.ts +15 -0
- package/src/workspace/migrations/003-seed-device-id.ts +17 -1
- package/src/workspace/migrations/004-extract-collect-usage-data.ts +33 -0
- package/src/workspace/migrations/005-add-send-diagnostics.ts +3 -0
- package/src/workspace/migrations/006-services-config.ts +49 -0
- package/src/workspace/migrations/007-web-search-provider-rename.ts +27 -0
- package/src/workspace/migrations/008-voice-timeout-and-max-steps.ts +3 -0
- package/src/workspace/migrations/009-backfill-conversation-disk-view.ts +4 -0
- package/src/workspace/migrations/010-app-dir-rename.ts +78 -0
- package/src/workspace/migrations/011-backfill-installation-id.ts +11 -0
- package/src/workspace/migrations/012-rename-conversation-disk-view-dirs.ts +44 -0
- package/src/workspace/migrations/013-repair-conversation-disk-view.ts +5 -0
- package/src/workspace/migrations/015-migrate-credentials-to-keychain.ts +153 -0
- package/src/workspace/migrations/016-extract-feature-flags-to-protected.ts +156 -0
- package/src/workspace/migrations/016-migrate-credentials-from-keychain.ts +150 -0
- package/src/workspace/migrations/017-seed-persona-dirs.ts +95 -0
- package/src/workspace/migrations/migrate-to-workspace-volume.ts +23 -1
- package/src/workspace/migrations/registry.ts +8 -0
- package/src/workspace/migrations/runner.ts +106 -2
- package/src/workspace/migrations/types.ts +4 -0
- package/src/__tests__/claude-code-skill-regression.test.ts +0 -206
- package/src/__tests__/claude-code-tool-profiles.test.ts +0 -99
- package/src/__tests__/diagnostics-export.test.ts +0 -288
- package/src/__tests__/local-gateway-health.test.ts +0 -209
- package/src/__tests__/secret-ingress-handler.test.ts +0 -120
- package/src/__tests__/swarm-conversation-integration.test.ts +0 -358
- package/src/__tests__/swarm-dag-pathological.test.ts +0 -547
- package/src/__tests__/swarm-orchestrator.test.ts +0 -463
- package/src/__tests__/swarm-plan-validator.test.ts +0 -384
- package/src/__tests__/swarm-recursion.test.ts +0 -197
- package/src/__tests__/swarm-router-planner.test.ts +0 -234
- package/src/__tests__/swarm-tool.test.ts +0 -185
- package/src/__tests__/swarm-worker-backend.test.ts +0 -144
- package/src/__tests__/swarm-worker-runner.test.ts +0 -288
- package/src/commands/__tests__/cc-command-registry.test.ts +0 -396
- package/src/commands/cc-command-registry.ts +0 -248
- package/src/config/bundled-skills/claude-code/SKILL.md +0 -53
- package/src/config/bundled-skills/claude-code/TOOLS.json +0 -47
- package/src/config/bundled-skills/claude-code/tools/claude-code.ts +0 -12
- package/src/config/bundled-skills/orchestration/SKILL.md +0 -33
- package/src/config/bundled-skills/orchestration/TOOLS.json +0 -35
- package/src/config/bundled-skills/orchestration/tools/swarm-delegate.ts +0 -12
- package/src/config/schemas/swarm.ts +0 -82
- package/src/logfire.ts +0 -135
- package/src/runtime/local-gateway-health.ts +0 -275
- package/src/security/secret-ingress.ts +0 -68
- package/src/swarm/backend-claude-code.ts +0 -225
- package/src/swarm/checkpoint.ts +0 -137
- package/src/swarm/graph-utils.ts +0 -53
- package/src/swarm/index.ts +0 -55
- package/src/swarm/limits.ts +0 -66
- package/src/swarm/orchestrator.ts +0 -424
- package/src/swarm/plan-validator.ts +0 -117
- package/src/swarm/router-planner.ts +0 -162
- package/src/swarm/router-prompts.ts +0 -39
- package/src/swarm/synthesizer.ts +0 -81
- package/src/swarm/types.ts +0 -72
- package/src/swarm/worker-backend.ts +0 -131
- package/src/swarm/worker-prompts.ts +0 -80
- package/src/swarm/worker-runner.ts +0 -170
- package/src/tools/claude-code/claude-code.ts +0 -610
- package/src/tools/swarm/delegate.ts +0 -205
|
@@ -1,264 +1,69 @@
|
|
|
1
|
-
# macOS Keychain Broker Architecture
|
|
1
|
+
# macOS Keychain Broker Architecture (Legacy)
|
|
2
2
|
|
|
3
|
-
**Status:**
|
|
4
|
-
**Last Updated:** 2026-03-
|
|
3
|
+
**Status:** Superseded by CES credential routing
|
|
4
|
+
**Last Updated:** 2026-03-22
|
|
5
5
|
**Owners:** macOS client + assistant runtime
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Current State
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The daemon no longer uses the keychain broker for credential operations. Credential storage is routed through the Credential Execution Service (CES):
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
1. **CES RPC** (primary) -- stdio RPC to the CES process. Default path for all local modes (desktop app, dev, CLI).
|
|
12
|
+
2. **CES HTTP** -- containerized/Docker/managed mode via `CES_CREDENTIAL_URL`.
|
|
13
|
+
3. **Encrypted file store** (fallback) -- used when CES is unavailable.
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
See [`assistant/docs/credential-execution-service.md`](../credential-execution-service.md) for the current credential architecture.
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
### What remains
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
The keychain broker is not fully deleted. These components still exist:
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
| Component | Location | Why it exists |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| Keychain broker client | `assistant/src/security/keychain-broker-client.ts` | Used only by workspace migrations 015 and 016 |
|
|
24
|
+
| Migration 015 | `assistant/src/workspace/migrations/015-migrate-credentials-to-keychain.ts` | Historical migration that copied encrypted store credentials into keychain |
|
|
25
|
+
| Migration 016 | `assistant/src/workspace/migrations/016-migrate-credentials-from-keychain.ts` | Reverse migration that copies keychain credentials back to the encrypted store for CES unification |
|
|
26
|
+
| Swift broker server | `clients/macos/vellum-assistant/Security/KeychainBrokerServer.swift` | UDS server in the macOS app; still compiled for release builds (`#if !DEBUG`) |
|
|
27
|
+
| Swift broker service | `clients/macos/vellum-assistant/Security/KeychainBrokerService.swift` | `SecItem*` wrapper used by the broker server |
|
|
28
|
+
| Gateway credential reader | `gateway/src/credential-reader.ts` | Still tries the keychain broker as a secondary fallback after CES, before the encrypted store |
|
|
22
29
|
|
|
23
|
-
|
|
30
|
+
The broker client and Swift server remain because migrations 015/016 must be able to read/write the keychain for users who previously stored credentials there. These migrations are append-only and cannot be removed. The gateway's broker fallback provides a read path for credentials that may still be in the keychain during the migration window.
|
|
24
31
|
|
|
25
|
-
###
|
|
32
|
+
### What was removed
|
|
26
33
|
|
|
27
|
-
|
|
34
|
+
- **`KeychainBackend`** class and `createKeychainBackend()` factory -- the daemon's `CredentialBackend` implementation that wrapped the broker client. Removed from `credential-backend.ts`.
|
|
35
|
+
- **`resolveBackendAsync()` keychain resolution path** -- the daemon no longer considers `VELLUM_DESKTOP_APP` or `VELLUM_DEV` for backend selection. Backend resolution in `secure-keys.ts` now follows the CES RPC > CES HTTP > encrypted store priority.
|
|
36
|
+
- **Dual-writing and broker-unavailable commit behavior** -- the daemon previously committed to the keychain backend even when the broker socket was unreachable, causing operations to fail visibly. This behavior is gone; CES RPC is the primary backend with encrypted store as a graceful fallback.
|
|
28
37
|
|
|
29
|
-
|
|
38
|
+
## Original Design (Historical)
|
|
30
39
|
|
|
31
|
-
|
|
32
|
-
| ---------------- | -------------------------------------------- | ----------------------------------------------------------------------- |
|
|
33
|
-
| Keychain backend | macOS Keychain via the broker UDS connection | Production app context (`VELLUM_DEV` is NOT `"1"`) and broker available |
|
|
34
|
-
| Encrypted store | `~/.vellum/protected/keys.enc` (AES-256-GCM) | `VELLUM_DEV=1`, broker unavailable, CLI-only, headless, CI |
|
|
40
|
+
The sections below document the original broker architecture for historical reference. They describe behavior that is no longer active in the daemon's credential resolution path.
|
|
35
41
|
|
|
36
|
-
|
|
42
|
+
### Original problem
|
|
37
43
|
|
|
38
|
-
|
|
44
|
+
Direct keychain access from the daemon process caused repeated macOS authorization prompts, especially during development with ad-hoc signed builds where every rebuild changed the signing identity.
|
|
39
45
|
|
|
40
|
-
|
|
41
|
-
graph LR
|
|
42
|
-
subgraph "macOS App Process"
|
|
43
|
-
SERVER["KeychainBrokerServer<br/>(NWListener on UDS)"]
|
|
44
|
-
SERVICE["KeychainBrokerService<br/>(SecItem* wrapper)"]
|
|
45
|
-
SERVER --> SERVICE
|
|
46
|
-
SERVICE --> KC["macOS Keychain"]
|
|
47
|
-
end
|
|
46
|
+
### Original topology
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
RESOLVE{"resolveBackend()"}
|
|
51
|
-
KB["Keychain Backend"]
|
|
52
|
-
EB["Encrypted Store Backend"]
|
|
53
|
-
RESOLVE -->|"VELLUM_DEV!=1<br/>+ broker available"| KB
|
|
54
|
-
RESOLVE -->|"VELLUM_DEV=1<br/>OR broker unavailable"| EB
|
|
55
|
-
end
|
|
48
|
+
The macOS app embedded a `KeychainBrokerServer` (NWListener on a Unix domain socket) that accepted JSON requests from the daemon and gateway, validated an auth token, and dispatched to `KeychainBrokerService` (a thin `SecItem*` wrapper). The daemon resolved either the keychain backend or encrypted store at startup based on `VELLUM_DESKTOP_APP` and `VELLUM_DEV` environment variables.
|
|
56
49
|
|
|
57
|
-
|
|
58
|
-
RUNTIME["Assistant Runtime (Bun)"] --> RESOLVE
|
|
59
|
-
GATEWAY["Gateway (Bun)"] -->|"read-only"| RESOLVE
|
|
50
|
+
### Message contract
|
|
60
51
|
|
|
61
|
-
|
|
62
|
-
```
|
|
52
|
+
Transport: Unix domain socket at `~/.vellum/keychain-broker.sock`, newline-delimited JSON.
|
|
63
53
|
|
|
64
|
-
|
|
54
|
+
| Method | Params | Result |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `broker.ping` | none | `{ pong: true }` |
|
|
57
|
+
| `key.get` | `{ account }` | `{ found, value? }` |
|
|
58
|
+
| `key.set` | `{ account, value }` | `{ stored: true }` |
|
|
59
|
+
| `key.delete` | `{ account }` | `{ deleted: true }` |
|
|
60
|
+
| `key.list` | none | `{ accounts: string[] }` |
|
|
65
61
|
|
|
66
|
-
|
|
67
|
-
- **No auth bootstrap problem.** The app writes the broker auth token to disk before launching the daemon, so the daemon always has a valid token at startup.
|
|
68
|
-
- **No keychain prompts on signed builds.** Items are stored with `kSecAttrAccessibleAfterFirstUnlock` under the `vellum-assistant` service name. A stable code-signing identity means macOS grants access without prompting after the first unlock.
|
|
69
|
-
- **No keychain interaction on debug builds.** The entire `KeychainBrokerServer` is compiled out with `#if !DEBUG`, so development builds use the encrypted file store exclusively.
|
|
70
|
-
- **Single-writer to resolved backend.** Each process resolves exactly one primary backend at startup. Writes go only to that backend. There is no dual-writing.
|
|
71
|
-
- **Encrypted file store as permanent fallback.** CLI-only, headless, and development environments always have the encrypted store (`~/.vellum/protected/keys.enc`) available.
|
|
62
|
+
This protocol is still used by migrations 015/016 via the broker client.
|
|
72
63
|
|
|
73
|
-
|
|
64
|
+
### Security model
|
|
74
65
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
| `clients/macos/vellum-assistant/Security/KeychainBrokerServer.swift` | UDS server using `NWListener`. Accepts newline-delimited JSON requests, validates auth token, dispatches to `KeychainBrokerService`. Compiled only for `!DEBUG` builds. |
|
|
80
|
-
| `clients/macos/vellum-assistant/Security/KeychainBrokerService.swift` | Thin `SecItem*` wrapper scoped to the `vellum-assistant` service. Provides `get`, `set`, `delete`, `list`. Uses `kSecAttrAccessibleAfterFirstUnlock`. Compiled only for `macOS`. |
|
|
81
|
-
|
|
82
|
-
### TypeScript side (runtime + gateway)
|
|
83
|
-
|
|
84
|
-
| File | Role |
|
|
85
|
-
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
86
|
-
| `assistant/src/security/credential-backend.ts` | `CredentialBackend` interface definition (`get`, `set`, `delete`, `list`) plus both adapter implementations: `KeychainBackend` (backed by the broker UDS client) and `EncryptedStoreBackend` (backed by `encrypted-store.ts` / `~/.vellum/protected/keys.enc`). Also exports factory functions `createKeychainBackend()` and `createEncryptedStoreBackend()`. |
|
|
87
|
-
| `assistant/src/security/keychain-broker-client.ts` | Async UDS client for the runtime. Persistent socket connection, request/response correlation, auth token caching with auto-refresh on `UNAUTHORIZED`. Falls back gracefully (returns safe defaults, never throws). |
|
|
88
|
-
| `assistant/src/security/secure-keys.ts` | Unified API surface. Resolves a single primary `CredentialBackend` at startup based on environment and broker availability. All writes go to the resolved backend only (single-writer). Reads check the primary backend first, with legacy fallback to the encrypted store for migration. Deletes clean up both stores to prevent stale keys. |
|
|
89
|
-
| `gateway/src/credential-reader.ts` | Read-only credential reader. Tries broker via native async UDS connection (`node:net`), falls back to encrypted store. All public credential read functions are async. |
|
|
90
|
-
|
|
91
|
-
## Message Contract
|
|
92
|
-
|
|
93
|
-
### Transport
|
|
94
|
-
|
|
95
|
-
- Unix domain socket: `~/.vellum/keychain-broker.sock`
|
|
96
|
-
- Socket path is derived from the data directory (e.g., `join(getRootDir(), "keychain-broker.sock")`)
|
|
97
|
-
- Newline-delimited JSON (`\n` as message boundary)
|
|
98
|
-
|
|
99
|
-
### Request envelope
|
|
100
|
-
|
|
101
|
-
```json
|
|
102
|
-
{
|
|
103
|
-
"v": 1,
|
|
104
|
-
"id": "uuid",
|
|
105
|
-
"token": "hex-auth-token",
|
|
106
|
-
"method": "key.get",
|
|
107
|
-
"params": { "account": "anthropic" }
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
The `v` field is a protocol version number (currently `1`). The server rejects requests with unsupported versions.
|
|
112
|
-
|
|
113
|
-
### Response envelope
|
|
114
|
-
|
|
115
|
-
Success:
|
|
116
|
-
|
|
117
|
-
```json
|
|
118
|
-
{
|
|
119
|
-
"id": "uuid",
|
|
120
|
-
"ok": true,
|
|
121
|
-
"result": { "found": true, "value": "sk-..." }
|
|
122
|
-
}
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Error:
|
|
126
|
-
|
|
127
|
-
```json
|
|
128
|
-
{
|
|
129
|
-
"id": "uuid",
|
|
130
|
-
"ok": false,
|
|
131
|
-
"error": { "code": "UNAUTHORIZED", "message": "Invalid auth token" }
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Methods
|
|
136
|
-
|
|
137
|
-
| Method | Params | Result |
|
|
138
|
-
| ------------- | -------------------- | ------------------------ |
|
|
139
|
-
| `broker.ping` | none | `{ pong: true }` |
|
|
140
|
-
| `key.get` | `{ account }` | `{ found, value? }` |
|
|
141
|
-
| `key.set` | `{ account, value }` | `{ stored: true }` |
|
|
142
|
-
| `key.delete` | `{ account }` | `{ deleted: true }` |
|
|
143
|
-
| `key.list` | none | `{ accounts: string[] }` |
|
|
144
|
-
|
|
145
|
-
### Error codes
|
|
146
|
-
|
|
147
|
-
- `UNAUTHORIZED` — invalid or missing auth token
|
|
148
|
-
- `INVALID_REQUEST` — malformed request, missing params, or unsupported protocol version
|
|
149
|
-
- `KEYCHAIN_ERROR` — SecItem operation failed
|
|
150
|
-
|
|
151
|
-
## Security Model
|
|
152
|
-
|
|
153
|
-
### Authentication
|
|
154
|
-
|
|
155
|
-
1. On app launch, the broker generates 32 random bytes via `SecRandomCopyBytes` and hex-encodes them as the auth token.
|
|
156
|
-
2. The token is written to `~/.vellum/protected/keychain-broker.token` with `0600` permissions. The parent directory is `0700`.
|
|
157
|
-
3. Every request must include the token. Requests with missing or invalid tokens are rejected before method dispatch.
|
|
158
|
-
4. If the app restarts (new token), the TS client detects `UNAUTHORIZED`, re-reads the token from disk, and retries once.
|
|
159
|
-
|
|
160
|
-
### Process boundary
|
|
161
|
-
|
|
162
|
-
- The UDS itself restricts access to local processes.
|
|
163
|
-
- The token file's `0600` permissions restrict readers to the same user.
|
|
164
|
-
- Together: only same-user local processes that can read the token file can authenticate.
|
|
165
|
-
|
|
166
|
-
### Keychain access control
|
|
167
|
-
|
|
168
|
-
- All items use `kSecAttrAccessibleAfterFirstUnlock` — secrets survive screen lock without re-prompting.
|
|
169
|
-
- All items are scoped to the `vellum-assistant` service name via `kSecAttrService`.
|
|
170
|
-
- On signed release builds, the stable code-signing identity means macOS trusts the app to access its own keychain items without prompting.
|
|
171
|
-
|
|
172
|
-
### Threat model
|
|
173
|
-
|
|
174
|
-
| Threat | Mitigation |
|
|
175
|
-
| ------------------------------------------- | ------------------------------------------------------------------------------------------ |
|
|
176
|
-
| Other-user process reads secrets | UDS + token file `0600` restrict to same user |
|
|
177
|
-
| Malicious local process impersonates broker | Client reads token from a known file path; attacker would need same-user file write access |
|
|
178
|
-
| Stale socket from unclean exit | Server calls `unlink()` on the socket path before binding |
|
|
179
|
-
| App restart invalidates cached token | Client detects `UNAUTHORIZED`, re-reads token, retries once |
|
|
180
|
-
|
|
181
|
-
### Future: XPC transport
|
|
182
|
-
|
|
183
|
-
XPC provides stronger caller identity guarantees via audit tokens and code requirement checks. This would replace the file-based auth token with kernel-enforced caller verification, preventing same-user impersonation. No timeline — the UDS + token model is sufficient for the current threat profile.
|
|
184
|
-
|
|
185
|
-
## Developer Experience
|
|
186
|
-
|
|
187
|
-
- **Debug builds:** The `#if !DEBUG` guard compiles out the entire `KeychainBrokerServer`. The broker socket is not created, so clients see the broker as unavailable and use the encrypted store. Developers never encounter keychain prompts during the edit-build-run cycle.
|
|
188
|
-
- **Release builds:** The broker starts automatically with the app. The daemon discovers the broker via the derived socket path (`join(getRootDir(), "keychain-broker.sock")`) and token file. No configuration needed.
|
|
189
|
-
- **CLI-only / headless:** No macOS app means no broker socket. All storage uses the encrypted file store. This is the expected path for CI, servers, and non-macOS platforms.
|
|
190
|
-
|
|
191
|
-
## Store-Routing Policy
|
|
192
|
-
|
|
193
|
-
### Backend resolution
|
|
194
|
-
|
|
195
|
-
At process startup, `secure-keys.ts` resolves a single primary `CredentialBackend` for the lifetime of the process:
|
|
196
|
-
|
|
197
|
-
| Condition | Resolved backend |
|
|
198
|
-
| ----------------------------------------------------- | ---------------- |
|
|
199
|
-
| `VELLUM_DEV` is NOT `"1"` **and** broker is available | Keychain backend |
|
|
200
|
-
| `VELLUM_DEV=1` **or** broker is unavailable | Encrypted store |
|
|
201
|
-
|
|
202
|
-
Once resolved, the backend does not change during the process lifetime. There is no runtime switching between backends.
|
|
203
|
-
|
|
204
|
-
### Read strategy
|
|
205
|
-
|
|
206
|
-
Reads go to the **primary backend first**. If the primary backend is the keychain backend and the key is not found, a legacy fallback read is attempted against the encrypted store. This fallback handles the migration period where keys written before the single-writer policy may still exist only in the encrypted store. When the primary backend is the encrypted store, there is no fallback -- the encrypted store is the sole source of truth.
|
|
207
|
-
|
|
208
|
-
### Write strategy
|
|
209
|
-
|
|
210
|
-
Writes go **only to the resolved primary backend**. There is no dual-writing. This eliminates the consistency problems that dual-writing introduced (partial failures leaving stores out of sync, unclear source of truth).
|
|
211
|
-
|
|
212
|
-
- Keychain backend resolved: writes go to the keychain via broker only.
|
|
213
|
-
- Encrypted store resolved: writes go to the encrypted file store only.
|
|
214
|
-
|
|
215
|
-
### Delete strategy
|
|
216
|
-
|
|
217
|
-
Deletes **always clean up both stores** regardless of the resolved backend. This ensures that stale keys do not linger in the non-primary store, which could cause unexpected reads through the legacy fallback path.
|
|
218
|
-
|
|
219
|
-
### `VELLUM_DEV` environment variable
|
|
220
|
-
|
|
221
|
-
Setting `VELLUM_DEV=1` forces the encrypted store as the sole backend, bypassing the keychain broker entirely even when the broker socket is available. This serves two purposes:
|
|
222
|
-
|
|
223
|
-
1. **Development ergonomics.** Developers running the daemon outside the macOS app context (e.g., `bun run` directly) avoid broker connectivity issues and keychain prompt noise.
|
|
224
|
-
2. **Deterministic testing.** Tests and CI environments get predictable encrypted-store-only behavior without depending on macOS Keychain infrastructure.
|
|
225
|
-
|
|
226
|
-
When `VELLUM_DEV` is not set or is set to any value other than `"1"`, backend resolution proceeds normally (broker availability check).
|
|
227
|
-
|
|
228
|
-
## Callsite Policy
|
|
229
|
-
|
|
230
|
-
### Async-only policy
|
|
231
|
-
|
|
232
|
-
**All credential access uses the async functions** (`getSecureKeyAsync`, `setSecureKeyAsync`, `deleteSecureKeyAsync`). These route through the resolved `CredentialBackend`, with legacy fallback reads to the encrypted store when the keychain backend is primary. The migration from sync to async is complete: the sync variants (`getSecureKey`, `setSecureKey`, `deleteSecureKey`) have been deleted and no longer exist in the codebase.
|
|
233
|
-
|
|
234
|
-
### Runtime request handlers (secret-routes, etc.)
|
|
235
|
-
|
|
236
|
-
All runtime HTTP handlers that write or delete secrets use the async APIs (`setSecureKeyAsync`, `deleteSecureKeyAsync`). These are the primary entry points for macOS app flows and route through the resolved backend.
|
|
237
|
-
|
|
238
|
-
### Gateway (credential-reader)
|
|
239
|
-
|
|
240
|
-
The gateway reads credentials via async `readCredential()` which tries the broker first (native async UDS), falling back to the encrypted store. The gateway never writes credentials -- that responsibility belongs to the assistant runtime.
|
|
241
|
-
|
|
242
|
-
### Sync function removal
|
|
243
|
-
|
|
244
|
-
The sync secure-key functions (`getSecureKey`, `setSecureKey`, `deleteSecureKey`) have been deleted. All code uses the async variants (`getSecureKeyAsync`, `setSecureKeyAsync`, `deleteSecureKeyAsync`).
|
|
245
|
-
|
|
246
|
-
## Migration
|
|
247
|
-
|
|
248
|
-
Existing encrypted store keys remain accessible through the legacy read fallback. When the keychain backend is the resolved primary, reads that miss in the keychain fall back to the encrypted store, so keys written before the single-writer policy are still reachable without a one-time migration step.
|
|
249
|
-
|
|
250
|
-
Over time, as keys are re-written through normal credential update flows, they will be written only to the resolved primary backend. The legacy fallback read path will eventually become a no-op as all keys migrate naturally to the keychain.
|
|
251
|
-
|
|
252
|
-
Deletes always clean up both stores, so stale keys in the non-primary store are removed as part of normal credential lifecycle operations.
|
|
253
|
-
|
|
254
|
-
The old `keychain.ts` module (which called `/usr/bin/security` CLI directly) has been deleted. The old keychain-to-encrypted migration code has been removed. All keychain access now flows exclusively through the broker.
|
|
255
|
-
|
|
256
|
-
## Extensibility
|
|
257
|
-
|
|
258
|
-
The `CredentialBackend` interface is the extension point for adding new storage backends. To add a new backend (e.g., Linux secret service via libsecret/D-Bus, 1Password CLI, cloud KMS):
|
|
259
|
-
|
|
260
|
-
1. Implement the `CredentialBackend` interface in a new module.
|
|
261
|
-
2. Wire the new backend into the resolution logic in `secure-keys.ts`.
|
|
262
|
-
3. The rest of the codebase is unaffected -- all callers go through the existing async API surface.
|
|
263
|
-
|
|
264
|
-
No changes to callsites, the gateway, or the broker protocol are needed when adding a backend.
|
|
66
|
+
- Auth token: 32 random bytes via `SecRandomCopyBytes`, written to `~/.vellum/protected/keychain-broker.token` (0600).
|
|
67
|
+
- UDS restricts to local processes; token file restricts to same user.
|
|
68
|
+
- Keychain items use `kSecAttrAccessibleAfterFirstUnlock` under the `vellum-assistant` service name.
|
|
69
|
+
- Debug builds compile out the entire broker server (`#if !DEBUG`).
|
|
@@ -249,22 +249,6 @@ sequenceDiagram
|
|
|
249
249
|
end
|
|
250
250
|
```
|
|
251
251
|
|
|
252
|
-
### Secret Ingress Blocking
|
|
253
|
-
|
|
254
|
-
```mermaid
|
|
255
|
-
graph TB
|
|
256
|
-
MSG["Inbound user_message / task_submit"] --> CHECK{"secretDetection.enabled<br/>+ blockIngress == true?"}
|
|
257
|
-
CHECK -->|no| PASS["Pass through to session"]
|
|
258
|
-
CHECK -->|yes| SCAN["scanText(content)<br/>regex + entropy detection"]
|
|
259
|
-
SCAN --> MATCH{"Matches found?"}
|
|
260
|
-
MATCH -->|no| PASS
|
|
261
|
-
MATCH -->|yes| BLOCK["Block message"]
|
|
262
|
-
BLOCK --> NOTIFY["Send error to client:<br/>'Message contains sensitive info'"]
|
|
263
|
-
BLOCK --> LOG["Log warning with<br/>detectedTypes + matchCount<br/>(never the secret itself)"]
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
The secret scanner includes pattern-based detection for Telegram bot tokens (format: `<8-10 digit bot_id>:<35-char secret>`), API keys from major providers, Slack tokens, and other common secret formats. This prevents users from accidentally pasting a Telegram bot token in chat — the token must be entered through the secure credential prompt flow or the Settings UI instead.
|
|
267
|
-
|
|
268
252
|
### Brokered Credential Use
|
|
269
253
|
|
|
270
254
|
```mermaid
|
|
@@ -305,7 +289,6 @@ The `allowOneTimeSend` config gate (default: `false`) enables a secondary "Send
|
|
|
305
289
|
| `assistant/src/tools/credentials/policy-validate.ts` | Policy input validation (allowedTools, allowedDomains) |
|
|
306
290
|
| `assistant/src/permissions/secret-prompter.ts` | HTTP secret_request/secret_response flow |
|
|
307
291
|
| `assistant/src/security/secret-scanner.ts` | Regex + entropy-based secret detection |
|
|
308
|
-
| `assistant/src/security/secret-ingress.ts` | Inbound message secret blocking |
|
|
309
292
|
| `clients/macos/.../SecretPromptManager.swift` | Floating panel UI for secure credential entry |
|
|
310
293
|
|
|
311
294
|
---
|
|
@@ -251,11 +251,11 @@ To dark-launch CES in managed deployments without user impact:
|
|
|
251
251
|
|
|
252
252
|
1. **Deploy the CES container image** via the `credential_executor_image` field in `POST /v1/internal/assistant-image-releases/`. The warm-pool manager picks it up and includes it in pod templates. The CES container starts, binds its bootstrap socket and health port (8090), but does nothing until an assistant connects.
|
|
253
253
|
|
|
254
|
-
2. **Verify sidecar health** using kubelet probes: `/healthz` (liveness) and `/readyz` (readiness, always returns 200; includes `rpcConnected` field for observability).
|
|
254
|
+
2. **Verify sidecar health** using kubelet probes: `/healthz` (liveness, returns `{"status": "ok"}`) and `/readyz` (readiness, always returns 200; includes `rpcConnected` field for observability).
|
|
255
255
|
|
|
256
256
|
3. **Enable `ces-tools`** first on a test cohort. The assistant spawns a local CES child process and registers tools. Verify tool registration, grant creation, and audit logging work end-to-end without affecting existing workflows.
|
|
257
257
|
|
|
258
|
-
4. **Enable `ces-managed-sidecar`** on the same cohort. The assistant switches from child-process transport to the bootstrap Unix socket. CES `/readyz` always returns 200
|
|
258
|
+
4. **Enable `ces-managed-sidecar`** on the same cohort. The assistant switches from child-process transport to the bootstrap Unix socket. CES `/readyz` always returns 200 with `{"status": "ok", "rpcConnected": <boolean>}`; check the `rpcConnected` field to verify the assistant has connected.
|
|
259
259
|
|
|
260
260
|
5. **Progressive rollout**: Widen the cohort by enabling flags on more assistants. Monitor for grant failures, materializer errors, and egress proxy issues.
|
|
261
261
|
|
|
@@ -25,6 +25,12 @@
|
|
|
25
25
|
*
|
|
26
26
|
* **Lifecycle**
|
|
27
27
|
* - `update_managed_credential` — Push an updated API key to CES after hatch
|
|
28
|
+
*
|
|
29
|
+
* **Credential CRUD**
|
|
30
|
+
* - `get_credential` — Retrieve a credential by account name
|
|
31
|
+
* - `set_credential` — Store or update a credential
|
|
32
|
+
* - `delete_credential` — Delete a credential by account name
|
|
33
|
+
* - `list_credentials` — List all credential account names
|
|
28
34
|
*/
|
|
29
35
|
|
|
30
36
|
import { z } from "zod/v4";
|
|
@@ -51,6 +57,14 @@ export const CesRpcMethod = {
|
|
|
51
57
|
ListAuditRecords: "list_audit_records",
|
|
52
58
|
/** Push an updated assistant credential to CES after post-hatch provisioning. */
|
|
53
59
|
UpdateManagedCredential: "update_managed_credential",
|
|
60
|
+
/** Retrieve a single credential by account name. */
|
|
61
|
+
GetCredential: "get_credential",
|
|
62
|
+
/** Store or update a credential by account name. */
|
|
63
|
+
SetCredential: "set_credential",
|
|
64
|
+
/** Delete a credential by account name. */
|
|
65
|
+
DeleteCredential: "delete_credential",
|
|
66
|
+
/** List all credential account names. */
|
|
67
|
+
ListCredentials: "list_credentials",
|
|
54
68
|
} as const;
|
|
55
69
|
|
|
56
70
|
export type CesRpcMethod =
|
|
@@ -421,6 +435,79 @@ export type UpdateManagedCredentialResponse = z.infer<
|
|
|
421
435
|
typeof UpdateManagedCredentialResponseSchema
|
|
422
436
|
>;
|
|
423
437
|
|
|
438
|
+
// ---------------------------------------------------------------------------
|
|
439
|
+
// get_credential
|
|
440
|
+
// ---------------------------------------------------------------------------
|
|
441
|
+
|
|
442
|
+
export const GetCredentialSchema = z.object({
|
|
443
|
+
/** The account name to look up. */
|
|
444
|
+
account: z.string(),
|
|
445
|
+
});
|
|
446
|
+
export type GetCredential = z.infer<typeof GetCredentialSchema>;
|
|
447
|
+
|
|
448
|
+
export const GetCredentialResponseSchema = z.object({
|
|
449
|
+
/** Whether the credential was found. */
|
|
450
|
+
found: z.boolean(),
|
|
451
|
+
/** The credential value (present only when found). */
|
|
452
|
+
value: z.string().optional(),
|
|
453
|
+
});
|
|
454
|
+
export type GetCredentialResponse = z.infer<
|
|
455
|
+
typeof GetCredentialResponseSchema
|
|
456
|
+
>;
|
|
457
|
+
|
|
458
|
+
// ---------------------------------------------------------------------------
|
|
459
|
+
// set_credential
|
|
460
|
+
// ---------------------------------------------------------------------------
|
|
461
|
+
|
|
462
|
+
export const SetCredentialSchema = z.object({
|
|
463
|
+
/** The account name to store the credential under. */
|
|
464
|
+
account: z.string(),
|
|
465
|
+
/** The credential value to store. */
|
|
466
|
+
value: z.string(),
|
|
467
|
+
});
|
|
468
|
+
export type SetCredential = z.infer<typeof SetCredentialSchema>;
|
|
469
|
+
|
|
470
|
+
export const SetCredentialResponseSchema = z.object({
|
|
471
|
+
/** Whether the credential was successfully stored. */
|
|
472
|
+
ok: z.boolean(),
|
|
473
|
+
});
|
|
474
|
+
export type SetCredentialResponse = z.infer<
|
|
475
|
+
typeof SetCredentialResponseSchema
|
|
476
|
+
>;
|
|
477
|
+
|
|
478
|
+
// ---------------------------------------------------------------------------
|
|
479
|
+
// delete_credential
|
|
480
|
+
// ---------------------------------------------------------------------------
|
|
481
|
+
|
|
482
|
+
export const DeleteCredentialSchema = z.object({
|
|
483
|
+
/** The account name to delete. */
|
|
484
|
+
account: z.string(),
|
|
485
|
+
});
|
|
486
|
+
export type DeleteCredential = z.infer<typeof DeleteCredentialSchema>;
|
|
487
|
+
|
|
488
|
+
export const DeleteCredentialResponseSchema = z.object({
|
|
489
|
+
/** The result of the delete operation. */
|
|
490
|
+
result: z.enum(["deleted", "not-found", "error"]),
|
|
491
|
+
});
|
|
492
|
+
export type DeleteCredentialResponse = z.infer<
|
|
493
|
+
typeof DeleteCredentialResponseSchema
|
|
494
|
+
>;
|
|
495
|
+
|
|
496
|
+
// ---------------------------------------------------------------------------
|
|
497
|
+
// list_credentials
|
|
498
|
+
// ---------------------------------------------------------------------------
|
|
499
|
+
|
|
500
|
+
export const ListCredentialsSchema = z.object({});
|
|
501
|
+
export type ListCredentials = z.infer<typeof ListCredentialsSchema>;
|
|
502
|
+
|
|
503
|
+
export const ListCredentialsResponseSchema = z.object({
|
|
504
|
+
/** The account names of all stored credentials. */
|
|
505
|
+
accounts: z.array(z.string()),
|
|
506
|
+
});
|
|
507
|
+
export type ListCredentialsResponse = z.infer<
|
|
508
|
+
typeof ListCredentialsResponseSchema
|
|
509
|
+
>;
|
|
510
|
+
|
|
424
511
|
// ---------------------------------------------------------------------------
|
|
425
512
|
// Full RPC contract type map
|
|
426
513
|
// ---------------------------------------------------------------------------
|
|
@@ -466,6 +553,22 @@ export interface CesRpcContract {
|
|
|
466
553
|
request: UpdateManagedCredential;
|
|
467
554
|
response: UpdateManagedCredentialResponse;
|
|
468
555
|
};
|
|
556
|
+
[CesRpcMethod.GetCredential]: {
|
|
557
|
+
request: GetCredential;
|
|
558
|
+
response: GetCredentialResponse;
|
|
559
|
+
};
|
|
560
|
+
[CesRpcMethod.SetCredential]: {
|
|
561
|
+
request: SetCredential;
|
|
562
|
+
response: SetCredentialResponse;
|
|
563
|
+
};
|
|
564
|
+
[CesRpcMethod.DeleteCredential]: {
|
|
565
|
+
request: DeleteCredential;
|
|
566
|
+
response: DeleteCredentialResponse;
|
|
567
|
+
};
|
|
568
|
+
[CesRpcMethod.ListCredentials]: {
|
|
569
|
+
request: ListCredentials;
|
|
570
|
+
response: ListCredentialsResponse;
|
|
571
|
+
};
|
|
469
572
|
}
|
|
470
573
|
|
|
471
574
|
/**
|
|
@@ -508,4 +611,20 @@ export const CesRpcSchemas = {
|
|
|
508
611
|
request: UpdateManagedCredentialSchema,
|
|
509
612
|
response: UpdateManagedCredentialResponseSchema,
|
|
510
613
|
},
|
|
614
|
+
[CesRpcMethod.GetCredential]: {
|
|
615
|
+
request: GetCredentialSchema,
|
|
616
|
+
response: GetCredentialResponseSchema,
|
|
617
|
+
},
|
|
618
|
+
[CesRpcMethod.SetCredential]: {
|
|
619
|
+
request: SetCredentialSchema,
|
|
620
|
+
response: SetCredentialResponseSchema,
|
|
621
|
+
},
|
|
622
|
+
[CesRpcMethod.DeleteCredential]: {
|
|
623
|
+
request: DeleteCredentialSchema,
|
|
624
|
+
response: DeleteCredentialResponseSchema,
|
|
625
|
+
},
|
|
626
|
+
[CesRpcMethod.ListCredentials]: {
|
|
627
|
+
request: ListCredentialsSchema,
|
|
628
|
+
response: ListCredentialsResponseSchema,
|
|
629
|
+
},
|
|
511
630
|
} as const;
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vellumai/assistant",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
|
+
"license": "MIT",
|
|
4
5
|
"type": "module",
|
|
5
6
|
"exports": {
|
|
6
7
|
".": "./src/index.ts"
|
|
@@ -28,7 +29,6 @@
|
|
|
28
29
|
},
|
|
29
30
|
"dependencies": {
|
|
30
31
|
"@agentclientprotocol/sdk": "^0.16.1",
|
|
31
|
-
"@anthropic-ai/claude-agent-sdk": "^0.2.42",
|
|
32
32
|
"@anthropic-ai/sdk": "^0.78.0",
|
|
33
33
|
"@google/genai": "^1.40.0",
|
|
34
34
|
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
@@ -70,7 +70,6 @@
|
|
|
70
70
|
"@vellumai/egress-proxy"
|
|
71
71
|
],
|
|
72
72
|
"devDependencies": {
|
|
73
|
-
"@pydantic/logfire-node": "^0.13.0",
|
|
74
73
|
"@types/archiver": "^7.0.0",
|
|
75
74
|
"@types/bun": "^1.2.4",
|
|
76
75
|
"@types/node": "^25.2.2",
|