Skip to content

lookup: hex-decode SALT_PKB before HMAC (AGG-117)#7

Merged
anthrax63 merged 1 commit into
mainfrom
agent/cto/a45a5f54
Jul 2, 2026
Merged

lookup: hex-decode SALT_PKB before HMAC (AGG-117)#7
anthrax63 merged 1 commit into
mainfrom
agent/cto/a45a5f54

Conversation

@anthrax63

Copy link
Copy Markdown
Member

Summary

  • vaultee-secrets returns SALT_PKB as an ASCII hex string; LookupService._salt_pkb was passing that through to hmac.new as the raw key. Rebuild-encrypt in DDM (pkb_beeline/scripts/encrypt/main.py::read_hex_secret) decodes it via bytes.fromhex. Different keys → every lookup missed the replica → 30-sec client timeout.
  • Fixed by hex-decoding the ASCII response before HMAC.
  • Added regression test that pins: LookupService's row_id_iin == rebuild-time HMAC over decoded salt bytes, and ≠ the buggy path.

Root cause verification

For real IIN 700205302324 from datalab_test.user_features_test:

  • Rebuild-encrypt formula (correct): hmac(bytes.fromhex(SALT_PKB), sha256hex(iin || iin_salt), sha256) = 81c9417ac6eabf47… — matches the row actually stored in aggregion.scoring_replica_pkb.
  • API pre-fix formula: hmac(SALT_PKB_hex.utf8, sha256hex(iin || iin_salt), sha256) = 92e49785e452a484… — this is exactly what DDM logs showed the API passing as row_id_iin for the failing run 5018c464-6e18-4d50-8277-5a67fcca90bb.

Test plan

  • pytest tests/ locally — 51/51 pass, including new tests/test_salt_decoding.py.
  • CI green (docker image build & push to selcloud registry).
  • Bump image tag in kartel-deploy prod overlay → Argo sync → /single?iin=700205302324 returns 200 with data (currently 408).

🤖 Generated with Claude Code

vaultee-secrets returns SALT_PKB as an ASCII hex string (64 chars for a
32-byte salt). rebuild-encrypt in DDM decodes it via bytes.fromhex before
using it as the HMAC key (pkb_beeline/scripts/encrypt/main.py::
read_hex_secret). LookupService was passing the raw ASCII response
through to hmac.new, producing a different key and every lookup missed
the replica.

Verified by comparing what the API sent to DDM (`row_id_iin=92e49785…`)
to what rebuild-encrypt would write for the same IIN under the decoded
salt (`row_id_iin=81c9417a…`), and confirming the latter exists in
aggregion.scoring_replica_pkb for real IINs from user_features_test.

Fixture change: FakeSecrets now models the real vaultee-secrets shape
(returns hex-string bytes, exposes decoded salt_bytes for assertions).
Added tests/test_salt_decoding.py to pin the regression — asserts that
the row_id_iin sent by LookupService equals the one rebuild-time HMAC
produces over the *decoded* salt, and that the buggy path (raw hex bytes
as HMAC key) produces a different value.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
@anthrax63 anthrax63 merged commit 9c6e51b into main Jul 2, 2026
3 checks passed
@anthrax63 anthrax63 deleted the agent/cto/a45a5f54 branch July 2, 2026 07:16
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