<!-- https://zerolog.ch/docs/vault · Docs / Keys and privacy -->
# Secrets vault

Store credentials the AI needs (a deploy token, a database password) encrypted, and attach them to a chat when needed.

## Stored encrypted

Each value is encrypted with AES-256-GCM under a key the server holds, so this is not end-to-end encryption. The vault list never contains values. On the Vault page you can reveal or copy a value; a revealed value hides itself after 30 seconds.

## Before attaching credentials

An entry can be attached to a chat only while its **Allow model access** switch is on. What the model gets depends on the chat. With the sandbox on, the value is written to a file under `/vault` in the container (mode 600). The model sees the name, user name, notes and path but not the value, and it can still read the file with commands, so a prompt-injected or misbehaving model could leak it. With the sandbox off, the server decrypts the value and includes it in plaintext in every request to the model provider for that chat.

A chat with an attached credential runs only on a route whose zero-data-retention commitment is confirmed. For Featherless that is the provider’s written commitment of 28 September 2026, which ZeroLog cannot enforce technically. On any other route the request is refused and nothing is sent. Such a chat is never moved to another provider, not after an error and not when a balance is empty. You can allow it manually for one chat; the chat then shows that the override is active, and you can revoke it. The requirement stays after you detach the credential, because the value may already sit in the transcript as tool output.

Editing or deleting an entry, or detaching it from a chat, wipes the copy in that chat’s running sandbox. If the wipe fails, ZeroLog says so and asks you to delete that chat’s sandbox.

Provider handling

### Know where credentials go

The vault protects saved credentials while stored. It cannot control how an AI provider handles content after a chat sends it.

For keys that agents should use without ever seeing them, see the [key proxy](https://zerolog.ch/docs/keyproxy). Plain-language overview: [API key proxy for AI agents](https://zerolog.ch/api-key-proxy-for-ai-agents).

## How a vault credential reaches a chat

Mermaid source of the diagram on this page:

```mermaid
%% Vault: store, attach, and the two ways a credential reaches the model. Facts from server/vault.js, routes/vault.js, routes/chats.js, sandbox.js, retention-core.js.
flowchart TB
  s["1. You save a credential<br/>AES-256-GCM, server key"]
  v["Vault<br/>(reveal or copy: hides<br/>after 30 s)"]
  at["2. Attach to a chat<br/>only if Allow model<br/>access is on"]
  sb["Sandbox on:<br/>file in /vault, mode 600<br/>model sees name and path"]
  nb["Sandbox off:<br/>plaintext in each request<br/>to the provider"]
  g["3. Route check:<br/>zero-data-retention<br/>confirmed?"]:::hot
  ok["Request goes out"]
  no["Refused, nothing sent<br/>(403 zdr_unconfirmed)<br/>no other provider"]
  ov["Your manual override<br/>for this one chat"]

  s --> v --> at
  at --> sb
  at --> nb
  sb --> g
  nb --> g
  g -->|yes| ok
  g -->|no| no
  no -.->|you allow it| ov
  ov -.-> ok

  classDef hot stroke:#8f7ac9
```
