Playbook Recipes

Ready-made playbook configurations for SIM swap, takeover, credential leak and port-out, with what each action actually changes.

Last reviewed September 16, 2026Fresh

Overview

Each recipe below is a trigger plus a list of actions to enter by hand in the Playbook Builder wizard. They are not seeded templates: the platform template library has no rows today, so the gallery in step 1 is empty and every playbook starts from scratch.

Building one. Dashboard > Playbooks > New playbook > Start from scratch, name it, pick or type the trigger event type, add the actions, then Activate Playbook. Order in the list is display only: all actions start together, each with its own 8-second budget.

What the actions change. Every action except webhook_callback operates on PasskeyBridge objects that belong to your whole organization: agent delegates, A2A negotiations, cached trust proofs, shadow identities, cross-references and BLAST tunnel sessions. None of them can act on one end user, freeze one account, end one person's session or disable one registered passkey, and none of them filters by the identifier in the signal. webhook_callback is the action that reaches your own systems, and your backend is where per-user work belongs.

What happens without any playbook. A hard signal that carries phone or phone_hash revokes every active agent delegate and every live A2A negotiation on the organization before any action runs. The recipes add to that; they do not cause it.

Recipe 1: SIM-swap response

Trigger: sim_swap (hard signal). Use sim_swap_detected as well if your carrier feed sends the confirmed variant; a playbook matches one exact type, so that is a second playbook.

Scenario: a carrier reports the SIM behind a number has changed, the usual precursor to account takeover on phone-based recovery.

OrderActionWhat it changesWhy it is here
1webhook_callbackPOSTs the signed envelope to your callback URLThe only action that reaches your systems: your backend locks the account, drops sessions and disables SMS recovery
2suspend_agentsDeactivates the organization's active agent delegates and clears their scopesAdds scope clearing on top of the automatic revocation
3freeze_credentialsInvalidates the organization's valid cached trust proofsForces fresh attestation instead of an offline proof issued before the swap
4revoke_tokensTears down open BLAST tunnel sessionsAny tunnel opened before the swap has to be renegotiated
5email_alertEmails the tenant admins groupPuts a human on it; the affected end user cannot be a recipient
6slack_webhookPosts to the registered Slack destinationSame alert in the channel the on-call watches
7log_eventRecords severity critical on the eventA marker in the action list for later filtering

Automatic, without any action: delegates revoked with narrowing_reason: "Hard signal: sim_swap", A2A negotiations set to revoked / auto_revoked with scopes and transaction limits zeroed, and an audit row with action parametric_revocation.triggered.

Recovery: re-delegate agents and re-establish negotiations once the number is confirmed back under the user's control. Restoring a delegate's original scopes is a dashboard action on the Agents tab rather than a playbook one.

Recipe 2: Account takeover containment

Trigger: account_takeover (hard signal).

Scenario: your own detection, or a provider's, concludes an account is in someone else's hands.

OrderActionWhat it changesWhy it is here
1webhook_callbackPOSTs the signed envelope to your callback URLYour backend performs the account-level lockdown
2quarantineRevokes cross-references, invalidates cached proofs and deactivates shadow identities in one actionThe widest single action: three subsystems at once
3revoke_sessionsRevokes active, negotiated and attested A2A negotiationsMarks them session_revoked rather than auto_revoked, so the reason is legible later
4email_alertEmails the tenant admins groupEscalation to a human
5slack_webhookPosts to the registered Slack destinationChannel visibility
6log_eventRecords severity criticalAudit marker

Difference from recipe 1: quarantine also revokes cross-reference bindings, which SIM-swap response leaves alone. It is not a softer option; both leave the delegates deactivated by the automatic hard-signal revocation.

Automatic: identical to recipe 1, because account_takeover is classified hard.

Recipe 3: Credential leak containment

Trigger: credential_leak (soft signal).

Scenario: credentials tied to the identifier you hash have turned up in breach data.

OrderActionWhat it changesWhy it is here
1webhook_callbackPOSTs the signed envelope to your callback URLYour backend forces the password reset and notifies the person; PasskeyBridge cannot email your end user
2step_up_authDeactivates the organization's active shadow identitiesThe next request through a shadow identity has to re-authenticate
3email_alertEmails the tenant admins groupTells your security team, who are the only people this action can reach
4log_eventRecords severity warningAudit marker

Automatic: no revocation. A soft signal dispatches one evaluate_tenant trust evaluation for the organization, debounced to one per signal type per 30 seconds, and the event records graduated_trust_evaluation.

Sending the password hash. Add credential_sha1, the uppercase SHA-1 of the password, to the ingest body and the pipeline runs a k-anonymity check against Have I Been Pwned and returns hibp_compromised and hibp_breach_count in the response. The plaintext never leaves your side.

Recipe 4: SS7 intercept response

Trigger: ss7_intercept (hard signal).

Scenario: signalling-layer interception of SMS or voice for a number you rely on.

OrderActionWhat it changesWhy it is here
1webhook_callbackPOSTs the signed envelope to your callback URLYour backend disables SMS-based verification for that number
2suspend_agentsDeactivates the organization's delegates and clears their scopesScope clearing on top of the automatic revocation
3freeze_credentialsInvalidates valid cached trust proofsNo offline proof survives the interception window
4revoke_tokensTears down open BLAST tunnel sessionsForces a fresh handshake
5email_alertEmails the tenant admins groupSS7 interception warrants a human
6log_eventRecords severity criticalAudit marker

Automatic: delegates and A2A negotiations revoked, as for every hard signal.

After it fires: the phone number is the compromised channel, so treat any SMS or voice verification on it as unavailable until the carrier confirms otherwise. Passkey authentication is unaffected by SS7.

Recipe 5: Device change monitoring

Trigger: device_change (soft signal). unusual_device is a second soft type and needs its own playbook.

Scenario: a new device appears on an account: a genuine upgrade, or an attacker after a credential theft.

OrderActionWhat it changesWhy it is here
1webhook_callbackPOSTs the signed envelope to your callback URLYour backend decides whether to challenge the session and whether to ask the user
2step_up_authDeactivates the organization's active shadow identitiesRe-authentication on the next request through one
3log_eventRecords severity infoA device-change trail on the event rows

Automatic: one debounced trust evaluation, no revocation.

Keep this one small. step_up_auth acts on every shadow identity the organization holds, not only the one behind this signal, so on a busy organization a frequent trigger makes it a blunt instrument. A playbook of webhook_callback plus log_event and a decision in your own backend is often the better shape for a routine soft signal.

Recipe 6: Velocity anomaly alert

Trigger: velocity_anomaly (soft signal).

Scenario: authentication attempts arriving faster, or from further apart, than a person could manage.

OrderActionWhat it changesWhy it is here
1slack_webhookPosts to the registered Slack destinationImmediate visibility while the burst is live
2webhook_callbackPOSTs the signed envelope to your callback URLYour backend raises monitoring or challenges the session
3log_eventRecords severity warningAudit marker

Automatic: one debounced trust evaluation, no revocation.

The trust engine watches velocity separately. Its velocity signal is computed from agent activity rows recorded through shield-agent-trust, more than 50 actions by one delegate in a 5-minute window, weighted up to 0.30 against the trust score. That is a different input from this signal, so a velocity anomaly in your application does not by itself move any delegate's score.

Alert on the rate instead of the event. For volume rather than individual signals, add an alert rule in the Observability tab on the events_per_hour metric with an operator, a threshold and a channel. Rules are evaluated every 5 minutes.

Recipe 7: Fraud ring detection

Trigger: credential_stuffing_attempt (soft signal).

Scenario: one campaign working through many accounts at once.

OrderActionWhat it changesWhy it is here
1webhook_callbackPOSTs the signed envelope to your callback URLYour backend correlates across accounts and rate-limits the source
2quarantineRevokes cross-references, invalidates cached proofs and deactivates shadow identitiesOrganization-wide, so reserve it for a campaign you are prepared to interrupt for everyone
3email_alertEmails the tenant admins groupCross-account investigation is human work
4slack_webhookPosts to the registered Slack destinationChannel visibility
5log_eventRecords severity warningAudit marker

Automatic: one debounced trust evaluation, no revocation.

Correlating across accounts. The clustering engine groups recent events for the organization by type, hashed-identifier prefix, time band and risk bucket, and surfaces them in Dashboard > Intelligence > Clusters on the Enterprise plan. The cross-reference API stores and lists bindings between SIM attestations and credentials for the organization; it has no lookup-by-hash action, so it answers "what is bound" rather than "who else shares this".

Consider the blast radius. If interrupting every agent and proof on the organization is too much for a stuffing campaign, drop action 2 and let the webhook drive a per-account response in your own system.

Recipe 8: Number port-out response

Trigger: port_out (hard signal). number_port and number_porting are separate hard types with the same treatment, and each needs its own playbook to match.

Scenario: the number has moved to another carrier.

OrderActionWhat it changesWhy it is here
1webhook_callbackPOSTs the signed envelope to your callback URLYour backend disables phone-based verification and locks the account
2suspend_agentsDeactivates the organization's delegates and clears their scopesScope clearing on top of the automatic revocation
3freeze_credentialsInvalidates valid cached trust proofsProofs issued before the port should not keep verifying
4email_alertEmails the tenant admins groupHuman review of a confirmed control change
5log_eventRecords severity criticalAudit marker

Automatic: delegates and A2A negotiations revoked, as for every hard signal.

Combining recipes and action limits

One playbook per signal. The oldest active playbook whose trigger matches is the one that runs, and no other playbook sees that signal. Two playbooks on sim_swap means the second is dead weight; combine the actions into the older row.

Order is display only. Actions all start together under Promise.all, each with its own 8-second budget, so there is no way to make an enforcement action complete before a notification goes out. If the sequence matters, drive it from your own backend off webhook_callback.

One of each type. The wizard refuses to add a type that is already present, so a playbook cannot hold two webhooks to different URLs. A second destination needs a second trigger type, or a fan-out in your own receiver.

Plan limits are not enforced. Starter's one playbook and Pro's ten are commercial terms; no function counts playbooks, and nothing refuses the next one.

Testing a playbook. Dashboard > Overview > Send test signal posts event_type: "test_signal" with x-pb-test-mode: true and metadata.source: "dashboard_simulator". Replay an attack in test mode sends six credential_stuffing_attempt signals, a failed_verification and a suspicious_login as test events and reports which of your playbooks matched, once per ten minutes. Both are real trips through the pipeline: the event rows are written with test_mode = true, nothing is metered, and only email_alert, slack_webhook and webhook_callback are suppressed (recorded as skipped_test_mode).

The exemption is the header or the key, never the event type. A signal with event_type: "test_signal" sent from your own backend with a live pb_live_ key is ordinary billed traffic: its playbook runs and its outbound actions really fire. What suppresses sends is x-pb-test-mode: true with a tenant-admin session, or a pb_test_ sandbox key. Neither of those suppresses hard-signal revocation, so never replay a hard signal against a production organization to "see what happens".

Hard signal reference.

Signal typeClassRevoked inline by the ingest pipeline
sim_swapHardAgent delegates and A2A negotiations
sim_swap_detectedHardAgent delegates and A2A negotiations
port_outHardAgent delegates and A2A negotiations
number_portHardAgent delegates and A2A negotiations
number_portingHardAgent delegates and A2A negotiations
device_compromiseHardAgent delegates and A2A negotiations
ss7_interceptHardAgent delegates and A2A negotiations
account_takeoverHardAgent delegates and A2A negotiations
scope_poisoningHardAgent delegates and A2A negotiations

Related from the blog