Secrets you store in ObserveOne are encrypted in the application before they are written, so the database only ever holds ciphertext. Here is what that covers and what it does not.
What gets encrypted#
- API check secrets: every value stored for
{{KEY}}resolution. - Autopilot suite secrets: the login credentials tests reference as
process.env.KEY. - Environment secrets: the per-environment values checks resolve at run time.
- CI tokens that post status checks and PR comments.
- Webhook signing secrets on deploy integrations.
- OAuth tokens for connected integrations.
Check results stay readable for debugging, so keep secrets out of anything your endpoints return.
How it works#
| Property | In practice |
|---|---|
| AES-256-GCM before storage | the database sees ciphertext, never plaintext |
| Authenticated | a tampered value fails to decrypt instead of returning garbage |
| Fresh random nonce per value | the same token saved twice produces different ciphertext |
The key lives outside the database, so a leaked backup or over-scoped query reveals nothing. Payloads are versioned, so the key scheme can evolve without a risky migration.
Write-only on top#
After a secret is saved, no read returns its value: endpoints return key names only. A new value replaces it, an empty value deletes it. No reveal button, no plaintext export.
Limitations#
- Server-side, not end-to-end: the service decrypts at send time to resolve
{{KEY}}references. - Check results are stored readable; encryption covers stored secrets, not what your API returns.
- No version history: replacing a value discards the old ciphertext.
The point#
A leaked backup should not leak your tokens. The same vault backs
ObserveOne's Autopilot:
generated Playwright tests log in via process.env.KEY, never a literal
password.