Skip to content

Recommend {443, 8443} as the hardened destination-port allowlist for webhook delivery #3557

@bokelley

Description

@bokelley

Background

pushNotificationConfig.url ports are unconstrained per the spec (see adcontextprotocol/adcp#3555 for the clarification request). Publisher SDKs implementing defense-in-depth against destination-port smuggling (a buyer URL like https://internal.example.com:6379/ smuggling traffic to internal Redis) need to know what port set is operationally safe to allowlist.

The Python SDK exports adcp.signing.DEFAULT_ALLOWED_PORTS = frozenset({443, 8443}) as the recommended set for operators who opt in to hardening. Without a spec recommendation, other SDKs will pick different sets and adopters running mixed-language deployments will hit interop issues.

Why it matters

Webhook receivers in production typically run on:

  • :443 — canonical HTTPS
  • :8443 — HTTPS-alt (IANA-registered)
  • :9443 — Tomcat default
  • :4443 — Spring Boot default
  • Custom ports for path-routed multi-tenant gateways

Of these, {443, 8443} are the standardized values. The non-standard ones (:9443, :4443, custom) are tooling defaults, not protocol values. A spec recommendation of {443, 8443} lets SDKs converge while operators with non-standard deployments keep the opt-out.

Proposed fix

Add a paragraph to docs/building/implementation/security.mdx#webhook-callbacks:

Recommended destination-port allowlist (hardened deployments). AdCP does not constrain pushNotificationConfig.url ports in the schema (#3555). Operators who want defense in depth against destination-port smuggling SHOULD allowlist {443, 8443} — the standard HTTPS and HTTPS-alt ports — and reject buyer URLs targeting other ports. Tomcat / Spring Boot / custom gateway deployments on non-standard TLS ports are legitimate; operators serving such buyers either widen the allowlist explicitly or remove it entirely. The choice is operator policy, not protocol. SDKs SHOULD expose this as an opt-in kwarg on the webhook-sender constructor.

Why now

The Python SDK ships DEFAULT_ALLOWED_PORTS = frozenset({443, 8443}) in adcp.signing. A spec recommendation lets the TS SDK and any third-party SDK converge on the same set without each picking different defaults.

Depends on #3555 being resolved (port-unconstrained clarification).

Surfaced by Python SDK foundation audit on adcp-client-python#297.

Metadata

Metadata

Assignees

No one assigned

    Labels

    claude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions