> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hexclave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Data Vault

> An encrypted key-value store for sensitive data, with zero-knowledge security

Data Vault is an encrypted key-value store built into Hexclave. It lets you securely store sensitive data — API tokens, connection strings, secrets, or any other values — without ever exposing plaintext to Hexclave's database or operators.

## How it works

Data Vault uses a **double encryption** design:

1. **Client-side encryption** — Your SDK encrypts values and hashes keys locally before they leave your server, using a secret that only you know. Hexclave never sees your plaintext keys or values.
2. **Server-side encryption** — Hexclave adds a second layer of envelope encryption using a rotating master key, so even the encrypted data at rest is further protected.

Because keys are hashed before storage, **you cannot list or enumerate keys** in a store. You must know the exact key to retrieve a value.

<Warning>
  If you lose your secret, your data is unrecoverable. Even Hexclave cannot decrypt your values without it. Keep your secret safe and backed up.
</Warning>

## Setup

### 0. Enable the Data Vault app

Before you can create stores, you need to enable the Data Vault app for your project:

1. Open your Hexclave dashboard
2. Go to **Apps**
3. Find and open **Data Vault**
4. Click **Enable**

### 1. Create a store

Go to your project's **Data Vault → Stores** page in the [Hexclave dashboard](https://app.hexclave.com) and click **Create Store**. Each project can have **multiple stores**, and each store is fully isolated from the others.

When creating a store you'll be asked for:

* **Store ID** (required) — the identifier you'll reference in your code. Must contain only letters, numbers, underscores, and hyphens, and cannot start with a hyphen. Store IDs are immutable once created.
* **Display Name** (optional) — a human-readable label shown in the dashboard. Defaults to `Store <id>` if left blank. Unlike the ID, the display name can be edited later from the store detail page.

Stores are stored in your project config under `dataVault.stores.<storeId>` and are part of your pushable configuration, so they propagate across branches like any other config setting.

### Managing a store

Click any store in the **Stores** list to open its detail page. From there you can:

* **Copy the Store ID** — useful when wiring it into your code or environment
* **Rename the store** — edit the Display Name and click **Save** to persist
* **Delete the store** — click **Delete Store**, then type the store ID into the confirmation dialog to confirm. **Deletion is irreversible**: all encrypted data in the store is permanently deleted, and Hexclave cannot recover it.

<Warning>
  Deleting a store cannot be undone. Make sure no production traffic references the store ID before removing it.
</Warning>

### 2. Generate a secret

Your secret can be any string, but for strong security it should be at least 32 characters long and provide 256 bits of entropy. Store it as an environment variable:

```bash title=".env" theme={null}
HEXCLAVE_DATA_VAULT_SECRET=your-randomly-generated-secret-here
```

### 3. Use the SDK

Data Vault is accessed through the **server app** only — it requires your secret server key.

```typescript title="server-example.ts" theme={null}
import { hexclaveServerApp } from "@/hexclave/server";

const store = await hexclaveServerApp.getDataVaultStore("my-store-id");

const key = user.id;

// Store a value
await store.setValue(key, "my-sensitive-value", {
  secret: process.env.HEXCLAVE_DATA_VAULT_SECRET,
});

// Retrieve a value
const value = await store.getValue(key, {
  secret: process.env.HEXCLAVE_DATA_VAULT_SECRET,
});
// value is the decrypted string, or null if the key doesn't exist
```

## API reference

### `getDataVaultStore(id)`

Returns a `DataVaultStore` object for the given store ID. The store must already exist in your project config (created via the dashboard).

```typescript theme={null}
const store = await hexclaveServerApp.getDataVaultStore("my-store-id");
```

### `store.getValue(key, { secret })`

Retrieves the decrypted value for the given key, or `null` if the key doesn't exist.

```typescript theme={null}
const value = await store.getValue("some-key", {
  secret: process.env.HEXCLAVE_DATA_VAULT_SECRET,
});
```

### `store.setValue(key, value, { secret })`

Stores an encrypted value for the given key. If the key already exists, it is overwritten.

```typescript theme={null}
await store.setValue("some-key", "some-value", {
  secret: process.env.HEXCLAVE_DATA_VAULT_SECRET,
});
```

## Security model

* **Keys** are hashed with an iterated hash (100,000 iterations) derived from your secret and the logical key. The server only stores the hash.
* **Values** are encrypted client-side using a derived key from the same secret + key pair, then re-encrypted server-side with KMS envelope encryption.
* **Your secret** never leaves your server. Hexclave's API only receives hashed keys and double-encrypted values.
* **No enumeration** — since only hashed keys are stored, there is no way to list all keys in a store. This is a deliberate security property.

## Use cases

* **Storing third-party API tokens** — safely persist user-specific tokens for external services
* **Connection strings** — store database or service connection strings per-tenant
* **Encryption keys** — use Data Vault as a key store for your own application-level encryption
* **Any sensitive per-user data** — anything you don't want in plaintext metadata fields
