Redact API keys and tokens from morpc.req logs and errors - #207
Merged
Merged
Conversation
Request URLs and parameter dicts were logged and put in exception messages as-is, so the Census API key (key=) ended up in notebook outputs. Add redact(), which replaces key, token, and api_key values with REDACTED, and use it wherever req.py logs or raises with a URL or parameters, plus the one rest_api log of a returned URL. get_file_safely re-raises requests' HTTPError with a redacted message, since requests includes the full URL. Fixes #206. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 24, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #206.
Change
morpc.req.redact(value): replaces the values of thekey,token, andapi_keyquery parameters (case-insensitive) withREDACTEDin a URL string or a parameter dict. It's public so other packages (e.g. morpc-census) can reuse it.morpc/req.pythat includesurl,r.url, orparamsnow goes throughredact(). That coversget_text_safely,get_json_safely,get_file_safely,post_safely, anddelete_safely.get_file_safelycatchesraise_for_status()'sHTTPErrorand re-raises it with a redacted message (from None, so the original message doesn't appear in the traceback), becauserequestsputs the full URL in that message.get_text_safelynow raisesHTTPErrorwith a message (redacted URL) andresponse, instead of a bareHTTPError.rest_api._max_record_countredacts the URL it logs.Requests themselves are unchanged; only what gets logged or raised is redacted.
Testing
tests/test_req.py. With a secretkey/tokenin the URL or params, each checks that the secret is absent from captured logs at DEBUG level and from the exception message. Paths covered:get_json_safely(204, 400, 404, success, JSON decode error),get_text_safely, andget_file_safely. There's also a unit test forredact(). All 8 failed before the change.test_req(11),test_frictionless,test_gpkg,test_morpc,test_release, andtest_geocodeall pass.test_utils: the same 4 datetime tests fail onmain.Not covered here
geoinfo_from_params; see Census API key leaks into INFO logs from geoinfo_from_params morpc-census#7.🤖 Generated with Claude Code