aiwarden

n8n community node for aiwarden — screen text for AI security threats (prompt injection, jailbreaks, PII, secrets) from any n8n workflow, without invoking an LLM.

Documentation

n8n-nodes-aiwarden

This package ships two nodes, both best-effort, per-workflow guardrails that
land all traffic in aiwarden under the n8n channel:

  1. aiwarden — a screening node you place around any AI node (Analyze Text /
    Analyze Agent Response). Works with any workflow. (documented below)
  2. aiwarden Chat Model — a wrapper you splice onto the wire between an n8n
    AI Agent and its Chat Model
    , so every model call is screened automatically
    with no IF nodes. (see "aiwarden Chat Model" below)

An n8n community node that wraps the AI node you already have
in a workflow (an AI Agent, an OpenAI / Anthropic node, an HTTP call to your LLM, …)
with a security guardrail. You keep your AI node unchanged; you insert the
aiwarden node right before it to screen the input, and optionally right after
it
to screen the reply. The aiwarden node never invokes an LLM itself — it
only inspects text (prompt injection, jailbreaks, PII, secrets, and more) by calling
aiwarden and returns an allow / warn / filter / block verdict you branch on.
Two operations:

Operation Endpoint Screens Verdict field
Analyze Text POST /analyze an incoming message, before your workflow acts action
Analyze Agent Response POST /analyze/{request_id}/complete a drafted reply, before it is shown status

The second operation is optional: call it only if you also want to govern what an
agent says back. It correlates to the first call through the request_id that
Analyze Text returns.

All traffic from this node lands in aiwarden under the n8n channel (the node
sends a fixed X-AIWarden-Source: n8n header), so it has its own security
profile, billing bucket, and managed-user channel.

What it is — and what it is NOT

It is a best-effort guardrail you add to a single workflow. You decide, per
workflow, to call the node on the incoming text (and optionally on the agent's
reply) and then honour the verdict — e.g. route to a "blocked" branch and return a
safe message when action = block, or suppress/rewrite a reply when
status = block.

It is NOT a tenant-wide control. The node only protects the workflows whose
authors explicitly add and wire it; anyone can remove it from a workflow. If you
need centralized, non-bypassable coverage, use aiwarden's proxy or browser
extension on the channels that support inline enforcement. This node complements
those; it does not replace them.

This honest scope is intentional. Do not present the node as tenant-wide
enforcement.

Installation

In a self-hosted n8n: Settings → Community Nodes → Install, enter
n8n-nodes-aiwarden. Or install manually in your n8n custom folder:

npm install n8n-nodes-aiwarden

See the n8n community nodes docs
for the full installation options.

Credentials

The node authenticates with an aiwarden API key sent as
Authorization: Bearer <key>. The key must be:

  • an API-channel key (the same kind used for the /ask and /analyze API),
  • scoped for analyze:prompt (or unscoped).

Create one from the aiwarden user portal (API Keys section). In n8n, add an
aiwarden API credential and paste the raw key (without the Bearer
prefix — the node adds it). The Base URL defaults to
https://api.aiwarden.ai; change it only for a self-hosted aiwarden.

The credential has no automatic test request: a test would have to run a real
/analyze call (which records an interaction and consumes quota), so the node
avoids side effects. Validate the connection with a real Analyze Text run.

Channel attribution (X-AIWarden-Source)

Every request sends a fixed header X-AIWarden-Source: n8n. This is what makes
the node's traffic show up under the dedicated n8n channel in aiwarden instead
of the generic api channel.

Usage

Start from the workflow you already have — a trigger, your AI node (AI Agent,
OpenAI, Anthropic, an HTTP call to your LLM…), and a reply. You do not change your
AI node
. You insert an aiwarden node just before it (screen the input) and,
optionally, a second one just after it (screen the reply), and use an IF node
to act on each verdict:

Your existing flow:
   Trigger  ->  YOUR AI NODE (AI Agent / OpenAI / ...)  ->  Reply to user

Same flow, with aiwarden wrapped around your AI node:

Trigger  (user message)
      |
      v
aiwarden  ->  Analyze Text             # NEW: screen the INPUT, before your AI node
      |        Text = {{ $json.chatInput }}
      |        returns { action, request_id, prompt_modified }
      v
IF  {{ $json.action }}  ==  "block"
      |
      |-- true  --> Reply: "Sorry, I can't help with that."   (skip the AI node entirely)
      |
      |-- false --> YOUR AI NODE         # UNCHANGED: your AI Agent / OpenAI / LLM call
                          |   drafts the reply as it does today
                          v
                    aiwarden  ->  Analyze Agent Response   # NEW (optional): screen the OUTPUT
                          |   Request ID    = {{ $('aiwarden').item.json.request_id }}
                          |   Agent Response = {{ $json.output }}   (your AI node's output field)
                          |   returns { status }
                          v
                    IF  {{ $json.status }}  ==  "block"
                          |-- true  --> Reply: safe fallback message
                          |-- false --> Reply: your AI node's answer

Your AI node stays exactly as it is — aiwarden does not replace it or call any LLM.
It only screens what goes in and what comes out.

Screen the incoming message (Analyze Text)

  1. Add the aiwarden node, operation Analyze Text.
  2. Map the user's message into Text.
  3. Branch your workflow on the returned action:
    • allow → continue as normal.
    • warn / filter → continue but log, or use the redacted text
      (prompt_modified).
    • block → stop and return a safe message; do not pass the text downstream.
  4. Optionally fill User email / Session ID so the activity is attributed
    in aiwarden analytics.
  5. Keep the returned request_id if you also plan to screen the reply.

Screen the agent's reply (Analyze Agent Response) — optional

  1. After a downstream node drafts the reply, add a second aiwarden node,
    operation Analyze Agent Response.
  2. Pass the Request ID from the Analyze Text step and the drafted reply as
    Agent Response.
  3. Branch on the returned status (block → suppress/replace the reply before
    it reaches the user; allow → send it).

Request / response reference

Analyze Text response (HTTP 200):

{
  "action": "block",
  "request_id": "…",
  "prompt_modified": "the text after any PII redaction (equals the original when unchanged)",
  "processing_time_ms": 1334,
  "redteam_events": [
    { "threat_type": "prompt_injection", "severity": "high", "action": "block" }
  ]
}

Analyze Agent Response response (HTTP 200):

{
  "status": "block",
  "reason": "Response blocked by Guard2: …",
  "request_id": "…",
  "record_id": "…",
  "redteam_events": [
    { "threat_type": "data_leak", "severity": "high", "action": "block" }
  ]
}

action (text) and status (response) are the fields to branch on. The node
calls the public aiwarden Core API at https://api.aiwarden.ai.

HTTP status codes are handled for you

aiwarden returns the verdict in the body but uses a non-2xx HTTP status when it
acts: an allow comes back as HTTP 200, a blocked verdict as HTTP 403
(with {"action":"block",...} in the body). The node sets
ignoreHttpStatusErrors, so it reads the body regardless of status and always
exposes action — you never have to handle status codes. Only an explicit
action: "block" should stop your workflow; a genuine error (invalid key, rate
limit, …) comes back as {"status":"error",...} with no action, so it naturally
falls through (fail-open) instead of throwing. Analysis typically takes ~1–8 s
(regex + on-prem classifier + translation on some paths); the node has a 20 s
timeout so it can never hang.

Latency — design the workflow to fail open

The analysis runs no LLM, but it does run the full detection stack (regex + an
on-prem AI classifier, plus translation on some paths). Observed latency ranges
from under a second to several seconds depending on the text and whether the
classifier path is warm. Do not put aiwarden on a critical path: set a
sensible timeout on the node and, on error or timeout, fail open (let the
workflow continue) rather than breaking it. aiwarden is a guardrail, never a
single point of failure.

aiwarden Chat Model (AI Agent wrapper)

For the n8n AI Agent, the package ships a second node — aiwarden Chat
Model
— that you place on the wire between the agent and its model instead
of adding Analyze nodes around the flow. It takes your real Chat Model as its
Model input and hands a guarded model back to the agent, so every model
call (including each step of a tool loop) is screened automatically.

Before:  AI Agent  --(Chat Model)-->  Azure OpenAI Chat Model

After:   AI Agent
            |  Chat Model
            v
         aiwarden Chat Model        # NEW: only the aiwarden API credential
            |  Model (input)
            v
         Azure OpenAI Chat Model    # UNCHANGED: your model + credentials, stays in n8n

Per model call the agent makes, the node:

  1. screens the prompt synchronously via POST /analyze — this is the gate:
    on action = block it returns a refusal to the agent without calling your
    LLM
    , and on filter it feeds the sanitized prompt_modified onward;
  2. calls your real model (delegated) and captures the reply + token usage;
  3. registers the reply + token cost + runs Guard2 in the background via
    POST /analyze/{request_id}/complete — this is fire-and-forget so it never
    adds latency to the agent's answer. (Only the input gate is synchronous, so
    the per-turn overhead is a single round-trip. If you need to block a reply
    inline, use the screening node's Analyze Agent Response instead.)

The node also forces non-streaming on the wrapped model so the input verdict can
gate the whole turn before any text is produced.

Your model and its credentials never leave n8n — aiwarden does not call the
LLM and never sees its credentials. The node needs only the aiwarden API
credential
.

n8n's AI Agent calls bindTools()/withConfig() on the model, which return
cloned model instances — the node re-applies its screening to those clones,
so tool-calling agents are covered too.

Wiring:

  1. Add aiwarden Chat Model next to your AI Agent.
  2. Connect your existing Chat Model to its Model input, then connect the
    aiwarden Chat Model node to the AI Agent's Chat Model input.
  3. Set the aiwarden API credential (same as the screening node).

Caveats (honest): the wrapper intercepts every model call, tool loops
included, so it adds one synchronous screening round-trip (/analyze) of latency
per call — set Analyze Timeout (Ms) to comfortably cover your aiwarden
deployment's analysis time (the hosted API can take several seconds per call) or
screening will time out and fail open. It disables streaming on that model so
the verdict can gate the whole turn before any text is emitted. It is
fail-open: if aiwarden is unreachable or times out, the call passes through to
your model unchanged. Same best-effort, per-workflow scope as the screening
node — not a tenant-wide control.

aiwarden Tool Guard (AI Agent tool wrapper)

The third node — aiwarden Tool Guard — governs what the agent does, not
what it says. You place it on the wire between the AI Agent and one of its
tools
: it takes your real tool (HubSpot, a Vector Store tool, an HTTP Request
tool, ...) as its Tool input and hands a guarded tool back to the agent.

Before:  AI Agent  --(Tool)-->  HubSpot "create contact"

After:   AI Agent
            |  Tool
            v
         aiwarden Tool Guard         # NEW: only the aiwarden API credential (AGENT-channel key)
            |  Tool (input)
            v
         HubSpot "create contact"    # UNCHANGED: your tool + credentials, stays in n8n

Per tool-call the agent decides to make, the node:

  1. asks aiwarden for a verdict via POST /api/agent/v1/execute
    (action_type=tool_use, tool_execution=caller) — this runs the agent
    governance
    aiwarden already has: agent status, managed-users (channel
    agent), 3-layer agent policies (tool allow/deny patterns), routing rules
    with applies_to=agent (real session_id/step_number), threat detection
    over the tool arguments, and rate limits;
  2. on deny it returns a refusal observation to the agent without executing
    the tool
    — the agent sees why and can adapt;
  3. on allow it executes your real tool (delegated) and returns its result.

The n8n AI Agent itself becomes a first-class aiwarden agent: the first
tool-call auto-registers it (status='discovered', passthrough log-only) under
the Agent ID the node sends (default n8n:<workflow id>). Activate it in
the aiwarden Agents page to turn on full governance; every tool-call then shows
up in the agent's dossier with agent_id, agent_tool_name and the workflow
name.

Credential: the same aiwarden API credential type, but the key inside
must be an agent-channel API key (the /api/agent/v1/* gateway rejects the
api-channel key the Chat Model / screening nodes use). Create one of type
agent in the aiwarden portal.

Caveats (honest): each tool-call adds one synchronous governance round-trip
(a policy lookup, much lighter than a full /analyze). Fail-open: if
aiwarden is unreachable or times out, the tool runs unchanged. A verdict of
pending_approval is enforced as deny in this version (a synchronous
tool-call cannot wait for a human; inline approval is a later phase). Same
best-effort, per-workflow scope as the other nodes — the workflow maker can
wire a tool straight to the agent and bypass the guard.

Use it together with the aiwarden Chat Model node for full coverage: the
Chat Model wrapper screens the content (prompts/replies, token cost), the
Tool Guard governs the actions (which tools run, with which arguments).

Build from source

npm install
npm run build   # tsc -> dist/, then copies icons into dist/

The compiled output in dist/ is what gets published. Publish to npm with
provenance
via GitHub Actions (required for n8n Creator-portal verification
since May 2026); that is done from the publisher's own npm org.

License

MIT

Discussion