Stoa Agent Risk Report

Repository: meridian-ops

Full repository scan · Stoa v0.6.0

12 agent candidates · 7 integrations · 7 critical findings

Stoa found 12 agent candidates — 9 at elevated exposure or above, with agents that can execute shell commands and send messages running on autonomy their declarations may not grant.

Top risk: AI002 · agents/payments.py:23 · LLM05 — Model output observed reaching a dangerous execution or injection sink. 5 fixes clear every critical finding.

Exposure = what the code makes possible, not what has happened. Fix first clears the criticals; Contradictions shows where your declarations don't match the code.

Scoreboard

how much risk, and where it sits · severity: critical high medium low

4
5
1
2
Severe 4Elevated 5Moderate 1Low 2
60 active findings — 7 critical · 9 high · 14 medium · 7 low · 23 info·3 suppressed·7 integrations·14 files scanned

Fix first

what to repair, in order

Model output observed reaching a dangerous execution or injection sinkcritical

Model output is executed or rendered without an interposed validation step.

Fix: Dispatch through a static mapping of permitted actions; never execute or render model output directly.

AI002agents/payments.py:23 +3 moreLLM05Art. 15
Why this fired

The value from `reply = llm.invoke(prompt).content # model output` (line 22) reaches a exec-class sink at line 23 with no interposed allowlist observed on the flow. Model output is attacker-influenceable whenever any untrusted content reaches the model (OWASP LLM02). This finding is gate-eligible. Analysis is intra-file; flows through other files are not visible.

Declared autonomy contradicts inferred autonomycritical

A declared-vs-observed contradiction — full detail in Contradictions.

DECL001agents/payments.py:23 +1 moreLLM06Art. 14
Possible hardcoded API credentialcritical

A credential is embedded in source where anyone with repo access can read it. OPENAI_FALLBACK = "sk-pro…[REDACTED:00d59b41db00]" # SEC001

Fix: Load the credential from a secret manager or environment variable.

SEC001agents/payments.py:8 +1 moreArt. 15
Why this fired

Possible hardcoded API credential (agents/payments.py:8). Load the credential from a secret manager or environment variable.

Possible hardcoded passwordcritical

A password is embedded in source rather than held in a secret store. DB_PASSWORD = "Sup3rS…[REDACTED:92179e7ad06e]" # SEC002

Fix: Load the password from a secret manager or environment variable.

SEC002agents/devops.py:6Art. 15
Why this fired

Possible hardcoded password (agents/devops.py:6). Load the password from a secret manager or environment variable.

Identifier suggesting sensitive data observed in an external model callhigh

Sensitive identifiers are placed into prompts that leave the trust boundary.

Fix: Pseudonymize sensitive fields before the model call and rejoin identifiers afterward.

AI004agents/payments.py:22 +1 moreLLM02Art. 10
Why this fired

An identifier suggesting a credential (`llm = ChatOpenAI(model="gpt-4o", api_key=os.getenv("OPENAI_API_KEY", OPENAI_FALLBACK)) # AI005 floating-alias`, line 9) is interpolated into a prompt passed to a model call at line 22. Identifier names suggest — but do not prove — sensitive data (OWASP LLM06). Values are never read or transmitted by Stoa; this finding is based on identifier names and flow shape only. Analysis is intra-file; flows through other files are not visible.

Contradictions

where declarations don't match the code — what a self-attested questionnaire can't catch

DECL001critical

Declared autonomy contradicts inferred autonomy

code: agents/payments.py:23

declared: stoa-declared.toml agents."a09ff38687e9".autonomy_intent

Agent `agent` is declared `human_approved`, but the scanner inferred `unrestricted_autonomous` from a side-effecting path with no correlated approval gate. Either the declaration is stale, or the approval control is missing.

DECL001critical

Declared autonomy contradicts inferred autonomy

code: web/support_bot.ts:12

declared: stoa-declared.toml agents."2e0ab9a50e4e".autonomy_intent

Agent `support_bot` is declared `recommend_only`, but the scanner inferred `unrestricted_autonomous` from a side-effecting path with no correlated approval gate. Either the declaration is stale, or the approval control is missing.

DECL004high

Scanned data class not present in declared data classes

code: agents/payments.py:8

declared: stoa-declared.toml agents."a09ff38687e9".data_classes

Agent `agent` has evidence of authentication-class data (SEC001 at line 8) that isn't in its declared data_classes.

DECL006 medium — 10 agents: Scanned agent has no declaration entry
agents/compliance.py:16
agents/devops.py:3
agents/fraud.py:9
agents/fraud.py:9
agents/legacy.py:10
agents/marketing.py:6
agents/payments.py:12
agents/research.py:3
agents/triage.py:2
mcp/script_tools.py:8

Agents

which agents carry the risk

payments·agentagents/payments.pySevere exposure25
payments·executoragents/payments.pySevere exposure25
devops·agentagents/devops.pySevere exposure19
support_botweb/support_bot.tsSevere exposure15

8 more agents — elevated and below ▸

Risk dimensions

what kinds of risk, and which rules they map to

Boundary leakage ● elevated4 elevated · 2 moderate

Sensitive data leaving the trust boundary via model calls or network egress

LLM02Art. 10Art. 15
9 evidence items
SEC002 · agents/devops.py:6AI004 · agents/fraud.py:15AI006 · agents/fraud.py:19DECL004 · agents/payments.py:8SEC001 · agents/payments.py:8AI004 · agents/payments.py:22AI004 · agents/payments.py:27SEC001 · tests/test_payments.py:1AI006 · web/support_bot.ts:12
Mandate overreach ● elevated3 elevated · 2 moderate

Agent reach exceeding its declared operating scope

LLM05LLM06Art. 14Art. 15
7 evidence items
AI003 · agents/devops.py:3AI003 · agents/payments.py:12CTRL006 · agents/payments.py:12DECL001 · agents/payments.py:23AI003 · web/support_bot.ts:10DECL001 · web/support_bot.ts:12approval observed
Unreviewed high-impact action ● elevated3 elevated · 2 moderate

High-impact actions reachable without an observed authorization or approval control

LLM06Art. 14
7 evidence items
AI003 · agents/devops.py:3AI003 · agents/payments.py:12DECL001 · agents/payments.py:23AI003 · web/support_bot.ts:10DECL001 · web/support_bot.ts:12approval observedauthentication observed
Output fidelity ● elevated2 elevated · 1 moderate

Incorrect or unsafe model output causing downstream harm; correctness itself is a runtime property

LLM05Art. 15
6 evidence items
SEC003 · agents/payments.py:18AI002 · agents/payments.py:23AI002 · agents/payments.py:29AI002 · web/support_bot.ts:11AI002 · web/support_bot.ts:12validation observed
Control coverage gap ◐ moderate0 elevated · 3 moderate

Absence of observed operating controls: auth, validation, rate limits, observability

LLM05LLM06Art. 11Art. 14Art. 15
27 evidence items
CTRL007 · agents/compliance.py:16DECL006 · agents/compliance.py:16CTRL007 · agents/devops.py:3DECL006 · agents/devops.py:3SEC002 · agents/devops.py:6CTRL007 · agents/fraud.py:9DECL006 · agents/fraud.py:9NET002 · agents/fraud.py:19CTRL007 · agents/legacy.py:10DECL006 · agents/legacy.py:10CTRL007 · agents/marketing.py:6DECL006 · agents/marketing.py:6SEC001 · agents/payments.py:8CTRL006 · agents/payments.py:12CTRL007 · agents/payments.py:12DECL006 · agents/payments.py:12CTRL007 · agents/research.py:3DECL006 · agents/research.py:3CTRL007 · agents/triage.py:2DECL006 · agents/triage.py:2CTRL007 · mcp/script_tools.py:8DECL006 · mcp/script_tools.py:8SEC001 · tests/test_payments.py:1CTRL007 · web/support_bot.ts:10authentication observedobservability observedvalidation observed
Injection & tamper surface ◐ moderate0 elevated · 3 moderate

Susceptibility surface for prompt injection, poisoning, or supply-chain tampering

LLM01LLM03Art. 15
3 evidence items
AI001 · agents/fraud.py:15AI005 · agents/research.py:7AI005 · agents/research.py:9
Proxy-tier Conduct variability (low) · Dependency drift (low) — indirect signals only, capped at moderate.
elevated moderate lowproxy signals only — runtime evaluation required

Standards

which risk classes were assessed — gaps kept visible

LLM01 assessedLLM02 assessedLLM03 assessedLLM04 not-assessedLLM05 assessedLLM06 assessedLLM07 not-assessedLLM08 not-assessedLLM09 proxyLLM10 partial
Appendix — full agent detail, all findings, standards alignment, and architecture

All agents

payments·agentSevere exposure

agents/payments.py · High confidence

Unrestricted-autonomous

4 critical4 high2 low3 info
  • database_write
  • payment_access
  • shell_execution
  • +1 more
Details & evidence

Detected because

  • LangChain agent construct at line 12
  • Tool or function schema at line 11
  • LLM provider import or reference at line 9
  • Multiple model call sites (2) — orchestration at line 1

Detection score: 10 · symbol: agent

Stack

Frameworks: langchain · Providers: openai

Capabilities (static evidence)

  • database_write
  • payment_access
  • shell_execution
  • tool_calling

Integrations · call sites

  • postgres × 3
  • stripe × 1

Attribution

Codeowners: @payments-team, @security · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
highDECL0048Scanned data class not present in declared data classes
credential evidence for `agent`, 'authentication' not declared
The scanner found evidence of a data class this agent touches that isn't in its declared data_classes. Update the declaration or confirm the finding is a false positive.
criticalSEC0018Possible hardcoded API credential
OPENAI_FALLBACK = "sk-pro…[REDACTED:00d59b41db00]" # SEC001
Load the credential from a secret manager or environment variable.
lowAI0059Model, endpoint, or artifact dependency observed without a pin or integrity control
ChatOpenAI(model="gpt-4o"
Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
infoAI00312Approval control not observed for high-impact tool capability
high-impact capability for candidate agent
Confirm an approval or human-in-the-loop control gates this capability; none was observed in this file.
infoAI00712Deterministic sampling not observed on high-impact-adjacent call sites
sampling config for candidate agent
Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
lowCTRL00612Sandboxing not observed on an exec path
Sandboxing not observed on an exec path for candidate agent
Confirm this execution path runs in a restricted environment (restricted env, container, sandboxed interpreter); none was observed near it.
infoCTRL00712No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate agent
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
highSEC00318Interpolated SQL statement
conn.cursor().execute(f"UPDATE ledger SET refunded=1 WHERE id={customer['id']}") # db_write
Use parameterized queries instead of string interpolation.
highAI00422Identifier suggesting sensitive data observed in an external model call
reply = llm.invoke(prompt).content # model output
Pseudonymize sensitive fields before the model call and rejoin identifiers afterward.
criticalAI00223Model output observed reaching a dangerous execution or injection sink
subprocess.run(reply, shell=True) # AI002 exec -> critical, GATE
Dispatch through a static mapping of permitted actions; never execute or render model output directly.
criticalDECL00123Declared autonomy contradicts inferred autonomy
autonomy_intent='human_approved' vs inferred='unrestricted_autonomous'
This agent was declared recommend-only or human-approved, but the scanner found a side-effecting path with no correlated approval gate. Either add the missing approval control, or correct the declaration.
highAI00427Identifier suggesting sensitive data observed in an external model call
reply = llm.invoke("summarize action").content # model output
Pseudonymize sensitive fields before the model call and rejoin identifiers afterward.
criticalAI00229Model output observed reaching a dangerous execution or injection sink
cursor.execute(f"INSERT INTO audit(note) VALUES ('{reply}')") # AI002/sql ⊃ SEC003
Dispatch through a static mapping of permitted actions; never execute or render model output directly.
payments·executorSevere exposure

agents/payments.py · High confidence

Unrestricted-autonomous

3 critical3 high1 medium2 low3 info
  • database_write
  • payment_access
  • shell_execution
  • +1 more
Details & evidence

Detected because

  • LangChain agent construct at line 12
  • Tool or function schema at line 11
  • LLM provider import or reference at line 9
  • Multiple model call sites (2) — orchestration at line 1

Detection score: 10 · symbol: executor

Stack

Frameworks: langchain · Providers: openai

Capabilities (static evidence)

  • database_write
  • payment_access
  • shell_execution
  • tool_calling

Integrations · call sites

  • postgres × 3
  • stripe × 1

Attribution

Codeowners: @payments-team, @security · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
criticalSEC0018Possible hardcoded API credential
OPENAI_FALLBACK = "sk-pro…[REDACTED:00d59b41db00]" # SEC001
Load the credential from a secret manager or environment variable.
lowAI0059Model, endpoint, or artifact dependency observed without a pin or integrity control
ChatOpenAI(model="gpt-4o"
Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
infoAI00312Approval control not observed for high-impact tool capability
high-impact capability for candidate executor
Confirm an approval or human-in-the-loop control gates this capability; none was observed in this file.
infoAI00712Deterministic sampling not observed on high-impact-adjacent call sites
sampling config for candidate executor
Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
lowCTRL00612Sandboxing not observed on an exec path
Sandboxing not observed on an exec path for candidate executor
Confirm this execution path runs in a restricted environment (restricted env, container, sandboxed interpreter); none was observed near it.
infoCTRL00712No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate executor
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
mediumDECL00612Scanned agent has no declaration entry
no declaration entry for `executor`
stoa-declared.toml exists but doesn't mention this agent. Add an [agents."<id>"] entry, even a partial one.
highSEC00318Interpolated SQL statement
conn.cursor().execute(f"UPDATE ledger SET refunded=1 WHERE id={customer['id']}") # db_write
Use parameterized queries instead of string interpolation.
highAI00422Identifier suggesting sensitive data observed in an external model call
reply = llm.invoke(prompt).content # model output
Pseudonymize sensitive fields before the model call and rejoin identifiers afterward.
criticalAI00223Model output observed reaching a dangerous execution or injection sink
subprocess.run(reply, shell=True) # AI002 exec -> critical, GATE
Dispatch through a static mapping of permitted actions; never execute or render model output directly.
highAI00427Identifier suggesting sensitive data observed in an external model call
reply = llm.invoke("summarize action").content # model output
Pseudonymize sensitive fields before the model call and rejoin identifiers afterward.
criticalAI00229Model output observed reaching a dangerous execution or injection sink
cursor.execute(f"INSERT INTO audit(note) VALUES ('{reply}')") # AI002/sql ⊃ SEC003
Dispatch through a static mapping of permitted actions; never execute or render model output directly.
devops·agentSevere exposure

agents/devops.py · High confidence

Recommend-only

1 critical2 medium2 info
  • cloud_resource_access
  • shell_execution
  • +1 more
Details & evidence

Detected because

  • Agno agent construct at line 3
  • Tool or function schema at line 8
  • LLM provider import or reference at line 7

Detection score: 8 · symbol: agent

Stack

Frameworks: agno · Providers: openai

Capabilities (static evidence)

  • cloud_resource_access
  • shell_execution
  • tool_calling

Integrations · call sites

  • aws × 2

Attribution

Codeowners: @sre-team · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
infoAI0033Approval control not observed for high-impact tool capability
high-impact capability for candidate agent
Confirm an approval or human-in-the-loop control gates this capability; none was observed in this file.
infoCTRL0073No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate agent
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
mediumDECL0063Scanned agent has no declaration entry
no declaration entry for `agent`
stoa-declared.toml exists but doesn't mention this agent. Add an [agents."<id>"] entry, even a partial one.
criticalSEC0026Possible hardcoded password
DB_PASSWORD = "Sup3rS…[REDACTED:92179e7ad06e]" # SEC002
Load the password from a secret manager or environment variable.
mediumAI0057Model, endpoint, or artifact dependency observed without a pin or integrity control
base_url="http://mlgw.internal-x.io/v1")
Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
support_botSevere exposure

web/support_bot.ts · Medium confidence

Unrestricted-autonomous

1 critical2 high1 medium1 low3 info
  • messaging
  • +3 more
Details & evidence

Detected because

  • LLM provider invocation at line 10
  • Tool or function schema at line 8
  • LLM provider import or reference at line 3

Detection score: 5 · symbol: support_bot

Stack

Frameworks: — · Providers: openai

Capabilities (static evidence)

  • customer_support
  • external_http
  • messaging
  • tool_calling

Integrations · call sites

  • slack × 1
  • zendesk × 1

Attribution

Codeowners: @platform-team · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
infoAI00310Approval control not observed for high-impact tool capability
high-impact capability for candidate support_bot
Confirm an approval or human-in-the-loop control gates this capability; none was observed in this file.
lowAI00510Model, endpoint, or artifact dependency observed without a pin or integrity control
openai('gpt-4o'
Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
infoAI00710Deterministic sampling not observed on high-impact-adjacent call sites
sampling config for candidate support_bot
Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
infoCTRL00710No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate support_bot
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
highAI00211Model output observed reaching a dangerous execution or injection sink
container.innerHTML = out.text; // AI002 markup (model output -> innerHTML)
Dispatch through a static mapping of permitted actions; never execute or render model output directly.
highAI00212Model output observed reaching a dangerous execution or injection sink
await fetch("https://acme.zendesk.com/api/v2/tickets.json", { method: "POST", body: out.text });
Dispatch through a static mapping of permitted actions; never execute or render model output directly.
mediumAI00612Identifier suggesting sensitive data observed flowing to a network egress sink
await fetch("https://acme.zendesk.com/api/v2/tickets.json", { method: "POST", body: out.text });
Strip sensitive fields before egress, or add the destination to [rules.AI006].allowed_hosts if org-approved.
criticalDECL00112Declared autonomy contradicts inferred autonomy
autonomy_intent='recommend_only' vs inferred='unrestricted_autonomous'
This agent was declared recommend-only or human-approved, but the scanner found a side-effecting path with no correlated approval gate. Either add the missing approval control, or correct the declaration.
analystElevated exposure

agents/fraud.py · High confidence

Recommend-only

2 high2 medium1 low3 info
  • messaging
  • +2 more
Details & evidence

Detected because

  • CrewAI agent construct at line 9
  • LLM provider invocation at line 15
  • LLM provider import or reference at line 4

Detection score: 8 · symbol: analyst

Stack

Frameworks: crewai · Providers: anthropic

Capabilities (static evidence)

  • external_http
  • messaging
  • vector_search

Integrations · call sites

  • pinecone × 4

Attribution

Codeowners: @platform-team · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
infoAI0079Deterministic sampling not observed on high-impact-adjacent call sites
sampling config for candidate analyst
Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
infoCTRL0079No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate analyst
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
mediumDECL0069Scanned agent has no declaration entry
no declaration entry for `analyst`
stoa-declared.toml exists but doesn't mention this agent. Add an [agents."<id>"] entry, even a partial one.
highAI00115Untrusted input observed flowing into prompt construction
verdict = client.messages.create(model="claude-3-5-sonnet", # default sampling -> AI007
Move untrusted content into a delimited user-role message and keep instruction text static.
mediumAI00415Identifier suggesting sensitive data observed in an external model call
verdict = client.messages.create(model="claude-3-5-sonnet", # default sampling -> AI007
Pseudonymize sensitive fields before the model call and rejoin identifiers afterward.
lowAI00515Model, endpoint, or artifact dependency observed without a pin or integrity control
model="claude-3-5-sonnet"
Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
highAI00619Identifier suggesting sensitive data observed flowing to a network egress sink
requests.post("https://siem.thirdparty-x.io/ingest", json=payload) # AI006 secret->egress
Strip sensitive fields before egress, or add the destination to [rules.AI006].allowed_hosts if org-approved.
infoNET00219Request timeout not observed
requests.post("https://siem.thirdparty-x.io/ingest", json=payload) # AI006 secret->egress
Pass an explicit timeout so a hung upstream cannot stall the agent.
fraud·crewElevated exposure

agents/fraud.py · High confidence

Recommend-only

2 high2 medium1 low3 info
  • messaging
  • +2 more
Details & evidence

Detected because

  • CrewAI agent construct at line 9
  • LLM provider invocation at line 15
  • LLM provider import or reference at line 4

Detection score: 8 · symbol: crew

Stack

Frameworks: crewai · Providers: anthropic

Capabilities (static evidence)

  • external_http
  • messaging
  • vector_search

Integrations · call sites

  • pinecone × 4

Attribution

Codeowners: @platform-team · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
infoAI0079Deterministic sampling not observed on high-impact-adjacent call sites
sampling config for candidate crew
Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
infoCTRL0079No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate crew
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
mediumDECL0069Scanned agent has no declaration entry
no declaration entry for `crew`
stoa-declared.toml exists but doesn't mention this agent. Add an [agents."<id>"] entry, even a partial one.
highAI00115Untrusted input observed flowing into prompt construction
verdict = client.messages.create(model="claude-3-5-sonnet", # default sampling -> AI007
Move untrusted content into a delimited user-role message and keep instruction text static.
mediumAI00415Identifier suggesting sensitive data observed in an external model call
verdict = client.messages.create(model="claude-3-5-sonnet", # default sampling -> AI007
Pseudonymize sensitive fields before the model call and rejoin identifiers afterward.
lowAI00515Model, endpoint, or artifact dependency observed without a pin or integrity control
model="claude-3-5-sonnet"
Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
highAI00619Identifier suggesting sensitive data observed flowing to a network egress sink
requests.post("https://siem.thirdparty-x.io/ingest", json=payload) # AI006 secret->egress
Strip sensitive fields before egress, or add the destination to [rules.AI006].allowed_hosts if org-approved.
infoNET00219Request timeout not observed
requests.post("https://siem.thirdparty-x.io/ingest", json=payload) # AI006 secret->egress
Pass an explicit timeout so a hung upstream cannot stall the agent.
campaignerElevated exposure

agents/marketing.py · Medium confidence

Recommend-only

1 medium1 info
  • email_send
Details & evidence

Detected because

  • AutoGen agent construct at line 6

Detection score: 5 · symbol: campaigner

Stack

Frameworks: autogen · Providers:

Capabilities (static evidence)

  • email_send

Integrations · call sites

  • sendgrid × 3

Attribution

Codeowners: @platform-team · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
infoCTRL0076No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate campaigner
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
mediumDECL0066Scanned agent has no declaration entry
no declaration entry for `campaigner`
stoa-declared.toml exists but doesn't mention this agent. Add an [agents."<id>"] entry, even a partial one.
research_agentElevated exposure

agents/research.py · High confidence

Recommend-only

1 high2 medium1 info
  • +1 more
Details & evidence

Detected because

  • OpenAI Agents SDK agent construct at line 3
  • Agent execution or orchestration call at line 15

Detection score: 8 · symbol: research_agent

Stack

Frameworks: openai_agents_sdk · Providers:

Capabilities (static evidence)

  • web_search

Integrations · call sites

None observed.

Attribution

Codeowners: @platform-team · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
infoCTRL0073No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate research_agent
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
mediumDECL0063Scanned agent has no declaration entry
no declaration entry for `research_agent`
stoa-declared.toml exists but doesn't mention this agent. Add an [agents."<id>"] entry, even a partial one.
highAI0057`trust_remote_code=True` observed on a model artifact load
reranker = AutoModel.from_pretrained("someorg/reranker", trust_remote_code=True) # AI005 trust-remote-code
Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
mediumAI0059Model, endpoint, or artifact dependency observed without a pin or integrity control
from_pretrained("sentence-transformers/all-MiniLM")
Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
script_toolsElevated exposure

mcp/script_tools.py · High confidence

Recommend-only

1 medium1 low2 info
  • shell_execution
  • +1 more
Details & evidence

Detected because

  • MCP server agent construct at line 8
  • LLM provider invocation at line 17
  • LLM provider import or reference at line 9

Detection score: 8 · symbol: script_tools

Stack

Frameworks: mcp · Providers: openai

Capabilities (static evidence)

  • mcp_tools
  • shell_execution

Integrations · call sites

None observed.

Attribution

Codeowners: @platform-team · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
infoAI0078Deterministic sampling not observed on high-impact-adjacent call sites
sampling config for candidate script_tools
Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
infoCTRL0078No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate script_tools
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
mediumDECL0068Scanned agent has no declaration entry
no declaration entry for `script_tools`
stoa-declared.toml exists but doesn't mention this agent. Add an [agents."<id>"] entry, even a partial one.
lowAI00517Model, endpoint, or artifact dependency observed without a pin or integrity control
model="gpt-4o"
Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
compliance_agentModerate exposure

agents/compliance.py · High confidence

Recommend-only

1 medium1 info
  • +1 more
Details & evidence

Detected because

  • LangChain agent construct at line 16
  • LangGraph agent construct at line 16
  • Tool or function schema at line 16
  • LLM provider import or reference at line 10

Detection score: 13 · symbol: compliance_agent

Stack

Frameworks: langchain, langgraph · Providers: anthropic

Capabilities (static evidence)

  • tool_calling

Integrations · call sites

None observed.

Attribution

Codeowners: @compliance-team · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
infoCTRL00716No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate compliance_agent
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
mediumDECL00616Scanned agent has no declaration entry
no declaration entry for `compliance_agent`
stoa-declared.toml exists but doesn't mention this agent. Add an [agents."<id>"] entry, even a partial one.
legacyLow exposure

agents/legacy.py · Medium confidence

Recommend-only

1 medium1 low1 info
  • +1 more
Details & evidence

Detected because

  • LLM provider invocation at line 10
  • Tool or function schema at line 6
  • LLM provider import or reference at line 4

Detection score: 5 · symbol: legacy

Stack

Frameworks: — · Providers: openai

Capabilities (static evidence)

  • tool_calling

Integrations · call sites

None observed.

Attribution

Codeowners: @platform-team · Last touched by: unknown

Findings in this file

SeverityRuleLineFinding
infoCTRL00710No kill-switch signal observed on the agent's entry path
No kill-switch signal observed on the agent's entry path for candidate legacy
Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
mediumDECL00610Scanned agent has no declaration entry
no declaration entry for `legacy`
stoa-declared.toml exists but doesn't mention this agent. Add an [agents."<id>"] entry, even a partial one.
lowAI00511Model, endpoint, or artifact dependency observed without a pin or integrity control
model="gpt-4o"
Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
triage_agentLow exposure

agents/triage.py · Medium confidence

Recommend-only

1 medium1 info
    Details & evidence

    Detected because

    • PydanticAI agent construct at line 2

    Detection score: 5 · symbol: triage_agent

    Stack

    Frameworks: pydantic_ai · Providers:

    Capabilities (static evidence)

    None observed.

    Integrations · call sites

    None observed.

    Attribution

    Codeowners: @platform-team · Last touched by: unknown

    Findings in this file

    SeverityRuleLineFinding
    infoCTRL0072No kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate triage_agent
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    mediumDECL0062Scanned agent has no declaration entry
    no declaration entry for `triage_agent`
    stoa-declared.toml exists but doesn't mention this agent. Add an [agents."<id>"] entry, even a partial one.

    NIST AI RMF alignment

    The evidence in this report maps to three NIST AI RMF functions. MAP — the agent inventory and the dimension matrix establish context: what agents exist and where their exposure sits. MEASURE — the findings and their file:line evidence, with OWASP and EU AI Act anchors, quantify and characterize that exposure. MANAGEstoa diff gating and the assurance export carry that evidence into change control and external review. This is an alignment aid, not a certification claim; GOVERN is an organizational function outside a static scan's view.

    All findings

    every finding, grouped — nothing omitted

    Security findings (22)
    SeverityRuleLocationConfidenceFindingRemediation
    criticalSEC002agents/devops.py:6HighPossible hardcoded password
    DB_PASSWORD = "Sup3rS…[REDACTED:92179e7ad06e]" # SEC002
    Load the password from a secret manager or environment variable.
    criticalSEC001agents/payments.py:8HighPossible hardcoded API credential
    OPENAI_FALLBACK = "sk-pro…[REDACTED:00d59b41db00]" # SEC001
    Load the credential from a secret manager or environment variable.
    criticalAI002agents/payments.py:23HighModel output observed reaching a dangerous execution or injection sink
    subprocess.run(reply, shell=True) # AI002 exec -> critical, GATE
    Dispatch through a static mapping of permitted actions; never execute or render model output directly.
    criticalAI002agents/payments.py:29HighModel output observed reaching a dangerous execution or injection sink
    cursor.execute(f"INSERT INTO audit(note) VALUES ('{reply}')") # AI002/sql ⊃ SEC003
    Dispatch through a static mapping of permitted actions; never execute or render model output directly.
    criticalSEC001tests/test_payments.py:1LowPossible hardcoded API credential
    FAKE = "sk-pro…[REDACTED:b559fd13432a]" # placeholder -> low confidence, never gates
    Load the credential from a secret manager or environment variable.
    highAI001agents/fraud.py:15HighUntrusted input observed flowing into prompt construction
    verdict = client.messages.create(model="claude-3-5-sonnet", # default sampling -> AI007
    Move untrusted content into a delimited user-role message and keep instruction text static.
    highAI006agents/fraud.py:19HighIdentifier suggesting sensitive data observed flowing to a network egress sink
    requests.post("https://siem.thirdparty-x.io/ingest", json=payload) # AI006 secret->egress
    Strip sensitive fields before egress, or add the destination to [rules.AI006].allowed_hosts if org-approved.
    highSEC003agents/payments.py:18MediumInterpolated SQL statement
    conn.cursor().execute(f"UPDATE ledger SET refunded=1 WHERE id={customer['id']}") # db_write
    Use parameterized queries instead of string interpolation.
    highAI004agents/payments.py:22HighIdentifier suggesting sensitive data observed in an external model call
    reply = llm.invoke(prompt).content # model output
    Pseudonymize sensitive fields before the model call and rejoin identifiers afterward.
    highAI004agents/payments.py:27HighIdentifier suggesting sensitive data observed in an external model call
    reply = llm.invoke("summarize action").content # model output
    Pseudonymize sensitive fields before the model call and rejoin identifiers afterward.
    highAI005agents/research.py:7High`trust_remote_code=True` observed on a model artifact load
    reranker = AutoModel.from_pretrained("someorg/reranker", trust_remote_code=True) # AI005 trust-remote-code
    Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
    highAI002web/support_bot.ts:11HighModel output observed reaching a dangerous execution or injection sink
    container.innerHTML = out.text; // AI002 markup (model output -> innerHTML)
    Dispatch through a static mapping of permitted actions; never execute or render model output directly.
    highAI002web/support_bot.ts:12HighModel output observed reaching a dangerous execution or injection sink
    await fetch("https://acme.zendesk.com/api/v2/tickets.json", { method: "POST", body: out.text });
    Dispatch through a static mapping of permitted actions; never execute or render model output directly.
    mediumAI005agents/devops.py:7HighModel, endpoint, or artifact dependency observed without a pin or integrity control
    base_url="http://mlgw.internal-x.io/v1")
    Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
    mediumAI004agents/fraud.py:15HighIdentifier suggesting sensitive data observed in an external model call
    verdict = client.messages.create(model="claude-3-5-sonnet", # default sampling -> AI007
    Pseudonymize sensitive fields before the model call and rejoin identifiers afterward.
    mediumAI005agents/research.py:9MediumModel, endpoint, or artifact dependency observed without a pin or integrity control
    from_pretrained("sentence-transformers/all-MiniLM")
    Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
    mediumAI006web/support_bot.ts:12HighIdentifier suggesting sensitive data observed flowing to a network egress sink
    await fetch("https://acme.zendesk.com/api/v2/tickets.json", { method: "POST", body: out.text });
    Strip sensitive fields before egress, or add the destination to [rules.AI006].allowed_hosts if org-approved.
    lowAI005agents/fraud.py:15LowModel, endpoint, or artifact dependency observed without a pin or integrity control
    model="claude-3-5-sonnet"
    Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
    lowAI005agents/legacy.py:11LowModel, endpoint, or artifact dependency observed without a pin or integrity control
    model="gpt-4o"
    Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
    lowAI005agents/payments.py:9LowModel, endpoint, or artifact dependency observed without a pin or integrity control
    ChatOpenAI(model="gpt-4o"
    Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
    lowAI005mcp/script_tools.py:17LowModel, endpoint, or artifact dependency observed without a pin or integrity control
    model="gpt-4o"
    Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
    lowAI005web/support_bot.ts:10LowModel, endpoint, or artifact dependency observed without a pin or integrity control
    openai('gpt-4o'
    Pin a reviewed model revision or dated snapshot and use a TLS endpoint from an allowlist.
    Reliability findings (1)
    SeverityRuleLocationConfidenceFindingRemediation
    infoNET002agents/fraud.py:19LowRequest timeout not observed
    requests.post("https://siem.thirdparty-x.io/ingest", json=payload) # AI006 secret->egress
    Pass an explicit timeout so a hung upstream cannot stall the agent.
    Review prompts (24)

    Review prompts are observations, not confirmed vulnerabilities: a control was not observed in the scanned file, but may exist elsewhere.

    SeverityRuleLocationConfidenceFindingRemediation
    lowCTRL006agents/payments.py:12LowSandboxing not observed on an exec path
    Sandboxing not observed on an exec path for candidate agent
    Confirm this execution path runs in a restricted environment (restricted env, container, sandboxed interpreter); none was observed near it.
    lowCTRL006agents/payments.py:12LowSandboxing not observed on an exec path
    Sandboxing not observed on an exec path for candidate executor
    Confirm this execution path runs in a restricted environment (restricted env, container, sandboxed interpreter); none was observed near it.
    infoCTRL007agents/compliance.py:16LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate compliance_agent
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoAI003agents/devops.py:3LowApproval control not observed for high-impact tool capability
    high-impact capability for candidate agent
    Confirm an approval or human-in-the-loop control gates this capability; none was observed in this file.
    infoCTRL007agents/devops.py:3LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate agent
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoAI007agents/fraud.py:9LowDeterministic sampling not observed on high-impact-adjacent call sites
    sampling config for candidate crew
    Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
    infoAI007agents/fraud.py:9LowDeterministic sampling not observed on high-impact-adjacent call sites
    sampling config for candidate analyst
    Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
    infoCTRL007agents/fraud.py:9LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate analyst
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoCTRL007agents/fraud.py:9LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate crew
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoCTRL007agents/legacy.py:10LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate legacy
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoCTRL007agents/marketing.py:6LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate campaigner
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoAI003agents/payments.py:12LowApproval control not observed for high-impact tool capability
    high-impact capability for candidate agent
    Confirm an approval or human-in-the-loop control gates this capability; none was observed in this file.
    infoAI003agents/payments.py:12LowApproval control not observed for high-impact tool capability
    high-impact capability for candidate executor
    Confirm an approval or human-in-the-loop control gates this capability; none was observed in this file.
    infoAI007agents/payments.py:12LowDeterministic sampling not observed on high-impact-adjacent call sites
    sampling config for candidate executor
    Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
    infoAI007agents/payments.py:12LowDeterministic sampling not observed on high-impact-adjacent call sites
    sampling config for candidate agent
    Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
    infoCTRL007agents/payments.py:12LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate executor
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoCTRL007agents/payments.py:12LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate agent
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoCTRL007agents/research.py:3LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate research_agent
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoCTRL007agents/triage.py:2LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate triage_agent
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoAI007mcp/script_tools.py:8LowDeterministic sampling not observed on high-impact-adjacent call sites
    sampling config for candidate script_tools
    Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
    infoCTRL007mcp/script_tools.py:8LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate script_tools
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    infoAI003web/support_bot.ts:10LowApproval control not observed for high-impact tool capability
    high-impact capability for candidate support_bot
    Confirm an approval or human-in-the-loop control gates this capability; none was observed in this file.
    infoAI007web/support_bot.ts:10LowDeterministic sampling not observed on high-impact-adjacent call sites
    sampling config for candidate support_bot
    Pin deterministic sampling (temperature=0) on consequential model call sites, or confirm variability is intended.
    infoCTRL007web/support_bot.ts:10LowNo kill-switch signal observed on the agent's entry path
    No kill-switch signal observed on the agent's entry path for candidate support_bot
    Consider a feature-flag or env-var gate that can disable this agent without a deploy; none was observed. This is the weakest signal in the control set -- informational only.
    Suppressed findings (3)
    RuleLocationFindingReason
    REL001agents/fraud.py:20Swallowed exceptionfire-and-forget telemetry
    REL001agents/legacy.py:12Swallowed exception
    SEC003lib/db.py:12Interpolated SQL statementtable name comes from the REPORTS enum above

    Architecture graph

    Agents, tools, providers, and capability-sinks this scan observed, with the findings that explain each connection. Every edge is declared (statically detected) — click any node or edge for evidence.

    Click a node or edge to see its detail.