Skip to content

set_intercept_url_allowlist: support {id}/{path:path} patterns (parity with trusted_endpoints) #20

@aural-psynapse

Description

@aural-psynapse

Follow-up to #14. PR #19 added {id}/{path:path} placeholder support to is_trusted_endpoint (the trust gate). The body-hook tamper allowlist is gated by a separate code path — set_intercept_url_allowlist and the _url_allowlist matcher in interceptor.py — which is still exact-match only.

Where

# src/provably/intercept/interceptor.py:60
def set_intercept_url_allowlist(urls: list[str] | None) -> None:
    ...
    _url_allowlist = {
        normalize_url_for_trust(str(u or "").strip()) for u in urls if (u or "").strip()
    }

# src/provably/intercept/interceptor.py:265
if _url_allowlist is not None and nurl not in _url_allowlist:
    return response
...
tamper = _url_allowlist is not None and nurl in _url_allowlist

nurl in _url_allowlist is set membership on the normalized URL, so a registered https://api.example.com/customers/{id} does not match a concrete https://api.example.com/customers/42.

Impact

With trust-gate patterns + allowlist exact-match, consumers with templated routes must:

  • register patterns in trusted_endpoints (clean), AND
  • enumerate concrete URLs separately for set_intercept_url_allowlist.

Parity with the trust gate lets the same templated entries cover both.

Suggested implementation

Same syntax: {name} for one segment, {name:path} for subtree. Store registered strings as-is (do not normalize placeholders away). Matcher walks the set: exact-match first, then pattern-match. Extract the matching helper PR #19 added to trusted_endpoints.py into a shared util so both code paths use it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions