Skip to content

feat: HMAC recipientHash with Key Vault key version - #100

Merged
patoperpetua merged 1 commit into
mainfrom
feat/89-recipient-hash-hmac
Sep 9, 2026
Merged

patoperpetua merged 1 commit into
mainfrom
feat/89-recipient-hash-hmac

Conversation

@patoperpetua

@patoperpetua patoperpetua commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace unsalted SHA-256 recipientHash with HMAC-SHA256 using Key Vault secret recipient-hash-hmac-key (via App Configuration), emitting {keyVersionId}.{digest16} so key rotations are visible in telemetry
  • Wire secret version into RECIPIENT_HASH_HMAC_KEY_VERSION on KV reference resolve; seed/deploy assert the new secret name (no secret values in git)
  • Update send-metrics and troubleshooting docs with format + migration guidance for historical bare-hex digests

Closes #89

Test plan

  • pnpm --filter @singleton-sd/post-kit-api test (236 pass)
  • Confirm Key Vault has secret name recipient-hash-hmac-key before deploy (value never pasted in GitHub)
  • After deploy, spot-check App Insights: new recipientHash matches ^[a-f0-9]{8}\.[a-f0-9]{16}$ and never contains raw addresses

Made with Cursor

Greptile Summary

The PR replaces deterministic unsalted recipient hashes with versioned HMAC-SHA256 identifiers backed by an Azure Key Vault secret.

  • Resolves the HMAC key and its Key Vault version through App Configuration.
  • Adds deployment and seeding checks for the new secret reference.
  • Updates telemetry validation, tests, operational queries, and migration documentation for legacy hashes.

Confidence Score: 5/5

The PR appears safe to merge with the new secret provisioned as required by the deployment workflow.

The key and version are resolved together on the supported deployment path, hashing fails closed without key material, and telemetry validation and operational guidance consistently use the new versioned format.

Important Files Changed

Filename Overview
apps/api/src/telemetry/logger.ts Replaces unsalted recipient hashing with validated, version-prefixed HMAC-SHA256 output and fails closed when key material is unavailable.
apps/api/src/config/app-configuration.ts Adds Key Vault resolution for the HMAC key and publishes the resolved secret version through a separate environment variable.
scripts/seed-appconfig.sh Generalizes App Configuration seeding to assert both Forward Email and recipient-hash Key Vault references.
.github/workflows/deploy-api.yml Extends deployment readiness checks to require both Key Vault secret names before seeding and deployment.
apps/api/src/test/recipient-hash-env.ts Supplies fixed non-secret HMAC configuration for send telemetry tests; current importers are test-only.
docs/operations/send-metrics-queries.md Documents the versioned hash format, historical bare digests, rotation behavior, and cross-cutover query guidance.

Sequence Diagram

sequenceDiagram
    participant Deploy as Deployment
    participant AppConfig as App Configuration
    participant KV as Key Vault
    participant API as Send API
    participant Logs as Application Insights
    Deploy->>KV: Verify recipient-hash-hmac-key exists
    Deploy->>AppConfig: Seed Key Vault reference
    API->>AppConfig: Load secret reference
    API->>KV: Resolve key and version
    KV-->>API: Secret value and version
    API->>API: Normalize recipient and compute HMAC-SHA256
    API->>Logs: Emit keyVersionId.digest16
Loading

Reviews (1): Last reviewed commit: "feat(api): HMAC recipientHash with Key V..." | Re-trigger Greptile

Replace unsalted SHA-256 recipient digests with HMAC-SHA256 keyed from
Key Vault secret recipient-hash-hmac-key, embedding a key-version id so
operators can distinguish rotations without offline address correlation.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 46 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: a6f92fc3-9ba7-4d1c-825d-015a31395b73

📥 Commits

Reviewing files that changed from the base of the PR and between c31904c and b7168a3.

📒 Files selected for processing (18)
  • .env.example
  • .github/workflows/deploy-api.yml
  • apps/api/README.md
  • apps/api/src/config/app-configuration.spec.ts
  • apps/api/src/config/app-configuration.ts
  • apps/api/src/functions/send.idempotency.spec.ts
  • apps/api/src/functions/send.security.spec.ts
  • apps/api/src/functions/send.spec.ts
  • apps/api/src/functions/send.tenant-sender.spec.ts
  • apps/api/src/telemetry/index.ts
  • apps/api/src/telemetry/logger.spec.ts
  • apps/api/src/telemetry/logger.ts
  • apps/api/src/test/recipient-hash-env.ts
  • docs/email-forward-email.md
  • docs/operations/send-metrics-queries.md
  • docs/operations/troubleshooting.md
  • infra/README.md
  • scripts/seed-appconfig.sh

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@patoperpetua

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 13 minutes.

@patoperpetua

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.


Your included review limit is currently reached under our Fair Usage Limits Policy. This review may still proceed through usage-based billing if eligible. Your next included review will be available in 46 minutes.

@patoperpetua

Copy link
Copy Markdown
Contributor Author

@greptileai

@patoperpetua
patoperpetua merged commit e0f1a05 into main Sep 9, 2026
3 checks passed
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.

Replace unsalted recipientHash with Key Vault HMAC digest

1 participant