TaipanStack v0.3.3 — Security & Resilience Patch¶
Overview¶
v0.3.3 is a patch release that deepens TaipanStack's security posture and resilience primitives while remaining 100% backwards compatible. It delivers SSRF protection, native async support in @safe, automatic structured logging for retries and circuit breaker state changes, expanded mutation coverage, and a new security patterns guide in the docs.
1. Async Support in @safe¶
File: src/taipanstack/core/result.py
The @safe decorator now transparently handles async def functions.
from taipanstack.core.result import safe
@safe
async def fetch_data(url: str) -> bytes:
async with httpx.AsyncClient() as client:
r = await client.get(url)
r.raise_for_status()
return r.content
result = await fetch_data("https://example.com")
match result:
case Ok(data): print(f"Got {len(data)} bytes")
case Err(exc): print(f"Error: {exc}")
What Changed¶
inspect.iscoroutinefunctiondetects coroutine functions at decoration time.- An internal
async_wrapperis created for coroutines; the existing syncwrapperis used otherwise. - Two
@overloadsignatures ensure mypy/pyright return the correct coroutine type. - Fully backwards-compatible — all existing sync usages are unaffected.
2. SSRF Protection (guard_ssrf)¶
File: src/taipanstack/security/guards.py
New guard_ssrf(url) enforces network-level SSRF protection at the perimeter.
from taipanstack.security.guards import guard_ssrf
result = guard_ssrf("http://169.254.169.254/latest/meta-data/")
# → Err(SecurityError("[ssrf] SSRF detected: hostname '169.254.169.254' resolves to private/reserved address 169.254.169.254"))
result = guard_ssrf("https://api.example.com/v1/data")
# → Ok("https://api.example.com/v1/data")
Blocked Ranges¶
| Network | Purpose |
|---|---|
10.0.0.0/8 |
RFC-1918 Class A |
172.16.0.0/12 |
RFC-1918 Class B |
192.168.0.0/16 |
RFC-1918 Class C |
169.254.0.0/16 |
Link-local / AWS EC2 metadata |
127.0.0.0/8 |
Loopback |
::1/128 |
IPv6 loopback |
fc00::/7 |
IPv6 unique local (ULA) |
fe80::/10 |
IPv6 link-local |
Contract¶
TypeErrorif input is not astr(developer contract violation).Err(SecurityError)for all detected SSRF attempts (domain error — no exceptions raised).Ok(url)if the URL is safe to fetch.
3. Automatic Structlog Integration¶
Files: src/taipanstack/utils/retry.py, src/taipanstack/utils/circuit_breaker.py
When structlog is installed and no manual callback is provided, structured events are now emitted automatically:
Retry¶
{
"event": "retry_attempted",
"function": "call_payment_api",
"attempt": 1,
"max_attempts": 3,
"error": "Connection refused",
"delay_seconds": 1.0
}
Circuit Breaker¶
{
"event": "circuit_state_changed",
"circuit": "payment_gateway",
"old_state": "closed",
"new_state": "open",
"failure_count": 5
}
When on_retry or on_state_change callbacks are explicitly set, the auto-log is suppressed — full backwards compatibility maintained.
4. Expanded Mutation Testing¶
File: pyproject.toml
[tool.mutmut]
paths_to_mutate = "src/taipanstack/security/sanitizers.py,src/taipanstack/security/validators.py,src/taipanstack/security/guards.py"
tests_dir = "tests/test_property_sanitizers.py,tests/test_security_validators.py,tests/test_security_guards.py,tests/test_security_ssrf.py"
The mutation testing surface grows from 1 file to 3, covering the entire security module.
5. Security Patterns Documentation¶
File: docs/patterns/security.md
New practical guide with three FastAPI-based examples showing how to combine @safe, guard_ssrf, guard_path_traversal, and @retry for end-to-end defence-in-depth.
6. Performance & Refactoring¶
Files: src/taipanstack/security/validators.py, src/taipanstack/security/guards.py
- Performance (#80): Optimized
guard_command_injectionby combining string type validation and dangerous pattern check into a single loop, reducing CPU overhead by ~5%. - Maintainability (#79): Refactored
validate_project_nameto dramatically reduce complexity. The single large method was decomposed into smaller, independent validation helpers, significantly improving code health and readability.
7. CI / Cross-Platform Fixes¶
Several fixes were applied to ensure the CI pipeline passes on all platforms (Ubuntu, macOS, Windows, Alpine, Arch, Fedora, openSUSE) and all Python versions (3.11–3.14):
| Fix | Detail |
|---|---|
Windows sys.executable |
Tests that called get_command_version(sys.executable) failed on Windows because the absolute path is not in the security whitelist. Changed to use command name "python". |
| Mypy strict | Reordered @overload signatures in result.py, removed stale # type: ignore comments in circuit_breaker.py and retry.py. |
| Ruff lint | Fixed ARG001, D401, PLC0415 in docs/overrides/hooks.py. Removed loose benchmark scripts from project root. |
| Ruff format | Applied auto-format to 4 test files with inconsistent line wrapping. |
Quality Summary¶
| Metric | v0.3.2 | v0.3.3 |
|---|---|---|
| Test Coverage | 100% | 100% |
Async @safe |
❌ | ✅ |
| SSRF Guard | ❌ | ✅ |
| Auto Structlog | ❌ | ✅ |
| Mutation Files | 1 | 3 |
| Perf Optimizations | 0 | 1 |
| Breaking Changes | 0 | 0 |