WORKFLOW LIBRARY

Security automation,
ready to run.

Real workflows. Not demos. Click Run Demo on any live card — watch the AI engine analyze phishing emails, flag impossible travel, identify malware, or triage suspicious URLs and generate containment plans in real time.

LIVE trigger: email_received

Phishing Email Triage

Full-stack phishing analysis: extract IOCs, enrich URLs against URLhaus, classify intent with GPT-4o-mini, score 0–100, route to quarantine or monitor. 9 steps, ~8 seconds end-to-end.

9 steps · ~8s runtime · GPT-4o-mini classifier
phishing-triage.yaml
name: Phishing Email Triage
version: "1.0"
trigger: email_received
inputs:
  - name: sender
  - name: subject
  - name: body
  - name: headers
  - name: attachments

steps:

  # 1-4. Extract IOCs (URLs, IPs, emails, base64)
  - id: extract_urls
    type: regex.extract
    with:
      input: "{{ inputs.body }}"
      pattern: "https?://[^\s\"'<>)\]\}]+"
      global: true

  - id: extract_ips
    type: regex.extract
    with:
      input: "{{ inputs.body }} {{ inputs.headers }}"
      pattern: "\\b(IP address pattern)\\b"
      global: true

  - id: extract_emails
    type: regex.extract
    with:
      input: "{{ inputs.body }}"
      pattern: "[a-zA-Z0-9._%+\\-]+@[a-zA-Z0-9.\\-]+\\.[a-zA-Z]{2,}"
      global: true

  - id: extract_base64
    type: regex.extract
    with:
      input: "{{ inputs.body }}"
      pattern: "[A-Za-z0-9+/]{40,}={0,2}"
      global: true

  # 5. URLhaus reputation (no API key needed)
  - id: enrich_urls
    type: http.post
    on_failure: continue
    with:
      url: "https://urlhaus-api.abuse.ch/v1/url/"
      headers:
        Content-Type: "application/x-www-form-urlencoded"
      body:
        url: "{{ steps.extract_urls.output.all[0] }}"

  # 6. LLM intent classification
  - id: analyze_intent
    type: llm.analyze
    with:
      model: gpt-4o-mini
      temperature: 0.1
      json_output: true
      system: "You are a senior email security analyst..."
      prompt: "Classify this email. Return JSON: classification, confidence, reasoning, signals"

  # 7. Combine IOC + LLM into 0-100 risk score
  - id: score
    type: transform
    with:
      compute:
        ioc_component: "min(url_count*15,30) + min(ip_count*10,10) + base64_bonus"
        llm_component: "confidence * direction_factor * 0.6"
        final_score:   "clamp(ioc + llm, 0, 100)"
        severity:      "score>=70?critical : score>=40?high : score>=20?medium : low"

  # 8. Route: quarantine if score >= 70, else monitor
  - id: route
    type: conditional
    with:
      if: "steps.score.output.final_score >= 70"

  # 9a/9b. Output verdict with IOCs and LLM reasoning
  - id: recommend_quarantine
    type: output
    if: "steps.route.output.result == true"
    with:
      value:
        verdict:             "{{ steps.analyze_intent.output.parsed.classification }}"
        recommended_action: quarantine
        score:               "{{ steps.score.output.final_score }}"
        severity:            "{{ steps.score.output.severity }}"
        llm_reasoning:      "{{ steps.analyze_intent.output.parsed.reasoning }}"
        phishing_signals:   "{{ steps.analyze_intent.output.parsed.phishing_signals }}"
        legitimate_signals: "{{ steps.analyze_intent.output.parsed.legitimate_signals }}"

  - id: recommend_monitor
    type: output
    if: "steps.route.output.result == false"
    with:
      value:
        verdict:             "{{ steps.analyze_intent.output.parsed.classification }}"
        recommended_action: monitor
        score:               "{{ steps.score.output.final_score }}"
        severity:            "{{ steps.score.output.severity }}"
        llm_reasoning:      "{{ steps.analyze_intent.output.parsed.reasoning }}"
        phishing_signals:   "{{ steps.analyze_intent.output.parsed.phishing_signals }}"
        legitimate_signals: "{{ steps.analyze_intent.output.parsed.legitimate_signals }}"

Run Demo

Submit a suspicious email. The engine runs all 9 steps live.

LIVE trigger: alert_triggered

Suspicious Login Investigation

Impossible-travel detection: geolocates current and prior login IPs, computes haversine distance and km/h, diffs device fingerprints, classifies risk with GPT-4o-mini, routes to block+MFA-reset, challenge, or monitor. 8 steps, ~6 seconds end-to-end.

8 steps · ~6s runtime · ip-api.com + GPT-4o-mini
suspicious-login.yaml
name: Suspicious Login Investigation
trigger: alert_triggered
inputs:
  - name: user_id
  - name: ip
  - name: user_agent
  - name: timestamp
  - name: last_known_ip
  - name: last_known_location
  - name: last_login_at

steps:

  # 1. Parse and normalize event fields
  - id: parse_event
    type: transform

  # 2. Geolocate current IP (ip-api.com, no key)
  - id: geoip_enrich
    type: http.get
    with:
      url: "http://ip-api.com/json/{{ inputs.ip }}?fields=status,country,city,lat,lon,isp,proxy,hosting"

  # 3. Geolocate prior known-good IP
  - id: geoip_enrich_prior
    type: http.get
    with:
      url: "http://ip-api.com/json/{{ inputs.last_known_ip }}?fields=status,country,city,lat,lon,isp,proxy,hosting"

  # 4. Haversine distance + impossible travel flag (>900 km/h)
  - id: impossible_travel
    type: transform
    with:
      compute:
        distance_km:   "haversine(lat1, lon1, lat2, lon2)"
        elapsed_hours: "(timestamp2 - timestamp1) / 3600000"
        speed_kmh:     "distance_km / elapsed_hours"
        is_impossible: "speed_kmh > 900 ? 'true' : 'false'"

  # 5. Parse OS/browser from user-agent strings
  - id: device_diff
    type: transform
    with:
      compute:
        current_os:      "parseOS(ua)"
        current_browser: "parseBrowser(ua)"
        device_changed:  "current_os !== prior_os ? 'true' : 'false'"

  # 6. GPT-4o-mini risk classification
  - id: llm_reasoning
    type: llm.analyze
    with:
      model:       gpt-4o-mini
      json_output: true
      prompt:      "Classify: benign|suspicious|malicious. Return JSON: classification, confidence, reasoning, risk_signals, benign_signals"

  # 7. Combine into 0-100 score (travel:40 + vpn:20 + device:15 + llm:25)
  - id: risk_score
    type: transform
    with:
      compute:
        final_score: "clamp(travel_pts + vpn_pts + device_pts + llm_pts, 0, 100)"
        severity:    "score>=70?critical : score>=40?high : medium"

  # 8a. score≥70 → block + force MFA reset
  - id: block_and_force_mfa_reset
    type: output
    if: "steps.risk_score.output.final_score >= 70"

  # 8b. 40–69 → challenge with MFA step-up
  - id: challenge_mfa
    type: output
    if: "steps.risk_score.output.final_score < 70"

Run Demo

Lagos login 9 minutes after Seattle — watch the engine flag impossible travel and block the account.

LIVE trigger: alert_triggered (EDR)

Malware Hash Lookup & Containment

Paste a SHA256 hash: validates format, queries MalwareBazaar (no key required), extracts malware family, scores severity 0–100 with GPT-4o-mini MITRE ATT&CK mapping, and emits a structured containment plan. 7 steps, ~6 seconds.

7 steps · ~6s runtime · MalwareBazaar + GPT-4o-mini
malware-hash-lookup.yaml
name: Malware Hash Lookup & Containment
trigger: alert_triggered
inputs:
  - name: sha256
  - name: host_id
  - name: process_name
  - name: observed_at

steps:

  # 1. Normalize inputs
  - id: parse_input
    type: transform

  # 2. Validate SHA256 format (64 hex chars)
  - id: validate_hash
    type: regex.extract
    with:
      input: "{{ inputs.sha256 }}"
      pattern: "^[a-fA-F0-9]{64}$"

  # 3. MalwareBazaar hash lookup (POST, no API key)
  - id: malwarebazaar_lookup
    type: http.post
    on_failure: continue
    with:
      url: "https://mb-api.abuse.ch/api/v1/"
      headers:
        Content-Type: "application/x-www-form-urlencoded"
      body:
        query: get_info
        hash:  "{{ inputs.sha256 }}"

  # 4. Extract family from signature/tags (Emotet, TrickBot, Cobalt Strike…)
  - id: family_classification
    type: transform
    with:
      compute:
        family: "matchKnownFamily(signature + tags)"
        first_seen: "{{ steps.malwarebazaar_lookup.output.body.data[0].first_seen }}"

  # 5. GPT-4o-mini: description, host impact, MITRE ATT&CK, containment bullets
  - id: llm_summary
    type: llm.analyze
    with:
      model:       gpt-4o-mini
      json_output: true
      prompt:      "Given MalwareBazaar data for {{ steps.family_classification.output.family }}, return JSON: description, host_impact, mitre_techniques[], containment_steps[]"

  # 6. Score 0–100: known family (40) + recent (20) + in bazaar (20) + vendor hits (20)
  - id: severity_score
    type: transform
    with:
      compute:
        score:    "clamp(family_pts + recent_pts + bazaar_pts + vendor_pts, 0, 100)"
        severity: "score>=70?critical : score>=40?high : medium"

  # 7. Emit containment plan: isolate_host, kill_process, block_hash_at_edr, quarantine_file
  - id: containment_plan
    type: output
    with:
      value:
        family:           "{{ steps.family_classification.output.family }}"
        score:            "{{ steps.severity_score.output.score }}"
        mitre_techniques: "{{ steps.llm_summary.output.parsed.mitre_techniques }}"
        actions:
          isolate_host:      "{{ inputs.host_id }}"
          block_hash_at_edr: "{{ inputs.sha256 }}"
          kill_process:      "{{ inputs.process_name }}"
          quarantine_file:   "{{ inputs.process_name }}"

Run Demo

Submit a known Emotet hash. The engine queries MalwareBazaar, classifies the family, and generates a containment plan in real time.

LIVE trigger: alert_triggered (proxy / SIEM)

Phishing URL / Domain Reputation Triage

Paste any URL: normalizes it, checks domain age via RDAP, queries URLhaus for known-malicious matches, inspects TLS cert metadata, detects homoglyph brand lookalikes, classifies with GPT-4o-mini (MITRE T1566.002), scores 0–100, and emits a structured proxy/DNS block + inbox quarantine plan. 8 steps, ~8 seconds.

8 steps · ~8s runtime · RDAP + URLhaus + crt.sh + GPT-4o-mini
phishing-url-triage.yaml
name: Phishing URL / Domain Reputation Triage
trigger: alert_triggered
inputs:
  - name: url
  - name: brand_list

steps:

  # 1. Normalize URL — strip tracking params, extract host/domain
  - id: url_normalize
    type: transform
    with:
      compute:
        hostname:   "new URL(inputs.url).hostname"
        domain:     "hostname.split('.').slice(-2).join('.')"
        has_ip_host: "/^\\d+(\\.\\d+){3}$/.test(hostname)"

  # 2. Domain age via RDAP (free, no key) — flag domains < 30 days old
  - id: domain_age_check
    type: http.get
    on_failure: continue
    with:
      url: "https://rdap.org/domain/{{ steps.url_normalize.output.domain }}"

  # 3. URLhaus lookup — known-malicious URL + host (no API key)
  - id: urlhaus_lookup
    type: http.post
    on_failure: continue
    with:
      url: "https://urlhaus-api.abuse.ch/v1/url/"
      headers:
        Content-Type: "application/x-www-form-urlencoded"
      body:
        url: "{{ steps.url_normalize.output.url_clean }}"

  # 4. TLS cert check via crt.sh — flag self-signed / LE < 7 days
  - id: tls_cert_check
    type: http.get
    on_failure: continue
    with:
      url: "https://crt.sh/?q={{ steps.url_normalize.output.domain }}&output=json&limit=5"

  # 5. Homoglyph detection — lookalike brands (paypa1, g00gle, etc.)
  - id: homoglyph_check
    type: transform
    with:
      compute:
        brand_match_found: "matchLookalike(hostname_normalized, brand_list)"
        suspicious_tld:    "hostname.endsWith('.xyz') || endsWith('.tk') ..."

  # 6. GPT-4o-mini — classify, MITRE T1566.002, containment guidance
  - id: gpt_analysis
    type: llm.analyze
    with:
      model:       gpt-4o-mini
      json_output: true
      prompt:      "Classify URL. Return JSON: classification, confidence, reasoning, mitre_techniques[], phishing_signals[], legitimate_signals[]"

  # 7. Score 0–100 (URLhaus:35, young domain:20, homoglyph:20, IP host:10, cert:10, LLM:30)
  - id: severity_score
    type: transform
    with:
      compute:
        score:    "clamp(urlhaus_pts + young_domain_pts + homoglyph_pts + ip_pts + cert_pts + llm_pts, 0, 100)"
        severity: "score>=70?critical : score>=40?high : score>=20?medium : low"

  # 8. Containment: block at proxy/DNS, notify user, quarantine inbox
  - id: containment_recommendation
    type: output
    with:
      value:
        classification: "{{ steps.gpt_analysis.output.parsed.classification }}"
        score:           "{{ steps.severity_score.output.score }}"
        severity:        "{{ steps.severity_score.output.severity }}"
        containment_actions:
          block_at_proxy:    "{{ steps.url_normalize.output.domain }}"
          block_at_dns:      "{{ steps.url_normalize.output.hostname }}"
          notify_user:       "Alert user who clicked this URL"
          quarantine_emails: "Search inbox for domain {{ steps.url_normalize.output.domain }}"

Run Demo

Submit a suspicious URL. The engine checks domain age, URLhaus, TLS certs, and homoglyph patterns — then GPT-4o-mini maps it to MITRE ATT&CK and recommends containment.

LIVE Multi-stage chain trigger: alert_triggered (EDR)

Ransomware Containment & IR Chain

Full incident response pipeline with conditional branching: parses EDR alert, looks up hash in MalwareBazaar, scores severity 0–100 with GPT-4o-mini, then branches — high-severity hosts get network-isolated, user-suspended, and volume-snapshotted. All paths collect forensic artifacts, extract IOCs, generate an exec-ready MITRE ATT&CK summary, post to Slack, and open a P1 ticket. 13 steps across 5 stages.

13 steps · 5 stages · ~12s runtime · MalwareBazaar + GPT-4o-mini
Stage 1
Detection & Enrichment
alert_parse hash_reputation host_context
Stage 2
Triage Decision
severity_score containment_decision
≥70 → isolate<70 → skip
Stage 3
Containment (score ≥ 70)
isolate_host disable_user snapshot_volumes
Stage 4
Forensics
collect_artifacts ioc_extraction
Stage 5
Notify & Report
incident_summary slack_notify ticket_create
ransomware-ir-chain.yaml
name: Ransomware IR Chain
trigger: alert_triggered
inputs:
  - name: host_id
  - name: user_id
  - name: sha256
  - name: process_name
  - name: behavior_flags

steps:

  # ── Stage 1: Detection & Enrichment ─────────────────────────────
  - id: alert_parse
    type: transform      # extract fields, score behavior indicators

  - id: hash_reputation
    type: http.post      # MalwareBazaar lookup (no API key)
    on_failure: continue

  - id: host_context
    type: transform      # prod/exec/dc = critical, dev = standard

  # ── Stage 2: Triage Decision ─────────────────────────────────────
  - id: severity_score
    type: llm.analyze    # GPT-4o-mini scores 0–100, MITRE reasoning
    with:
      model: gpt-4o-mini
      json_output: true

  - id: containment_decision
    type: conditional   # BRANCH: score >= 70 → isolate, else monitor
    with:
      if: "steps.severity_score.output.parsed.score >= 70"

  # ── Stage 3: Containment (only if score >= 70) ──────────────────
  - id: isolate_host
    type: transform      # simulated CrowdStrike /contain API
    if: "steps.containment_decision.output.result == true"

  - id: disable_user
    type: transform      # simulated Okta deactivate
    if: "steps.containment_decision.output.result == true"

  - id: snapshot_volumes
    type: transform      # simulated AWS EBS snapshot for forensics
    if: "steps.containment_decision.output.result == true"

  # ── Stage 4: Forensics Collection ───────────────────────────────
  - id: collect_artifacts
    type: transform      # assemble process tree, net conns, modified files

  - id: ioc_extraction
    type: llm.analyze    # IPs, domains, hashes, mutex, dropped files
    with:
      model: gpt-4o-mini
      json_output: true

  # ── Stage 5: Notification & Reporting ───────────────────────────
  - id: incident_summary
    type: llm.analyze    # exec-ready summary, T1486 + T1490 ATT&CK map
    with:
      model: gpt-4o-mini
      json_output: true

  - id: slack_notify
    type: transform      # mock webhook → #security-incidents

  - id: ticket_create
    type: output         # P1 Jira ticket with full IR dossier

Run Demo

Submit a canned EDR alert. The engine runs all 5 stages — watch the containment decision branch in real time based on the severity score.

LIVE Cloud trigger: alert_triggered (cloud monitoring / scheduled)

Cloud Storage Exposure Hunter

Detects publicly exposed S3 and GCS buckets: probes for public listing, samples up to 50 objects, flags sensitive patterns (SQL dumps, .env files, credentials, PEM keys, customer CSVs), HEAD-checks the first hit for content type, classifies sensitivity and blast radius with GPT-4o-mini, recommends containment (block / rotate-and-quarantine / monitor), and maps to MITRE T1530 + T1078. 10 steps, ~15s end-to-end.

10 steps · ~15s runtime · S3 + GCS + GPT-4o-mini
cloud-storage-exposure-hunter.yaml
name: Cloud Storage Exposure Hunter
trigger: alert_triggered
inputs:
  - name: bucket_url
    description: "s3://bucket, gs://bucket, or HTTPS URL"

steps:

  # 1. Normalize URL → provider + bucket_name
  - id: normalize_bucket
    type: transform

  # 2. Probe public listing (S3 list-type=2 / GCS JSON)
  - id: probe_public_listing
    type: http.get
    on_failure: continue

  # 3. Count total exposed objects, sample 20 keys
  - id: count_objects
    type: transform

  # 4. Flag sensitive patterns (.sql, .env, .pem, credentials, prod)
  - id: flag_sensitive_patterns
    type: transform

  # 5. HEAD first sensitive key → Content-Type + size
  - id: head_sample_object
    type: http.get
    on_failure: continue

  # 6. GPT-4o-mini sensitivity: score 0-100, data_classes, blast_radius
  - id: llm_classify_sensitivity
    type: llm.analyze
    with:
      model: gpt-4o-mini
      json_output: true

  # 7. GPT-4o-mini action: block-public-access | rotate-keys-and-quarantine | monitor
  - id: llm_recommend_action
    type: llm.analyze
    with:
      model: gpt-4o-mini
      json_output: true

  # 8. MITRE: T1530 always; T1078 if credentials exposed
  - id: mitre_mapping
    type: transform

  # 9. Severity: ≥80 critical, 50-79 high, 20-49 medium, <20 low
  - id: severity_calc
    type: transform

  # 10. Output verdict panel
  - id: output
    type: output
Live Demo Uses public S3/GCS endpoints — no credentials required
SAMPLES:
LIVE trigger: alert_triggered (brand monitoring / scheduled)

Brand Impersonation & Typosquat Hunter

Brand-protection pipeline: pulls all TLS certs containing your brand token from crt.sh, dedupes candidates, scores each by Levenshtein distance and homoglyph visual similarity, checks registration age via RDAP (flags domains <14 days), queries URLhaus for known-malicious matches, classifies with GPT-4o-mini (MITRE T1583.001), and emits a ranked verdict panel with recommended actions (file UDRP / monitor / report / ignore). 10 steps, ~15s end-to-end.

10 steps · ~15s runtime · crt.sh + RDAP + URLhaus + GPT-4o-mini
brand-impersonation-hunter.yaml
name: Brand Impersonation & Typosquat Hunter
trigger: alert_triggered
inputs:
  - name: brand_domain
    description: "Brand domain to protect (e.g. stripe.com)"

steps:

  # 1. Derive brand token from domain (e.g. 'stripe' from 'stripe.com')
  - id: extract_brand
    type: regex.extract
    with:
      input:   "{{ inputs.brand_domain }}"
      pattern: "^([^.]+)"

  # 2. crt.sh — all certs issued containing brand token as substring
  - id: crt_lookup
    type: http.get
    on_failure: continue
    with:
      url: "https://crt.sh/?q=%25{{ steps.extract_brand.output.brand_token }}%25&output=json&deduplicate=Y"

  # 3. Dedupe + filter legit subdomains from brand domain itself
  - id: candidates_filter
    type: transform
    with:
      compute:
        candidates_raw: "dedupe(filter(crt_results, not(isLegitSubdomain)))"

  # 4. Levenshtein + homoglyph score (0↔g, 1↔l, rn↔m, etc.)
  - id: homoglyph_score
    type: transform
    with:
      compute:
        scored_candidates: "sortDesc(map(candidates, scoreBySimilarity))"

  # 5. RDAP — registration date + registrar for top candidate
  - id: rdap_top
    type: http.get
    on_failure: continue
    with:
      url: "https://rdap.org/domain/{{ steps.homoglyph_score.output.top_candidate }}"

  # 6. URLhaus — known-malicious check for top candidate
  - id: urlhaus_top
    type: http.post
    on_failure: continue
    with:
      url: "https://urlhaus-api.abuse.ch/v1/host/"
      body:
        host: "{{ steps.homoglyph_score.output.top_candidate }}"

  # 7. GPT-4o-mini — classify each as likely-typosquat | suspicious-lookalike | benign-coincidence
  - id: llm_classify
    type: llm.analyze
    with:
      model:       gpt-4o-mini
      json_output: true
      prompt:      "Classify candidates. MITRE T1583.001. Return JSON: overall_risk, overall_score, summary, classifications, top_offenders[], brand_protection_actions[]"

  # 8–10. Score, severity, output verdict panel
  - id: brand_verdict
    type: output
    with:
      value:
        score:            "{{ steps.risk_score.output.score }}"
        severity:         "{{ steps.risk_score.output.severity }}"
        total_candidates: "{{ steps.candidates_filter.output.candidates_count }}"
        top_offenders:    "{{ steps.llm_classify.output.parsed.top_offenders }}"
        classifications:  "{{ steps.llm_classify.output.parsed.classifications }}"
        recommended_actions: "file UDRP | monitor | report | ignore"

Run Demo

Enter a brand domain. The engine scans certificate transparency logs, scores every look-alike by homoglyph similarity, checks registration age, and classifies each with GPT-4o-mini. Real typosquats surface in ~15 seconds.

NEW trigger: alert_triggered

SaaS Misconfiguration Hunter

Audit OAuth app permissions, S3 ACLs, AWS IAM policies, and Google Workspace scopes. Score misconfigs 0–100 with prioritized remediation steps and runbooks.

8 steps · ~12s runtime · AWS + GCP + OAuth coverage

Run Demo

Submit an AWS account. The engine audits S3 ACLs, IAM policies, and OAuth scopes.

NEW trigger: alert_triggered

Threat Intel Enrichment

Correlate IOCs (IP, domain, URL, hash) against AlienVault OTX, AbuseIPDB, and Google Safe Browsing. Multi-source intelligence in seconds — not minutes.

5 steps · ~6s runtime · 3 threat feeds

Run Demo

Submit an IP address. The engine checks it against all 3 threat feeds simultaneously.

NEW trigger: alert_triggered

Vulnerability Prioritization

Ingest CVE feeds, cross-reference with your asset inventory, and rank by CVSS + business context. Prioritize what actually puts you at risk, not what the scanner flagged.

7 steps · ~10s runtime · NVD + EPSS + CISA KEV

Run Demo

Submit a CVE. The engine fetches CVSS from NVD, checks CISA KEV, calculates EPSS.

Run these on your own data

Connect your own triggers and run any workflow against real events. Plans start at $299/mo.

See plans →
SUBSCRIBE NOW

Start automating today.

Three plans, no seat caps, no per-alert fees. Run any workflow live right now — then subscribe when you're ready.

Need to compare features first? See full pricing →

Request a Workflow

Want a workflow we don't have yet?

Tell us what alert is eating your week. Every submission goes directly to the founder's inbox — and the highest-signal ones ship next.

Got it. You're on the list.

Check your inbox — confirmation on the way.

See pricing