feat(phase-2): workstream 1 — HashiCorp Vault credential storage
Vault is optional — server falls back to bcrypt (Phase 1 behaviour) when VAULT_ADDR is not set. Full coexistence: existing bcrypt credentials continue to work until rotated. Changes: - src/vault/VaultClient.ts — wraps node-vault KV v2; writeSecret, readSecret, verifySecret (constant-time), deleteSecret - src/db/migrations/005_add_vault_path.sql — vault_path column on credentials - CredentialRepository — createWithVaultPath, updateVaultPath methods - CredentialService — routes generate/rotate through Vault when configured; bcrypt path unchanged - OAuth2Service — verifies via Vault when vaultPath set, bcrypt otherwise - src/app.ts — createVaultClientFromEnv() wired into service layer - ICredentialRow — vaultPath field added - docs/devops/environment-variables.md — VAULT_ADDR, VAULT_TOKEN, VAULT_MOUNT - docs/devops/vault-setup.md — dev quickstart, production config, migration guide - tests: 33/33 unit tests pass (VaultClient + CredentialService Vault path) - node-vault + @types/node-vault installed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -76,6 +76,47 @@ Every authenticated request verifies the JWT signature using this key. If this k
|
||||
|
||||
These variables have defaults and do not need to be set for local development.
|
||||
|
||||
### `VAULT_ADDR`
|
||||
|
||||
HashiCorp Vault server address. **Required to enable Vault integration (Phase 2).**
|
||||
|
||||
| | |
|
||||
|-|-|
|
||||
| **Required** | No (Vault is optional) |
|
||||
| **Format** | URL string |
|
||||
| **Example** | `VAULT_ADDR=http://127.0.0.1:8200` |
|
||||
|
||||
When set alongside `VAULT_TOKEN`, new credentials are stored in Vault KV v2 instead of as bcrypt hashes in PostgreSQL. Existing bcrypt credentials continue to work unchanged until rotated. See [Vault setup guide](vault-setup.md).
|
||||
|
||||
---
|
||||
|
||||
### `VAULT_TOKEN`
|
||||
|
||||
Vault authentication token. Required when `VAULT_ADDR` is set.
|
||||
|
||||
| | |
|
||||
|-|-|
|
||||
| **Required** | Only when `VAULT_ADDR` is set |
|
||||
| **Format** | String |
|
||||
| **Example** | `VAULT_TOKEN=hvs.XXXXXXXXXXXXXXXXXXXXXX` |
|
||||
|
||||
Use a Vault service token scoped to `read`, `write`, and `delete` on `{VAULT_MOUNT}/data/agentidp/*` and `{VAULT_MOUNT}/metadata/agentidp/*`.
|
||||
|
||||
---
|
||||
|
||||
### `VAULT_MOUNT`
|
||||
|
||||
KV v2 secrets engine mount path.
|
||||
|
||||
| | |
|
||||
|-|-|
|
||||
| **Required** | No |
|
||||
| **Default** | `secret` |
|
||||
| **Format** | String (no leading or trailing slash) |
|
||||
| **Example** | `VAULT_MOUNT=agentidp` |
|
||||
|
||||
---
|
||||
|
||||
### `PORT`
|
||||
|
||||
HTTP port the Express server listens on.
|
||||
@@ -141,6 +182,11 @@ MIIEowIBAAKCAQEA...
|
||||
JWT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkq...
|
||||
-----END PUBLIC KEY-----"
|
||||
|
||||
# HashiCorp Vault (Phase 2 — optional, omit to use bcrypt mode)
|
||||
# VAULT_ADDR=http://127.0.0.1:8200
|
||||
# VAULT_TOKEN=hvs.XXXXXXXXXXXXXXXXXXXXXX
|
||||
# VAULT_MOUNT=secret
|
||||
```
|
||||
|
||||
> Do not commit `.env` to version control. Add it to `.gitignore`.
|
||||
|
||||
Reference in New Issue
Block a user