feat(crypto): bind GCM ciphertext to entity context via AAD#83
Merged
Conversation
Add Additional Authenticated Data (AAD) to AES-256-GCM encrypt/decrypt, preventing ciphertext relocation between database rows. SSO client secrets are bound to org_id, MFA TOTP secrets to user_id, and the doctor encryption sentinel to a fixed label. Also adds dev/specs/sso-secret-storage.md documenting the full encryption architecture for external sharing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 tasks
scarson
added a commit
that referenced
this pull request
Apr 8, 2026
…tes (#84) * chore(deps): bump github.com/go-jose/go-jose/v4 from 4.1.3 to 4.1.4 (#71) Bumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.1.3 to 4.1.4. - [Release notes](https://github.com/go-jose/go-jose/releases) - [Commits](go-jose/go-jose@v4.1.3...v4.1.4) --- updated-dependencies: - dependency-name: github.com/go-jose/go-jose/v4 dependency-version: 4.1.4 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Sam Carson <samuel.carson@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump defu from 6.1.4 to 6.1.6 in /web (#72) Bumps [defu](https://github.com/unjs/defu) from 6.1.4 to 6.1.6. - [Release notes](https://github.com/unjs/defu/releases) - [Changelog](https://github.com/unjs/defu/blob/main/CHANGELOG.md) - [Commits](unjs/defu@v6.1.4...v6.1.6) --- updated-dependencies: - dependency-name: defu dependency-version: 6.1.6 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Sam Carson <samuel.carson@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump picomatch in /web (#66) Bumps and [picomatch](https://github.com/micromatch/picomatch). These dependencies needed to be updated together. Updates `picomatch` from 4.0.3 to 4.0.4 - [Release notes](https://github.com/micromatch/picomatch/releases) - [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md) - [Commits](micromatch/picomatch@4.0.3...4.0.4) Updates `picomatch` from 2.3.1 to 2.3.2 - [Release notes](https://github.com/micromatch/picomatch/releases) - [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md) - [Commits](micromatch/picomatch@4.0.3...4.0.4) --- updated-dependencies: - dependency-name: picomatch dependency-version: 4.0.4 dependency-type: indirect - dependency-name: picomatch dependency-version: 2.3.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Sam Carson <samuel.carson@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/danielgtaylor/huma/v2 from 2.37.2 to 2.37.3 (#69) Bumps [github.com/danielgtaylor/huma/v2](https://github.com/danielgtaylor/huma) from 2.37.2 to 2.37.3. - [Release notes](https://github.com/danielgtaylor/huma/releases) - [Commits](danielgtaylor/huma@v2.37.2...v2.37.3) --- updated-dependencies: - dependency-name: github.com/danielgtaylor/huma/v2 dependency-version: 2.37.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump google.golang.org/genai from 1.50.0 to 1.52.0 (#70) Bumps [google.golang.org/genai](https://github.com/googleapis/go-genai) from 1.50.0 to 1.52.0. - [Release notes](https://github.com/googleapis/go-genai/releases) - [Changelog](https://github.com/googleapis/go-genai/blob/v1.52.0/CHANGELOG.md) - [Commits](googleapis/go-genai@v1.50.0...v1.52.0) --- updated-dependencies: - dependency-name: google.golang.org/genai dependency-version: 1.52.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/lib/pq from 1.11.2 to 1.12.0 (#60) Bumps [github.com/lib/pq](https://github.com/lib/pq) from 1.11.2 to 1.12.0. - [Release notes](https://github.com/lib/pq/releases) - [Changelog](https://github.com/lib/pq/blob/master/CHANGELOG.md) - [Commits](lib/pq@v1.11.2...v1.12.0) --- updated-dependencies: - dependency-name: github.com/lib/pq dependency-version: 1.12.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/setup-go from 6.3.0 to 6.4.0 (#68) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 6.3.0 to 6.4.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](actions/setup-go@4b73464...4a36011) --- updated-dependencies: - dependency-name: actions/setup-go dependency-version: 6.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @tailwindcss/vite from 4.2.1 to 4.2.2 in /web (#65) Bumps [@tailwindcss/vite](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/@tailwindcss-vite) from 4.2.1 to 4.2.2. - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.2.2/packages/@tailwindcss-vite) --- updated-dependencies: - dependency-name: "@tailwindcss/vite" dependency-version: 4.2.2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump yaml from 2.8.2 to 2.8.3 in /web (#67) Bumps [yaml](https://github.com/eemeli/yaml) from 2.8.2 to 2.8.3. - [Release notes](https://github.com/eemeli/yaml/releases) - [Commits](eemeli/yaml@v2.8.2...v2.8.3) --- updated-dependencies: - dependency-name: yaml dependency-version: 2.8.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Sam Carson <samuel.carson@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump vue-router from 5.0.3 to 5.0.4 in /web (#63) Bumps [vue-router](https://github.com/vuejs/router) from 5.0.3 to 5.0.4. - [Release notes](https://github.com/vuejs/router/releases) - [Commits](vuejs/router@v5.0.3...v5.0.4) --- updated-dependencies: - dependency-name: vue-router dependency-version: 5.0.4 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump eslint from 10.0.3 to 10.1.0 in /web (#64) Bumps [eslint](https://github.com/eslint/eslint) from 10.0.3 to 10.1.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](eslint/eslint@v10.0.3...v10.1.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.1.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @vitest/eslint-plugin in /web (#62) Bumps [@vitest/eslint-plugin](https://github.com/vitest-dev/eslint-plugin-vitest) from 1.6.12 to 1.6.13. - [Release notes](https://github.com/vitest-dev/eslint-plugin-vitest/releases) - [Commits](vitest-dev/eslint-plugin-vitest@v1.6.12...v1.6.13) --- updated-dependencies: - dependency-name: "@vitest/eslint-plugin" dependency-version: 1.6.13 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/jackc/pgx/v5 from 5.8.0 to 5.9.1 (#59) Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.8.0 to 5.9.1. - [Changelog](https://github.com/jackc/pgx/blob/master/CHANGELOG.md) - [Commits](jackc/pgx@v5.8.0...v5.9.1) --- updated-dependencies: - dependency-name: github.com/jackc/pgx/v5 dependency-version: 5.9.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump vite from 7.3.1 to 8.0.1 in /web (#61) Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.1 to 8.0.1. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/create-vite@8.0.1/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 8.0.1 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): remove vite-plugin-vue-devtools (no Vite 8 support) The plugin's transitive dep vite-plugin-inspect doesn't support Vite 8 yet (vuejs/devtools#1071). It was installed but never registered in vite.config.ts. The Vue DevTools browser extension provides equivalent functionality. Re-add when upstream updates the peer dep range. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat(crypto): bind GCM ciphertext to entity context via AAD (#83) Add Additional Authenticated Data (AAD) to AES-256-GCM encrypt/decrypt, preventing ciphertext relocation between database rows. SSO client secrets are bound to org_id, MFA TOTP secrets to user_id, and the doctor encryption sentinel to a fixed label. Also adds dev/specs/sso-secret-storage.md documenting the full encryption architecture for external sharing. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(deps): bump reka-ui from 2.9.2 to 2.9.3 in /web (#80) Bumps [reka-ui](https://github.com/unovue/reka-ui) from 2.9.2 to 2.9.3. - [Release notes](https://github.com/unovue/reka-ui/releases) - [Commits](unovue/reka-ui@v2.9.2...v2.9.3) --- updated-dependencies: - dependency-name: reka-ui dependency-version: 2.9.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump vue from 3.5.30 to 3.5.32 in /web (#79) Bumps [vue](https://github.com/vuejs/core) from 3.5.30 to 3.5.32. - [Release notes](https://github.com/vuejs/core/releases) - [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md) - [Commits](vuejs/core@v3.5.30...v3.5.32) --- updated-dependencies: - dependency-name: vue dependency-version: 3.5.32 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump github.com/lib/pq from 1.12.0 to 1.12.3 (#76) Bumps [github.com/lib/pq](https://github.com/lib/pq) from 1.12.0 to 1.12.3. - [Release notes](https://github.com/lib/pq/releases) - [Changelog](https://github.com/lib/pq/blob/master/CHANGELOG.md) - [Commits](lib/pq@v1.12.0...v1.12.3) --- updated-dependencies: - dependency-name: github.com/lib/pq dependency-version: 1.12.3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump google.golang.org/genai from 1.52.0 to 1.52.1 (#75) Bumps [google.golang.org/genai](https://github.com/googleapis/go-genai) from 1.52.0 to 1.52.1. - [Release notes](https://github.com/googleapis/go-genai/releases) - [Changelog](https://github.com/googleapis/go-genai/blob/main/CHANGELOG.md) - [Commits](googleapis/go-genai@v1.52.0...v1.52.1) --- updated-dependencies: - dependency-name: google.golang.org/genai dependency-version: 1.52.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump oxlint and eslint-plugin-oxlint to ~1.58.0 eslint-plugin-oxlint 1.58.0 adds a peerDependency on oxlint ~1.58.0, so both must be bumped together. Lint and tests verified. Closes #78. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(deps-dev): bump @types/node from 24.12.0 to 25.5.2 in /web (#77) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.12.0 to 25.5.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-version: 25.5.2 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): upgrade TypeScript 5.9 to 6.0 - Bump typescript from ~5.9.3 to ~6.0.2 - Bump @vue/tsconfig from ^0.9.0 to ^0.9.1 (adds TS6 peer support) - Remove deprecated baseUrl from tsconfig.json and tsconfig.app.json (TS6 resolves paths relative to the tsconfig file by default) Type-check, lint, and all 419 unit tests pass. Closes #81. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * revert(deps): revert TypeScript 6 upgrade, keep baseUrl removal openapi-typescript@7.13.0 requires peer typescript ^5.x with no TS6 support yet. Revert typescript and @vue/tsconfig version bumps. Keep the baseUrl removal from tsconfig.json and tsconfig.app.json — paths resolve relative to the tsconfig file without it on TS 5.9 too, and this prepares for TS6 when the ecosystem catches up. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * chore(lint): disable require-mock-type-parameters rule New in oxlint 1.58.0 under the correctness category. Requires type parameters on all vi.fn() calls — a style preference, not a correctness issue. Disable rather than modifying 147 test call sites. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Revert "chore(lint): disable require-mock-type-parameters rule" This reverts commit 1763dbb. * fix(lint): add type parameters to all vi.fn() mock calls oxlint 1.58.0 enables require-mock-type-parameters under correctness. Untyped vi.fn() returns Mock<(...args: any[]) => any>, silently discarding type safety on mock arguments and return values. Add explicit type parameters to all 147 vi.fn() call sites across 28 test files. All tests pass (419/419). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(lint): use precise mock types where generic unknown breaks type-check Three files needed more specific type parameters than the generic (...args: unknown[]) => unknown pattern: - CreateWatchlistDialog: cast mock.calls access for body property access - client.test.ts: type fetchMock as typeof fetch (assigned to globalThis.fetch) - CveDetailView: type mockGET first arg as string (used in mockImplementation) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(lint): match proxy signature to typed mockGET in CveDetailView test The spread proxy (...args: unknown[]) can't spread into a (string, ...unknown[]) parameter. Match the proxy's signature. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Encrypt,Decrypt, andDecryptWithFallbackininternal/crypto/aes.goorg_id, MFA TOTP secrets bound touser_id, doctor sentinel bound to fixed label — prevents ciphertext relocation between database rowsorg_idper row and pass as AAD during re-encryptiondev/specs/sso-secret-storage.mddocumenting the full encryption architectureTest plan
go build ./...andgo vet ./...clean🤖 Generated with Claude Code