Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

RFC: Dual webhook signatures for migrating signature schemes

Aperta
#1,068 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
35/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
go

Direzione di ricerca

Start by reviewing the RFC’s proposed compat signature configuration and migration flows, then examine the existing default webhook signature behavior; the issue does not name implementation files or tests. The first scope is default webhook mode, with a migration guide also required. Done means the RFC’s open naming and design questions are resolved and the proposed behavior and scope are agreed.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

Let a deployment send two webhook signature formats on the same request for a transition period. Operators can then move to Outpost from a webhook system they built themselves or from another provider, or change signature schemes, without breaking receivers' verification code.

Motivation

A receiver's verification code is coupled to the signature format: header names, signed content, encoding, key derivation. Two cases change that format for existing receivers:

  1. Changing the scheme of a running deployment, e.g. moving from a custom template to a different one, or renaming headers.
  2. Moving to Outpost from a previous webhook system, self-built or another provider. Receivers verify that system's headers. Outpost sends its own.

Today both are hard cutovers. Every receiver has to deploy new verification code at the moment the operator flips the config.

Approach

Add a second, optional set of webhook signature config. If it is set, Outpost signs each request twice and sends both sets of headers: the primary signature as today, plus the second one built from the alternative config. If it isn't set, nothing changes.

The second set takes the same options as the primary signature (header name, content template, header template, encoding, algorithm). When configured, it applies to every webhook destination in the deployment, until the operator removes the config.

Naming

The second config set needs a name. Options:

  • DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_HEADER_NAME
  • DESTINATIONS_WEBHOOK_LEGACY_SIGNATURE_HEADER_NAME
  • DESTINATIONS_WEBHOOK_ALT_SIGNATURE_HEADER_NAME
  • DESTINATIONS_WEBHOOK_SIGNATURE_HEADER_NAME_COMPAT (suffix form)
  • DESTINATIONS_WEBHOOK_SIGNATURE_HEADER_NAME_1 (numbered)

The rest of this RFC uses COMPAT as a prefix group (destinations.webhook.compat.* in YAML). The mechanism doesn't depend on the term, and feedback on it is welcome.

Proposal

The second signature set is called the compat signature below.

Operator config
Key Description
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_HEADER_NAME Name of the compat signature header. Setting it enables the feature.
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_CONTENT_TEMPLATE Same semantics as SIGNATURE_CONTENT_TEMPLATE
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_HEADER_TEMPLATE Same semantics as SIGNATURE_HEADER_TEMPLATE
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_ENCODING hex | base64
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_ALGORITHM e.g. hmac-sha256
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_SECRET_ENCODING How the HMAC key is derived from the stored secret: raw (default) | base64 | hex
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_SECRET_PREFIX Prefix stripped from the secret before decoding, e.g. whsec_
DESTINATIONS_WEBHOOK_COMPAT_HEADERS Comma-separated name=template pairs (same shape as OTEL_EXPORTER_OTLP_HEADERS, \, for a literal comma), for companion headers the other scheme requires (ID, timestamp). A plain map in YAML config.

Both signatures use the same destination secret (including previous_secret during rotation) and the same timestamp. Receivers keep their existing secret.

Two of these options are new capabilities:

  • Secret encoding/prefix. The default mode uses the secret string as the HMAC key. Other schemes base64-decode it after a prefix. Without this, one secret can't serve both schemes. For symmetry, the same two options are added to the primary signature (DESTINATIONS_WEBHOOK_SIGNATURE_SECRET_ENCODING / _SECRET_PREFIX).
  • Compat headers. If the previous signature covered values sent in other headers (an event ID, a timestamp in a different format), receivers read those headers to verify it. Compat headers reproduce them under the names and formats receivers expect. Templates receive the same fields as the signature content template, minus the body.
Example: compat signature in Standard Webhooks format
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_HEADER_NAME=webhook-signature
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_CONTENT_TEMPLATE={{.EventID}}.{{.Timestamp.Unix}}.{{.Body}}
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_HEADER_TEMPLATE=v1,{{index .Signatures 0}}{{range slice .Signatures 1}} v1,{{.}}{{end}}
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_ENCODING=base64
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_SECRET_ENCODING=base64
DESTINATIONS_WEBHOOK_COMPAT_SIGNATURE_SECRET_PREFIX=whsec_
DESTINATIONS_WEBHOOK_COMPAT_HEADERS=webhook-id={{.EventID}},webhook-timestamp={{.Timestamp.Unix}}

Migration flows

Changing the signature scheme of a running deployment

  1. Copy the current signature settings to the COMPAT_* keys.
  2. Set the new primary scheme. Every request now carries both.
  3. Announce a sunset date. Receivers switch verification.
  4. At sunset, remove the COMPAT_* keys.

Moving to Outpost from a previous webhook system

  1. Set COMPAT_* to the previous scheme.
  2. Create a destination per existing endpoint with its current secret.
  3. Every request carries both signatures until the operator removes the compat config.

Not in scope

Two additions came up during review and are left out until there is a need for them:

  • Limiting which destinations receive it, by a creation cutoff timestamp or a per-destination setting. Open as a follow-up if feedback asks for it.
  • A sunset timestamp that stops the compat signature automatically. Removing the config does the same.

Scope

  • default webhook mode first (#1069). Follow-up (#1072): fold standard mode into the default provider as a preset (fixed templates, base64 encoding, whsec_ secret decoding, fixed header names, whsec_ format enforced on create). Compat then works in both modes with no extra code, and the secret-encoding option lets standard accept existing secrets during a default → standard migration, which its strict validation blocks today.
  • A compat header name that matches a primary header (signature or system headers) is rejected at boot. Compat headers override a destination's custom_headers with the same name.
  • Templates are validated at startup, same as the primary ones.
  • Docs: a "Migrating webhook signatures" guide covering both flows.

Alternatives considered

  • List of N named schemes. Needs structured config, and migrating from more than one scheme at a time isn't a real case. A single slot can grow into a list later.
Lingua principale
Go
Stelle
1.1k
Fork
70
Merge medio
1g 3h
PR unite (30g)
50

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di hookdeck/outpost

Tutte le issue di hookdeck/outpost

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.