Appearance
Webhooks
ordyn-webhooks lets external systems trigger endpoint jobs and infrastructure jobs through HTTP webhooks.
The webhook service receives public HTTP requests, authenticates them according to each webhook definition, and makes normalized request data available to the triggered job.
Use webhooks when another application should start an Ordyn job, for example:
- a monitoring system detects a condition and asks Ordyn to remediate the affected machine
- a CI or deployment platform starts an infrastructure build or administration job
- a company portal starts a controlled endpoint action without giving the caller direct Ordyn server access
- another automation tool passes structured data into an Ordyn job
Webhooks are available in Administration > Services on the Webhooks tab.
How it works
At a high level:
- An admin creates a webhook service client in Ordyn.
- An admin issues a service-client enrollment token scoped to that webhook service client.
- The
ordyn-webhooksservice enrolls through the configured Edge service by using the scoped token once. - An admin creates a webhook definition with endpoint or infrastructure scope.
- External systems call the public webhook URL.
- The webhook service validates and normalizes the request.
- Ordyn records the event and starts matching endpoint automations or infrastructure job automations.
The webhook service accepts public ingress traffic. It does not require external callers to reach the Ordyn server directly.
The webhook service connects outbound to its assigned Edge service for enrollment and Ordyn communication.
Service clients
A webhook service client represents one running ordyn-webhooks instance.
Create it in Administration > Services on the Webhooks tab by selecting Create client.
The service client needs:
- name
- edge service
- public base URL
- enabled state
The public base URL is the externally reachable base address for that webhook service, for example:
text
https://ordyn-webhooks.example.comOrdyn uses this value to display the full URL for each webhook. The service accepts webhook calls under:
text
<public base URL>/v1/hooks/<webhook slug>After creating a service client, issue a service-client enrollment token for it from the enrollment tokens page. Run the service enrollment command with that token. The command stores the service-client certificate state on disk, and the token is only needed for that enrollment.
Each webhook service client has a detail page that shows connection state, version, current certificate serial, certificate expiration, enrollment timestamps, and the configured public base URL. Admins can enable or disable the service client and revoke the current certificate from the detail page. After revocation, follow the forced stop, enroll, and start workflow below before the service can connect. See service-client certificate lifetime and renewal for the renewal workflow.
Runtime configuration
The service needs these values at runtime:
| Environment variable | Purpose |
|---|---|
ORDYN_WEBHOOK_EDGE_HOST | Edge host used for service-client enrollment and the service-client websocket. |
ORDYN_WEBHOOK_SERVICE_CLIENT_ID | The service client ID from Ordyn. |
ORDYN_WEBHOOK_PUBLIC_BASE_URL | Public base URL shown in Ordyn for webhook URLs. |
Configure these values before following the installation and enrollment workflow below. Enrollment state is stored in /data/service-client-v1 on the persistent webhooks-data volume.
Common optional values:
| Environment variable | Purpose |
|---|---|
ORDYN_WEBHOOK_BODY_LIMIT | Maximum accepted request body size. |
Backend webhook event retention is configured separately:
| Environment variable | Purpose |
|---|---|
ORDYN_WEBHOOK_EVENT_RETENTION_DAYS | Number of days to keep stored webhook event payloads in Ordyn. Defaults to 30. Set to 0 or lower to disable pruning. |
Installation
Prerequisites:
Checkout the webhook deployment folder from the Ordyn compose repository:
bash
if [ ! -d /opt/ordyn-compose/.git ]; then
git clone --filter=blob:none --sparse https://github.com/ordyn-project/compose.git /opt/ordyn-compose
fi
cd /opt/ordyn-compose
git sparse-checkout add webhooksCreate the environment file:
bash
cd /opt/ordyn-compose/webhooks
cp .env.example .envSet these values in .env:
dotenv
SERVICE_DOMAIN=ordyn-webhooks.example.com
ORDYN_WEBHOOK_EDGE_HOST=ordyn-edge.example.com
ORDYN_WEBHOOK_SERVICE_CLIENT_ID=<service-client-id>
ORDYN_WEBHOOK_PUBLIC_BASE_URL=https://ordyn-webhooks.example.comPull and verify the service image:
bash
docker compose pull
python3 /opt/cosign-docker-verify/verify.pyContinue only when the webhook image verifies successfully and no failed verification message appears. Issue a service-client enrollment token for the webhook service client in Ordyn, stop any running service container, and enroll the persistent service state:
bash
docker compose stop webhooks
printf '%s' '<enrollment-token>' | docker compose run --rm -T --no-deps webhooks npm run enroll -- --token-stdinAfter enrollment succeeds, start the service:
bash
docker compose up -d webhooksTo renew, recover, or replace its service-client certificate, issue a new token and run forced enrollment while the service is stopped:
bash
docker compose stop webhooks
printf '%s' '<enrollment-token>' | docker compose run --rm -T --no-deps webhooks npm run enroll -- --token-stdin --forceRun docker compose up -d webhooks only after forced enrollment succeeds. Do not use docker compose exec for enrollment.
The webhook service needs public HTTPS ingress for /v1/hooks/. The provided compose file routes that path through Traefik.
Public ingress
The service exposes incoming webhook calls at:
text
/v1/hooks/:slugThe slug is generated by Ordyn when the webhook is created. It is part of the copied webhook URL.
Only that ingress path needs to be publicly reachable. Service-client enrollment and control traffic are outbound from the webhook service to edge.
Source-IP authentication uses caller addresses forwarded by Traefik.
Configure rate limiting on public webhook routes when a webhook endpoint is exposed to untrusted networks or high-volume callers.
Webhook definitions
A webhook definition belongs to one webhook service client and has either endpoint or infrastructure scope.
Create it in Administration > Services on the Webhooks tab by selecting Create webhook.
A webhook has:
- service client
- scope
- endpoint when the scope is
Endpoint - name
- allowed HTTP methods
- authentication mode
- optional source IP allowlist
- optional job variable mappings
- enabled state
An endpoint-scoped webhook is bound to one approved endpoint and can match endpoint automations for that endpoint. An infrastructure-scoped webhook has no endpoint and can match automations configured on infrastructure jobs.
The scope and endpoint cannot be changed while an automation references the webhook. Remove those references before changing its scope or endpoint. A referenced webhook also cannot be deleted.
The incoming request does not select an endpoint, infrastructure job, Runner pool, or Runner.
Disabled webhooks are not accepted by the ingress service and do not trigger jobs.
Allowed methods
Each webhook can allow one or more HTTP methods:
GETPOSTPUTPATCHDELETE
The default method is POST.
If a request uses a method that is not allowed, the service rejects it before forwarding an event to Ordyn.
Authentication
Webhook authentication is configured per webhook definition.
Supported modes:
| Mode | Behavior |
|---|---|
| Unauthenticated | No token is required. Use only for trusted networks or low-risk integrations. |
| Bearer token | The caller sends Authorization: Bearer <token>. |
| Header token | The caller sends the token in the configured header, for example X-Ordyn-Webhook-Token. |
| Source IP allowlist | The caller source IP must match one configured IP address or CIDR range. |
Bearer-token and header-token values are hashed before they are stored in Ordyn. Tokens are not shown again after saving.
Source IP allowlists support individual IP addresses and CIDR ranges, for example:
text
203.0.113.10
203.0.113.0/24
2001:db8::/32Source-IP checks use the caller address forwarded by Traefik.
Request payloads
The webhook service stores and forwards a normalized request shape.
It records:
- webhook ID and slug
- receive timestamp
- HTTP method
- source IP
- content type
- sanitized headers
- query parameters
- parsed body
- raw body
JSON request bodies are parsed as JSON. application/x-www-form-urlencoded bodies are parsed into fields. Other body types are forwarded as text in the normalized request.
Sensitive caller tokens are used for authentication and should not be treated as job input.
Connect Webhooks To Jobs
The webhook scope determines where it can be selected.
Endpoint Jobs
Configure an endpoint event automation with:
- event
Webhook received - an endpoint-scoped webhook definition
- the endpoint job to run
- an optional maximum random delay
The automation matches only when:
- the webhook definition is active
- the webhook's endpoint is approved
- the automation is enabled
- the automation resolves to the webhook's endpoint
- the automation references the received webhook
When multiple matching automations exist for the endpoint, Ordyn evaluates them in their configured order. The optional random delay can spread bursts when an external system sends many events.
Infrastructure Jobs
- Create a webhook definition with scope
Infrastructure. - Open
Operations>Infrastructure Jobs. - Select the job that should run and open its
Automationstab. - Add an event automation with event
Webhook received. - Select the webhook and configure an optional maximum random delay.
Each matching automation starts the infrastructure job that owns it. The job runs once using the Runner pool selected in its overview. It does not create endpoint targets.
Job validity windows apply when the webhook event is processed. An event outside the job's allowed start window does not start a run.
See Infrastructure Jobs for the complete workflow.
Job variables
Triggered jobs receive webhook trigger details under:
text
trigger.webhookThe run also has trigger.type set to webhook_received and trigger.source set to webhook. See Variables for the full trigger field list.
Webhook definitions can also map selected request values to short job variables under:
text
webhook.<name>For example, a mapping with:
| Name | Path |
|---|---|
build_id | body.build.id |
makes the value available as:
text
{{ webhook.build_id }}Mapping paths are evaluated against the normalized request, so useful prefixes are usually:
bodyqueryheaderssource_ipmethodcontent_type
Use mappings for values that job authors should consume directly. Use trigger.webhook.* when a job needs the full request context.
Example
An external system sends:
bash
curl -X POST \
https://ordyn-webhooks.example.com/v1/hooks/3d72... \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
--data '{"build":{"id":"2026.06.25.1"},"action":"restart-service"}'With a variable mapping:
| Name | Path |
|---|---|
build_id | body.build.id |
action | body.action |
the triggered job can use:
text
{{ webhook.build_id }}
{{ webhook.action }}
{{ trigger.webhook.source_ip }}Events and diagnostics
Ordyn stores each received webhook event with the normalized request, mapped variables, matching automations, dispatched automations, and any dispatch error.
Webhook events are retained for 30 days by default. Ordyn removes events outside the retention window according to ORDYN_WEBHOOK_EVENT_RETENTION_DAYS.
The webhook definition shows the last receive timestamp and last error. Common last-error causes are:
- the webhook's endpoint is not approved
- no enabled endpoint automation matched the webhook and endpoint
- no enabled infrastructure automation matched the webhook
- the webhook was received while the definition was inactive
Service-client connection state is shown on the Webhooks page. It includes connection status, version, certificate serial, last enrollment, last connection, last seen time, and last error.
Support bundles
Webhook service clients participate in service-client log bundles.
Use support bundles when troubleshooting:
- webhook service enrollment problems
- service-client connection loss
- runtime configuration not reaching the service
- received requests not triggering jobs
- authentication failures reported by the webhook service
Select the webhook service client as a log source when creating a service-client log bundle.
Security recommendations
Use token authentication or source-IP allowlists for production webhooks.
Prefer:
- HTTPS on public webhook routes
- long random bearer or header tokens
- source-IP allowlists when the caller has stable egress addresses
- one webhook per integration purpose
- endpoint scope for integrations that should act on one approved endpoint
- infrastructure scope for integrations that should start infrastructure jobs
- narrowly configured automations for the intended jobs
- mapped variables for the specific fields a job needs
Avoid:
- unauthenticated public webhooks
- passing secrets in request bodies unless the job genuinely requires them
- using a shared webhook for unrelated external systems
- exposing service-client control paths publicly
Permissions
Webhooks Readviews webhook service clients, definitions, URLs, and events.Webhooks Create,Webhooks Update, andWebhooks Deletemanage webhook definitions.- Endpoint automation permissions control endpoint webhook automations.
Jobs Run,Runners Execute, andWebhooks Readare required to manage infrastructure webhook automations.
Limitations
Limitations:
- an endpoint-scoped webhook targets one approved endpoint
- an infrastructure-scoped webhook does not target an endpoint
- the webhook scope and endpoint are fixed while the webhook is referenced by an automation
- the incoming payload does not select the endpoint, job, Runner pool, or Runner
- authentication is configured per webhook definition, not per automation
- request bodies are normalized for job input, but Ordyn does not transform arbitrary payload formats beyond JSON and form parsing
Use variable mappings to adapt different caller payload shapes into stable job variables.