πŸ—οΈ 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

TypeTriggerWhat it does
audit_logAnyWrites a structured decision record to the Control Core audit trail
notificationAnySends an alert via Slack, Teams, PagerDuty, or email
webhookAnyPOSTs a payload to any HTTPS endpoint
siem_logAnyForwards a structured event to Splunk, QRadar, or any SIEM
approval_gateon_allowPauses the request and requires human approval before it proceeds
break_glass_notifyon_denyNotifies on-call when a user requests emergency override access
policy_triggerAnyActivates a secondary control or workflow

πŸ“ž Supported triggers

TriggerFires when…
on_allowThe control decision is Allow
on_denyThe control decision is Deny
on_maskThe control applies a masking transformation
on_errorAn evaluation error occurs
alwaysAfter 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_log action 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_deny for actionable security alerts
  • Prefer role/group recipients over individual-only routing
  • Use always sparingly 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):

  1. First deploy with audit_log + notification only β€” verify approver receives the notification
  2. Test the full approval loop in sandbox: request β†’ notification β†’ approve β†’ confirm request proceeds
  3. Enable approval_gate only after routing is validated
  4. 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_role matches an existing role in your platform
  • Verify notify_destination_ref is 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_ref and notify_channels destination 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

SymptomCheck
Action did not fireBOUNCER_ENABLE_POST_DECISION_ACTIONS=true in Bouncer config; trigger matches decision outcome
Webhook timeoutUse async/low-latency endpoint; avoid always trigger on high-traffic controls
Notification not deliveredDestination config in Settings β†’ Integrations; channel credentials are valid
Approval gate blocking all requestsapprover_role is set and approver can access Approval Inbox

Full: Troubleshooting Controls