Skip to content

WebhookGatewayService

Target

This page describes intended behaviour or structure. No implementation is claimed unless a section is explicitly marked Current implementation or Evidence.

Bounded context BC-17 Connectors & Webhooks
Platform / plane Integration Platform / Capability & Tools
Deployment granularity standalone host
Status target · ConnectSoft.Factory.Integration.Webhooks
Built from connectsoft-apigateway · libraries: connectsoft-extensions-rate-limiting, connectsoft-extensions-saas-abstractions, connectsoft-extensions-messaging-model, connectsoft-extensions-persistence-model-nhibernate, connectsoft-extensions-observability
Decisions ADR-0012, ADR-0017
Traceability FR-05 FUX-02 NFR-02 NFR-09 NFR-18 XL-16

Purpose and responsibilities

Inbound webhooks are the Factory's only unauthenticated-by-token public surface, so they get the smallest possible host: WebhookGatewayService is built from the API gateway template, runs as a separate conditional deployment (only when a tenant subscribes to vendor events), and does three things per delivery: identify the ingress and its connector scheme, verify the signature and the replay window, deduplicate and capture the payload by hash. It then emits a verified delivery for ConnectorRegistryService and answers the vendor; it never dispatches to a workflow or a target and holds no credential beyond the signing secrets brokered per connector.

Context and boundaries

flowchart LR
    S["WebhookGatewayService"]
    ext_generated_products["ext-generated-products"] -->|sync-http| S
    S -->|event| ConnectorRegistryService["ConnectorRegistryService"]
    S -->|grpc| ArtifactService["ArtifactService"]
    S -->|grpc| SecretBrokerService["SecretBrokerService"]
    S -. "InboundDeliveryVerified" .-> E_InboundDeliveryVerified(("event"))
    S -. "InboundDeliveryRejected" .-> E_InboundDeliveryRejected(("event"))
Hold "Alt" / "Option" to enable pan & zoom

Domain model

InboundDelivery — One inbound HTTP delivery at a subscription's ingress identity — headers hash, signature check, timestamp and replay window, deduplication key, payload capture and the verification outcome. (catalog entry)

Field Type Required Description
inboundId guid yes
tenantId string yes
ingressRef string yes
subscriptionId guid no
connectorId string no
externalId string no
dedupKey string no
signatureValid bool yes
outcome enum:VerificationOutcome yes
payloadRef string no
payloadHash hash no
receivedAt datetime yes

Invariants:

  • A delivery is forwarded only when the ingress is known, the signature verifies under the connector's scheme and the timestamp is inside the replay window; everything else is rejected with its outcome and no payload is dispatched.
  • Payloads are captured by hash to the artifact store and never logged.
  • The gateway is stateless beyond the deduplication cache; the connector module holds the delivery lifecycle.

Events: InboundDeliveryVerified, InboundDeliveryRejected · Tables: InboundDeliveries · Repository: InboundDeliveryRepository

erDiagram
    InboundDelivery {
        guid inboundId PK
        string tenantId
        string ingressRef
        guid subscriptionId
        string connectorId
        string externalId
        string dedupKey
        bool signatureValid
        enum_VerificationOutcome outcome
        string payloadRef
        hash payloadHash
        datetime receivedAt
    }
Hold "Alt" / "Option" to enable pan & zoom

Entities and value objects

None modelled

No entities or value objects are modelled for this item yet.

Data model and storage

Store Role Engine / profile Tables
Integration store primary azure-sql / nhibernate-sqlserver InboundDeliveries
Artifact content store blob blob / azure-blob —
Cache and coordination cache redis / azure-cache —
Table Owner Columns Indexes
dbo.InboundDeliveries InboundDelivery 12 1

Full DDL: appendix.

APIs

Method Path Operation Scope Side effects Idempotency Gateway Summary
POST /webhooks/{ingressRef} ReceiveWebhook factory.webhooks.receive shared-write key-header GW-06 Vendor webhook endpoint per subscription ingress identity; verifies and captures, returns 202 or the rejection status.
GET /webhooks/health WebhookHealth factory.health.read read natural GW-06 Liveness and readiness of the ingress.

None modelled

No gRPC methods are modelled for this item yet.

Messages

Event Topic Scope / v Aggregate Consumers Summary
InboundDeliveryVerified connectors.ingress.v1.inbound-delivery-verified integration / 1 InboundDelivery ConnectorRegistryService, DashboardService A delivery passed signature and replay checks and its payload is captured.
InboundDeliveryRejected connectors.ingress.v1.inbound-delivery-rejected integration / 1 InboundDelivery AuditService, DashboardService A delivery was rejected with its outcome.

InboundDeliveryVerified payload:

Field Type Required Description
inboundId guid yes
tenantId string yes
subscriptionId guid yes
connectorId string yes
externalId string yes
dedupKey string yes
payloadRef string yes
payloadHash hash yes

InboundDeliveryRejected payload:

Field Type Required Description
inboundId guid yes
tenantId string yes
ingressRef string yes
outcome enum:VerificationOutcome yes
Command Handled by Result events Summary
ReceiveWebhook InboundDelivery InboundDeliveryVerified, InboundDeliveryRejected
Event Producer Handler Purpose
ConnectorSubscriptionChanged ConnectorRegistryService RefreshIngressTable Know which ingress identities are active and which scheme verifies them.

Workers and jobs

None modelled

No workers are modelled for this item yet.

Actors and grains

None modelled

No grains are modelled for this item yet.

Sagas and long-running flows

None modelled

No sagas are modelled for this item yet.

Options and configuration

Section Key Type Default Reloadable Secret Summary
Integration:Webhooks MaxPayloadKb int 1024 yes no Payload size limit.
Integration:Webhooks ReplayWindowMinutes int 5 yes no Timestamp tolerance for signed deliveries.
Integration:Webhooks RatePerMinutePerIngress int 600 yes no Rate limit per ingress identity.

Metrics and observability

Metric Instrument Unit Dimensions Summary
connectsoft.factory.integration.webhooks_received counter {delivery} connector, outcome Inbound deliveries by outcome.
connectsoft.factory.integration.webhook_latency histogram s connector Verification latency.

Security

Authentication none
Scopes factory.webhooks.receive (Vendor-signed deliveries (signature is the authentication).); factory.health.read (Health probes.)
Roles Observer
Tenant isolation row-filter
Data classification confidential
Max side-effect class shared-write
Secrets webhook-signing-secrets (key-vault, rotate 90 d)

The signature is the authentication: an unknown ingress, a bad signature, a timestamp outside the replay window, an oversized payload or a rate-limited sender is rejected with its outcome and no payload reaches any target. Payloads are captured to the artifact store by hash and never logged.

Dependencies

Outbound

Target Kind Purpose Failure mode Required
ConnectorRegistryService event Verified deliveries to record and dispatch. queue yes
ArtifactService grpc Payload capture by hash. fail-fast yes
SecretBrokerService grpc Signing secrets per connector scheme. fail-fast yes

Inbound

Target Kind Purpose Failure mode Required
ext-generated-products sync-http Vendor and product webhooks. — yes

Failure and recovery

Scenario Detection Recovery Data impact RTO (min)
Signing secret rotated at the vendor BadSignature rate rises for one connector rotation task on the connection; deliveries rejected until rotated, vendor retries delayed deliveries 60
Ingress flood RateLimited outcomes per-ingress rate limits; vendor backoff; no payload loss for accepted deliveries none 0

NFR targets

Target Class value (pilot-interactive) Override
latency_p95_ms 2000 —
availability_pct 99.5 —
throughput_rps 50 —
rpo_minutes 15 —
rto_minutes 240 —
cost_class low —

Deployment

Granularity standalone host
Topologies saas-default, hybrid
Runtime container-apps; replicas 1–8
Ports https 7950

Deployed on Azure Container Apps in the saas-default and hybrid profiles only; an on-prem installation uses polling subscriptions instead of inbound webhooks unless the customer exposes an ingress.

Current implementation

ConnectSoft.ApiGatewayTemplate exists; no webhook ingress, scheme verification or capture exists.

Later capabilities

Vendor-specific replay negotiation; signed acknowledgements; ingress per region.

Decisions and traceability

Family Ids
FR FR-05
FUX FUX-02
NFR NFR-02, NFR-09, NFR-18
XL XL-16