Safeguard Docs
Integrations

IAST agents

Install the Safeguard IAST agent in your Java, Node.js or Python application. What it reports, the agent token it needs, configuration, overhead and uninstall.

Availability

Always-on reporting is switched on per workspace. If you do not see the IAST agents cards under Integrations, ask your Safeguard contact. The agent packages themselves are public on registry.safeguard.sh.

What it does

The Safeguard IAST agent runs inside your application and watches untrusted request input travel to a dangerous operation: a SQL statement, a shell command, a file path. When request input reaches one of those operations, the agent reports the flow with the route, the parameter, and the file and line of the code that consumed it. Findings appear as IAST vulnerabilities on the project you chose when you issued the agent token, de-duplicated by route, sink and stack, with a "last seen" for every agent process. The cards are under Integrations > Configure > IAST agents, one per language.

There are agents for Java (and every JVM language), Node.js (JavaScript and TypeScript) and Python. .NET, Go, Ruby and PHP agents are not available yet.

The agent has two modes:

  • Always-on. The agent reports to https://api.safeguard.sh/gpt/api/v1/iast for as long as the application runs. This is what this page sets up.
  • Scan mode. The agent reports to the collector a running Safeguard IAST scan hosts, only for the length of the scan. That mode is configured on the scanner and works as before.

Public vs private

PublicPrivate
What you enterNothing: installing the agent needs no credentialAn agent token in the application's environment
Credential neededNone to download the packagesA Safeguard agent token (sg_iast_...) to report
What you getThe agent package or imageFindings delivered into one project

Supported auth methods

MethodUse it whenNotes
Agent token (sg_iast_...)Always-on reporting from an installed agentOne token per integration (one application, one project). Sent as Authorization: Bearer.
Scan agent tokenScan mode onlySet on the IAST scanner; valid only while that scan runs

Permissions required

The agent token only lets an agent send reports. It cannot read findings, change settings or reach any other Safeguard API.

Agent token

PermissionRequired?What Safeguard uses it for
Report to the always-on collectorRequiredAccepting hello and report requests from the agent and filing findings into the token's project
Workspace administrator, to issue the tokenRequiredOnly a workspace administrator, signed in, can issue, rotate or revoke an agent token

Least privilege: issue one token per application, so revoking one never interrupts another.

Token types

Token typeWorks?Notes
Agent token (sg_iast_...)YesShown once when issued or rotated; Safeguard stores only its SHA-256
Registry pull tokenNot neededThe agent packages are public
Personal or API keysNoThe collector accepts agent tokens only

Expiry: agent tokens do not expire. Rotate them on your own schedule, and revoke a token as soon as an application is retired.

What we never need: database credentials, cloud credentials, source code access or write access to anything in your environment.

Step-by-step setup

Issue an agent token

  1. Open Integrations, choose the Configure tab and the IAST agents section.
  2. Under Agent tokens, click Issue token, name the application and choose the project its findings go to.
  3. Copy the token. It is shown only once. Store it as a secret (a Kubernetes Secret, your CI secret store, a vault), never in an image or a repository.

Install the agent

The packages are public on registry.safeguard.sh and signed. Pick your language.

Java (any JVM language). Download the JAR, or add it as a Maven or Gradle dependency.

curl -fsSLo iast-agent.jar https://registry.safeguard.sh/maven/sh/safeguard/iast-agent/1.0.1/iast-agent-1.0.1.jar
SAFEGUARD_IAST_TOKEN=sg_iast_... java -javaagent:iast-agent.jar -jar app.jar
<repositories>
  <repository><id>safeguard</id><url>https://registry.safeguard.sh/maven/</url></repository>
</repositories>
<dependency>
  <groupId>sh.safeguard</groupId>
  <artifactId>iast-agent</artifactId>
  <version>1.0.1</version>
  <scope>runtime</scope>
</dependency>
repositories { maven { url = uri("https://registry.safeguard.sh/maven/") } }
configurations { create("safeguardIast") }
dependencies { "safeguardIast"("sh.safeguard:iast-agent:1.0.1") }

Requests to any servlet (javax or jakarta: Tomcat, Jetty, Undertow, Spring MVC) and to the JDK's com.sun.net.httpserver are captured with no code change.

Node.js (JavaScript and TypeScript). Copy the agent out of the public image and preload it:

COPY --from=registry.safeguard.sh/iast/agent:1.0.1 /opt/safeguard/node /opt/safeguard/node
ENV NODE_OPTIONS="--require=/opt/safeguard/node/register.js"

Or install the package from registry.safeguard.sh. Point the @safeguard-sh scope at the registry in .npmrc first, then install and preload it:

# .npmrc
@safeguard-sh:registry=https://registry.safeguard.sh/npm/

npm install @safeguard-sh/iast@1.0.1
SAFEGUARD_IAST_TOKEN=sg_iast_... node --require @safeguard-sh/iast/register server.js

The package was first published as @safeguard/iast. That name still installs from registry.safeguard.sh but is deprecated: on npmjs.com the @safeguard scope belongs to someone else, so use @safeguard-sh/iast, Safeguard's own scope. The preload captures every request on an http or https server with no code change. With Express, also mount the middleware first, so the agent sees what Express parses:

app.use(require('/opt/safeguard/node').middleware());

Python.

pip install --index-url https://registry.safeguard.sh/pypi/simple/ safeguard-iast==1.0.1
SAFEGUARD_IAST_TOKEN=sg_iast_... safeguard-iast-run gunicorn app:app

safeguard-iast-run runs any Python program under the agent, gunicorn's forked workers included. Flask and Django requests are captured with no code change. For ASGI apps (FastAPI, Starlette), wrap the app: app = safeguard_iast.instrument_asgi(app).

Docker. Copy the agent out of the public image:

COPY --from=registry.safeguard.sh/iast/agent:1.0.1 /opt/safeguard/java/iast-agent.jar /opt/safeguard/iast-agent.jar
ENV JAVA_TOOL_OPTIONS="-javaagent:/opt/safeguard/iast-agent.jar"

The image also holds the Node.js agent at /opt/safeguard/node and the Python agent at /opt/safeguard/python.

Kubernetes. An init container copies all three agents into a shared volume:

spec:
  initContainers:
    - name: safeguard-iast
      image: registry.safeguard.sh/iast/agent:1.0.1
      args: ["/safeguard"]
      volumeMounts:
        - { name: safeguard-iast, mountPath: /safeguard }
  containers:
    - name: app
      env:
        - name: SAFEGUARD_IAST_TOKEN
          valueFrom: { secretKeyRef: { name: safeguard-iast, key: token } }
        - name: SAFEGUARD_IAST_APP
          value: acme-api
        # Java
        - name: JAVA_TOOL_OPTIONS
          value: "-javaagent:/safeguard/java/iast-agent.jar"
        # Node.js (instead of the Java line)
        # - name: NODE_OPTIONS
        #   value: "--require=/safeguard/node/register.js"
        # Python (instead of the Java line)
        # - name: PYTHONPATH
        #   value: "/safeguard/python/safeguard_iast/bootstrap:/safeguard/python"
      volumeMounts:
        - { name: safeguard-iast, mountPath: /safeguard, readOnly: true }
  volumes:
    - name: safeguard-iast
      emptyDir: {}
kubectl create secret generic safeguard-iast --from-literal=token=sg_iast_...

Configuration

VariableMeaning
SAFEGUARD_IAST_TOKENThe agent token. A token starting sg_iast_ selects always-on mode.
SAFEGUARD_IAST_ENDPOINTCollector base URL. Default https://api.safeguard.sh/gpt/api/v1/iast.
SAFEGUARD_IAST_APPThe application name shown against findings and agents.
SAFEGUARD_IAST_ENABLED0 turns an always-on agent off without uninstalling it. In scan mode, 1 turns it on.
SAFEGUARD_IAST_COLLECTORScan mode only: the scan's collector, for example http://scanner:7878.
SAFEGUARD_IAST_DEBUG1 logs what the agent instrumented.

Check it is reporting

Start the application. Its log shows safeguard-iast 1.0.1 attached (... always-on ...). Within five minutes the agent appears under Last seen on the language card. Findings appear on the project as the application serves requests that reach a vulnerable operation.

Verify the signatures

Every package carries a signature, an SBOM and signed provenance, made with the same key as Safeguard Gold:

cosign verify --key https://registry.safeguard.sh/_gold/keys/cosign.pub --insecure-ignore-tlog registry.safeguard.sh/iast/agent:1.0.1
curl -fsSL https://registry.safeguard.sh/_products/attest/iast/pypi/safeguard-iast/1.0.1/provenance

Webhooks and triggers

This integration has no webhooks. The agent reports as the application runs: findings are batched every 5 seconds, a heartbeat goes out every 5 minutes, and a flow already reported is re-sent at most every 15 minutes with only its new observations.

What we read and store

  • Read: inside your process, the agent registers request input (query parameters, headers, cookies, servlet form parameters, parsed bodies in Express) for the length of the request, and checks it at SQL, command, file, SSRF, deserialisation and template operations.
  • Stored: for each distinct flow, the vulnerability class, the route (GET /users/:id), the parameter name and kind, the source and sink symbols with file and line, a redacted excerpt of the value that reached the sink, how often it was seen, and first and last seen. For each agent process, its runtime, version, application name, host and last seen.
  • Not stored: the raw report and request bodies are never stored. A value that arrived in a body or form field, a cookie or an authorisation header keeps no excerpt at all. Secrets (API keys, tokens, passwords in URLs) are redacted, and query values whose names suggest a secret are replaced.
  • No customer data from this integration is sent to third-party LLMs.

What each agent detects

AgentDetectsKnown limits
JavaSQL (every JDBC driver), command (Runtime.exec, ProcessBuilder), path (FileInputStream, FileOutputStream), deserialisation, SSRFWork moved to another thread (@Async, executors) is not tracked. Traces have two frames, source and sink. Reading servlet parameters parses form bodies, as the servlet API does.
Node.jsSQL (mysql, mysql2, pg, sqlite3, better-sqlite3, mssql, oracledb, sequelize, knex), command (exec, and spawn/execFile with a shell), path (fs), new Function, SSRF (axios, node-fetch, got), MongoDBCommonJS only: an application loading its own code as native ESM is not covered. eval cannot be wrapped. Path parameters (/users/:id) are not tracked.
PythonSQL (sqlite3, psycopg2/psycopg, PyMySQL, MySQLdb, oracledb, pyodbc), command (os.system, subprocess with a shell), path, eval/exec, SSRF, deserialisation, template injection, log injection, XXEValues built with f-strings are recovered by recognising the request value at the sink. A value that passes through a C extension loses its taint and is not reported.

The agents report what they observe on real requests and prefer missing a flow to reporting one that did not happen: parameterised queries, subprocess without a shell and values shorter than 6 characters are never reported.

Overhead

The agent wraps the dangerous operations in process and checks them only while a request is in flight; outside a request a check returns at once. Reporting never blocks a request: findings go on a bounded queue (2,048 entries) drained by a background thread or timer, repeats are counted locally, and at most 10,000 distinct flows are tracked per process. We have not published benchmark figures; measure on a staging copy of your service before you roll out widely.

Troubleshooting

Message you seeCauseFix
collector refused registration (401) or The agent token is not valid.The token is mistyped, or is not an agent tokenCopy the token again, or issue a new one
The agent token has been revoked. (403)The token was revoked, or its rotation grace endedIssue or rotate a token and update the secret
Always-on IAST agents are not enabled for this workspace. (403)Always-on reporting is off for your workspaceAsk your Safeguard contact
Rate limit reached for this agent token. (429)Many processes report at onceNothing: the agent waits and retries. Use one token per application.
The report is over ... bytes (413)A report was too largeNothing: the agent sends at most 100 findings per report
collector at ... not reachable yetNo network route to api.safeguard.sh at start-upThe agent instruments anyway and delivers once it can connect. Allow outbound HTTPS to api.safeguard.sh.
No attached line in the logNo token in the environment, or SAFEGUARD_IAST_ENABLED=0Check the variables reach the process

Rotation and disconnect

  • Rotate: on the card, click Rotate on the token. You can keep the old token working for up to 60 minutes while you update the secret everywhere, then it stops.
  • Revoke: click Revoke. The token stops working within 30 seconds; agents using it are refused.
  • Uninstall: remove -javaagent, --require or safeguard-iast-run (or the init container and the environment variables) and redeploy. Setting SAFEGUARD_IAST_ENABLED=0 turns the agent off without a rebuild. Revoke the token afterwards.

Vendor references

On this page