Skip to content

fix: key separation, audit coverage, tenant store semantics - #7

Merged
dickyibrohim merged 1 commit into
mainfrom
fix/key-separation-audit-tenant
Mar 29, 2026
Merged

fix: key separation, audit coverage, tenant store semantics#7
dickyibrohim merged 1 commit into
mainfrom
fix/key-separation-audit-tenant

Conversation

@dickyibrohim

Copy link
Copy Markdown
Owner

Summary

  • Security: derive audit HMAC key and tenant master key via HKDF instead of reusing raw master key bytes. Wire in the existing derive_audit_key() that was never called.
  • Security: add audit event emission to deterministic encrypt/decrypt paths (previously only randomized paths were audited).
  • Bug fix: InMemoryKeyRepository::store_tenant_key now returns Ok(()) for existing active keys, matching PostgreSQL ON CONFLICT DO NOTHING semantics.
  • Eliminate redundant lock pattern in TenantKeyManager::get_tenant_key.
  • Add Vault::decrypt_stream_with_version for explicit DEK version control.
  • Add defensive u32 overflow guard in stream encryption chunk count.
  • 20 new integration tests with end-to-end production simulation.

Bump version to 0.1.1.

Test plan

  • cargo test --workspace — 370 tests pass (350 unit + 20 new)
  • cargo clippy --all-targets --all-features -- -D warnings — 0 warnings
  • cargo fmt --all -- --check — pass
  • cargo doc --no-deps --all-features — pass
  • Key separation verified: audit key ≠ master key ≠ tenant key
  • Deterministic encrypt/decrypt audit events verified via InMemoryAuditSink
  • Concurrent tenant key access (100 tasks) — no deadlock
  • Full e2e: encrypt, decrypt, blind index, streaming, tenant, crypto-shredding, audit chain integrity

Security:
- Derive audit HMAC key and tenant master key via HKDF with
  domain-separated info strings instead of reusing raw master key
  bytes. The existing derive_audit_key() was already written but
  never wired into the Vault builder.
- Add audit event emission to encrypt_field_deterministic and
  decrypt_field_deterministic. Previously only the randomized
  encrypt/decrypt paths were audited.

Bug fix:
- InMemoryKeyRepository::store_tenant_key now returns Ok(()) when
  a tenant key already exists (matching PostgreSQL ON CONFLICT DO
  NOTHING), instead of erroneously returning TenantAlreadyErased.

Improvements:
- TenantKeyManager::get_tenant_key: eliminate redundant lock-drop-
  relock pattern. Clone wrapped_key under single lock acquisition.
- Add Vault::decrypt_stream_with_version for explicit DEK version.
- Add defensive u32 overflow guard in encrypt_stream chunk count.
- Add 20 integration tests covering all changes with e2e production
  simulation.

Bump version to 0.1.1.
@dickyibrohim
dickyibrohim merged commit 91b0a48 into main Mar 29, 2026
8 checks passed
@dickyibrohim
dickyibrohim deleted the fix/key-separation-audit-tenant branch March 29, 2026 03:54
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