Integration guide
This guide shows the common patterns: retrieving a secret at startup and tokenizing
sensitive content. All requests use the base URL http://<host>:4000/api/v1 and the
header Authorization: Token <your-api-token>.
Initial setup (once, by a human admin)
Section titled “Initial setup (once, by a human admin)”- Run first-time setup to create your tenant, admin, and default vault.
- Issue a scoped API token for your service.
- Store the secrets your app needs, and note their IDs.
Node.js
Section titled “Node.js”A small client wrapping the endpoints your app uses:
class ContextDataVault { constructor( private baseUrl: string, private token: string, ) {}
private async request(path: string, init: RequestInit = {}) { const res = await fetch(`${this.baseUrl}/api/v1${path}`, { ...init, headers: { Authorization: `Token ${this.token}`, 'Content-Type': 'application/json', ...init.headers, }, }); if (!res.ok) throw new Error(`ContextDataVault ${res.status}: ${await res.text()}`); return res.json(); }
getSecretValue(id: string) { return this.request(`/secrets/${id}/value`); }
tokenize(vaultId: string, content: string) { return this.request('/tokens', { method: 'POST', body: JSON.stringify({ vaultId, content }), }); }
resolve(token: string) { return this.request(`/tokens/${token}/resolve`); }}Retrieve a credential at startup (hard‑fail — the app should not run without it):
const vault = new ContextDataVault(process.env.CDV_URL!, process.env.CDV_TOKEN!);const { value: openaiKey } = await vault.getSecretValue(process.env.OPENAI_SECRET_ID!);Python
Section titled “Python”import requests
class ContextDataVault: def __init__(self, base_url: str, token: str): self.base = f"{base_url}/api/v1" self.headers = {"Authorization": f"Token {token}"}
def get_secret_value(self, secret_id: str) -> dict: r = requests.get(f"{self.base}/secrets/{secret_id}/value", headers=self.headers) r.raise_for_status() return r.json()
def tokenize(self, vault_id: str, content: str) -> dict: r = requests.post(f"{self.base}/tokens", headers=self.headers, json={"vaultId": vault_id, "content": content}) r.raise_for_status() return r.json()
def resolve(self, token: str) -> dict: r = requests.get(f"{self.base}/tokens/{token}/resolve", headers=self.headers) r.raise_for_status() return r.json()Error handling patterns
Section titled “Error handling patterns”- Hard‑fail for secret retrieval. If a required credential can’t be fetched, stop startup rather than run in a degraded, insecure state.
- Graceful degradation for tokenization. If tokenization is unavailable, decide deliberately whether to proceed without it or block — don’t silently send raw content downstream.
- Handle revoked tokens. A
403/404on resolve means the token was revoked or its grant expired. Treat it as an expected condition, not a crash. - Respect rate limits. Back off on
429responses.
Environment variables your app needs
Section titled “Environment variables your app needs”CDV_URL=https://acme.contextdatavault.com # your vault endpointCDV_TOKEN=<scoped-api-token> # issued during setup# Reference IDs for the secrets/vault your app uses:OPENAI_SECRET_ID=<secret-id>CDV_VAULT_ID=<vault-id>