Safeguard
Product•

Safeguard IAST: Live App Scans, Runtime Agents and SARIF Results

Run IAST against a live app you own: scan a URL, install an agent for Java, Node.js or Python, or bring IAST results as SARIF, then triage the real flows.

Safeguard Security Team
40 min read

To get interactive application security testing (IAST) results you can act on, run your application with an instrumentation agent inside it, drive real requests through it (your integration tests, a crawl of the live app, or ordinary staging traffic), and keep only the flows where untrusted request input actually reached a dangerous operation such as a SQL statement, a shell command or a file path. Each finding should name the route, the parameter, and the file and line that consumed the value, so a developer can fix it the same day. If another tool already produces IAST results, bring them in as SARIF so they sit next to everything else instead of in a separate report. Only ever test applications you own or are authorised to test.

This post walks through how to plan and run that work with any tooling, then shows how Safeguard IAST does it: scanning a live app URL, always-on agents for Java, Node.js and Python, and importing IAST results you already have.

Key takeaways

  • IAST watches your own code from the inside while it serves requests. It reports a flow only when request input reaches a sink, which is why its findings come with a route, a parameter and a code location rather than a guess.
  • IAST only sees code paths that requests exercise. Thin tests or a shallow crawl give thin results, so coverage planning is half the job.
  • NIST SP 800-53 Rev. 5 names interactive application security testing directly in control enhancement SA-11(9), and NIST SP 800-218 (the SSDF) asks you to test executable code and document the results under PW.8.
  • SARIF 2.1.0 from OASIS is a standard exchange format for analysis results. A result can carry a code flow from source to sink and, for web analysis tools, the web request that triggered it.
  • Safeguard IAST (GA) appears on the Integrations page as a card that scans a live app URL with a headless browser, or takes IAST results you upload as SARIF.
  • Safeguard IAST agents (GA) run inside Java (and every JVM language), Node.js and Python applications. In always-on mode they report to Safeguard for as long as the application runs; in scan mode they report to a running Safeguard IAST scan only for the length of that scan.
  • Findings land 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 agent token can only send reports. It cannot read findings, change settings or reach any other Safeguard API.
  • SAST and DAST (GA), policies and gates (GA) with Block, Warn and Notify actions and approval through exceptions, and the Safeguard CLI (GA) sit around IAST in the same platform.
  • Safeguard has not published agent benchmark figures. Measure overhead on a staging copy of your service before a wide rollout.

The situation

The trigger is usually one of three things.

A penetration test or a DAST run reported an injection on an endpoint, and the developers cannot find the line of code that is responsible. The report has a URL and a payload; it does not have a stack trace.

An auditor or a customer questionnaire asks how you test running code, not just source code, and "we run a scanner on pull requests" is not the whole answer they want.

Or the static analysis backlog has grown so long that nobody trusts it, and the AppSec lead wants a second signal that says which of those source to sink paths actually execute when the application handles a real request.

In each case the person asking is usually the Head of AppSec or a senior engineer who owns a service, and the deadline is the next release or the next audit window. A bad week looks like this: a finding that might be real sits in a ticket, three people argue about whether the parameter is reachable, someone runs an aggressive scan against a shared staging environment that other teams depend on, and the report that comes out still points at a URL instead of a file.

IAST is built for exactly this gap. It sits inside the process, so when a request parameter flows into a query, it knows the parameter name, the route, the function that built the query and the line where it ran. The hard parts are not the agent. They are authorisation, coverage, token handling and getting results into the same place as your other findings.

The rules behind it

Nothing here is legal, regulatory or audit advice. The point is to show which published requirements make runtime testing a reasonable expectation, so you can map your own evidence to them.

NIST SP 800-53 Rev. 5, SA-11 and SA-11(9)

SA-11, Developer Testing and Evaluation, asks the organisation to require developers of a system or component to plan and carry out security testing and evaluation, and to document the results. Its enhancements spell out techniques. SA-11(9) is titled Interactive Application Security Testing, and requires the developer to employ interactive application security testing tools to identify flaws and document the results. If you work to a FedRAMP or agency baseline that pulls in SA-11 enhancements, or a customer contract that references 800-53, runtime instrumentation is no longer exotic. It is a named control.

NIST SP 800-218, the Secure Software Development Framework

The SSDF groups practices under Prepare the Organization (PO), Protect the Software (PS), Produce Well-Secured Software (PW) and Respond to Vulnerabilities (RV). PW.8 is "Test Executable Code to Identify Vulnerabilities and Verify Compliance with Security Requirements". Its tasks ask you to decide whether executable code testing should be performed and of what kind (PW.8.1), and then to scope the testing, design the tests, perform the testing and document the results, including recording and triaging all discovered issues and recommended remediations in the development team's workflow or issue tracking system (PW.8.2). The examples under PW.8.2 include integrating dynamic vulnerability testing into the project's automated test suite, using fuzz testing tools to find input handling issues, and recording the root causes of discovered issues. IAST is one way to do the dynamic part with code level evidence.

The "record and triage in the team's workflow" clause is worth reading twice. A runtime finding that only lives in a PDF does not meet it.

OWASP and CWE: what IAST is looking for

The OWASP Top 10:2025 lists Injection as A05 and describes it as an application flaw that lets untrusted user input be sent to an interpreter, such as a browser, a database or a command line. That is the same shape an IAST agent watches for: untrusted input on one side, an interpreter call on the other. The CWE entries behind the classes most agents watch for are:

ClassCWEWhat reaching the sink means
SQL injectionCWE-89Request input became part of a SQL statement that was then executed
OS command injectionCWE-78Request input reached a shell or process launch
Path traversalCWE-22Request input built a file path that the application opened
Server side request forgeryCWE-918Request input chose the destination of an outbound request
Deserialisation of untrusted dataCWE-502Request data was deserialised into objects

Runtime evidence helps most here, because whether the input really reached the dangerous call is what static analysis approximates and an in-process agent observes.

SARIF 2.1.0, the exchange format

The Static Analysis Results Interchange Format (SARIF) version 2.1.0 was approved as an OASIS Standard on 27 March 2020. Its abstract describes a format for the output of static analysis tools, but it also defines web request and web response objects that it notes are primarily useful to web analysis tools, which model the interaction between a web client and a server. A SARIF log holds one or more runs; each run names the tool that produced it and lists its results. A result carries a rule ID, a level, a message and locations, and it can carry a code flow (an ordered list of locations that trace data from source to sink), a web request and web response (for tools that test web applications), and partial fingerprints that let a consumer recognise the same result across runs. That combination is what makes SARIF a good carrier for IAST output.

Authorisation

Every method in this post sends requests to, or runs code inside, an application. Do it only for applications you own or have written authorisation to test. For hosted dependencies of your app (payment, identity, email and messaging providers), leave them out of scope unless their owner has said yes in writing. Safeguard's own docs for its dynamic testing describe the same stance: verified targets only, strict scope, and non-destructive checks by default.

How IAST actually works

An IAST agent is a library that loads into your process before your code runs and wraps a set of functions.

On the JVM, the agent uses the Java instrumentation API (the java.lang.instrument package). A JAR passed with -javaagent gets a chance to transform classes as they load, so it can wrap JDBC calls, process launches and file streams without any change to your source.

In Node.js, the --require command line option preloads a module at start-up. The preloaded module patches http, database drivers, child_process and fs before the application imports them.

In Python, the interpreter's site module runs sitecustomize at start-up if one is on the path, which gives an agent the same early hook. A launcher that sets the path and then runs your program does the same job.

Once loaded, the agent does two things. It marks values that arrive from the request (query parameters, headers, cookies, form fields, parsed bodies) as untrusted. Then, at each wrapped sink, it checks whether any of those untrusted values reached the call. If one did, it records a flow: where the value came from, where it ended up, the route and the stack.

That design explains IAST's strengths and its limits:

  • Strength: evidence. A reported flow happened. The parameter name and the code location are facts, not inference.
  • Strength: framework awareness for free. The agent does not need to model your router or ORM, because it sees the request and the sink at run time.
  • Limit: coverage. Code that no request reaches is invisible. A route that only runs on the first of the month will not show up from a test run on the fifteenth.
  • Limit: propagation edges. If a value is copied through native code, a C extension, a background thread or a message queue, an agent may lose track of it. Good agents document where.
  • Limit: it is not a fix. IAST tells you that a flow exists. Whether the right fix is a parameterised query, an allow list or removing the feature is still an engineering decision.

Step by step, with or without Safeguard

These steps work whatever tool you use. The Safeguard specific version follows later.

1. Pick the applications and write down who owns them

Start with services that take untrusted input from the internet and talk to a database, a shell, a file system or other HTTP services. For each, record the owning team, the runtime (JVM, Node.js, Python or something else), the frameworks, and the environment you will test in.

2. Get authorisation in writing

For your own services, this is usually an internal change ticket that names the environment, the dates and the person who can stop the test. For anything hosted by someone else, get the owner's written permission or leave it out. Keep the record; auditors ask for it.

3. Choose the environment

Staging or a dedicated test environment first. IAST agents are designed to run in production too, but you want to measure overhead and noise on a copy before you put an agent next to real customers. Use test accounts and synthetic data, so that whatever the agent records is not someone's personal information.

4. Choose how requests will reach the code

This is the coverage decision, and it matters more than the tool.

Request sourceGood forWatch out for
Your integration and end to end testsRepeatable runs in CI; known coverageTests often cover happy paths only
A crawl of the live app with a headless browserDiscovering pages, forms and client side routes a human would hitLogin flows, multi step forms and destructive buttons need care
Normal staging traffic from QARealistic pathsCoverage changes week to week
Production traffic (always-on agent)Real usage, rare pathsOverhead, data handling and change control must be settled first

Most teams combine two: tests in CI for repeatability, and either a crawl or always-on staging for breadth.

5. Install the agent and keep its credential out of images

Whatever the tool, the agent needs some way to report. Treat that credential like any other service secret: inject it at run time from a secret store, never bake it into an image or commit it to a repository, and use one credential per application so revoking one never interrupts another.

6. Prove the agent is attached before you trust a quiet result

A run with no findings is only meaningful if the agent was loaded. Check the start-up log line, check that the agent shows up as alive in whatever console you use, and send one known request through a route that you know reaches a database. If nothing arrives, fix the install before you read anything into the silence.

7. Drive traffic, then stop

Run the tests or the crawl. For scan style runs, decide a time box. For always-on, decide a review cadence.

8. Triage each flow

For each reported flow, read the route, the parameter, the source and sink, and the code location. Then answer three questions: is the input really untrusted in production, does anything between source and sink make it safe that the agent could not see, and what is the smallest fix? Record the decision in the team's tracker, which is what PW.8.2 asks for.

9. Export or import results as SARIF

If your IAST tool and your findings system are different products, SARIF is the bridge. Export from the tool, import into the system where your SAST, DAST and dependency findings already live, and keep the file per release as evidence.

10. Decide what blocks a release

Runtime findings are high signal, but they arrive after code is merged and deployed to a test environment. Decide in advance whether a confirmed IAST flow blocks promotion to production, raises a warning, or notifies the owner. Write the exception process down at the same time.

A same-day checklist

Copy this into the change ticket:

  • Application, owner, runtime and framework recorded
  • Written authorisation for the environment and dates, with a named stop contact
  • Test accounts and synthetic data in place
  • Agent credential issued per application and stored in the secret store
  • Start-up log shows the agent attached; agent visible as alive
  • One known database request sent and observed
  • Request source chosen (tests, crawl, staging traffic) and time box set
  • Third-party hosts excluded from any crawl
  • Triage owner named; results recorded in the tracker
  • SARIF export kept with the release record
  • Rollback: how to switch the agent off without a rebuild

Live app scan or always-on agent?

A scan is a bounded event. You point it at an environment, it drives traffic for a while, the agents report to the scan, and when the scan ends, so does the reporting. That suits CI pipelines, release candidates and one-off checks before an audit.

An always-on agent keeps reporting as long as the application runs. That suits staging environments that see a lot of QA traffic, and production once you are comfortable with overhead and data handling. It finds the rare paths that a crawl will never click.

Many teams use both: a scan per release candidate and an always-on agent in staging.

What does a headless browser crawl add?

A modern web app builds much of its navigation in the browser. A crawler that only follows links in server rendered HTML misses routes that client side code creates, forms that appear after a click, and API calls that a single page application makes in the background. A headless browser loads the page the way a user's browser would, runs its scripts, and can follow what appears. Combined with an agent inside the server, it turns those background API calls into instrumented requests, so a flow from a JSON body field to a SQL query shows up with its route.

The cautions are the obvious ones. A crawler will press buttons. Point it at an environment where pressing "delete account" or "send invoice" does no harm, give it a test account, and keep third-party hosts out of scope.

When should you bring IAST results in as SARIF?

When the tool that found the issue is not the tool your developers live in. The SARIF route makes sense if:

  • you already run an IAST product, or a research team produces runtime traces, and you want those findings next to SAST, DAST and dependency findings
  • an external tester delivers results as SARIF and you want them tracked like your own
  • you need to keep a per release evidence file in a standard format for an assessor

It makes less sense to export and re-import between two products you could connect directly, because each hop is a chance to lose fingerprints and history.

Which SARIF fields matter for IAST?

If you produce or consume SARIF for runtime results, these are the parts of the 2.1.0 specification that carry IAST meaning:

SARIF elementWhat it should carry for an IAST flow
tool.driver.name and rulesThe tool, and a rule per vulnerability class, ideally with a CWE reference
result.ruleId and levelThe class (for example SQL injection) and how serious the producer considers it
result.messageA plain sentence: which parameter reached which operation
result.locationsThe file and line of the sink, as a physical location
result.codeFlowsThe ordered path from source to sink, as thread flow locations
result.webRequestThe method and target of the request that triggered the flow
result.partialFingerprintsA stable identity so the same flow is recognised across runs
result.baselineStateWhether the flow is new, unchanged, updated or absent compared with a baseline
result.suppressionsA recorded decision to accept or dismiss, with a justification

An illustrative minimal result, written by hand from the specification (not Safeguard output, and not run through any tool):

{
  "version": "2.1.0",
  "runs": [
    {
      "tool": {
        "driver": {
          "name": "example-iast",
          "rules": [ { "id": "sql-injection", "name": "SqlInjection" } ]
        }
      },
      "results": [
        {
          "ruleId": "sql-injection",
          "level": "error",
          "message": { "text": "Query parameter id reached a SQL statement." },
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": { "uri": "src/main/java/app/UserRepository.java" },
                "region": { "startLine": 42 }
              }
            }
          ],
          "webRequest": { "method": "GET", "target": "/users/1" },
          "partialFingerprints": { "routeSink/v1": "GET /users/:id|executeQuery" }
        }
      ]
    }
  ]
}

Two habits help. Put the route template, not the concrete URL, into whatever you fingerprint on, so /users/1 and /users/2 are one finding. And never put raw request bodies, cookies or authorisation headers into the message or the web request object. A SARIF file travels further than you think.

Does IAST slow the application down?

It adds work, because every wrapped call does a check. The only number worth trusting is one you measure: run the same load test with and without the agent on a staging copy, and compare latency and CPU. Prefer agents that check only while a request is in flight and never block a request on reporting.

How Safeguard does this

Safeguard IAST (GA) sits on the Integrations page alongside SAST and DAST (GA). Everything below comes from Safeguard's docs, chiefly the IAST agents page, plus the description on the Integrations card. Commands are shown as the docs show them; they were not run for this post. Use them only on applications you own or are authorised to test.

1. Find the card and choose how results arrive

On the Integrations page, the Safeguard IAST card describes two ways in: scan a live app URL with a headless browser, or upload IAST results you already have as SARIF. The docs add a third, longer running route: always-on IAST agents, configured under Integrations > Configure > IAST agents, with one card per language.

The agent docs describe two modes, which map onto the earlier choice:

  • Scan mode. The agent reports to the collector that a running Safeguard IAST scan hosts, only for the length of the scan. That mode is configured on the scanner, with a scan agent token that is valid only while that scan runs.
  • Always-on. The agent reports to Safeguard's IAST collector for as long as the application runs. This is what the rest of this section sets up.

Always-on reporting is switched on per workspace. If you do not see the IAST agents cards under Integrations, the docs say to ask your Safeguard contact.

2. 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. The docs say to store it as a secret (a Kubernetes Secret, your CI secret store, a vault), never in an image or a repository.

Only a workspace administrator, signed in, can issue, rotate or revoke an agent token. Tokens start with sg_iast_ and are sent as a bearer token. Safeguard stores only a SHA-256 hash of each token. One token covers one integration: one application, one project. The collector accepts agent tokens only; personal and API keys do not work there.

The permission model is narrow by design. The docs say the agent token only lets an agent send reports. It cannot read findings, change settings or reach any other Safeguard API. Safeguard also says it never needs database credentials, cloud credentials, source code access or write access to anything in your environment for this integration.

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

3. Install the agent

Follow the install steps for your runtime on the Safeguard IAST agents docs page; the commands and versions there are the current ones, and they were not run for this post.

What the docs cover, by language and runtime:

Language or runtimeHow the agent attachesWhat is captured with no code change
Java and every JVM languageA Java agent JAR attached with -javaagent, downloaded directly or added as a Maven or Gradle dependencyRequests to any servlet (javax or jakarta: Tomcat, Jetty, Undertow, Spring MVC) and to the JDK's built-in com.sun.net.httpserver
Node.js (JavaScript and TypeScript)Preloaded with --require, copied from Safeguard's public agent imageEvery request on an http or https server. With Express, also mount the agent's middleware first, so it sees what Express parses
PythonA launcher, safeguard-iast-run, that runs any Python program under the agent, gunicorn's forked workers includedFlask and Django requests. ASGI apps (FastAPI, Starlette) are wrapped with safeguard_iast.instrument_asgi(app)
DockerCopy the agent out of the public agent image and set the language's start-up optionThe image holds the Java, Node.js and Python agents
KubernetesAn init container copies all three agents into a shared volume; the app container sets the token from a Kubernetes Secret and the start-up option for its languageSame as the language rows above

The agents are public packages, so installing one needs no credential; the token is only needed to report. The init container pattern is a standard Kubernetes feature: init containers run to completion before the app containers start, which makes them a clean way to drop files into a shared volume without changing the application image.

The docs also describe how to check the packages' signatures and signed provenance before you deploy them. Do that as part of your normal artifact admission process.

4. Configure it

The agent reads a short list of environment variables:

VariableMeaning (from the docs)
SAFEGUARD_IAST_TOKENThe agent token. A token starting sg_iast_ selects always-on mode
SAFEGUARD_IAST_ENDPOINTCollector base URL; defaults to Safeguard's IAST collector
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
SAFEGUARD_IAST_DEBUG1 logs what the agent instrumented

SAFEGUARD_IAST_ENABLED=0 is your rollback switch. It turns the agent off without a rebuild, which is the answer to step 11 of the checklist.

5. Check it is reporting

Start the application. Its log shows a line beginning safeguard-iast 1.0.1 attached that names always-on mode. 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.

That last sentence is the coverage point again. An attached agent on an idle service reports nothing. Send traffic.

6. Read the findings

Findings appear as IAST vulnerabilities on the project you chose when you issued the token. They are de-duplicated by route, sink and stack, so the same flow hit a thousand times is one finding, and each agent process has its own "last seen". For each distinct flow, Safeguard stores:

  • the vulnerability class
  • the route, as a template such as 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

That is enough to act on without reproducing the request.

7. Know what each agent covers

The docs list what each agent detects and where it stops. Summarised:

AgentWatchesKnown limits from the docs
JavaSQL through any 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 or 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 such as /users/:id are not tracked
PythonSQL (sqlite3, psycopg2 and psycopg, PyMySQL, MySQLdb, oracledb, pyodbc), command (os.system, subprocess with a shell), path, eval and 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

There are no agents for .NET, Go, Ruby or PHP yet.

The docs are explicit about the design choice: 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 six characters are never reported. That is a deliberate trade toward fewer false alarms, and it means a quiet result is not proof of safety. Pair IAST with SAST (GA) for the paths your requests do not reach.

8. Know what is read and stored

Inside your process, the agent registers request input (query parameters, headers, cookies, servlet form parameters, and parsed bodies in Express) for the length of the request, and checks it at SQL, command, file, SSRF, deserialisation and template operations.

What is not stored matters as much:

  • raw report bodies and raw 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
  • credential-like values in URLs are redacted, and query values whose names suggest a credential are replaced

Safeguard's docs also state that no customer data from this integration is sent to third-party LLMs. For each agent process, Safeguard stores its runtime, version, application name, host and last seen.

9. Overhead, in Safeguard's words

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 drained by a background thread or timer, repeats are counted locally, and the number of distinct flows tracked per process is capped. Safeguard has not published benchmark figures and tells you to measure on a staging copy of your service before you roll out widely. That is the right advice for any agent.

10. Troubleshoot

The docs map the messages you will see to their causes:

MessageCauseFix
collector refused registration (401) or The agent token is not valid.Token mistyped, or not an agent tokenCopy the token again, or issue a new one
The agent token has been revoked. (403)Token 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 the workspaceAsk your Safeguard contact
Rate limit reached for this agent token. (429)Many processes reporting 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 caps the findings in each report
collector at ... not reachable yetNo network route to the API 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

The integration has no webhooks. The agent reports as the application runs, sends a periodic heartbeat, and re-sends a flow it already reported only with its new observations.

11. Rotate, revoke and uninstall

  • Rotate: on the card, click Rotate on the token. The old token keeps 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, and agents using it are refused.
  • Uninstall: remove -javaagent, --require or safeguard-iast-run (or the init container and the environment variables) and redeploy. Revoke the token afterwards.

12. Running a live app scan

For the scan route on the Safeguard IAST card, the same agents run in scan mode: they report to the collector that the running scan hosts, with a scan agent token set on the scanner and valid only while that scan runs, and SAFEGUARD_IAST_ENABLED=1 turns them on. The card describes the scan as driving a live app URL with a headless browser. Treat the URL exactly as you would a DAST target: your own application, a test environment, a test account and a time box. Safeguard's DAST docs describe the safety controls it enforces for dynamic testing (verified targets only, strict scope, rate limits and non-destructive checks by default), and those are the same expectations to set for any live scan.

13. Uploading IAST results as SARIF

If an IAST run happened elsewhere, the card lets you upload its results as SARIF so they sit in Safeguard with the rest of your findings. Before you upload, check the file against the field table earlier in this post: a rule ID per class, the sink's file and line, a code flow if the tool produces one, and no raw request bodies or credentials in messages.

14. Where IAST sits in the rest of Safeguard

IAST is one signal among several:

  • SAST (GA) traces source to sink in code that has not run, across functions and files, for JavaScript and TypeScript, Python and Java, with CWE and OWASP mapping. It covers the paths your tests never exercise.
  • DAST (GA) tests a running, verified target from outside with safe, non-destructive requests, inside an allow-listed scope, with a full audit trail.
  • Policies and gates (GA) apply Block, Warn or Notify to findings in your pipelines, with approval handled through exceptions rather than as a separate gate action.
  • The Safeguard CLI (GA) runs SAST and DAST locally or in CI, and the local runner (GA) keeps scans on a machine you control.

Safeguard's application security docs describe a unified findings model for SAST, DAST and SCA, where a DAST confirmed runtime issue can be linked to the SAST sink that produced it. The IAST agents page does not say whether IAST findings join that correlation or which gate rules can act on them; ask before you design a release gate around it.

What Safeguard does not do

  • It does not test code your requests never reach. IAST sees only exercised paths. Coverage is your test suite's and your crawl's job, and SAST covers the rest.
  • It does not ship agents for every runtime. Java and the JVM languages, Node.js and Python are covered. .NET, Go, Ruby and PHP agents are not available yet.
  • It does not follow every propagation edge. Work handed to another thread on the JVM, native ESM in Node.js, path parameters in Node.js, and values that pass through a Python C extension are documented gaps.
  • It does not report what it is not sure of. Parameterised queries, shell-less process launches and very short values are never reported. A quiet project is not a clean bill of health.
  • It does not publish overhead numbers. You have to measure on your own service.
  • It does not decide authorisation for you. You confirm that you own, or are authorised to test, every application and URL you instrument or scan.
  • It does not fix the code. IAST findings tell you where a flow happens. The fix, its review and its release remain your engineers' work.
  • It does not turn always-on reporting on by itself. That is switched on per workspace; if the cards are missing, ask your Safeguard contact.

Common mistakes

  • Reading silence as safety. No findings from an agent that never attached, or from a service that served no traffic, means nothing. Check the attached line and Last seen first.
  • One token for every service. It makes rotation a fleet-wide outage and hides which service is reporting. Issue one per application.
  • Baking the token into the image. It ends up in every registry mirror and every layer cache. Inject it at run time from the secret store.
  • Crawling an environment where buttons have consequences. A headless browser will click "delete". Use a test environment and test accounts.
  • Letting the crawl wander onto third-party hosts. Payment, identity and email providers are not yours to test.
  • Jumping straight to production. Measure overhead and review what is stored on staging first, then decide.
  • Ignoring the documented limits. If your Java service does its database work in @Async methods, plan SAST coverage for that path instead of expecting IAST to see it.
  • Importing SARIF without fingerprints. Each upload then looks like a new set of findings, and triage history is lost.
  • Putting request bodies into SARIF messages. The file travels; the data in it should not.
  • Leaving agents in place after an application is retired. Remove the agent and revoke the token in the same change.

FAQ

What is Safeguard IAST?

Safeguard IAST (GA) is interactive application security testing in Safeguard. From the Integrations page you can scan a live app URL with a headless browser, upload IAST results as SARIF, or install always-on agents in Java, Node.js and Python applications that report flows from request input to dangerous operations.

Which languages do Safeguard IAST agents support?

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

Do I need to change my code to use the IAST agent?

Mostly no. Java servlet containers, Node.js http and https servers, and Flask and Django are captured with no code change. Express needs the agent's middleware mounted first, and ASGI apps such as FastAPI and Starlette need the app wrapped with safeguard_iast.instrument_asgi.

What can the IAST agent token access?

Only the collector. The docs say it lets an agent send reports and nothing else: it cannot read findings, change settings or reach any other Safeguard API. Only a signed-in workspace administrator can issue, rotate or revoke one.

Does the Safeguard IAST agent store request data?

It stores, per distinct flow, the class, route, parameter name and kind, source and sink with file and line, a redacted excerpt of the value, counts and first and last seen. Raw request and report bodies are never stored, and values from bodies, form fields, cookies and authorisation headers keep no excerpt.

Can I run the IAST agent in production?

The always-on mode reports for as long as the application runs, and the docs describe a design that never blocks requests on reporting. Safeguard has not published benchmark figures, so measure on a staging copy first and settle data handling and change control before production.

How do I turn the IAST agent off quickly?

Set SAFEGUARD_IAST_ENABLED=0. It turns an always-on agent off without uninstalling it or rebuilding the image. To remove it fully, take out the agent flag or init container, redeploy and revoke the token.

Why does my IAST project show no findings?

Check that the log shows the attached line, that the agent appears under Last seen, and that requests are reaching routes that touch a database, shell, file or outbound call. Remember the agents deliberately skip parameterised queries, shell-less process launches and very short values.

How is IAST different from DAST and SAST in Safeguard?

DAST (GA) tests a verified target from outside. SAST (GA) reads source code without running it. IAST (GA) watches from inside the running process and reports flows that actually happened. They cover different gaps, and the docs describe linking DAST and SAST findings in one model.

Can I bring IAST results from another tool into Safeguard?

Yes. The Safeguard IAST card on the Integrations page takes IAST results uploaded as SARIF.

Related reading

The fastest IAST finding to close is one in a dependency your own code calls into, because the fix may already exist upstream. When it does not, or when the flow passes through a vulnerable library rather than your own code, these are the routes Safeguard offers.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.

3. Gold Registry: start from components that are already fixed

Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingSafeguard policies and gates in CI
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The Safeguard CLI demo is a real terminal session: the CLI is asked to fix a lodash CVE in a repository, reads the finding and the advisory, edits package.json, runs the install and tests with approval, and pushes nothing. Since CLI v11.10.0 it asks before any command that changes something, not before every command. It does not show IAST, but it shows the same review-first habit you want when an IAST finding turns into a code change.

Click through it at your own pace, or open it full screen.

The local runner demo shows setting up the runner on your own machine, approving it with its device code, and then scanning from the terminal. It is a useful picture of keeping scans on infrastructure you control, which is where the SAST half of an IAST plus SAST pairing runs.

Click through it at your own pace, or open it full screen.

The Claude demo shows connecting Claude to the Safeguard MCP server with OAuth and choosing which tools Claude can use. Once findings are in your projects, the triage questions from this post (which project, which severity, which component) can be asked from there in plain language.

Click through it at your own pace, or open it full screen.

Quick check

Your IAST agent has been installed in staging for a week and the project shows no findings. What do you check first?

Check that the application log shows the agent's attached line and that the agent appears under Last seen, then confirm that requests are actually reaching routes that touch a database, shell, file or outbound call. A quiet result means nothing until you know the agent was loaded and exercised.

Why issue one agent token per application rather than one for the whole fleet?

Because revoking or rotating a token then affects only one application, and findings and agent health stay tied to the right project. A shared token turns every rotation into a fleet-wide change and hides which service is reporting.

Sources

Get started: download Safeguard at safeguard.sh/download and read the setup guides at docs.safeguard.sh/docs.

Last reviewed: 25 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.