Action Destinations

Audience: Platform administrators, compliance officers Time: ~10 min Prerequisites: Control Plane deployed and reachable; admin role in the Control Plane UI; NOTIFICATION_ENCRYPTION_KEY (Fernet) configured in your secret store; HTTPS egress allowed from the Control Plane to your destination endpoints.

Action Destinations are the outbound integrations that Control Core uses to fan out post-decision actions: webhooks, SIEM events, workflow runners, approval queues, and break-glass paging.

When a control author drops a webhook, siem_log, approval_gate, workflow, policy_trigger, or break_glass_notify action into a control, the destination_ref field references one of the destinations registered on this page. Without a configured destination, an action is metadata only — configure it here to make it real.

Notification channels (Email, Slack, Teams, PagerDuty, ServiceNow, Webhook) are managed separately under Settings → Notifications. Action Destinations covers post-decision delivery profiles and SIEM only. The two surfaces share the same encrypted credential store but have independent CRUD, audit, and runtime delivery paths.

Page layout

The page renders Overview & Routing as static reference content at the top, followed by two tabs:

SectionPurpose
Overview & Routing (top of page, not a tab)Short intro, links to related configuration (PIPs, Approval Gates, Notifications, Audit Logs), and optional context pulled from this guide. The detailed action-type routing matrix is below — it is no longer duplicated as a large card in the Control Plane UI.
Destination Profiles (tab)Built-in named destinations (webhook_generic, api_gateway, workflow_router, policy_engine, approval_queue, break_glass_bridge). Each has an endpoint URL, encrypted credential, enabled toggle, and a Test button.
SIEM (tab)Single SIEM destination used for both bulk audit forwarding and siem_log post-decision actions. Supports Splunk, Microsoft Sentinel, IBM QRadar, Elastic, and custom HTTP collectors.

A header badge such as 4/6 configured summarizes how many destination profiles are wired up.

Action type routing matrix

Use this table when authoring context_config.post_decision_actions to see which surface backs each action shape. Configure the underlying profile or channel in the tabs described above.

Action / needWhere it is configured
Webhookwebhook_generic destination profile, or a Notification webhook channel under Settings → Notifications
API / policy triggerapi_gateway profile, or workflow_router where you pass workflow identifiers in action config
SIEMSIEM tab on this page (bulk audit + siem_log actions)
EmailSMTP channel under Settings → Notifications (notification / email actions resolve channels by id)
Trigger workflowworkflow_router profile + workflow_id (and related fields) in the action configuration
Break-glassbreak_glass_bridge profile plus the paging / notification channel referenced in the action
Human approvalapproval_queue profile plus manager or approver notification routing (see Approval gates)
Audit logcontrol_core_audit — always-on internal destination for Control Plane audit retention (not a customer-editable profile)

Troubleshooting: If an action never fires, verify the destination_ref on the control matches a ready profile on this page (or a valid notification channel id for notification / email), then confirm the post-decision dispatcher logs in the Control Plane API.

Where did the "Notification Channels" tab go? It was consolidated into the Notifications page to enforce a single owner for channel CRUD. All channel management (add, edit, test, disable) now lives under Settings → Notifications. The legacy in-page tab can be temporarily re-enabled with the control_plane_paths.action_destinations_channels_tab feature flag — see Feature flag (legacy view) below.

How actions reach a destination

Control Builder / Rego editor
        │   sets destination_ref
        ▼
context_config.post_decision_actions  (stored on the control)
        │
        ▼
Bouncer                               (enforces decision, emits audit)
        │   POST /audit/bouncer-logs or /audit/access-logs
        ▼
Control Plane                         (single instance per environment)
        ├── SIEM outbox processor             → batch send (every 30s)
        └── Post-Decision Action Dispatcher   → destination profiles,
                │                                channels (resolved by id),
                │                                SIEM, approval gates,
                │                                break-glass bridge
                ▼
        Destination profile transports for webhooks/workflow/policy/
        approval/break-glass; channel services (Email/Slack/Teams/
        PagerDuty/ServiceNow/Webhook) for `notification` and `email`
        actions, configured under Settings → Notifications.

The Bouncer never talks to outbound integrations directly. All side effects originate from the Control Plane so that the data path stays fast and stateless and so all credentials remain in one encrypted store.

Troubleshooting: If a configured destination shows no traffic in Audit Logs, check Settings → Bouncers → <bouncer> → Heartbeat to confirm the Bouncer is sending decision audits to the Control Plane. Common causes: Bouncer pointed at the wrong Control Plane URL, network egress blocked from Bouncer to Control Plane, or audit ingestion paused. Full reference: Troubleshooting → Controls.

Configure a Destination Profile

  1. Open Settings → Action Destinations and stay on the Destination Profiles tab. (~30 sec)
  2. For the destination you want to wire up (e.g. Generic Webhook Endpoint): (~2 min per profile)
    • Enter the Endpoint URL (HTTPS recommended).
    • Enter a Credential Ref alias for documentation purposes (for example opsgenie_prod_key). This is what the control stores; the real secret never lands in the control bundle.
    • Enter the actual Credential / Bearer Token. It is encrypted at rest with NOTIFICATION_ENCRYPTION_KEY (Fernet) and never returned in API responses. A Stored badge appears once it has been saved.
    • Add Notes / Routing Guidance so other operators know what the destination is for.
  3. Toggle Enabled if you want the destination active. (~5 sec)
  4. Click Save Destination Profiles. (~5 sec)
  5. Click Test to send a probe payload (POST with a small JSON body). The page shows the HTTP status code or the failure reason. (~10 sec)

Troubleshooting: If Test fails with a connection error, run curl -v <endpoint> from the same host as the Control Plane API. Common causes: egress firewall blocks outbound to the endpoint host, DNS resolution fails inside the cluster, or the destination's TLS chain is not in the Control Plane container's trust store. Fix at the network layer, not by disabling TLS verification.

The status badge next to each profile reflects the live configuration:

BadgeMeaning
ConfiguredEndpoint set, integration row is active.
Not configuredNo endpoint URL stored yet.
DisabledToggled off; controls referencing it will skip dispatch.

Configure the SIEM Destination

The SIEM tab manages the single SIEM destination used by:

  • The audit ingest pipeline (every audit log is enqueued for SIEM forwarding via the SIEM outbox).
  • Control siem_log post-decision actions (the dispatcher ensures an outbox row exists for the audit event).

Steps:

  1. Toggle Enable SIEM forwarding on. (~5 sec)
  2. Choose the SIEM Type (Splunk, Sentinel, QRadar, Elastic, custom). (~5 sec)
  3. Enter the Endpoint URL (e.g. Splunk HEC /services/collector). (~30 sec)
  4. Paste the API Key. Once saved, the field shows a Stored badge and you can leave it blank on subsequent edits to keep the existing key. (~30 sec)
  5. Click Save SIEM, then Test Connection to validate. (~15 sec)

The SIEM outbox is processed by the scheduler every 30 seconds with retry/dead-letter handling. The status panel under the form shows the last successful send and last error timestamp.

Troubleshooting: If the outbox stays at pending for more than 60 seconds, check the Control Plane API logs for siem_outbox_processor entries. Common causes: SIEM endpoint rejecting the batch shape (look for the Last error panel), Control Plane scheduler not running, or the SIEM provider rate-limiting bulk submissions. The SIEM tab's Test Connection button bypasses the outbox and sends a single probe — use it to isolate transport vs. batch issues.

Reference: Action types and where they go

Action typeDestination
webhookwebhook_generic profile or a webhook channel (channel:<id>, configured under Notifications).
notificationAn email/Slack/Teams/PagerDuty/ServiceNow/webhook channel (channel:<id>) — configured under Notifications.
emailAn SMTP channel — configured under Notifications.
siem_logThe SIEM destination on the SIEM tab of this page.
audit_logcontrol_core_audit (always-on internal destination, no configuration needed).
workflowworkflow_router profile (with workflow_id in the action config).
approval_gateapproval_queue profile + a notification channel (notify_destination_ref) for approver pings. See Approval Gates.
policy_triggerpolicy_engine profile (always-on internal destination).
break_glass_notifybreak_glass_bridge profile + paging channel (PagerDuty/Teams/email under Notifications).

Credential storage and rotation

  • All credentials are encrypted with NOTIFICATION_ENCRYPTION_KEY (a Fernet key supplied via your secret store — Azure Key Vault, AWS Secrets Manager, HashiCorp Vault, or Kubernetes Secret).
  • Credentials are never returned in GET /integrations/ responses. The API surfaces a credential_set: true|false boolean instead.
  • To rotate a credential, paste the new value into the Credential / Bearer Token field and click Save Destination Profiles.
  • To clear a credential, toggle the destination Disabled or replace it with a different alias.
  • Demo deployments only (DEMO_MODE=true) accept an ephemeral key — production deployments must supply NOTIFICATION_ENCRYPTION_KEY or the encryption service refuses to start.

Note: Notification channel credentials are stored in a separate table (notification_channels.encrypted_credentials) with the same Fernet key. The two stores never share rows; rotating NOTIFICATION_ENCRYPTION_KEY re-keys both.

Testing the end-to-end flow

After configuring a destination:

  1. Open the control in Author Controls → Visual Builder.
  2. Go to Step 5 — Context & Actions.
  3. Add an action (e.g. webhook with trigger on_deny).
  4. Pick the destination profile from the dropdown. The wizard shows a Configured / Not configured / Disabled / Pending badge next to each option, sourced live from this page.
  5. Save and deploy the control.
  6. Trigger a matching decision (using the Control Testing sandbox or a real request through the bouncer).
  7. Watch Settings → Audit Logs for the decision row, and confirm the external system received the payload (webhook 200, SIEM event, etc.). For channel deliveries (notification / email), watch the delivery log under Notifications.

Feature flag (legacy view)

The in-page Notification Channels tab was consolidated into the Notifications page (single owner for channel CRUD). If a customer install needs the legacy view during a migration window, set the runtime feature flag:

Flag keyDefaultEffect when ON
control_plane_paths.action_destinations_channels_tabfalse (OFF)Re-renders the legacy Notification Channels tab on the Action Destinations page. The tab is marked deprecated in the UI and will be removed in a future release.

The flag is read at runtime by useFeatureFlags() in the Control Plane UI; no rebuild is required. Toggle it from Settings → Feature Flags or via PATCH /api/v1/feature-flags/effective. Channel CRUD remains unique to the Notifications page even when the legacy tab is enabled — the legacy tab is read/write but operationally redundant.

Backend isolation (for SREs)

Action Destinations and Notification Channels are physically separated in the data layer. This is a ship-blocker invariant — they must never be merged.

ConcernAction DestinationsNotification Channels
DB tableintegrations (filtered by type='action_destination')notification_channels
Control Plane API path/integrations//v1/notifications/channels
Encrypted credential fieldconfiguration._encrypted_credential (per-row JSON blob)notification_channels.encrypted_credentials (dedicated column)
Credential redaction helperOperates on Integration rows onlyOperates on NotificationChannel rows only
Runtime delivery pathPost-Decision Action Dispatcher → profile transports / SIEM outboxNotification Delivery Service → channel adapters + notification_delivery_log
UI owner/settings/action-destinations/settings/notifications

If you ever need to validate the separation in a customer install (e.g. after a migration), the platform ships a regression suite that asserts the data-layer disjointness — no shared rows or fields — as part of every release build.

Troubleshooting

SymptomLikely causeFix
Test probe returns 401/403Wrong credentialPaste new credential into the Credential / Bearer Token field and save.
Test probe returns connection errorEndpoint unreachable from control planeCheck egress rules / DNS / TLS cert.
Action dispatches but recipient sees nothingRecipient is on a notification channel, not a destination profileCheck Settings → Notifications → Delivery Log instead of this page.
unconfigured badge in wizard for a profile you savedEndpoint URL is emptyRe-open the profile and ensure the URL is saved.
SIEM outbox stuck at pendingScheduler not running, or endpoint rejecting batchesCheck Control Plane scheduler logs and the Last error panel on the SIEM tab.
"I can't find the Notification Channels tab"The tab was moved to the Notifications pageManage channels under Settings → Notifications.

Next steps