Skip to content
Closed
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
disable the recurring loop.

### Security
- Reject non-exact integer subclasses in connection-pool count fields before
finite capacity is retained. Exact built-in integers and reviewed ASCII
decimal strings remain supported and normalize to built-in integers; callers
using custom integer subclasses must convert them deliberately before trusted
policy construction.
- Require the request timeout policy to use the exact `EgressTimeoutPolicy` type
during trusted construction. Timeout-policy subclasses are rejected before
transport dispatch can dynamically invoke an overridden `as_httpcore_timeout()`,
Expand Down
7 changes: 7 additions & 0 deletions docs/research/connection-pool-resource-limits.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ an exact `EgressConnectionPoolPolicy` with different documented field values
instead. This boundary does not claim EgressWeave sandboxes arbitrary Python
code already executing inside the embedding process.

Count fields accept only exact built-in integers when callers use the integer
form; the reviewed ASCII decimal-string form remains supported and normalizes to
exact integers, while integer subclasses are rejected before finite pool-capacity
values are retained. This supported configuration-integrity boundary
does not make EgressWeave a Python sandbox for arbitrary code already running in
the host process.

`max_connections` must be a positive integer or ASCII decimal string.
`max_keepalive_connections` may be zero to retain no idle connections but must
not exceed total capacity. `keepalive_expiry_seconds` must be a finite
Expand Down
2 changes: 1 addition & 1 deletion src/egressweave/connection_pool_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def _normalize_connection_count(
"""Return one exact ASCII-compatible connection-count limit."""
if isinstance(value, bool):
raise TypeError(f"{field_name} must be an integer or ASCII decimal string")
if isinstance(value, int):
if type(value) is int:
normalized = value
elif isinstance(value, str):
if not value or not value.isascii() or not value.isdecimal():
Expand Down
27 changes: 27 additions & 0 deletions tests/test_connection_pool_count_value_documentation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""Documentation contracts for exact connection-pool count value types."""

from __future__ import annotations

from pathlib import Path

REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
POOL_GUIDE_PATH = (
REPOSITORY_ROOT / "docs" / "research" / "connection-pool-resource-limits.md"
)
CHANGELOG_PATH = REPOSITORY_ROOT / "CHANGELOG.md"


def test_connection_pool_guide_documents_exact_builtin_count_values() -> None:
"""Keep operator guidance aligned with the primitive-value integrity boundary."""
guide = POOL_GUIDE_PATH.read_text(encoding="utf-8")

assert "Count fields accept only exact built-in integers" in guide
assert "integer subclasses are rejected" in guide
assert "does not make EgressWeave a Python sandbox" in guide


def test_changelog_records_connection_count_value_sealing() -> None:
"""Record the pre-1.0 primitive-value tightening in release history."""
changelog = CHANGELOG_PATH.read_text(encoding="utf-8")

assert "Reject non-exact integer subclasses in connection-pool count fields" in changelog
41 changes: 41 additions & 0 deletions tests/test_connection_pool_count_value_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Security contracts for exact connection-pool count value types."""

from __future__ import annotations

import pytest

from egressweave import EgressConnectionPoolPolicy


class _ConnectionCountSubclass(int):
"""Represent an unreviewed integer subclass crossing trusted configuration."""


@pytest.mark.parametrize(
"field_name",
["max_connections", "max_keepalive_connections"],
)
def test_connection_pool_policy_rejects_integer_subclasses(field_name: str) -> None:
"""Reject non-exact integers before retaining finite pool-capacity values."""
with pytest.raises(TypeError, match=field_name):
EgressConnectionPoolPolicy(
**{field_name: _ConnectionCountSubclass(1)} # type: ignore[arg-type]
)


def test_connection_pool_policy_keeps_reviewed_count_input_forms() -> None:
"""Continue accepting exact integers and reviewed ASCII decimal strings."""
exact_integer = EgressConnectionPoolPolicy(
max_connections=8,
max_keepalive_connections=2,
)
decimal_string = EgressConnectionPoolPolicy(
max_connections="8",
max_keepalive_connections="2",
)

assert type(exact_integer.max_connections) is int
assert type(exact_integer.max_keepalive_connections) is int
assert decimal_string == exact_integer
assert type(decimal_string.max_connections) is int
assert type(decimal_string.max_keepalive_connections) is int
Loading