Integrations reference
Integrations send gateway events to systems outside the dashboard, such as an email when a user registers, a Slack message when a gateway is disabled, or a webhook or stream record for every policy decision. Each integration joins one endpoint, where messages go, with one event set, which events it delivers, and holds the template for the message. One endpoint or event set can serve several integrations, so a Slack channel used for gateway alerts and payment alerts is configured once.
Upgrading to 1.0.1 turns each existing integration into an endpoint and an integration with the same name, and an event set named <name> events (migrated). Review the Integrations page after the upgrade:
- An integration delivers an event from every gateway, user, and connection point that raises it. An integration that was attached to some gateways or connection points now receives their events from all of them.
- Integrations of the removed Surface and Identity categories, and integrations that received no events, such as one attached to nothing, keep only their endpoint. Add an event set and an integration to deliver to that endpoint again.
- Some migrated integrations and endpoints arrive disabled, for example an endpoint whose URL no longer passes the gateway’s checks. Review each disabled one before you turn on Active.
- Custom variables (those starting with
_) and variables that no event of the event set fills are removed from templates. The Slack channel override is removed, and the Slack sender name and icon move to the endpoint. - A Governance Audit integration keeps the delivery limits it had. One that relied on the appliance-wide audit selection, rather than its own Events to send, receives limits of 20 attempts and 7 days (604,800 seconds). Clear them under Governance Audit delivery if your destination must receive every record.
Integrations page
Select Integrations in the sidebar. The page has three tabs, Integrations, Endpoints, and Event Sets, and one filter box that searches all three by name, description, type, and event.
| Tab | Columns | Actions |
|---|---|---|
| Integrations | Name, Endpoint (name and type), Event set (name and event count), Status | Add Integration, send a test, edit, delete |
| Endpoints | Name, Type, Status, Used by | Add Endpoint, send a test, edit, delete |
| Event Sets | Name, Events (count, with an audit badge when the set holds Governance Audit events), Used by | Add Event Set, edit, delete |
Used by counts the integrations that use the endpoint or event set, and hovering over it names them. An endpoint or event set in use can’t be deleted: its delete button stays disabled and its tooltip names the integrations using it. Delete or change those integrations first. An integration whose endpoint or event set is missing shows Missing endpoint or Missing event set in red.
Every user with the User role or higher can open the page and see each endpoint’s destination. Stored credentials are never shown. Only administrators can add, change, and test endpoints, event sets, and integrations, and delete them.
Endpoints
An endpoint is where integrations deliver: an SMTP server and its recipients, a Slack incoming webhook, an HTTPS webhook, or a stream topic, with the credentials to reach it. Select Add Endpoint on the Endpoints tab.
| Field | Required | Default | Description |
|---|---|---|---|
| Name | Yes | Empty | Display name, shown in the Endpoint dropdown of the integration editor. |
| Description | No | Empty | Optional note. |
| Type | Yes | Email (SMTP) | Email (SMTP), Slack, Webhook, or Stream (Kafka, Kinesis, Pulsar, Redis). Set once: a saved endpoint keeps its type, because its integrations’ templates are written for it. |
| Active | No | On | A disabled endpoint receives nothing, whatever its integrations’ status. |
The Configuration card below shows the fields of the selected type.
Email (SMTP)
| Field | Required | Default | Description |
|---|---|---|---|
| SMTP host | Yes | Empty | SMTP server hostname, for example smtp.example.com. |
| SMTP port | Yes | 587 | Usually 587 with STARTTLS or 465 with TLS. |
| SMTP username | Yes | Empty | SMTP sign-in name. |
| SMTP password | Yes | Empty | SMTP password. A stored credential. |
| From | Yes | Empty | Sender address, for example gateway@example.com. |
| To | Yes | Empty | Recipient addresses, one per line or separated by commas. |
| Cc | No | Empty | Copy recipients, one per line. |
| Bcc | No | Empty | Blind copy recipients, one per line. |
| Use TLS | No | On | Implicit TLS, as on port 465. |
| Use STARTTLS | No | On | Upgrades a plain connection to TLS, as on port 587. |
Slack
| Field | Required | Default | Description |
|---|---|---|---|
| Incoming webhook URL | Yes | Empty | The Slack incoming webhook URL, for example https://hooks.slack.com/services/.... The URL carries its own credential, so it is a stored credential. |
| Sender name | No | Empty | Display name for the message sender, for example Agent Gateway. |
| Sender icon | No | Empty | Emoji shown as the sender’s icon, for example :robot_face:. |
Messages go to the channel the incoming webhook was created for in Slack.
Webhook
| Field | Required | Default | Description |
|---|---|---|---|
| URL | Yes | Empty | The http or https URL that receives each message. Saving refuses a URL whose host resolves to a non-public address, such as a private, loopback, or link-local one. |
| Method | No | POST | POST, PUT, or PATCH. |
| Signing secret | No | Empty | When set, each request carries an X-Webhook-Signature-256: sha256=<hex> header so the receiver can check the sender. A stored credential. |
| Headers | No | Empty | Extra request headers as a JSON object of header names to text values, for example {"Authorization": "Bearer ..."}. A header value may be $SECRET:<secret_id> to use a stored secret. Kept like a password, since headers often carry credentials. |
Every webhook request carries an X-Webhook-Timestamp header with the Unix time in seconds, and the signature covers the timestamp and the body, so a receiver can reject replayed requests. The gateway sets Content-Type, X-Webhook-Timestamp, and X-Webhook-Signature-256 itself, so Headers can’t set them, and saving an endpoint that tries to is refused.
Stream
| Field | Required | Default | Description |
|---|---|---|---|
| Platform | Yes | Apache Kafka | Apache Kafka, Amazon Kinesis, Apache Pulsar, or Redis Streams. |
| Topic or stream | Yes | Empty | The topic (Kafka, Pulsar) or stream (Kinesis, Redis Streams) to publish to. |
| Brokers | Yes, for Kafka and Pulsar | Empty | Broker addresses separated by commas, for example broker-1:9092,broker-2:9092. Shown for Kafka and Pulsar. |
| Authentication | No | None | None or SASL PLAIN. Shown for Kafka. |
| SASL username | Yes, with SASL PLAIN | Empty | Shown when Authentication is SASL PLAIN. |
| SASL password | Yes, with SASL PLAIN | Empty | Shown when Authentication is SASL PLAIN. A stored credential. |
| AWS region | Yes, for Kinesis | Empty | Region of the Kinesis stream, for example eu-west-1. The gateway uses its host’s AWS credentials. Shown for Kinesis. |
| Partition key | No | Empty | Kinesis partition key. Shown for Kinesis. |
| Redis URL | Yes, for Redis Streams | Empty | Redis connection URL, for example redis://cache:6379. The URL may carry a password, so it is a stored credential. Shown for Redis Streams. |
Stored credentials
SMTP password, Incoming webhook URL, Signing secret, Headers, SASL password, and Redis URL are write-only. Once saved, the form shows A value is stored. It is never shown. with these buttons:
- Replace opens the field for a new value. Keep stored value cancels the replacement.
- Clear removes the stored value when you save, and Undo cancels that. Required fields have no Clear.
Instead of typing a value into SMTP password, Incoming webhook URL, Signing secret, SASL password, or Redis URL, pick a secret from Use a stored secret below the field. The field then holds $SECRET:<secret_id>, shown as written, and the gateway reads the secret’s current value from Secrets at each delivery. One credential can then serve several endpoints, and changing the secret’s value takes effect on the next delivery. The list offers appliance-wide secrets to users who can view secrets.
A secret that an endpoint uses can’t be deleted. The Secrets page reports the failed delete with the names of the endpoints using it. Point those endpoints at another value first.
Endpoint test
Send test on a saved endpoint, or the paper-plane icon on its row, sends the endpoint type’s default message once, without retries. Save your changes first: the test uses the saved endpoint. A successful test shows Test message sent to the endpoint name. A failed one shows Test failed: with the reason, and stays until dismissed.
Event sets
An event set picks the events an integration delivers, from the whole event catalogue. One event set can serve several integrations. Select Add Event Set on the Event Sets tab.
| Field | Required | Description |
|---|---|---|
| Name | Yes | Display name, shown in the Event set dropdown of the integration editor. |
| Description | No | Optional note. |
| Events | Yes, at least one | The events to deliver, grouped by family, with Governance Audit events grouped by area. A group checkbox selects or clears the whole group, and Search events filters by name and description. |
An event is delivered for every gateway, user, or connection point that raises it. There is no filter by resource.
While integrations use the event set, the form names them. A change that leaves one of them with template variables that no remaining event fills is refused.
Event catalogue
| Group | Events |
|---|---|
| Gateway | Gateway Created, Gateway Updated, Gateway Deleted, Gateway Status Changed (enabled or disabled), Gateway Accessed (viewed) |
| User | User Registered, User Approved, User Updated (role, status, or profile changed), User Deleted, User Login, User Profile Accessed |
| Connection Point | Connection Point Connected: someone connected through a connection point with its secret |
| x402 Payments | x402 Verification Failed, x402 Settlement Failed, x402 Transaction Completed, x402 Cleanup Completed |
| MPP Payments | MPP Verification Failed, MPP Payment Verified, MPP Challenge Issued |
| Governance Audit | Every audit event, grouped as Governance Audit: Policies, Governance Audit: Trust, and so on. The same events as Events to keep on the Settings Security tab. |
A SAML sign-in that creates a user raises User Registered, and one that changes the user’s role, status, or primary flag raises User Updated, before User Login.
Integrations
An integration sends the events of an event set to an endpoint. Select Add Integration on the Integrations tab.
| Field | Required | Default | Description |
|---|---|---|---|
| Name | Yes | Empty | Display name. |
| Description | No | Empty | Optional note. |
| Endpoint | Yes | None | Where to deliver. Disabled endpoints are marked disabled in the list. Add an endpoint opens a new endpoint form. |
| Event set | Yes | None | Which events to deliver, with each set’s event count. Add an event set opens a new event set form. |
| Active | No | On | A disabled integration delivers nothing. |
The Template card shows its fields once an endpoint is selected, and the Governance Audit delivery card appears when the event set holds Governance Audit events.
Each event goes to every active integration whose event set holds it and whose endpoint is active. Each integration is delivered on its own, so a slow or unreachable endpoint doesn’t hold up the others. A transient failure, such as a timeout or a 5xx or 429 response, is retried up to five times with growing delays. Other failures, such as a 4xx response, aren’t retried. Governance Audit records follow their own delivery rules, described under Governance Audit delivery.
Template
The Template card shows the fields of the endpoint’s type. A field left empty sends the default shown in it, so an empty template still sends a complete message.
| Endpoint type | Field | Default | Description |
|---|---|---|---|
| Subject | ${EVENT_NAME} | Email subject. | |
| Body | ${EVENT_SUMMARY} | Email body. | |
| Format | Plain text | Plain text or HTML. With Plain text, a body that contains <html or <body tags is sent as HTML. In HTML, values filled into the body are escaped so they can’t add markup or links. | |
| Slack | Message | *${EVENT_NAME}* and ${EVENT_SUMMARY} on the next line | Slack mrkdwn. Values are escaped so they can’t mention people or add links. |
| Webhook, Stream | Payload | The default payload below | A JSON object. Saving fails until the text is a JSON object. |
The default webhook and stream payload is:
{
"event_type": "${EVENT_TYPE}",
"event_name": "${EVENT_NAME}",
"timestamp": "${TIMESTAMP}",
"appliance_id": "${APPLIANCE_ID}",
"summary": "${EVENT_SUMMARY}",
"data": "${EVENT_DATA}"
}In a webhook or stream payload, a string that is exactly ${EVENT_DATA} or ${AUDIT_RECORD} is sent as a JSON object. Inside other text, and in email and Slack messages, these variables are inserted as JSON text.
The Variables list beside the template shows every variable the event set’s events fill, with a description. Select one to insert it at the cursor. A template that uses a variable no event of the event set fills can’t be saved, and a warning names it. A variable with no value for the delivered event is sent empty.
Integration test
Send test in the editor, or the paper-plane icon on the integration’s row, sends one real message for one event of the event set, the one whose event ID sorts first, filled with sample values. It is delivered, not simulated. In the editor, the test sends the integration as it stands on screen, saved or not, and is unavailable while the form has a problem that would stop it being saved. A successful test shows Test message for the event sent to the endpoint name.
Governance Audit delivery
Shown when the event set holds Governance Audit events. Audit records are kept in a journal on the appliance and retried until delivered, unless these limits skip them.
| Field | Default | Description |
|---|---|---|
| Give up on a record after | Empty: retry until delivered | Under Delivery limits, in attempts. After this many failed attempts, the integration skips the record so the records after it can be delivered. While the destination is down, records are also skipped once they reach this limit. |
| Skip records older than | Empty: deliver records of any age | Under Delivery limits, in seconds. Records older than this are skipped for this integration instead of delivered, including a record still being retried. |
Each value is a whole number of 1 or more, or empty.
- Each audit record is one delivery, so an email or Slack integration sends one message per record. Webhook and stream integrations suit busy appliances.
- Delivery is at least once, so a record can arrive more than once, for example after a restart. Every new record carries a unique
event_id, so deduplicate on it at the receiver. - A destination that stops accepting records falls behind and catches up in order once it recovers. Without delivery limits, its oldest records are skipped only when the backlog grows past its cap.
- Turning off Active on the integration or its endpoint pauses delivery. A paused integration lets go of its undelivered records, and once active again it receives only the records produced after that.
- Records leave the appliance with the caller’s email and name, request details, and the signed VP. Send them only to a destination cleared for that data.
To start an audit integration from the Audit page, select Forward records. It opens a new event set named Governance Audit with every audit event selected. Once an integration receives audit records, the button reads Forwarding to N integrations and opens the Integrations page.
Template variables
Use ${VARIABLE} in any template field. Every event fills the common variables. Each event also fills its own, and the Variables list in the editor shows exactly which ones the selected event set offers.
Common variables
| Variable | Description |
|---|---|
${EVENT_TYPE} | The event’s ID, for example gateway.created or audit.policy_decision. |
${EVENT_NAME} | The event’s display name, for example Gateway Created. |
${EVENT_SUMMARY} | One line on what happened, written for people. |
${EVENT_DATA} | The event’s values as JSON. For a Governance Audit event, the audit record. |
${TIMESTAMP} | RFC 3339 time the event occurred. For an audit record, the record’s own timestamp. |
${APPLIANCE_ID} | The Appliance ID set on the Settings System tab. Empty while none is set. |
Gateway events
| Variable | Description |
|---|---|
${OLD_STATE} | The gateway before the change, as JSON. Empty for a create. |
${NEW_STATE} | The gateway after the change, as JSON. Empty for a delete. |
${GATEWAY_ID} | ID of the gateway. |
${GATEWAY_NAME} | Name of the gateway. |
${GATEWAY_DESCRIPTION} | Description of the gateway. |
${GATEWAY_DID} | Decentralised Identifier (DID) of the gateway. |
${GATEWAY_TYPE} | Type of the gateway. |
${GATEWAY_STATUS} | Status of the gateway after the event. |
${GATEWAY_OLD_STATUS} | Status of the gateway before the change. Gateway Status Changed only. |
User events
| Variable | Description |
|---|---|
${OLD_STATE} | The user before the change, as JSON. Empty for a create. |
${NEW_STATE} | The user after the change, as JSON. Empty for a delete. |
${USER_ID} | ID of the user. |
${USERNAME} | Username of the user. |
${USER_EMAIL} | Email of the user, when known. |
${USER_ROLE} | Role of the user. |
${USER_STATUS} | Status of the user. |
For user events, ${OLD_STATE} and ${NEW_STATE} carry only user_id, role, status, is_primary, created_at, and updated_at. Add ${USERNAME} or ${USER_EMAIL} only when the destination needs them.
Connection point events
| Variable | Description |
|---|---|
${CP_ID} | ID of the connection point that received the connection. |
${CP_NAME} | Name of the connection point. |
${CP_DESCRIPTION} | Description of the connection point. |
${GATEWAY}, ${GATEWAY_ID} | ID of the connection point’s gateway. |
${MEDIATOR_ID} | ID of the mediator the connection arrived through. |
${MESSAGE_ID} | ID of the connection-setup message. |
${MESSAGE_TYPE} | DIDComm type of the connection-setup message. |
${FROM_DID} | DID of whoever connected. |
${MESSAGE_BODY} | Body of the connection-setup message, as JSON. |
${RECEIVED_AT} | RFC 3339 time the connection-setup message was received. |
${DATE}, ${TIME}, ${DATETIME} | Delivery date (YYYY-MM-DD), time (HH:MM:SS), and both (YYYY-MM-DD HH:MM:SS). |
Payment events
| Variable | Events | Description |
|---|---|---|
${CORRELATION_ID} | x402 events except x402 Cleanup Completed | ID correlating the payment’s requests. |
${SURFACE_ID} | MPP events, and x402 events except x402 Cleanup Completed | ID of the Agent Surface that took the payment. |
${SURFACE_NAME} | MPP events | Name of the Agent Surface that took the payment. |
${TX_HASH} | x402 events except x402 Cleanup Completed | On-chain transaction hash. |
${AMOUNT}, ${NETWORK} | x402 Transaction Completed | Amount paid and the network it settled on. |
${SETTLEMENT_METHOD} | x402 Settlement Failed, x402 Transaction Completed | How the payment was settled. |
${ERROR_MESSAGE} | x402 Verification Failed, x402 Settlement Failed, MPP Verification Failed | Why the payment step failed. |
${TRANSACTIONS_DELETED}, ${RETENTION_DAYS} | x402 Cleanup Completed | Transactions the cleanup removed, and the days transactions are kept. |
${PAYMENT_METHOD} | MPP Verification Failed, MPP Payment Verified | Payment method the caller used. |
${RESOURCE_URL} | MPP events | URL of the paid resource. |
${REFERENCE} | MPP Payment Verified | Payment reference returned by the verifier. |
${SEVERITY} | All payment events | info or error. |
Governance Audit events
| Variable | Description |
|---|---|
${AUDIT_RECORD} | The complete audit record as JSON, in the same shape as a VP Audit Log entry, including its event_id and signed VP. |
${AUDIT_CATEGORY} | The audit event, for example policy_decision, trust_check, or auth_failed. ${EVENT_TYPE} carries the same value as audit.<event>. |
${AUDIT_TRACE_ID} | Request trace ID shared by every audit record written for the same request. |
${AUDIT_SURFACE_ID} | ID of the surface the record belongs to. |
${AUDIT_SURFACE_NAME} | Name of the surface the record belongs to. |
${AUDIT_PROTOCOL} | Protocol of the surface, for example a2a or mcp. |
${AUDIT_AGENT_DID} | DID of the agent the record was written for. |
${AUDIT_VIA_FABRIC} | true when the request crossed a gateway-to-gateway connection, otherwise false. |
${AUDIT_PRINCIPAL} | The authenticated caller: their email, else display name, else the authenticated subject such as the JWT sub, API key name, DID, or mTLS principal. Empty when the request had no authenticated caller. |
${AUDIT_PRINCIPAL_EMAIL} | Email of the authenticated caller, when their credential carries one. |
${AUDIT_PRINCIPAL_NAME} | Display name of the authenticated caller, when their credential carries one. |
${AUDIT_AUTH_METHOD} | How the caller authenticated, for example jwt_bearer, api_key, did_auth, or mtls. Empty for an unauthenticated request. |
${AUDIT_DECISION} | allow or deny on a policy decision record. Empty on other records. |
${AUDIT_DENY_REASON} | Deny reason reported by the policy on a denied policy decision record. Empty otherwise. |
${AUDIT_POLICY_NAME} | Name of the policy that made a policy decision. Empty on other records. |
${AUDIT_POLICY_VERSION} | Version of the enforced policy revision on a policy decision record, when the policy is versioned. |
${AUDIT_POLICY_CONTENT_HASH} | sha256:<hex> hash of the exact Rego enforced on a policy decision record, when known. |
${AUDIT_VP_JWT} | Signed Verifiable Presentation (JWT) attached to the record. |
${AUDIT_VP_FINGERPRINT} | sha256:<hex> fingerprint of the signed VP attached to the record. |
The default payload’s "data": "${EVENT_DATA}" already carries the full audit record, including its event_id, as a JSON object. ${AUDIT_RECORD} and ${AUDIT_VP_JWT} are large, so keep them out of email and Slack messages.
Related
- Set up event notifications: Create an endpoint, an event set, and an integration, and send a test.
- Send audit events to an external system: Deliver Governance Audit records to a SIEM, webhook, or stream.
- Audit log: How audit records are selected, journaled, and delivered.
- Secrets: Store a credential once and use it from several endpoints.
Glad to hear it. Thanks for letting us know.
Sorry to hear that. Thanks for letting us know.