Add secrets documentation and inline env migration script
Document secret storage in DATABASE.md and DEVELOPING.md. Update SPEC-implementation with company_secrets schema and indexes. Add migrate-inline-env-secrets script for converting existing plain env values to managed secrets (dry-run by default, --apply to commit). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -120,3 +120,39 @@ The database mode is controlled by `DATABASE_URL`:
|
||||
| `postgres://...supabase.com...` | Hosted Supabase |
|
||||
|
||||
Your Drizzle schema (`packages/db/src/schema/`) stays the same regardless of mode.
|
||||
|
||||
## Secret storage
|
||||
|
||||
Paperclip stores secret metadata and versions in:
|
||||
|
||||
- `company_secrets`
|
||||
- `company_secret_versions`
|
||||
|
||||
For local/default installs, the active provider is `local_encrypted`:
|
||||
|
||||
- Secret material is encrypted at rest with a local master key.
|
||||
- Default key file: `./data/secrets/master.key` (auto-created if missing).
|
||||
- CLI config location: `.paperclip/config.json` under `secrets.localEncrypted.keyFilePath`.
|
||||
|
||||
Optional overrides:
|
||||
|
||||
- `PAPERCLIP_SECRETS_MASTER_KEY` (32-byte key as base64, hex, or raw 32-char string)
|
||||
- `PAPERCLIP_SECRETS_MASTER_KEY_FILE` (custom key file path)
|
||||
|
||||
Strict mode to block new inline sensitive env values:
|
||||
|
||||
```sh
|
||||
PAPERCLIP_SECRETS_STRICT_MODE=true
|
||||
```
|
||||
|
||||
You can set strict mode and provider defaults via:
|
||||
|
||||
```sh
|
||||
pnpm paperclip configure --section secrets
|
||||
```
|
||||
|
||||
Inline secret migration command:
|
||||
|
||||
```sh
|
||||
pnpm secrets:migrate-inline-env --apply
|
||||
```
|
||||
|
||||
@@ -56,3 +56,32 @@ pnpm dev
|
||||
## Optional: Use External Postgres
|
||||
|
||||
If you set `DATABASE_URL`, the server will use that instead of embedded PostgreSQL.
|
||||
|
||||
## Secrets in Dev
|
||||
|
||||
Agent env vars now support secret references. By default, secret values are stored with local encryption and only secret refs are persisted in agent config.
|
||||
|
||||
- Default local key path: `./data/secrets/master.key`
|
||||
- Override key material directly: `PAPERCLIP_SECRETS_MASTER_KEY`
|
||||
- Override key file path: `PAPERCLIP_SECRETS_MASTER_KEY_FILE`
|
||||
|
||||
Strict mode (recommended outside local trusted machines):
|
||||
|
||||
```sh
|
||||
PAPERCLIP_SECRETS_STRICT_MODE=true
|
||||
```
|
||||
|
||||
When strict mode is enabled, sensitive env keys (for example `*_API_KEY`, `*_TOKEN`, `*_SECRET`) must use secret references instead of inline plain values.
|
||||
|
||||
CLI configuration support:
|
||||
|
||||
- `pnpm paperclip onboard` writes a default `secrets` config section (`local_encrypted`, strict mode off, key file path set) and creates a local key file when needed.
|
||||
- `pnpm paperclip configure --section secrets` lets you update provider/strict mode/key path and creates the local key file when needed.
|
||||
- `pnpm paperclip doctor` validates secrets adapter configuration and can create a missing local key file with `--repair`.
|
||||
|
||||
Migration helper for existing inline env secrets:
|
||||
|
||||
```sh
|
||||
pnpm secrets:migrate-inline-env # dry run
|
||||
pnpm secrets:migrate-inline-env --apply # apply migration
|
||||
```
|
||||
|
||||
@@ -275,7 +275,21 @@ Invariant: each event must attach to agent and company; rollups are aggregation,
|
||||
- `details` jsonb null
|
||||
- `created_at` timestamptz not null default now()
|
||||
|
||||
## 7.12 Required Indexes
|
||||
## 7.12 `company_secrets` + `company_secret_versions`
|
||||
|
||||
- Secret values are not stored inline in `agents.adapter_config.env`.
|
||||
- Agent env entries should use secret refs for sensitive values.
|
||||
- `company_secrets` tracks identity/provider metadata per company.
|
||||
- `company_secret_versions` stores encrypted/reference material per version.
|
||||
- Default provider in local deployments: `local_encrypted`.
|
||||
|
||||
Operational policy:
|
||||
|
||||
- Config read APIs redact sensitive plain values.
|
||||
- Activity and approval payloads must not persist raw sensitive values.
|
||||
- Config revisions may include redacted placeholders; such revisions are non-restorable for redacted fields.
|
||||
|
||||
## 7.13 Required Indexes
|
||||
|
||||
- `agents(company_id, status)`
|
||||
- `agents(company_id, reports_to)`
|
||||
@@ -288,6 +302,8 @@ Invariant: each event must attach to agent and company; rollups are aggregation,
|
||||
- `heartbeat_runs(company_id, agent_id, started_at desc)`
|
||||
- `approvals(company_id, status, type)`
|
||||
- `activity_log(company_id, created_at desc)`
|
||||
- `company_secrets(company_id, name)` unique
|
||||
- `company_secret_versions(secret_id, version)` unique
|
||||
|
||||
## 8. State Machines
|
||||
|
||||
|
||||
Reference in New Issue
Block a user