Skip to main content

Webhooks

The Webhook System enables external notifications based on the Events system within InfraHub, which also powers the Activity Log.

Configuring webhooks

Infrahub support two different types of webhooks:

  • Standard Webhook sends event information to an external endpoint.
  • Custom Webhook allows the ability to tie events to a transformation to configure the payload being sent to an external endpoint.
note

Custom webhooks might be useful in situations where the endpoint needs a specific payload to be successful. A use-case that might need this would be triggering external actions in platforms like GitHub and Gitlab.

Webhooks can be configured to trigger on specific event types, such as:

  • infrahub.branch.merged
  • infrahub.node.updated

This allows you to tailor webhooks for specific use cases.

Configuring branch types

Webhooks can also be configured to trigger based on branch types:

  • Other Branches – All branches except the default branch.
  • Default Branch – Only the default branch.
  • All Branches – Every branch.

This flexibility ensures that webhooks only trigger when relevant, depending on the use case. For example, you might configure a webhook to notify an external system only when a user makes changes directly to the default branch.

Node kind

Node kinds can be configured to only trigger webhooks for specific nodes. For example only send webhooks for the node kind of InfraDevice.

note

Node kind can only be used where node_kind is True in Infrahub events. Below are some example events that are enabled:

  • infrahub.node.created
  • infrahub.node.updated
  • infrahub.node.deleted
  • infrahub.artifact.created
  • infrahub.artifact.deleted
  • infrahub.group.member_added
  • infrahub.group.member_removed
  • infrahub.validator.member_removed

Webhook configuration details

  • Description: A description can be set to identify the webhooks purpose.
  • URL: The destination URL can be configured, such as http://ansible-eda:8080.

Shared key for security

A shared key can be configured to sign webhook requests. This key ensures the authenticity and integrity of the webhook message.

When a webhook is sent:

  1. The sender generates a signature using the shared key.
  2. The signature is included in the request headers.

The receiver then uses the same shared key to verify the signature, confirming that the message has not been tampered with and that it is from a trusted source.

Python FastAPI Example
webhook-reciever.py
import hmac
import hashlib
import base64
from fastapi import FastAPI, Request, HTTPException
import uvicorn

app = FastAPI()
SHARED_KEY = b"supersecretkey"


def verify_signature(message_id, timestamp, payload, received_signature):
data = f"{message_id}.{timestamp}.{payload}".encode()
expected_signature = base64.b64encode(
hmac.new(SHARED_KEY, data, hashlib.sha256).digest()
).decode("utf-8")
return hmac.compare_digest(f"v1,{expected_signature}", received_signature)


@app.get("/")
async def health_check():
return {"status": "success", "message": "Webhook server is running"}


@app.post("/")
async def catch_all(request: Request):
headers = request.headers
message_id = headers.get("webhook-id")
timestamp = headers.get("webhook-timestamp")
received_signature = headers.get("webhook-signature")
payload = await request.json()

if not all([message_id, timestamp, received_signature, payload]):
raise HTTPException(
status_code=400, detail="Missing required headers or payload"
)

if not verify_signature(message_id, timestamp, payload, received_signature):
raise HTTPException(status_code=403, detail="Invalid webhook signature")

return {"status": "success", "message": "Webhook received and verified"}


if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8200)

Validating HTTPS certificates

When using webhooks over HTTPS, you can configure your system to validate certificates to ensure that the receiver has a valid HTTPS certificate, adding an extra layer of security.

Example payloads

Here are some example payloads of some events that may be sent.

{
"data": {
"branch_id": "182c6a84-4af4-736b-35a6-c514e640ca8b",
"branch_name": "test",
"sync_with_git": false
},
"id": "2ece726f-8574-488c-92f7-ee9a56485b46",
"branch": null,
"account_id": "182c6918-8880-5252-3611-c51ae7e0d6a5",
"occured_at": "2025-03-13 16:44:32.321142+00:00",
"event": "infrahub.branch.created"
}