Skip to content

fix: encrypt exchange account credentials at rest - #153

Open
ArjanM8 wants to merge 1 commit into
Open-Trader:devfrom
ArjanM8:fix/encrypt-exchange-account-credentials-at-rest
Open

fix: encrypt exchange account credentials at rest#153
ArjanM8 wants to merge 1 commit into
Open-Trader:devfrom
ArjanM8:fix/encrypt-exchange-account-credentials-at-rest

Conversation

@ArjanM8

@ArjanM8 ArjanM8 commented Aug 2, 2026

Copy link
Copy Markdown

apiKey, secretKey and password on ExchangeAccount were stored as plaintext in the database. Anyone with read access to the SQLite/ Postgres file (or a backup of it) could read every configured exchange API key in the clear.

This adds transparent AES-256-GCM encryption/decryption at the single choke point where exchange accounts are read/written (the xprisma Prisma Client extension), so every existing caller of xprisma.exchangeAccount.* keeps working unchanged with plaintext values in memory, while the DB itself only ever stores ciphertext.

The encryption key is kept separate from the database: either an operator-supplied CREDENTIALS_ENCRYPTION_KEY env var, or an auto-generated key persisted to ~/.opentrader/credentials.key (0600) on first run. This means a leaked DB file/backup alone is not enough to recover stored credentials.

Backwards compatible: existing plaintext rows are detected (no "enc:v1:" prefix) and passed through as-is on read, and get encrypted the next time they're written.

apiKey, secretKey and password on ExchangeAccount were stored as
plaintext in the database. Anyone with read access to the SQLite/
Postgres file (or a backup of it) could read every configured
exchange API key in the clear.

This adds transparent AES-256-GCM encryption/decryption at the single
choke point where exchange accounts are read/written (the `xprisma`
Prisma Client extension), so every existing caller of
`xprisma.exchangeAccount.*` keeps working unchanged with plaintext
values in memory, while the DB itself only ever stores ciphertext.

The encryption key is kept separate from the database: either an
operator-supplied CREDENTIALS_ENCRYPTION_KEY env var, or an
auto-generated key persisted to ~/.opentrader/credentials.key (0600)
on first run. This means a leaked DB file/backup alone is not enough
to recover stored credentials.

Backwards compatible: existing plaintext rows are detected (no
"enc:v1:" prefix) and passed through as-is on read, and get encrypted
the next time they're written.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant