# Secrets vault overview

Every credential lives in the **secrets vault** — the `secrets` table in the local SQLite database, encrypted with **AES-256-GCM** at rest. The plaintext value is never written to disk unencrypted, never returned in an API response, and never recorded in an audit log.

## How it works

- **Master key** — resolved from `MADARX_MASTER_KEY`. On a first install with an empty secrets table, a random key is generated and written to `.env.local` with a warning.
- **Scopes** — a secret can be stored at `agent:<id>`, `project:<id>`, or `global`. Resolution order when a tool needs a value: `agent` → `project` → `global` → `process.env`.
- **Status only** — list and read endpoints return name, scope, and status (`set` / `unset`) — never the value. The Settings pages and Cmd+K modals follow the same rule.

## Setting and rotating

- Set or rotate from anywhere with **⌘K** (see [Set an API key](/help/set-api-key)).
- Under the hood: `POST /api/secrets` creates or updates; `PATCH /api/secrets/<name>` rotates; `DELETE` revokes. All are admin/owner-gated and audited.

## Migrating from env

If you have credentials in `process.env` / `.env.local`, migrate them into the vault:

```bash
node scripts/migrate-env-to-secrets.mjs
```

The `process.env` fallback keeps things working during migration.

## Related

- [Set an API key](/help/set-api-key)
