NAME

SignalWire::Security::WebhookMiddleware - Plack middleware enforcing SignalWire webhook signatures

SYNOPSIS

use SignalWire::Security::WebhookMiddleware;

my $wrapped = SignalWire::Security::WebhookMiddleware->wrap(
    app         => $psgi_app,
    signing_key => $ENV{SIGNALWIRE_SIGNING_KEY},
    paths       => [ '/', '/swaig', '/post_prompt' ],
    trust_proxy => 1,
);

DESCRIPTION

Wraps a PSGI app so that incoming POST requests must carry a valid X-SignalWire-Signature header (or the legacy X-Twilio-Signature) matching the configured signing key. Invalid or missing signatures produce a 403 without ever invoking the wrapped app.

The raw body is captured before validation and stashed on the env as signalwire.raw_body; psgi.input is rewound (or replaced with a buffer) so downstream handlers can re-read.

OPTIONS

app

PSGI coderef. Required.

signing_key

The customer's Signing Key from the SignalWire Dashboard. If empty, the middleware is a passthrough (AgentBase logs a startup warning in that case).

paths

Optional arrayref of paths to gate. When set, only those paths require a signature; other paths pass through unchecked.

methods

Arrayref of HTTP methods to gate. Defaults to ['POST'].

trust_proxy

Honor X-Forwarded-Proto / X-Forwarded-Host when reconstructing the public URL. Default true.

public_url_base

Hard-override the URL base (e.g. for tests). Takes precedence over everything else.