Skip to content

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.iscoroutinefunction detects coroutine functions at decoration time.
  • An internal async_wrapper is created for coroutines; the existing sync wrapper is used otherwise.
  • Two @overload signatures 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

  • TypeError if input is not a str (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_injection by combining string type validation and dangerous pattern check into a single loop, reducing CPU overhead by ~5%.
  • Maintainability (#79): Refactored validate_project_name to 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