Validates that an incoming webhook request genuinely originated from Treasury Prime.
Treasury Prime doesn't use HMAC request signing. Instead, validation is
configured per-TreasuryPrime.Webhook object via a basic_user /
basic_secret pair you choose when creating the webhook (see
TreasuryPrime.Webhook.create/3). When set, every notification sent to
that webhook's URL includes an Authorization header equal to
"Basic " <> Base.encode64("#{basic_user}:#{basic_secret}") — i.e. the
exact same shape as the header you send when authenticating your
requests to Treasury Prime, just compared in the other direction.
Usage
defmodule MyAppWeb.TreasuryPrimeWebhookController do
use MyAppWeb, :controller
@basic_user "myapp"
@basic_secret System.fetch_env!("TREASURY_PRIME_WEBHOOK_SECRET")
def create(conn, params) do
header = conn |> Plug.Conn.get_req_header("authorization") |> List.first()
if TreasuryPrime.WebhookSignature.valid?(header, @basic_user, @basic_secret) do
event = TreasuryPrime.WebhookEvent.parse!(params)
MyApp.Webhooks.handle(event)
send_resp(conn, 200, "")
else
send_resp(conn, 401, "")
end
end
endComparison is done in constant time to avoid leaking information about the expected secret through response-time side channels.
Summary
Functions
Returns true if authorization_header (the raw value of the incoming
request's Authorization header, with or without a leading "Basic ")
matches the expected value for the given basic_user/basic_secret pair
configured on the TreasuryPrime.Webhook object.
Functions
Returns true if authorization_header (the raw value of the incoming
request's Authorization header, with or without a leading "Basic ")
matches the expected value for the given basic_user/basic_secret pair
configured on the TreasuryPrime.Webhook object.
Returns false (never raises) for nil, malformed, or mismatched input —
safe to call directly on a possibly-missing header.