Repository navigation
fix(records): withhold personal credentials over Tor (#131) - #134
JordanCoin wants to merge 2 commits into
Conversation
With network.tor on, the route notice said "real IP hidden" while OPENFOIA_MUCKROCK_TOKEN, OPENFOIA_NARA_API_KEY and the OPENFOIA_GOVINFO_API_KEY env fallback still went out with each request and named the user to the server. RecordAdapter._personal_credential() now returns None over Tor and sets credentials_withheld. MuckRock (token optional), NARA (key required) and DataGovAdapter (govinfo, fec, regulations; falls back to DEMO_KEY) resolve their credential through it in the constructor, so every path is covered, not only get_adapter. get_adapter no longer special-cases Tor. NARA over Tor: has_key is False, `records search/fetch -s nara` exit with a message that the personal key would identify you, --all-sources lists it as skipped. The route line gains ", credentials withheld" when an adapter held one back. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWQw8DDrDZ2tFzswSSEtce
The key is tied to an account and named the user even with the real IP hidden. Over Tor the request goes keyless and a 401/403 reports the key as withheld rather than missing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FWQw8DDrDZ2tFzswSSEtce
|
Review (Claude opus reviewer, read-only, 2026-11-06): FIX FIRST, then MERGE. Enumerated every credential source: config api.data.gov key, OPENFOIA_GOVINFO_API_KEY, OPENFOIA_MUCKROCK_TOKEN, OPENFOIA_NARA_API_KEY/CATALOG_API_KEY all withheld over Tor on every construction path (explicit arg, env, config); no |
Closes #131
With
network.tor: true, personal credentials no longer leave the machine.RecordAdapter._personal_credential()(records/base.py) returns None over Tor and setscredentials_withheld. MuckRock, NARA andDataGovAdapterresolve their credential through it in the constructor, so every caller is covered,get_adapterincluded.get_adapterno longer special-cases Tor.Authorizationtoken over Tor.DEMO_KEYover Tor even withOPENFOIA_GOVINFO_API_KEYset andapi_key=None.has_keyis False over Tor.records search -s nara/records fetch -s naraexit 1 with "NARA Catalog API needs your personal API key, which would identify you, so NARA is not used over Tor."--all-sourcesshowsskipped (personal key not sent over Tor). Direct mode is unchanged.via Tor, real IP hidden, credentials withheldwhen an adapter held one back (search, search --all-sources, fetch, download).The crossref Tor DEMO_KEY guard is unchanged. It is now redundant but harmless.
test_records_nara.py::test_objects_use_the_configured_tor_policyasserted thatfetch -s nara --objectsran over Tor. That fetch sends the key, so the test now asserts it exits before any request.Tests: per-adapter MockTransport checks for TOR and DIRECT in
tests/test_security_egress_adapters.py. The CLI exit and route-line tests are intests/test_security_egress_cli.pybecause thetor_recordsfixture lives there. Full suite: 592 passed. The 2TestLLMExtractionfailures need Ollama and were already failing.🤖 Generated with Claude Code
https://claude.ai/code/session_01FWQw8DDrDZ2tFzswSSEtce