How it works

Three stages. One pull request your team reviews.

  1. Scan

    acme-corp / payments-agent

    1/3

    1. Scan

    2. Attack

    3. Protect

    GitHub connected · Armorer Security installed on acme-corpDeep agentic analysis · ~18m left5 of 10ETA confidence: medium · heartbeat 4s ago

    Choose the repository to scan first

    4 repositories granted · Read-only (Contents)

    • acme/payments-agentPrivateLangChain + MCP tools detected
    • acme/support-copilotPrivateOpenAI Assistants detected
    • acme/data-pipelinePrivateNo agent code detected
    • acme/docs-sitePublicNo agent code detected
    Start scan on payments-agent →
    UNTRUSTED INPUTSTHE AGENTITS TOOLSWHAT THOSE REACHInbound emailuntrusted sourceWeb contentuntrusted sourceVendor docsuntrusted sourcepayments-agentLangChain · 3 toolsbrowse_webtoolquery_ledgertoolsend_paymenttoolStripe APIcredential: live keyPostgres · ledgerprivileged effectSlack #financeprivileged effectRetrieval indexblind spot

    Swipe the map sideways to follow a route end to end →

    • Candidate routes
    • Connected
    • Could not resolve

    Routes found

    1 critical · 1 high · 1 medium

    Exploring how tool calls chain — 3 candidate paths so far

    • #1CRITICALemail → browse_web → send_paymentcandidate · potential
    • #2HIGHvendor docs → query_ledger exfilcandidate · potential
    • #3MEDIUMweb → memory poisoningblocked

    What this scan could not see

    • Retrieval index — not reachable from the twin
    • 2 unknown frontiers on the attack map

    Coverage is not completeness — blind spots stay listed.

  2. Attack

    acme-corp / payments-agent

    2/3

    1. Scan

    2. Attack

    3. Protect

    Criticalemail → browse_web → send_payment

    Armorer copilot

    Autonomous · asks when needed

    Approve the attack run on path #1? Approved

    Isolated rebuilt twin · crafted email injection · no production access

    Approve path #1Review the path
    UNTRUSTED INPUTSTHE AGENTITS TOOLSWHAT THOSE REACHInbound emailuntrusted sourceWeb contentuntrusted sourceVendor docsuntrusted sourcepayments-agentLangChain · 3 toolsbrowse_webtoolquery_ledgertoolsend_paymenttoolStripe APIcredential: live keyPostgres · ledgerprivileged effectSlack #financeprivileged effectRetrieval indexblind spot

    Swipe the map sideways to follow a route end to end →

    • Proven path
    • Connected
    • Could not resolve

    A crafted email steers the agent to fetch a web page, and what that page says reaches the arguments of a payment.

    1. 1

      email

      untrusted source

    2. 2

      browse_web

      external content

    3. 3

      send_payment

      Stripe API · live key

    4. A drafted $4,900 transfer to an attacker-controlled account

  3. Protect

    acme-corp / payments-agent

    3/3

    1. Scan

    2. Attack

    3. Protect

    BeforeAfter fix2 files changed+18−3armorer/fix-path-1
    tools/browse_web.py+4 −1
    • def fetch(url: str) -> str:
    • Removed return page_text
    • Added return Provenance.tag(page_text, source="web", trust="untrusted")
    agents/payments_agent.py+14 −2
    • def send_payment(amount, dest, *, ctx):
    • Added if Provenance.untrusted_influence(ctx, on=("amount", "dest")):
    • Added raise RequireHumanReview("untrusted content shaped payment args")
    • return stripe.transfer(amount, dest)

    Why this control?

    The cheaper options don’t hold. Blocking browse_web breaks three approved workflows. Filtering the page text is bypassable. Checking provenance at the argument boundary is the narrowest place where the attack must pass and your approved work never does.

    Your reviewers merge itArmorer never merges. Two approvals are required on this repo.

    Path #1 · with the proposed control

    1. Inbound email

      untrusted source

    2. browse_web
    3. INFLUENCES_ARGUMENT
      Argument provenance checkcontrol · proposed

      inserted at the argument boundary

    4. BLOCKED
      send_payment
    5. USES_CREDENTIAL
      Stripe API

      credential: live key

    Verified in the twin before anything ships

    • Exploit path #1re-ran 20× in the isolated twinBLOCKED 20/20
    • Approved workflowsyour 12 golden tasksSTILL PASSING 12/12
    • Added latencyat the consequential action+3.4 ms avg

Customers

A risk question becomes a decision.

We had an agent we weren't comfortable giving more access to. Armorer showed us how it could be abused. It stopped being a debate about opinions.
TILCO TradingTilen Terčelj Schweizer · CEO, TILCO Trading Ltd
My worry with a security safeguard is that it quietly breaks something a customer depends on. Armorer made that a test, not an assumption.
HeyHireDaniel Sakhai · CTO, HeyHire

Backed by Y Combinator · Fall 2026