Skip to content

Configuration

phil/standard-webhooks-bundle
# config/packages/phil_standard_webhooks.yaml
phil_standard_webhooks:
    # The keys this application signs with: whsk_ (v1a) or whsec_ (v1). The first is the current one; during a
    # rotation, the others sign beside it, so that receivers that know only the old key keep accepting.
    signing_keys: ['%env(WEBHOOK_SIGNING_KEY)%']
    # The keys deliveries are verified with: whpk_ (v1a) or whsec_ (v1).
    verification_keys: ['%env(PARTNER_PUBLIC_KEY)%']
    # How many seconds a delivery's timestamp may be from the clock, either way. 300 when left out.
    tolerance: 300
    # This receiver's name: an envelope must give it as its "audience". null, the default, accepts any.
    audience: shop
    # The Doctrine connection that keeps the processed ids; null keeps them elsewhere. "default" when left out,
    # null without DoctrineBundle.
    connection: default
    # Whether deliveries may go to a loopback, private, link-local or reserved address. false when left out.
    allow_private_networks: false
    # Whether deliveries may go to an http URL rather than https only. false when left out.
    allow_plain_http: false
    # Whether deliveries may go to localhost or under .localhost, with allow_private_networks. false when left out.
    allow_localhost: false

Every key is optional: an application that only receives configures no signing key, one that only sends no verification key. Keys are read when first used, not when the container is built, so that they can come from environment variables; a key that cannot be read fails the first delivery that needs it. The verification keys are read by the first request whose controller takes a VerifiedWebhook argument, and by no other: an unreadable one answers that webhook endpoint with a server error, never another page of the application.

allow_private_networks and allow_plain_http guard the sender against server-side request forgery (sending.md). Turn them on only for receivers the application itself trusts, such as a test kernel at http://localhost with allow_localhost.

Refused at build timeMessage
A key the bundle does not knowUnrecognized option "…" under "phil_standard_webhooks"
audience: ''The audience is a name, or null to accept any
tolerance: 0Should be greater than or equal to 1

Generating keys

bin/console phil:standard-webhooks:generate-key        # v1a: whsk_… for the sender, whpk_… for the receivers
bin/console phil:standard-webhooks:generate-key v1     # v1: one whsec_… shared by the sender and one receiver

The command prints the keys once and keeps nothing: put the secret in the application's secret store.

The services

ServiceWhat it is
Phil\StandardWebhooks\WebhookReceiverPublic; over VerificationKeyProvider, the tolerance and the audience
Phil\StandardWebhooks\VerificationKeyProviderAn alias of Phil\StandardWebhooks\FixedKeys, the configured keys
Phil\StandardWebhooks\Signer, Phil\StandardWebhooks\VerifierThe library's own
Phil\StandardWebhooksBundle\Application\SigningKeysThe configured signing keys
Phil\StandardWebhooksBundle\Infrastructure\Http\WebhookSenderPublic; over the http_client service
Phil\StandardWebhooks\ProcessedWebhookRepositoryPublic; an alias of DbalProcessedWebhooks, with a connection

Keys that change

Configured keys are fixed. For keys published by a sender and fetched — a key document, a rotation without a deployment —, write a VerificationKeyProvider and alias it: the receiver then uses it, and reloads it once before refusing a delivery. The library's extension points (doc/extension-points.md of phil/standard-webhooks) show one.

# config/services.yaml
services:
    App\Webhook\PublishedKeyProvider: ~
    Phil\StandardWebhooks\VerificationKeyProvider: '@App\Webhook\PublishedKeyProvider'

The same holds for Phil\StandardWebhooks\ProcessedWebhookRepository, to keep the processed ids elsewhere.