Commit Graph

4 Commits

Author SHA1 Message Date
Matthew Meszaros b9a5871308 feat: key the cipher service by organization ID
cipher.CipherService.Cipher(ctx, orgID) now resolves, generates, and
caches DEKs per organization (Redis key decrypted_key:<orgID>).
Platform-level secrets keep the zero-UUID identity, renamed to
platformCipherID since it no longer partitions against user keys.
2026-06-10 17:16:26 +02:00
Matthew Meszaros 99226338c9 infra(encryptedkeys): pluggable DEK store with HTTP proxy for workers
New encryptedkeys.Store interface with three impls:

  postgres  - backend default, durable via PG
  dynamodb  - existing AWS path, also covers Scylla Alternator via
              AWS_ENDPOINT_URL_DYNAMODB
  http      - worker-side adapter that talks to the backend's new
              /api/v1/internal/dek/:userID endpoint, so workers never
              connect directly to Postgres

The HTTP endpoint sits behind a new InternalAuthMiddleware that does
constant-time bearer-token compare against INTERNAL_API_TOKEN. Fail-
closed if the env var is unset.

cipher.Service now takes an encryptedkeys.Store instead of a Dynamo
repository. The old internal/repository/dynamo_user_encrypted_keys.go
is deleted (the file also had a pre-existing copy-paste bug using
EmailMessageMapTable in Get/Del that's gone with it).

New migration 38 adds user_encrypted_keys (user_id PK, encrypted_data_key,
created_at, updated_at).

20 tests cover HTTP round-trip, conflict semantics, factory selection,
middleware auth (fail-closed / wrong-scheme / timing-safe / happy path),
and DEK handler responses through gin's test harness.
2026-05-27 14:42:11 +00:00
Matthew Meszaros 7fe8e663d5 fix: propagate parent context instead of context.TODO in cipher service
The ctx parameter was already available from the Cipher method but
wasn't being passed to the DynamoDB Put call for new DEK storage.
2026-04-09 12:06:54 +00:00
Matthew Meszaros 772c19820d New Repository: Add Backend Code 2026-01-17 14:11:14 +00:00