Skip to content

fix(security): redact encrypted value and IV from secret reads - #6

Merged
merlik787-droi merged 1 commit into
mainfrom
fix/redact-secret-material
Oct 9, 2026
Merged

merlik787-droi merged 1 commit into
mainfrom
fix/redact-secret-material

Conversation

@merlik787-droi

Copy link
Copy Markdown
Contributor

Problem

The secrets API returns the Secret entity directly, so GET /secrets and GET /secrets/:id include the stored encryptedValue and iv. Exposing ciphertext + IV to every API caller is unnecessary (decryption already goes through GET /secrets/:id/value) and widens the attack surface. This is the follow-up flagged in #1.

Fix

  • Secret.encryptedValue and Secret.iv are now @Column({ ..., select: false }), so they are excluded from all default reads (find, findOne, getAllSecrets, and the entity returned by create/update/rotate responses).
  • getSecretValue() — the only place that needs the material — loads them explicitly via createQueryBuilder('secret').addSelect(['secret.encryptedValue', 'secret.iv']).
  • Added a test asserting getSecretValue uses that explicit selection and decrypts correctly.

Writes are unaffected: createSecret/updateSecret/rotateSecret set the fields in memory and save() persists them.

Acceptance criteria

  • GET /secrets / GET /secrets/:id no longer expose encryptedValue or iv
  • GET /secrets/:id/value still decrypts correctly
  • lint / format / type-check / tests / build pass

Verification (in microservices/config-service)

npm run lint:check    → clean
npm run format:check  → clean
npm run type-check    → clean
npm test              → 3 suites, 12 tests passed
npm run build         → nest build OK

The secrets endpoints returned the Secret entity as-is, exposing each
secret's stored ciphertext and IV via GET /secrets and GET /secrets/:id.
Even though the material is encrypted, exposing it (and the IV) widens the
attack surface and is unnecessary for callers, who should use the decrypt
endpoint.

- Mark Secret.encryptedValue and Secret.iv as select: false so they are
  never loaded for reads
- Load them explicitly (explicit addSelect) only in getSecretValue, the
  one place decryption happens
- Add a test covering the explicit selection in getSecretValue
@merlik787-droi
merlik787-droi merged commit b8484af into main Oct 9, 2026
@merlik787-droi
merlik787-droi deleted the fix/redact-secret-material branch October 9, 2026 11:51
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.

2 participants