Build a Vault Connector
Implement the vault connector interface to become a HUMΛN-compatible vault provider
The Vault Connector Contract
Implement six actions, return ciphertext, never decrypt. That's it. Your connector receives opaque bytes and returns opaque bytes. The client holds the keys; you hold the ciphertext.
The Invariant
Your connector is a ciphertext carrier. You will receive opaque bytes and you will return opaque bytes. You will never see plaintext. This is the security guarantee, not a limitation. If your connector ever decrypts data, it violates the contract and cannot be a HUMΛN vault provider.
Critical: The server must never have a plaintext decoder. The VaultConnectorTestHarness includes a ciphertext opacity assertion — it verifies that your connector returns only ciphertext and IV, never decrypted content.
Implementing the Manifest
Required actions: vault:store, vault:retrieve, vault:delete, vault:list, vault:migrate-in, vault:export. Optional: vault:share.
{ "id": "my-vault-connector", "name": "My Vault", "description": "Self-hosted vault with ciphertext-only storage", "provider": "acme", "version": "1.0.0", "capabilities": ["vault/read", "vault/write", "vault/admin", "vault/migrate"], "actions": [ { "name": "vault:store", "paramsSchema": { ... } }, { "name": "vault:retrieve", "paramsSchema": { ... } }, { "name": "vault:delete", "paramsSchema": { ... } }, { "name": "vault:list", "paramsSchema": { ... } }, { "name": "vault:export", "paramsSchema": { ... } }, { "name": "vault:migrate-in", "paramsSchema": { ... } } ]}Wiring Up the API
The API routes delegate to the connector via invoke(). Extend BaseConnector from @human/connector-sdk and implement the dispatch pattern. The vault API at /v1/vault/:entityDid/:namespace/:collection calls your connector when the org's vault_endpoint points to your deployment.
The Migration Protocol
vault:export produces documents with their original doc_id preserved. vault:migrate-in accepts documents with explicit IDs. Why: vault:// URI stability. If a migration changes doc IDs, it breaks every pointer in every Passport. The URI vault://did:human:alice/health/mri/scan-2026.dcm must resolve to the same document after migration.
// vault:export — return documents with doc_id preserved{ documents: [{ doc_id: "scan-2026.dcm", ciphertext: "...", iv: "...", metadata: {} }] }
// vault:migrate-in — accept documents with explicit doc_idPOST body: { documents: [{ doc_id: "scan-2026.dcm", ciphertext: "...", iv: "..." }] }Testing Your Connector
Use the VaultConnectorTestHarness from @human/connector-vault/test-harness. Smoke tests: store → retrieve round-trip, doc ID stability across migrate (when implemented), ciphertext opacity (assert server never has a plaintext decoder).
import { VaultConnectorTestHarness } from '@human/connector-vault/test-harness';
const harness = new VaultConnectorTestHarness({ entityDid: 'did:human:test', invoke: async (action, params) => myConnector.invoke(action, params),});
const result = await harness.runAll();if (!result.passed) { throw new Error(result.error ?? 'Harness failed');}Registering in the Marketplace
Submit your connector with ConnectorRegistration, distribution: 'marketplace', and capabilities: ['vault/read', 'vault/write', 'vault/admin', 'vault/migrate']. Orgs can then select your vault as their vault_endpoint during setup.
Next Steps
Understand what your connector protects before you build it. Read Your Data, Your Key to see the full sovereignty model.
Your Data, Your Key