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

# Vault

> A zero-knowledge, encrypted store for the credentials your agents need — logins with TOTP, API keys, and other secrets.

The Wirebox **Vault** gives your agents the credentials they need to act in the
real world: website logins (with two-factor TOTP), API keys, and freeform
secrets. It completes the picture alongside email and phone — an agent can now
sign up for a service, receive the verification email, **and** store and reuse
the resulting login, including its 2FA codes.

<Info>
  The vault is **zero-knowledge**: all encryption and decryption happen on your
  side (in the SDK, CLI, or your browser). The server only ever stores
  ciphertext — Wirebox never sees your secrets.
</Info>

***

## How It Works

Two keys are involved, and only one of them ever reaches the server:

| Key | Purpose | Sent to Wirebox? |
| :- | :- | :- |
| **API key** (`wb_live_...`) | Authenticates your requests | Yes (as a Bearer token) |
| **Vault key** (`WBV-...`) | Unlocks decryption, locally | **Never** |

When you unlock the vault, your vault key is stretched with **Argon2id** into a
master key, which unwraps an organization encryption key held only in memory.
That key encrypts and decrypts each secret with **AES-256-GCM**. The server
stores the ciphertext and some plaintext metadata (a secret's name and type),
nothing more.

<Warning>
  There are no recovery codes. If you lose your vault key, the vault cannot be
  decrypted and must be re-initialized. Store the key somewhere safe — a
  password manager or your secrets manager of choice.
</Warning>

***

## Secret Types

| Type | Fields |
| :- | :- |
| `login` | `username`, `email`, `password`, `service_url`, and an optional `totp` object |
| `api_key` | `key`, optional `service_url` |
| `other` | `data` (freeform) |

The `totp` object on a login holds `secret` (base32), plus optional
`algorithm` (`sha1`/`sha256`/`sha512`), `digits` (`6`/`8`), and `period`
(`30`/`60`).

***

## Two Roles

The vault separates **managing** secrets from **using** them:

* An **admin** (a Console session or an admin API key) initializes the vault,
  creates and edits secrets, and grants agents access.
* An **agent** (an identity-scoped API key with the `vault:read` scope) can
  unlock the vault and read **only the secrets it has been granted** — the
  server filters ciphertext per identity, so an agent can never download a
  secret it was not given, even though it holds the vault key.

***

## Initialize the Vault

Done once per organization. A strong vault key is generated and returned — save
it now.

<CodeGroup>
  ```python Python theme={null}
  from wirebox import Wirebox

  wb = Wirebox()  # admin API key via WIREBOX_API_KEY

  result = wb.vault.initialize()
  print("Vault key (store this securely):", result.vault_key)
  print(result.warning)
  ```

  ```ts TypeScript theme={null}
  import { Wirebox } from "@wirebox-sh/sdk";

  const wb = new Wirebox(); // admin API key via WIREBOX_API_KEY

  const { vaultKey, warning } = await wb.vault.initialize();
  console.log("Vault key (store this securely):", vaultKey);
  console.log(warning);
  ```

  ```bash CLI theme={null}
  # Prints a generated vault key — store it securely.
  wirebox vault init

  # Or bring your own key:
  wirebox vault init --vault-key "my-strong-vault-key"
  ```
</CodeGroup>

You can also initialize the vault from the [Console](https://wirebox.sh/console/vault).

***

## Unlock the Vault

Unlocking derives the key client-side and returns a handle you can read and
write secrets through. The vault key is read from the argument, or from the
`WIREBOX_VAULT_KEY` environment variable.

<CodeGroup>
  ```python Python theme={null}
  import os

  vault = wb.vault.unlock(os.environ["WIREBOX_VAULT_KEY"])
  ```

  ```ts TypeScript theme={null}
  const vault = await wb.vault.unlock(process.env.WIREBOX_VAULT_KEY);
  ```

  ```bash CLI theme={null}
  # Commands that need the vault key read it from --vault-key or WIREBOX_VAULT_KEY.
  export WIREBOX_VAULT_KEY="WBV-..."
  ```
</CodeGroup>

***

## Create Secrets

Payloads are encrypted locally before upload. Secrets are addressed later by
**name or id**, so give them clear names.

<CodeGroup>
  ```python Python theme={null}
  from wirebox.vault import VaultSecretType, LoginPayload, ApiKeyPayload, parse_totp_uri

  # A login with two-factor TOTP
  vault.create_secret(
      type=VaultSecretType.LOGIN,
      name="GitHub",
      payload=LoginPayload(
          username="eva",
          password="s3cr3t",
          service_url="https://github.com",
          totp=parse_totp_uri("otpauth://totp/GitHub:eva?secret=JBSWY3DPEHPK3PXP"),
      ),
  )

  # An API key
  vault.create_secret(
      type=VaultSecretType.API_KEY,
      name="Stripe",
      payload=ApiKeyPayload(key="sk_live_...", service_url="https://api.stripe.com"),
  )
  ```

  ```ts TypeScript theme={null}
  import { VaultSecretType, parseTotpUri } from "@wirebox-sh/sdk";

  // A login with two-factor TOTP
  await vault.createSecret({
    type: VaultSecretType.LOGIN,
    name: "GitHub",
    payload: {
      username: "eva",
      password: "s3cr3t",
      service_url: "https://github.com",
      totp: parseTotpUri("otpauth://totp/GitHub:eva?secret=JBSWY3DPEHPK3PXP"),
    },
  });

  // An API key
  await vault.createSecret({
    type: VaultSecretType.API_KEY,
    name: "Stripe",
    payload: { key: "sk_live_...", service_url: "https://api.stripe.com" },
  });
  ```

  ```bash CLI theme={null}
  # Login with TOTP. Omit --password to be prompted; pass "-" to read from stdin.
  wirebox vault add --type login --name GitHub \
    --username eva --password \
    --url https://github.com \
    --totp-uri "otpauth://totp/GitHub:eva?secret=JBSWY3DPEHPK3PXP"

  # API key
  wirebox vault add --type api_key --name Stripe --key - --url https://api.stripe.com
  ```
</CodeGroup>

<Tip>
  TOTP can be added from an `otpauth://` URI (as above) or, in the
  [Console](https://wirebox.sh/console/vault), by uploading the QR image shown
  during a service's 2FA setup.
</Tip>

***

## Read Secrets

Secrets come back decrypted from the unlocked vault. List metadata without the
vault key; read values after unlocking. Secrets are addressed by **name or id**.

<CodeGroup>
  ```python Python theme={null}
  # Metadata only (no vault key needed)
  summaries = wb.vault.list_secrets(type="login")

  # Decrypted values
  login = vault.get_login("GitHub")
  print(login.username, login.password)

  print(vault.get_api_key("Stripe").key)
  ```

  ```ts TypeScript theme={null}
  // Metadata only (no vault key needed)
  const summaries = await wb.vault.listSecrets({ type: "login" });

  // Decrypted values
  const login = vault.getLogin("GitHub");
  console.log(login.username, login.password);

  const stripe = vault.getApiKey("Stripe");
  console.log(stripe.key);
  ```

  ```bash CLI theme={null}
  # List metadata
  wirebox vault list --type login

  # Values are masked by default; reveal explicitly, or extract one field.
  wirebox vault get GitHub
  wirebox vault get GitHub --reveal
  wirebox vault get GitHub --field password
  ```
</CodeGroup>

***

## Generate TOTP Codes

For a login that has TOTP configured, generate the current one-time code
client-side.

<CodeGroup>
  ```python Python theme={null}
  code = vault.get_totp_code("GitHub")
  print(code.code, f"expires in {code.expires_in_seconds}s")
  ```

  ```ts TypeScript theme={null}
  const code = await vault.getTotpCode("GitHub");
  console.log(code.code, `expires in ${code.expiresInSeconds}s`);
  ```

  ```bash CLI theme={null}
  wirebox vault totp GitHub
  ```
</CodeGroup>

***

## Update and Delete

In the SDK, an update re-encrypts the payload you pass, so provide the complete
payload (read it first) to change one field. The CLI merges the fields you pass.

<CodeGroup>
  ```python Python theme={null}
  login = vault.get_login("GitHub")
  login.password = "rotated-secret"
  vault.update_secret("GitHub", payload=login)

  vault.delete_secret("GitHub")
  ```

  ```ts TypeScript theme={null}
  await vault.updateSecret("GitHub", {
    payload: { ...vault.getLogin("GitHub"), password: "rotated-secret" },
  });

  await vault.deleteSecret("GitHub");
  ```

  ```bash CLI theme={null}
  wirebox vault set GitHub --password
  wirebox vault rm GitHub
  ```
</CodeGroup>

***

## Give an Agent Access

This is the end-to-end flow for letting an autonomous agent use a credential.

**1. Create an identity-scoped API key with the `vault:read` scope.** In the
[Console](https://wirebox.sh/console/keys), create an API key scoped to the
agent and check **Allow vault access (vault:read)**. This key authenticates the
agent and lets it read the vault.

**2. Grant the agent access to specific secrets.** Secrets are addressed by
name or id; the CLI also accepts an agent handle.

<CodeGroup>
  ```python Python theme={null}
  eva = wb.get_identity("eva")
  wb.vault.grant_access("GitHub", eva.id)
  ```

  ```ts TypeScript theme={null}
  const eva = await wb.getIdentity("eva");
  await wb.vault.grantAccess("GitHub", eva.id);
  ```

  ```bash CLI theme={null}
  wirebox vault access grant GitHub -i @eva
  ```
</CodeGroup>

**3. Give the agent its two keys** — the `vault:read` API key
(`WIREBOX_API_KEY`) and the vault key (`WIREBOX_VAULT_KEY`). The agent can now
unlock and read only what it was granted:

<CodeGroup>
  ```python Python theme={null}
  from wirebox import Wirebox

  wb = Wirebox()  # WIREBOX_API_KEY = the agent's vault:read key
  vault = wb.vault.unlock()  # WIREBOX_VAULT_KEY from the environment

  login = vault.get_login("GitHub")
  code = vault.get_totp_code("GitHub")
  # Use login.username / login.password / code.code to sign in.
  ```

  ```ts TypeScript theme={null}
  import { Wirebox } from "@wirebox-sh/sdk";

  const wb = new Wirebox(); // WIREBOX_API_KEY = the agent's vault:read key
  const vault = await wb.vault.unlock(); // WIREBOX_VAULT_KEY from the environment

  const login = vault.getLogin("GitHub");
  const code = await vault.getTotpCode("GitHub");
  // Use login.username / login.password / code.code to sign in.
  ```
</CodeGroup>

Revoke access at any time; it takes effect on the next unlock:

<CodeGroup>
  ```python Python theme={null}
  wb.vault.revoke_access("GitHub", eva.id)
  ```

  ```ts TypeScript theme={null}
  await wb.vault.revokeAccess("GitHub", eva.id);
  ```

  ```bash CLI theme={null}
  wirebox vault access revoke GitHub -i @eva
  wirebox vault access list GitHub
  ```
</CodeGroup>

***

## API Reference

For the raw REST endpoints — remember that payloads are ciphertext produced
client-side — see the [Vault API reference](/api-reference/vault/overview).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.