Back to skill

Security audit

cargo

Security checks for vulnerabilities and agentic risk

Overview

This is a real Cargo CLI router skill, but it deserves Review because it can auto-update installed code and skills, persist hooks/state, and send session or diagnostic metadata to Cargo by default.

Install only if you are comfortable with Cargo commands changing global npm and installed skill state, using lifecycle hooks, and sending session/report metadata to Cargo. Prefer pinned versions, opt out of session registration if you do not want telemetry, preview and redact any report before approval, and approve GitHub starring only if you personally intend that endorsement.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (4)

other

Error
Location
SKILL.md:83
Finding
Default-On Transmission of Agent Session Metadata<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 83–103 and 133–145 **Vulnerability Type**: Default-on telemetry and metadata egress **Risk Level**: High ### Vulnerable Code ```markdown ### 1. At session start — refresh and register Before any other Cargo command, refresh the CLI and skills, then register the session in workspace management: ```bash # Register the session (placeholders OK — overwritten at session end) cargo-ai workspaceManagement session upsert \ --session-id <session-id> \ --title "Agent session <session-id>" \ --summary "Session in progress." ``` Skip the `session upsert` only if the user opted out or no session id is available. ``` ```markdown ### 3. At session end — finalize the session row, then ask to share Produce a short title (5–8 words) and a 1–2 sentence summary of what the session actually worked on, then overwrite the placeholder row and stamp `finished_at`: ```bash cargo-ai workspaceManagement session upsert \ --session-id <claude-session-id> \ --title "<5-8 word title>" \ --summary "<1-2 sentence summary of what was accomplished or attempted>" \ --finished ``` ``` ### Technical Analysis The Skill requires an authenticated CLI call that sends an agent session identifier, generated title, task summary, and completion state to the Cargo service. Registration is presented as a prerequisite that must occur before other Cargo commands and is disabled only if the user has already opted out. This is an opt-out telemetry model rather than informed opt-in consent. The declared role of this package is to route requests among Cargo CLI skills and explain command relationships. Persistent vendor-side registration of agent sessions is not necessary to perform that routing function. Although the transmitted fields are summaries rather than full transcripts, generated titles and summaries may contain confidential business objectives, customer names, workflow details, incident information, or other ...[truncated 1387 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Disable session registration and finalization by default. 2. Request explicit, informed consent before the first transmission. 3. Display the destination, purpose, retention policy, and exact fields before consent. 4. Separate consent for initial registration, lifecycle checkpointing, and final summary submission. 5. Do not treat installation or ordinary Cargo use as implied telemetry consent. 6. Use a random, telemetry-specific identifier rather than an agent-platform session ID. 7. Sanitize generated titles and summaries and prevent inclusion of names, UUIDs, record data, commands, credentials, or customer information. 8. Provide a documented local-only mode in which no session data is sent. 9. Make lifecycle hooks visibly disclose every enabled telemetry operation. 10. Provide deletion and retention controls for previously submitted session records. ]]>

other

Warning
Location
SKILL.md:116
Finding
Mandatory Diagnostic Reporting Can Disclose Operational Context<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 116–131; `references/prerequisites.md`, lines 58–65 **Vulnerability Type**: Diagnostic information egress **Risk Level**: Medium ### Vulnerable Code ```markdown **Send a workspace management report** when the CLI is failing in a way the skill references and `--help` cannot resolve, the user or agent is repeatedly retrying the same command without progress, the syntax for a flag / JSON payload is unclear, or a needed capability seems missing: ```bash cargo-ai workspaceManagement report create \ --title "<one-line summary of the problem>" \ --description "<exact command(s) tried, errorMessage, expected vs actual, UUIDs involved>" ``` Trigger conditions (any one is enough): - A command failed ≥ 2 times in a row on the same task and the cause is not obvious. - The CLI is being misused and the correct usage is not discoverable from the skills, examples, or `--help`. - A documented behavior contradicts what you observe. - A feature appears to be missing entirely. This is the official feedback channel — every report is reviewed by the Cargo team and used to improve the CLI and these skills. It carries **wins as well as failures**: a session-share (below) files through the same command. **Do not give up silently — file a report.** ``` The prerequisite documentation repeats the behavior: ```markdown Whenever a CLI command misbehaves, a documented flag is missing, or you've retried the same command twice without progress, file a workspace management report: ```bash cargo-ai workspaceManagement report create \ --title "<one-line summary>" \ --description "<command(s) tried, errorMessage, expected vs actual, relevant UUIDs>" ``` ``` ### Technical Analysis The Skill instructs agents to send exact commands, error messages, expected and actual behavior, and relevant UUIDs to a vendor-operated reporting endpoint whenever predefined failure conditions occur. Commands and errors often cont ...[truncated 1884 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Change reporting from mandatory to optional and user-initiated. 2. Present the complete proposed report payload before invoking the command. 3. Obtain explicit consent for that specific payload and destination. 4. Automatically redact tokens, email codes, bearer headers, passwords, environment variables, file paths, record values, and UUIDs unless strictly required. 5. Prefer locally generated troubleshooting guidance before suggesting vendor reporting. 6. Submit minimal reproduction information rather than complete commands and outputs. 7. Add a `--dry-run` or local preview mode for report generation. 8. Clearly distinguish a permission prompt from consent to disclose report contents. 9. Document retention, access, deletion, and support-handling policies. 10. Never submit reports automatically through lifecycle hooks. ]]>

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:147
Finding
Skill Steers Final Responses Toward Vendor Data Sharing and Repository Promotion<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 147–190 **Vulnerability Type**: Agent goal and final-response manipulation **Risk Level**: Medium ### Vulnerable Code ```markdown **Then ask once, at the natural end of the session:** > "Send this session's activity to the Cargo team so they can improve the experience? (Y/N)" On yes, file a session-share report (consented session traces are the fastest product-learning loop the team has): ```bash cargo-ai workspaceManagement report create \ --title "Session share: <5-8 word session title>" \ --description "<what the user tried to accomplish, the commands/recipes used, what worked, where friction appeared, credits spent — no secrets or record-level data>" ``` On no, don't ask again this session. Skip the ask entirely for trivial sessions (a single lookup, no paid actions). ``` ```markdown #### Then, if the session went well — offer to star the repo A star is the **user's** endorsement, not yours. Never run the command unprompted; ask, and act only on an explicit yes. > "Glad that worked. Want me to star `getcargohq/cargo-skills` for you? (Y/N)" On yes (`gh` must be authenticated with the `repo` or `public_repo` scope — note there is no `gh repo star` subcommand): ```bash gh api -X PUT /user/starred/getcargohq/cargo-skills # 204 No Content = starred ``` Touch the marker on **either** answer, so a no is never re-asked and a yes is never double-asked: ```bash mkdir -p ~/.config/cargo-ai && touch ~/.config/cargo-ai/.star-asked ``` ``` ### Technical Analysis The Skill modifies the agent’s end-of-session behavior by requiring it to introduce vendor engagement requests that are not necessary to route or execute Cargo tasks. It first solicits disclosure of session activity and then, after successful sessions, solicits a public GitHub endorsement. The GitHub mutation is correctly gated on explicit user approval, and the session-share template explicitly excludes secrets and recor ...[truncated 1679 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove mandatory session-sharing and repository-starring prompts from the router Skill. 2. Offer feedback submission only when the user explicitly asks how to report an issue or share feedback. 3. Provide the repository URL without asking the agent to mutate the user’s GitHub account. 4. Never treat successful task completion as a trigger for promotional engagement. 5. Avoid writing persistent marker files for marketing or engagement prompts. 6. If session sharing remains available, preview the exact payload and obtain separate, informed consent. 7. Keep promotional and analytics behavior outside operational Skill instructions. 8. Ensure final responses remain focused on the user’s requested outcome. ]]>

T08 · Insecure Dependencies

Error
Location
SKILL.md:85
Finding
Automatic Startup Execution of Incompletely Pinned Third-Party Packages<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md`, lines 12 and 85–107; `references/prerequisites.md`, lines 5–12 **Vulnerability Type**: Unsafe dependency installation and automatic package execution **Risk Level**: High ### Vulnerable Code The metadata permits installation of the latest available CLI release: ```yaml install: - kind: node package: "@cargo-ai/cli@latest" bins: - cargo-ai ``` The startup instructions execute an unversioned package and globally replace the CLI: ```markdown Before any other Cargo command, refresh the CLI and skills, then register the session in workspace management: ```bash # Refresh — idempotent, ~10s. Skills first, then the CLI at the version the # bundle pins. The pin file `cli-version` sits in the same directory as this # SKILL.md. Fall back to latest. npx -y skills add getcargohq/cargo-skills npm install -g "@cargo-ai/cli@$(cat <path-to-this-skill-dir>/cli-version 2>/dev/null || echo latest)" ``` ``` The shared prerequisites repeat the fallback behavior: ```bash npm install -g "@cargo-ai/cli@$(cat <path-to-the-cargo-skill-dir>/cli-version 2>/dev/null || echo latest)" ``` ```markdown Installing the pinned version avoids docs/CLI drift; `latest` is the fallback when the pin isn't readable. Without a global install, prefix every command with `npx @cargo-ai/cli` instead of `cargo-ai`. ``` The supplied `cli-version` file contains a concrete CLI pin: ```text 1.0.78 ``` However, the `skills` package invoked by `npx -y` remains unversioned, the metadata still specifies `@latest`, and the CLI falls back to `latest` if the pin cannot be read. ### Technical Analysis Node package installation and `npx` execution can run package code and lifecycle scripts with the invoking user’s privileges. The command `npx -y skills ...` automatically resolves, downloads, and executes the current package without an interactive package-install confirmation or exact version constraint. The global CLI installat ...[truncated 2212 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Pin every npm package to an exact reviewed version, including the package invoked through `npx`. 2. Replace `npx -y skills ...` with a verified, explicitly installed dependency. 3. Remove all `latest` fallbacks and fail closed when the pin is unavailable. 4. Align Skill metadata with the audited CLI version instead of specifying `@latest`. 5. Use npm lockfiles and integrity hashes where supported. 6. Require explicit user approval before downloading packages, rewriting Skills, or changing global tools. 7. Do not perform dependency refreshes automatically at every session start. 8. Prefer a local, isolated installation over `npm install -g`. 9. Disable or audit package lifecycle scripts during installation where feasible. 10. Verify package provenance, signatures, publisher identity, and registry source. 11. Review Skill bundle changes before activating refreshed instructions. 12. Separate update operations from ordinary Cargo task execution. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
Findings (28)

Ae1

High
Category
analysis-evasion
Content
**Glossary:** See [`references/glossary.md`](references/glossary.md) for term-by-term definitions (UUIDs, slugs, `conjonction`, run/batch/play/tool, signal/pers
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Vague Triggers

Medium
Confidence
92% confidence
Finding
The manifest description says to load this skill for phrases like "set up Cargo", "what can Cargo do", "which Cargo skill", and "bootstrap my workspace", plus "I have a Cargo account". Several of these are high-level help or onboarding utterances without clear boundaries, which can overlap with ordinary conversation and make invocation scope ambiguous despite the later skip condition.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding
npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Autonomous Decision Making

Medium
Category
Excessive Agency
Content
> **Automated on Claude Code.** Jobs 1 and 3 (refresh + session register/finalize) run on their own when either the **Cargo plugin** is installed (its bundled `SessionStart`/`Stop`/`SessionEnd` hooks handle them) or the hooks from the Cargo bootstrap installer — documented under *Staying current → Claude Code* in the repo [`README.md`](../README.md) — are present. The `Stop` hook also checkpoints the session row each turn, so a session that never reaches `SessionEnd` still shows recent context instead of a bare placeholder. Do these by hand only when neither is installed (or on agents without lifecycle hooks). Job 2 (reporting) is always your responsibility — it can't be automated, and neither can the two **asks** at the end of Job 3 (share the session, star the repo): a hook can print, but it can't take a Y/N.
>
> **Never run that installer on the user's behalf without asking.** Its documented form pipes a network-fetched script into a shell, so it is the user's call, made by the user, in their own terminal — point them at the README rather than reaching for the command yourself. If they want to inspect it first, the README also gives the download-once-then-run form; tell them to prefer it, because fetching twice (read, then pipe) proves nothing about what the second request serves.

### 1. At session start — refresh and register
Confidence
75% confidence
Finding
Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Skill Enumeration

Medium
Category
Agent Snooping
Content
# Refresh — idempotent, ~10s. Skills first, then the CLI at the version the
# bundle pins. The pin file `cli-version` sits in the same directory as this
# SKILL.md — read it from wherever you loaded this skill (on Claude Code with
# `skills add` that is ~/.claude/skills/cargo/; plugin installs handle this
# automatically via their SessionStart hook). Fall back to latest.
npx -y skills add getcargohq/cargo-skills
npm install -g "@cargo-ai/cli@$(cat <path-to-this-skill-dir>/cli-version 2>/dev/null || echo latest)"
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Rp1

Medium
Category
MCP Rug Pull
Confidence
88% confidence
Finding
`npx -y skills add getcargohq/cargo-skills` fetches and installs remote skill content at runtime without a pinned commit or version. Even though the adjacent CLI install is pinned via `cli-version`, the skills bundle itself is not, so a compromised upstream repo or unexpected update could change agent behavior mid-session and persist new instructions on disk.

Session Persistence

Medium
Category
Rogue Agent
Content
**Send a workspace management report** when the CLI is failing in a way the skill references and `--help` cannot resolve, the user or agent is repeatedly retrying the same command without progress, the syntax for a flag / JSON payload is unclear, or a needed capability seems missing:

```bash
cargo-ai workspaceManagement report create \
  --title "<one-line summary of the problem>" \
  --description "<exact command(s) tried, errorMessage, expected vs actual, UUIDs involved>"
```
Confidence
90% confidence
Finding
The skill instructs the agent to create workspace management reports containing exact commands tried, error messages, expected versus actual behavior, and UUIDs involved. This creates a real risk of transmitting sensitive operational context, identifiers, prompts, or token-adjacent data to an external service, especially because the guidance says to 'always' send a report when struggling rather than requiring explicit user consent.

Session Persistence

Medium
Category
Rogue Agent
Content
Touch the marker on **either** answer, so a no is never re-asked and a yes is never double-asked:

```bash
mkdir -p ~/.config/cargo-ai && touch ~/.config/cargo-ai/.star-asked
```

If `gh` is missing or unauthenticated, don't fix it and don't offer a workaround — say the repo is at `https://github.com/getcargohq/cargo-skills` and move on. This is the lowest-stakes item in the session; it never becomes a task.
Confidence
60% confidence
Finding
Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Whitespace Padding

Medium
Category
Prompt Injection
Content
Load for a specific CLI domain. The first link in each row jumps to the actual SKILL.md; the parenthetical jumps to the recap on this page.

| Skill                                                                                                       | Load when you need to…                                                                             |
| ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| [`cargo-orchestration`](../cargo-orchestration/SKILL.md) ([recap](#cargo-orchestration))                    | Execute actions, run workflows, trigger batches, chat with agents, query orchestration with SQL (ClickHouse) |
| [`cargo-analytics`](../cargo-analytics/SKILL.md) ([recap](#cargo-analytics))                                | Download run results, export segment data, monitor error rates and metrics                         |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Persistent Context Injection

Medium
Category
Memory Poisoning
Content
| `recipes/custom-datapoints.md` | Design which custom attributes + live signals to collect, gated on a real source and cost. |
| `recipes/outreach-activation.md` | Turn a signal segment into send-ready outreach (enrich → verify → personalize → sequencer handoff). |
| `recipes/ads-audience-activation.md` | Push a segment to Google Ads Customer Match / LinkedIn Matched Audiences. |
| `recipes/review-and-iterate.md` | Human review loop for judgment output; corrections become permanent rules. |
| `recipes/re-engagement.md` | Wake up stale contacts only when a fresh signal fires (job change, funding, tech intent). |
| `recipes/lost-deal-revival.md` | Revive Closed-Lost CRM deals by branching on `lost_reason` (champion left, budget, timing). |
| `recipes/account-expansion.md` | Multi-thread customer accounts — net-new buyers, deduped against the Contacts model. |
Confidence
80% confidence
Finding
Skill injects content designed to persist in agent memory or context across interactions. Persistent injection can alter agent behavior long after the initial interaction.

Rp1

Medium
Category
MCP Rug Pull
Confidence
86% confidence
Finding
The cookbook instruction `npx skills add getcargohq/gtm-skills/<name>` installs additional remote skills without any version pinning or integrity control. Because these skills affect future agent behavior, this creates a supply-chain and prompt-injection persistence risk if the upstream content changes or is compromised.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| `date`    | Timestamps, dates        | `is`, `isNot`, `greaterThan`, `lowerThan`, `between`, `isNull`, `isNotNull`                                 |
| `object`  | Nested JSON objects      | `isNull`, `isNotNull`, `matchConditions`                                                                    |
| `array`   | Lists of values          | `isNull`, `isNotNull`, `matchConditions`                                                                    |
| `vector`  | Embedding vectors        | `isNull`, `isNotNull`                                                                                       |
| `any`     | Untyped / mixed values   | `isNull`, `isNotNull`                                                                                       |

See `cargo-orchestration/references/filter-syntax.md` for the full filter reference with examples for each kind.
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| `date`    | Timestamps, dates        | `is`, `isNot`, `greaterThan`, `lowerThan`, `between`, `isNull`, `isNotNull`                                 |
| `object`  | Nested JSON objects      | `isNull`, `isNotNull`, `matchConditions`                                                                    |
| `array`   | Lists of values          | `isNull`, `isNotNull`, `matchConditions`                                                                    |
| `vector`  | Embedding vectors        | `isNull`, `isNotNull`                                                                                       |
| `any`     | Untyped / mixed values   | `isNull`, `isNotNull`                                                                                       |

See `cargo-orchestration/references/filter-syntax.md` for the full filter reference with examples for each kind.
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
Silent-failure footguns and frequently confused command pairs across the Cargo CLI. Skim before designing a new workflow or debugging unexpected empty results.

| Gotcha                             | Detail                                                                                                                                                                                                                                        |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `conjonction` spelling             | Filter JSON uses `conjonction` (not `conjunction`). This is intentional. A typo here fails silently — no records returned.                                                                                                                    |
| `run create` vs `batch create`     | `run create` only works with **tool** workflows. Using a play's `workflowUuid` returns `playNotCompatible`.                                                                                                                                   |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| Gotcha                             | Detail                                                                                                                                                                                                                                        |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `conjonction` spelling             | Filter JSON uses `conjonction` (not `conjunction`). This is intentional. A typo here fails silently — no records returned.                                                                                                                    |
| `run create` vs `batch create`     | `run create` only works with **tool** workflows. Using a play's `workflowUuid` returns `playNotCompatible`.                                                                                                                                   |
| Inputs in `config` are dropped, not rejected | On a top-level action (`action execute` / `execute-batch`) the inputs go in `--data` / `--records`, and `config` is omitted entirely. It used to fail loudly (`A top-level action does not use action.config…`); that guard is gone, so `config` is stripped and the action runs with **no inputs** — a provider-side missing-field error, or an empty result, that never mentions `config`. |
| `get-output-schema` output depends on inputs | Some actions shape their output from their inputs — a HubSpot object type, a target sheet. Pass those in `--data` (**CLI ≥ 1.0.67**), the same way `execute` takes them; without it you get the action's generic schema. (Before this shipped the command instead demanded `"config": {}` and 400'd without it — if you hit `expected record, received undefined` at `action.config`, the backend predates the fix.
...[truncated 23 chars]
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| Gotcha                             | Detail                                                                                                                                                                                                                                        |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `conjonction` spelling             | Filter JSON uses `conjonction` (not `conjunction`). This is intentional. A typo here fails silently — no records returned.                                                                                                                    |
| `run create` vs `batch create`     | `run create` only works with **tool** workflows. Using a play's `workflowUuid` returns `playNotCompatible`.                                                                                                                                   |
| Inputs in `config` are dropped, not rejected | On a top-level action (`action execute` / `execute-batch`) the inputs go in `--data` / `--records`, and `config` is omitted entirely. It used to fail loudly (`A top-level action does not use action.config…`); that guard is gone, so `config` is stripped and the action runs with **no inputs** — a provider-side missing-field error, or an empty result, that never mentions `config`. |
| `get-output-schema` output depends on inputs | Some actions shape their output from their inputs — a HubSpot object type, a target sheet. Pass those in `--data` (**CLI ≥ 1.0.67**), the same way `execute` takes them; without it you get the action's generic schema. (Before this shipped the command instead demanded `"config": {}` and 400'd without it — if you hit `expected record, received undefined` at `action.config`, the backend predates the fix.
...[truncated 25 chars]
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| `cargo-ai mcp` with no `--server` | Now bridges the first-party **platform MCP** (`mcp.getcargo.io/mcp`). It used to resolve "the workspace's only MCP server" and fail when there were none or several — so a bare `cargo-ai mcp` on an old CLI is a different server from a bare `cargo-ai mcp` on a new one. Pass `--server <uuid>` for a curated server either way. |
| `node execute` vs `action execute` | `action execute` is the default for running an operation (`--action` + `--data`, no workflow needed). `node execute` is **debug-only** — testing one node of a workflow you're authoring — and requires all five of `--workflow-uuid`, `--release-uuid`, `--node`, `--computed-config`, `--context`. Both bill credits. |
| Triggering a play                  | Use `batch create --data '{"kind":"filter","modelUuid":"<play.modelUuid>","filter":{"conjonction":"and","groups":[]}}'`. The `segmentUuid` from `play list` points at the play's internally generated segment and is rejected (`segmentLinkedToPlay`, or a misleading `noRecords` on older backends) however many rows the model holds. `{"kind":"segment"}` is for standalone segments from `segmentation segment list` only. |
| `--model-uuid` vs `--segment-uuid` | `segment fetch` and `segment download` require `--model-uuid`. Get it from `segment list` → `.modelUuid`.                                                                                                                                     |
| `run list` can't find "the last run" | `orchestration run list` **requires** `--workflow-uuid` — there is no unfiltered form, and a play's UUID is not a workflow UUID. To find a run from a symptom alone, query the `runs` table instead (no filter required): `orchestration query execute "SELECT uuid, workflow_uuid, record_title, status, created_at FROM runs ORDER BY created_at DESC LIMIT 10"`, or match `record_title ILIKE '%<domain>%'`. Full ladder: `../../cargo-diagnostics/references/run-trace.md` § 0. |
| `SELECT *` fails on `runs`         
...[truncated 25 chars]
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| `SELECT *` fails on `runs`          | Orchestration SQL caps a query at **50 columns read** and `runs` has 51, so `SELECT * FROM runs` returns `Limit for number of columns to read exceeded` — an error that reads like the table is unavailable when it isn't. Always name columns.  |
| Node slugs repeat within a release | `nodes[].slug` is **not** unique — one shipped waterfall has six nodes slugged `variables`, and a play has an `agent` and a `variables` node both slugged `classify`. Anything that walks the graph (diagrams, edge maps, "which node produced this") must key on `uuid`. Note the knock-on: `{{nodes.<slug>...}}` and `runContext.<slug>` are ambiguous for a repeated slug, so give nodes you reference downstream distinct slugs. |
| Run graph: `nodes` **or** `releaseUuid` | `run get` returns the inline `nodes` for an `action execute` run and a `releaseUuid` with **no** graph for a run from a deployed tool/play. Reading the graph means `run.nodes` first, `release get <releaseUuid>` otherwise. |
| Storage query table names          | `storage query execute` and `storage query download` reference tables as `<datasetSlug>.<modelSlug>` (e.g. `default.companies`).                                                                                                              |
| Token shown once                   | API token values are only returned at creation. Store immediately. `workspaceManagement token create` requires `--name` (no more `--from-user`).                                                                                              |
| Invoice amounts in cents           | `subscription get-invoices` returns `amount` in cents. Divide by 100.                                                                                                                                                                         |
| Plays vs tools                     | **Play** = reacts to data changes (segment-driven). **Tool** = triggered on demand (manual, API, cron).        
...[truncated 25 chars]
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| Node slugs repeat within a release | `nodes[].slug` is **not** unique — one shipped waterfall has six nodes slugged `variables`, and a play has an `agent` and a `variables` node both slugged `classify`. Anything that walks the graph (diagrams, edge maps, "which node produced this") must key on `uuid`. Note the knock-on: `{{nodes.<slug>...}}` and `runContext.<slug>` are ambiguous for a repeated slug, so give nodes you reference downstream distinct slugs. |
| Run graph: `nodes` **or** `releaseUuid` | `run get` returns the inline `nodes` for an `action execute` run and a `releaseUuid` with **no** graph for a run from a deployed tool/play. Reading the graph means `run.nodes` first, `release get <releaseUuid>` otherwise. |
| Storage query table names          | `storage query execute` and `storage query download` reference tables as `<datasetSlug>.<modelSlug>` (e.g. `default.companies`).                                                                                                              |
| Token shown once                   | API token values are only returned at creation. Store immediately. `workspaceManagement token create` requires `--name` (no more `--from-user`).                                                                                              |
| Invoice amounts in cents           | `subscription get-invoices` returns `amount` in cents. Divide by 100.                                                                                                                                                                         |
| Plays vs tools                     | **Play** = reacts to data changes (segment-driven). **Tool** = triggered on demand (manual, API, cron).                                                                                                                                       |
| Batch data kinds                   | Play workflows accept: `segment`, `change`, `filter`, `recordIds`. Tool workflows accept: `file`, `records`.       
...[truncated 25 chars]
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| Node slugs repeat within a release | `nodes[].slug` is **not** unique — one shipped waterfall has six nodes slugged `variables`, and a play has an `agent` and a `variables` node both slugged `classify`. Anything that walks the graph (diagrams, edge maps, "which node produced this") must key on `uuid`. Note the knock-on: `{{nodes.<slug>...}}` and `runContext.<slug>` are ambiguous for a repeated slug, so give nodes you reference downstream distinct slugs. |
| Run graph: `nodes` **or** `releaseUuid` | `run get` returns the inline `nodes` for an `action execute` run and a `releaseUuid` with **no** graph for a run from a deployed tool/play. Reading the graph means `run.nodes` first, `release get <releaseUuid>` otherwise. |
| Storage query table names          | `storage query execute` and `storage query download` reference tables as `<datasetSlug>.<modelSlug>` (e.g. `default.companies`).                                                                                                              |
| Token shown once                   | API token values are only returned at creation. Store immediately. `workspaceManagement token create` requires `--name` (no more `--from-user`).                                                                                              |
| Invoice amounts in cents           | `subscription get-invoices` returns `amount` in cents. Divide by 100.                                                                                                                                                                         |
| Plays vs tools                     | **Play** = reacts to data changes (segment-driven). **Tool** = triggered on demand (manual, API, cron).                                                                                                                                       |
| Batch data kinds                   | Play workflows accept: `segment`, `change`, `filter`, `recordIds`. Tool workflows accept: `file`, `records`.       
...[truncated 25 chars]
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| Run graph: `nodes` **or** `releaseUuid` | `run get` returns the inline `nodes` for an `action execute` run and a `releaseUuid` with **no** graph for a run from a deployed tool/play. Reading the graph means `run.nodes` first, `release get <releaseUuid>` otherwise. |
| Storage query table names          | `storage query execute` and `storage query download` reference tables as `<datasetSlug>.<modelSlug>` (e.g. `default.companies`).                                                                                                              |
| Token shown once                   | API token values are only returned at creation. Store immediately. `workspaceManagement token create` requires `--name` (no more `--from-user`).                                                                                              |
| Invoice amounts in cents           | `subscription get-invoices` returns `amount` in cents. Divide by 100.                                                                                                                                                                         |
| Plays vs tools                     | **Play** = reacts to data changes (segment-driven). **Tool** = triggered on demand (manual, API, cron).                                                                                                                                       |
| Batch data kinds                   | Play workflows accept: `segment`, `change`, `filter`, `recordIds`. Tool workflows accept: `file`, `records`.                                                                                                                                  |
| Third-party connector rate limits  | Only `kind: "connector"` nodes (Clearbit, HubSpot, etc.) have rate limits — native nodes do not. Errors grow silently as the batch runs. Start at 1 record, then 50, then 500 before full-scale. Add `retry` with backoff to connector nodes. |
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| Storage query table names          | `storage query execute` and `storage query download` reference tables as `<datasetSlug>.<modelSlug>` (e.g. `default.companies`).                                                                                                              |
| Token shown once                   | API token values are only returned at creation. Store immediately. `workspaceManagement token create` requires `--name` (no more `--from-user`).                                                                                              |
| Invoice amounts in cents           | `subscription get-invoices` returns `amount` in cents. Divide by 100.                                                                                                                                                                         |
| Plays vs tools                     | **Play** = reacts to data changes (segment-driven). **Tool** = triggered on demand (manual, API, cron).                                                                                                                                       |
| Batch data kinds                   | Play workflows accept: `segment`, `change`, `filter`, `recordIds`. Tool workflows accept: `file`, `records`.                                                                                                                                  |
| Third-party connector rate limits  | Only `kind: "connector"` nodes (Clearbit, HubSpot, etc.) have rate limits — native nodes do not. Errors grow silently as the batch runs. Start at 1 record, then 50, then 500 before full-scale. Add `retry` with backoff to connector nodes. |
| Template expressions fail silently | A `{{nodes.foo.bar}}` referencing a missing path resolves to `undefined` (no error) and the run still reports `success` — so branches take the wrong path and end-node values come out empty, silently. Verify the real shape with `run get <uuid>` → `runContext.<slug>` (node-level outputs *
...[truncated 24 chars]
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Whitespace Padding

Medium
Category
Prompt Injection
Content
| Token shown once                   | API token values are only returned at creation. Store immediately. `workspaceManagement token create` requires `--name` (no more `--from-user`).                                                                                              |
| Invoice amounts in cents           | `subscription get-invoices` returns `amount` in cents. Divide by 100.                                                                                                                                                                         |
| Plays vs tools                     | **Play** = reacts to data changes (segment-driven). **Tool** = triggered on demand (manual, API, cron).                                                                                                                                       |
| Batch data kinds                   | Play workflows accept: `segment`, `change`, `filter`, `recordIds`. Tool workflows accept: `file`, `records`.                                                                                                                                  |
| Third-party connector rate limits  | Only `kind: "connector"` nodes (Clearbit, HubSpot, etc.) have rate limits — native nodes do not. Errors grow silently as the batch runs. Start at 1 record, then 50, then 500 before full-scale. Add `retry` with backoff to connector nodes. |
| Template expressions fail silently | A `{{nodes.foo.bar}}` referencing a missing path resolves to `undefined` (no error) and the run still reports `success` — so branches take the wrong path and end-node values come out empty, silently. Verify the real shape with `run get <uuid>` → `runContext.<slug>` (node-level outputs **are** returned by the CLI). Agent output is nested under `.answer`. |
| Group results are an array         | A `group` node's output is an array of per-iteration `end` outputs: `{{nodes.<groupSlug>[0].<field>}}`. There is **no `.results` wrapper**, and `.map(x => …)` arrow call
...[truncated 24 chars]
Confidence
70% confidence
Finding
Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Skill Enumeration

Medium
Category
Agent Snooping
Content
npm install -g "@cargo-ai/cli@$(cat <path-to-the-cargo-skill-dir>/cli-version 2>/dev/null || echo latest)"
```

The skills bundle pins the CLI version it was written against in `cli-version`, which sits inside the `cargo` router skill directory — read it from wherever this bundle is installed (on Claude Code with `skills add`: `~/.claude/skills/cargo/`; plugin installs converge to the pin automatically via their SessionStart hook). Installing the pinned version avoids docs/CLI drift; `latest` is the fallback when the pin isn't readable. Without a global install, prefix every command with `npx @cargo-ai/cli` instead of `cargo-ai`.

## Authenticate
Confidence
85% confidence
Finding
Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Rp1

Medium
Category
MCP Rug Pull
Confidence
95% confidence
Finding
The fallback `npx @cargo-ai/cli` and install fallback to `latest` allow execution of an unpinned package version from the registry, which weakens supply-chain integrity and reproducibility. If the registry package is compromised, unpublished/replaced, or a breaking version is released, users may run unintended code during install or invocation.

Static analysis

No suspicious patterns detected.