Human-in-the-loop for security agents

Containment is a decision, not a trigger.

The on-duty analyst authorizes containment from their phone, and the authorization is saved with the incident.

How does a SOC AI agent get an analyst to authorize a containment action?

Pushary lets a SOC AI agent get an analyst to authorize a containment action from their phone. Put one call before the host isolation, the account disable or the block. The analyst taps Approve or Deny on the lock screen. Your agent waits for that answer instead of firing on a confidence score. If nobody answers in time, the containment does not run. Every authorization is saved to attach to the incident record.

What needs a yes

The calls that should not be automatic

isolateHost(hostId)
Pulling a machine off the network stops an intrusion. It also stops the person using it. On the wrong host during business hours, that is its own incident.
disableAccount(userId)
Disabling the wrong account locks out someone who was doing their job. A false positive here hits a real person right away, and they call the help desk within minutes.
blockIndicator(type, value)
Blocking an indicator that turns out to be a shared IP or domain takes down services that had nothing to do with the alert.
revokeSessions(userId)
Revoking every session is a fair response to stolen credentials and an unfair one to a noisy detection. Telling those apart is the analyst's job.

The code

One call inside the step you already have

Wrap the action, not the whole agent. Everything the agent does that is safe keeps running without asking anyone.

bash
pip install pushary
one call
import os
from pushary import PusharyServer

px = PusharyServer(api_key=os.environ["PUSHARY_API_KEY"])

def contain(alert, action):
    # Enrichment and evidence collection never wait for anyone.
    context = enrich(alert)

    if action.reversible and context.confidence > 0.95:
        return apply(action)

    decision = px.decisions.ask(
        external_id=alert.duty_analyst_id,
        type="confirm",
        question=(
            f"{action.summary} on {action.target}? "
            f"Confidence {context.confidence:.0%}. Impact: {action.user_impact}."
        ),
    )

    if not decision["approved"]:
        return annotate(alert, "containment not authorized")
    return apply(action)

Who answers

The approver is not at a desk

The approver is the analyst on duty, and out of hours that is one person covering a lot. The usual setup is a bot posting the containment in a channel with a button. That works by day. At 03:00, nobody may be reading that channel. Then the intrusion keeps going while the right decision waits. Pushary reaches the analyst's phone, by the id your duty rota already uses.

If we wait for a human, does the attacker not just get more time?

Sometimes, which is why you choose per action rather than per incident. Enrichment, evidence collection and anything you can cleanly undo should run now and be reviewed after. That covers most of what a SOC agent does. Gate the actions whose cost when wrong is close to the cost of the intrusion: isolating a production host, disabling an executive's account, blocking a shared service. For those, firing on a confidence score only moves the outage somewhere else. Gating works when the answer comes back in a minute, instead of whenever someone checks a channel. And when time runs out, the action does not run, and the saved record shows that it timed out.

Worth reading: NIST SP 800-61 on computer security incident handling.

$99/ month, Partner plan

Add it to your product. Your users never make a Pushary account or pay us.

What the Partner plan covers

FAQ

Questions, answered

Can we auto-approve high confidence detections and gate the rest?
Yes, and that is the shape we recommend. It lives in your code. Branch on reversibility and confidence. Apply the action directly when both are comfortable, and ask the analyst otherwise. For example, apply a reversible action above 95% confidence and ask about everything else. Keep the gated set small, so analysts do not start approving on reflex.
Does this replace our on-call paging tool?
No. Paging tells a person something is happening. Pushary asks them one specific question and returns the answer to the agent that is waiting, which a paging tool does not do. Most teams keep both, because the alert and the authorization are different jobs.
What does the incident record look like afterwards?
One saved row per authorization. It holds the question as the analyst saw it, including the confidence and impact you put in it, plus their answer, who they are and the time. You can export it. Pushary keeps it for your plan's history window: 90 days on Partner Launch, 365 on Partner Growth. Each answer is also sent as a signed webhook, if you want it written straight into your case management.
What if the analyst is mid-incident and misses it?
The containment does not happen. That is the safe default for an action you judged risky enough to gate. Your agent can then ask a secondary analyst by a different user id. Set the timeout to match how long you can afford to wait on that action. The unanswered request stays saved and visible.

Put a person on the step that needs one.

Connect a user once, ask with one call, and run the action only on a yes. Every answer is saved.

Start free