Skip to content

feat: derive secret AAD through a named helper #1863 - #1868

Closed
DmytroZaichenkoDev wants to merge 1 commit into
feat/issue-1863-1-layout-seamfrom
feat/issue-1863-3-secret-aad
Closed

DmytroZaichenkoDev wants to merge 1 commit into
feat/issue-1863-1-layout-seamfrom
feat/issue-1863-3-secret-aad

Conversation

@DmytroZaichenkoDev

@DmytroZaichenkoDev DmytroZaichenkoDev commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Part 2 of 2 for #1863. Part 1 is #1866.

Why

Encrypted fields are bound to the resource's physical path: the path is the AES-GCM additional authenticated data. AAD has to match byte for byte at decrypt, so a re-addressed resource is not stale — its secrets are unopenable, and unrecoverable without the old path.

That affects config secrets (SecretFieldProcessor), external-service credentials, and background-job payloads. Five call sites derived the AAD inline, which made the coupling invisible.

What

ResourceSecretAad — one named place the AAD comes from, with two overloads:

  • deriveFor(ResourceDescriptor) — what the five sites use today.
  • deriveFor(String absoluteFilePath) — so a caller that moves an encrypted resource can decrypt with the source path and encrypt with the destination one.

Invariant

Same bytes as before; no behaviour change. ResourceSecretAadTest asserts the descriptor and path forms agree, and that different paths produce different AAD.

Notes for review

This is a prerequisite for migrating encrypted resources, not the migration itself. Two things are deliberately not here:

  • The key axis is untouched — CredentialEncryptionService still resolves the CEK internally, so this does not enable key rotation.
  • The three services still derive the AAD at their public entry points; path-accepting entry points would be needed before a migrator can drive both sides.

Both belong in the migration work, with their own review.

@DmytroZaichenkoDev
DmytroZaichenkoDev force-pushed the feat/issue-1863-3-secret-aad branch from 31cb172 to e0966ee Compare August 31, 2026 11:13
@DmytroZaichenkoDev
DmytroZaichenkoDev changed the base branch from feat/issue-1863-2-tenant-layout to feat/issue-1863-1-layout-seam August 31, 2026 11:13
Encrypted fields are bound to the resource's physical path through the AES-GCM
AAD, which five call sites derived inline. They now share ResourceSecretAad,
which also accepts a path directly, so a caller that moves an encrypted resource
can decrypt with the source path and encrypt with the destination one.

Same bytes as before; no behaviour change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@DmytroZaichenkoDev

Copy link
Copy Markdown
Contributor Author

Closing as out of scope for #1863, which is addressing only.

This existed so a migrator could supply source and destination paths explicitly for AES-GCM AAD. The migration approach has since settled on moving encrypted resources through their owning service — reading decrypts at the source, writing re-encrypts at the destination — which needs no explicit-path plumbing, so the reason for the helper is gone.

What remains is a pure refactor (five inline AAD derivations into one named place), which CODE_STYLE.md would rightly call a 'while I'm here' change on an addressing issue.

The finding itself is recorded — encrypted fields are cryptographically bound to their physical path, so a byte copy makes them unopenable. It belongs to the migration phase, where it will have a real caller. The diff here stays available on this closed PR.

@DmytroZaichenkoDev
DmytroZaichenkoDev deleted the feat/issue-1863-3-secret-aad branch September 1, 2026 09:44
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