Skip to content

fix(rpc): redact validator private keys from call receipts and explorer payloads - #1765

Closed
kriss39 wants to merge 4 commits into
genlayerlabs:v0.123-devfrom
kriss39:fix/redact-private-keys-call-paths
Closed

kriss39 wants to merge 4 commits into
genlayerlabs:v0.123-devfrom
kriss39:fix/redact-private-keys-call-paths

Conversation

@kriss39

@kriss39 kriss39 commented Sep 14, 2026

Copy link
Copy Markdown

What

Receipt.node_config always carries the executing validator's private_key (Node._create_enhanced_node_config). #1731 added _sanitize_rpc_private_keys to the transaction/block getters, but three other paths still hand the raw receipt to the client:

  • sim_call (and therefore sim_estimateTransactionFees) returns receipt.to_dict() unredacted;
  • gen_call, eth_call and sim_call raise execution failed with data.receipt = receipt.to_dict() unredacted whenever contract execution fails;
  • the explorer REST API (/explorer/transactions*, /explorer/address/{addr}) serializes consensus_data / consensus_history verbatim, including leader_receipt[*].node_config.private_key and validators[*].node_config.private_key.

This PR:

  • moves the helpers to a small backend/protocol_rpc/redaction.py (so the explorer can use them without importing endpoints), keeping the endpoints._sanitize_rpc_private_keys name for the existing call sites;
  • applies the redaction to the sim_call result, the three execution failed error payloads and _serialize_tx;
  • adds tests/unit/protocol_rpc/test_receipt_private_key_redaction.py: sim_call result, gen_call / eth_call error data, and explorer _serialize_tx (redacted by default, shown with SHOW_VALIDATOR_PRIVATE_KEYS_IN_RPC=true, matching the fix: redact validator private keys from RPC #1731 tests).

Why

On a hosted Studio anyone can issue an anonymous sim_call against a registered validator, make any gen_call fail, or GET /explorer/transactions?limit=100, and read the validators' signing keys. SHOW_VALIDATOR_PRIVATE_KEYS_IN_RPC keeps working as the local-debug escape hatch.

Testing done

  • PYTHONPATH=. pytest tests/unit --ignore=tests/unit/test_rpc_endpoint_manager.py → 1569 passed, 7 skipped.
  • The four new negative tests fail on v0.123-dev without the backend change (the sim_call result and the error payloads contain the key; explorer node_config keeps private_key) and pass with it.
  • black / ruff clean on the touched files.

Decisions made

  • Redaction is applied at the response boundary only; the receipt object used internally (e.g. by sim_estimateTransactionFees for fee accounting) is unchanged.
  • No issue was created first (small, self-contained fix; CONTRIBUTING §3.1).

Checks

  • I have tested this code
  • I have reviewed my own PR
  • I have created an issue for this PR
  • I have set a descriptive PR title compliant with conventional commits

Reviewing tips

The diff in endpoints.py is mostly the moved helper definitions; the behavioural change is the three _sanitize_rpc_private_keys(receipt.to_dict()) wraps plus the two lines in explorer/queries.py.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 16add833-0455-484f-975d-c6e9a00c2b58

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@kriss39

kriss39 commented Sep 27, 2026

Copy link
Copy Markdown
Author

@MuncleUscles gentle ping on this one when you get a chance.

@danieljrc888

Copy link
Copy Markdown
Contributor

Thanks! Reviewed: the redaction covers exactly the paths #1731 left open (sim_call and its fee-estimate reuse, the execution-failed error data in gen_call/sim_call/eth_call, and explorer _serialize_tx), and I found no other public leak path. I merged current v0.123-dev into the branch (d0bc026e, no conflicts); tests/unit/: 1677 passed, 7 skipped. Will squash on landing.

The committee entries come from Validator.to_dict(), which includes
private_key, and _serialize_tx returned them unsanitized.
@danieljrc888

Copy link
Copy Markdown
Contributor

Correction to my earlier note: there was one more leak path. leader_timeout_validators in the explorer API (_serialize_tx) holds committee entries built from Validator.to_dict(), which includes private_key, and it was returned unsanitized.

Pushed e414e69 on top of this branch (fast-forward, no force push):

  • explorer/queries.py: wrap leader_timeout_validators in sanitize_rpc_private_keys
  • test_explorer_serialize_tx_redacts_private_keys now covers that field (fails without the fix)

Unit suite: 1677 passed, 7 skipped. Smaller non-blocking notes from review: message_handler/types.py has a near-duplicate redaction helper that could reuse redaction.py, and the env flag is re-read on every recursion step.

@danieljrc888 danieljrc888 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed for the v0.123 release candidate; unit suite and CI green.

@danieljrc888

Copy link
Copy Markdown
Contributor

/run-e2e all

Frozen landing cut: #1765 alone, head e414e69211aadd8de49eeef562e3344b0539b25e over v0.123-dev@e59ddfbaa15f19a2d856f184e3e27a30c3007cb2; no cross-repository Depends-On. Full component and stack coverage (no stack selector). Native CI is green. Merge is authorized once this E2E is green.

danieljrc888 added a commit that referenced this pull request Oct 21, 2026
Lands four reviewed fork PRs together after a full E2E run on this exact head:

- #1765: redact validator private keys from call receipts and explorer payloads
- #1715: bind postgres, redis and ollama host ports to loopback
- #1773: normalize addresses in raw-SQL balance operations
- #1789: normalize the address in sim_fundAccount

Co-authored-by: Kanan <93033289+kriss39@users.noreply.github.com>
Co-authored-by: Starling <82058629+Starling-spell@users.noreply.github.com>
Co-authored-by: Alicepoltora <Alicepoltora@users.noreply.github.com>
@danieljrc888

Copy link
Copy Markdown
Contributor

Landed in v0.123-dev via #1797 (squash 9e907cd), which combined #1765, #1715, #1773 and #1789 at their reviewed heads and passed full E2E. Your commits are credited with Co-authored-by. Thanks for the fix!

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.

2 participants