ποΈ Actions & Post-Decision Flows
Audience: Control authors, security engineers, compliance officers Time: ~10 min
Post-decision actions run after a control evaluates a request. They do not change the allow/deny outcome β they add operational side-effects: notifications, approvals, audit events, and integrations.
π§ Action types reference
| Type | Trigger | What it does |
|---|---|---|
audit_log | Any | Writes a structured decision record to the Control Core audit trail |
notification | Any | Sends an alert via Slack, Teams, PagerDuty, or email |
webhook | Any | POSTs a payload to any HTTPS endpoint |
siem_log | Any | Forwards a structured event to Splunk, QRadar, or any SIEM |
approval_gate | on_allow | Pauses the request and requires human approval before it proceeds |
break_glass_notify | on_deny | Notifies on-call when a user requests emergency override access |
policy_trigger | Any | Activates a secondary control or workflow |
π Supported triggers
| Trigger | Fires when⦠|
|---|---|
on_allow | The control decision is Allow |
on_deny | The control decision is Deny |
on_mask | The control applies a masking transformation |
on_error | An evaluation error occurs |
always | After every evaluation regardless of outcome |
π Canonical action shape (JSON)
{
"type": "<action_type>",
"trigger": "<trigger>",
"enabled": true,
"config": {
"destination_ref": "<configured-destination-id>",
"credential_ref": "<credential-reference>"
}
}
Actions use references to destinations and credentials configured in Settings β Integrations β raw credentials are never stored inside a control.
π Examples
audit_log β always write a decision record
{
"type": "audit_log",
"trigger": "always",
"enabled": true,
"config": {
"destination_ref": "control_core_audit",
"level": "info",
"message": "Decision for {{subject.id}} on {{resource.name}}: {{decision}}"
}
}
Best practice: Add an
audit_logaction to every control. It provides decision traceability without affecting request flow.
siem_log β forward denials to Splunk or QRadar
{
"type": "siem_log",
"trigger": "on_deny",
"enabled": true,
"config": {
"destination_ref": "splunk_hec",
"credential_ref": "siem_prod_token",
"severity": "high",
"event_type": "control_decision"
}
}
Recommended fields to include in SIEM events:
- Trigger and decision outcome
- Control name and version
- Resource path and method
- Environment and Bouncer ID
webhook β call an external API
{
"type": "webhook",
"trigger": "on_deny",
"enabled": true,
"config": {
"url": "https://hooks.example.com/control-event",
"method": "POST"
}
}
Webhook dispatch is asynchronous with a bounded request timeout. Use always only for low-cost telemetry endpoints to avoid adding latency.
notification β alert via Slack or Teams
{
"type": "notification",
"trigger": "on_deny",
"enabled": true,
"config": {
"destination_ref": "slack_security_channel",
"message": "Access denied: {{subject.id}} attempted {{action}} on {{resource.name}}"
}
}
Best practices:
- Use
on_denyfor actionable security alerts - Prefer role/group recipients over individual-only routing
- Use
alwayssparingly to avoid alert fatigue
Supported channels: in-app, Slack, Teams, PagerDuty, email.
approval_gate β pause and require human approval
{
"type": "approval_gate",
"trigger": "on_allow",
"enabled": true,
"config": {
"destination_ref": "approval_queue",
"approver_role": "security_manager",
"ttl_minutes": 30,
"reason_required": true,
"notify_destination_ref": "slack_security_channel"
}
}
approval_gate pauses request execution. The request only proceeds after an approver with the configured role approves it via the Controls β Approval Inbox.
Rollout guidance (to avoid breaking flows):
- First deploy with
audit_log+notificationonly β verify approver receives the notification - Test the full approval loop in sandbox: request β notification β approve β confirm request proceeds
- Enable
approval_gateonly after routing is validated - Start with narrow scope (one endpoint or user group) before expanding
Troubleshooting: Requests blocked after adding approval gate?
- Check pending approvals in Controls β Approval Inbox and Settings β Approval Gates
- Confirm
approver_rolematches an existing role in your platform- Verify
notify_destination_refis configured so approvers are notified
break_glass_notify β emergency override path
{
"type": "break_glass_notify",
"trigger": "on_deny",
"enabled": true,
"config": {
"destination_ref": "break_glass_bridge",
"notify_channels": "email,siem",
"require_reason": true,
"ttl_minutes": 15
}
}
Pair break_glass_notify with audit_log on on_deny so every emergency access attempt produces a decision record for audit.
Troubleshooting: Break-glass path still fails after notification?
- Verify
destination_refandnotify_channelsdestination refs exist and are active in Settings β Integrations- Confirm TTL and reason requirements are documented in your runbook and communicated to users who need emergency access Full reference: Troubleshooting Controls
π Safe staged rollout pattern
For high-impact controls (approval gates, break-glass, hard denies on critical paths):
Stage 1: audit_log (always) + notification (on_deny) β Confirm routing
Stage 2: Enable approval_gate in sandbox, narrow scope β Validate loop
Stage 3: Promote to production in narrow scope β Monitor audit logs
Stage 4: Expand scope β Confirm no disruption
π Configuring destinations and credentials
All destinations and credentials are configured in Settings β Integrations, not inside individual controls. This allows:
- Multiple controls to share the same destination
- Credential rotation without editing individual controls
- Centralised audit of outbound integration activity
π οΈ Troubleshooting
| Symptom | Check |
|---|---|
| Action did not fire | BOUNCER_ENABLE_POST_DECISION_ACTIONS=true in Bouncer config; trigger matches decision outcome |
| Webhook timeout | Use async/low-latency endpoint; avoid always trigger on high-traffic controls |
| Notification not delivered | Destination config in Settings β Integrations; channel credentials are valid |
| Approval gate blocking all requests | approver_role is set and approver can access Approval Inbox |
Full: Troubleshooting Controls