Goal
Bring 4 standalone security utilities from the TypeScript SDK into the Python SDK. These were identified during the cross-SDK alignment audit — TypeScript has them, Python does not.
Why
The TypeScript SDK includes security hygiene utilities that protect against credential leaks and enable reusable validation checks. Python either lacks the functionality entirely or has it locked inside a monolithic function that can't be called independently.
Gaps
1. filter_sensitive_headers(headers: dict) -> dict
What TS does: Strips authorization, cookie, x-api-key, proxy-authorization, set-cookie headers from a header dict before passing to user callbacks.
Where TS uses it: AgentBase.ts:1661 — called before every user callback that receives request headers.
Python today: Nothing. Python passes raw request headers straight to user handlers with no filtering. Grep across the entire Python codebase confirmed zero equivalent (filter_sensitive_headers, redact.*header, header.*filter, sensitive.*header — no matches).
Impact: Medium — security hygiene. User callback handlers receive auth tokens they shouldn't see.
Fix: Add filter_sensitive_headers() to utils/ or a new security.py. Wire it into the agent handler code path before user callbacks.
2. redact_url(url: str) -> str
What TS does: Replaces ://user:secret@host with ://user:****@host before logging.
Where TS uses it: AgentBase.ts:1828 — called before logging proxy URLs.
Python today: Nothing. Python logs proxy URLs with full user:password@host credentials visible. Grep confirmed zero equivalent (redact_url, redact.*url, url.*redact, mask.*url — no matches).
Impact: Medium — credentials leak into Python logs.
Fix: Add redact_url() to utils/. Wire into logging paths that output proxy URLs.
3. is_valid_hostname(host: str) -> bool
What TS does: Standalone check — rejects whitespace, slashes, control chars in hostname strings.
Where TS uses it: AgentBase.ts:1186 — called independently (not as part of full URL validation).
Python today: The logic exists inside validate_url() at utils/url_validator.py:34, but it's bundled — you can't call hostname validation without running full URL validation (DNS resolution, private-IP blocking, scheme checks). Not exported standalone.
Impact: Low — logic exists but isn't reusable. Callers that only need hostname validation must either duplicate the check or run the full URL validator unnecessarily.
Fix: Extract the hostname-validation logic from validate_url() into a standalone is_valid_hostname() export in utils/url_validator.py.
4. is_private_ip(ip: str) -> bool
What TS does: Standalone check — detects RFC1918, loopback, link-local, IPv6 private ranges.
Where TS uses it: Inside resolveAndValidateUrl (same module as #3).
Python today: The logic exists inside validate_url() via the _BLOCKED_NETWORKS list — same bundled situation as #3. Not exported standalone.
Impact: Low — logic exists but isn't reusable.
Fix: Extract from validate_url() into a standalone is_private_ip() export in utils/url_validator.py.
Reference
Goal
Bring 4 standalone security utilities from the TypeScript SDK into the Python SDK. These were identified during the cross-SDK alignment audit — TypeScript has them, Python does not.
Why
The TypeScript SDK includes security hygiene utilities that protect against credential leaks and enable reusable validation checks. Python either lacks the functionality entirely or has it locked inside a monolithic function that can't be called independently.
Gaps
1.
filter_sensitive_headers(headers: dict) -> dictWhat TS does: Strips
authorization,cookie,x-api-key,proxy-authorization,set-cookieheaders from a header dict before passing to user callbacks.Where TS uses it:
AgentBase.ts:1661— called before every user callback that receives request headers.Python today: Nothing. Python passes raw request headers straight to user handlers with no filtering. Grep across the entire Python codebase confirmed zero equivalent (
filter_sensitive_headers,redact.*header,header.*filter,sensitive.*header— no matches).Impact: Medium — security hygiene. User callback handlers receive auth tokens they shouldn't see.
Fix: Add
filter_sensitive_headers()toutils/or a newsecurity.py. Wire it into the agent handler code path before user callbacks.2.
redact_url(url: str) -> strWhat TS does: Replaces
://user:secret@hostwith://user:****@hostbefore logging.Where TS uses it:
AgentBase.ts:1828— called before logging proxy URLs.Python today: Nothing. Python logs proxy URLs with full
user:password@hostcredentials visible. Grep confirmed zero equivalent (redact_url,redact.*url,url.*redact,mask.*url— no matches).Impact: Medium — credentials leak into Python logs.
Fix: Add
redact_url()toutils/. Wire into logging paths that output proxy URLs.3.
is_valid_hostname(host: str) -> boolWhat TS does: Standalone check — rejects whitespace, slashes, control chars in hostname strings.
Where TS uses it:
AgentBase.ts:1186— called independently (not as part of full URL validation).Python today: The logic exists inside
validate_url()atutils/url_validator.py:34, but it's bundled — you can't call hostname validation without running full URL validation (DNS resolution, private-IP blocking, scheme checks). Not exported standalone.Impact: Low — logic exists but isn't reusable. Callers that only need hostname validation must either duplicate the check or run the full URL validator unnecessarily.
Fix: Extract the hostname-validation logic from
validate_url()into a standaloneis_valid_hostname()export inutils/url_validator.py.4.
is_private_ip(ip: str) -> boolWhat TS does: Standalone check — detects RFC1918, loopback, link-local, IPv6 private ranges.
Where TS uses it: Inside
resolveAndValidateUrl(same module as #3).Python today: The logic exists inside
validate_url()via the_BLOCKED_NETWORKSlist — same bundled situation as #3. Not exported standalone.Impact: Low — logic exists but isn't reusable.
Fix: Extract from
validate_url()into a standaloneis_private_ip()export inutils/url_validator.py.Reference
src/SecurityUtils.tssignalwire/utils/url_validator.pytemp/sdk-alignment/validated/typescript/__functions__VALIDATED_REPORT.mdin the docs repo