Threat model

Keep credential values out of the agent's reach

Developer tools execute third-party code in a high-trust context. For built-in HTTP and SSH, Sallyport keeps the stored reusable credential out of that ambient context and mediates each invocation locally.

Credential value

Sallyport does not intentionally add resolved credentials to agent results, approvals, audit events, logs, or errors. It does not inspect or rewrite executor responses, which may contain sensitive target-supplied data.

Authorization

Vault state, per-call controls, and live process identity decide whether a tool invocation can start.

Evidence

Every admitted tool invocation needs a durable encrypted intent row first. Catalog discovery does not.

Why this exists

How a compromised dependency reaches credentials

A trusted package or workflow already runs where developers and CI keep reusable credentials. Once that code turns malicious, reading and exporting those credentials can be a single execution path.

trusted code pathambient credential collection
Trusted dependencyMaintainer or release path compromised
Lifecycle executionInstall, build, or CI step
Developer or CI contextCode runs with existing user access
Environment variables
Credential files
Process memory
Installed AI tools
Attacker destinationStolen credentials remain reusable
A compromised trusted dependency runs a lifecycle script inside a developer or CI process. It collects secrets from environment variables, files, process memory, and installed AI tools, then sends them to an attacker-controlled destination.

Recent incidents used this path

The details vary by campaign. In each case, malicious code executed close to credentials that other systems would accept later.

  1. May 2026

    Malicious TanStack packages

    Eighty-four malicious versions across 42 @tanstack packages ran an install-time payload that harvested cloud credentials, GitHub tokens, and SSH keys, then attempted to spread through packages maintained by each victim.

    TanStack security advisory
  2. Late 2025

    Shai-Hulud npm campaigns

    Compromised packages used install-time execution to steal secrets and spread with stolen credentials. Later variants added CI-specific behavior and self-hosted runner abuse.

    GitHub supply chain review
  3. August 2025

    Nx S1ngularity

    Malicious Nx package versions ran a post-install script that scanned developer systems for sensitive data, attempted to use local AI tools, and uploaded results through GitHub CLI.

    Nx incident postmortem
GitHub Docs: why a compromised runner can harvest and deliberately exfiltrate referenced secrets
Control point

Remove reusable credentials from the process

A secret in an environment variable or file is data the process can copy. A Sallyport-managed credential is instead an input to a local operation, subject to vault state, approval, target binding, and audit.

Ambient credential

Built-in HTTP / SSH

Compromised code
Reads reusable value
Sends or stores it
credential copied
Compromised code
Structured operation
Sallyport boundaryState, identity, approval, durable intent
Attach auth / sign SSH
Requested / configured target
Encrypted vault
deny or askcredential reaches only executor / recipient pathauthorized misuse or sensitive output remains
In the ambient path, compromised code reads a reusable credential and sends it anywhere. In the Sallyport built-in HTTP and SSH path, the code submits a structured operation. Sallyport may deny or ask, attaches an HTTP credential or signs an SSH challenge inside the executor, and sends the operation to the requested or configured target. The target result is returned without content inspection or rewriting and may contain sensitive data.

For built-in HTTP and SSH, a package cannot read the stored credential from the agent's environment. It must request an operation that can be denied, gated per call, constrained to the requested or configured target, and journaled. The target response is returned without content inspection or rewriting.

This does not stop malicious code from running or prove an approved request is benign. HTTP and SSH targets may return sensitive data. Remote MCP servers receive configured authentication; local stdio servers receive bound credentials in their environment. Treat every target and upstream as a trusted credential recipient.

Decision ladder

The same checks run on every admitted invocation

The compiled ladder applies to tool invocation. Upstream initialize and tools/list traffic manages the catalog outside this path and receives no invocation intent row.

  1. 01

    Vault ready

    Any other state denies agent actions.

    deny | next

  2. 02

    Target resolves

    Required target and credential metadata must exist.

    deny | next

  3. 03

    Per-call check

    Flagged keys or upstreams ask every time.

    ask | next

  4. 04

    Process admission

    Admit the live process by session, allowlist, session card, or observe mode. This does not identify which loaded package or inherited byte source made the request.

    ask | next

  5. 05

    Audit intent

    The encrypted intent must be durable before execution.

    deny | run

  6. 06

    Execute and return the result

    Run the channel, append the outcome, and return the bounded executor result without content inspection or rewriting. Results may contain sensitive data.

    result

An exact-cdhash allowlist stops matching after a binary update. A publisher entry can keep matching same-identity updates, so a compromised publisher or signing path remains trusted. Either entry skips only the session card.

Coverage

Controls and residual risk

The model has an explicit boundary. Residual risk is part of it.

ThreatWhat Sallyport changesWhat remains
Malicious dependency reads files or environmentFor built-in HTTP and SSH, Sallyport does not place the stored credential in the agent environment or intentionally add it to results, logs, approvals, or audit events. Executor results are returned without content inspection or rewriting.Credentials outside Sallyport remain exposed. Local stdio MCP servers receive bound credentials and inherit Sallyport's environment.
Prompt-injected or compromised approved agentPer-call keys still require a click or Touch ID. Sallyport rechecks live process identity on later invocations.Admission covers the process, not each package or byte. Loaded code and writers to an inherited socket or pipe inherit that admission.
Credential redirected to another hostHTTP credentials attach only for a matching host and path. Credentialed requests do not follow redirects; uncredentialed redirects stay on the same host and port and cannot downgrade HTTPS.Current DNS validation does not pin the checked address through connection, so a rebinding gap remains.
Local audit history is editedEncrypted rows and the signed ciphertext chain detect edits, reordering, internal gaps, and signer substitution. A separate signed local checkpoint detects rollback behind it.A post-checkpoint tail can be lost after an unclean shutdown. Complete consistent local rollback needs an off-device witness to distinguish it from restoration.
An upstream puts secrets in MCP catalog metadataChoose and review upstream server code as part of the trust boundary. Sallyport returns tool results, errors, and authenticated catalog metadata without credential-content filtering, subject to documented size and description limits.Initialize and tools/list are outside invocation audit. Their names, descriptions, and schemas are arbitrary upstream-controlled content and may contain credentials or other sensitive data.
Root or code execution inside SallyportSecure Enclave gates private key use and the vault remains encrypted at rest.Root, disabled SIP, or in-process code execution can control an unlocked vault. Sallyport is not a host sandbox or antivirus.
Hard limits

What this model does not claim

Sallyport reduces credential exposure and adds control around use. It does not turn hostile local code into trusted code.

01

Approval is not intent analysis

A session card identifies the process and its provenance. It does not determine whether every request inside that session is safe.

02

Process admission is not component isolation

A session identifies the live process. Code loaded into it, or a component writing through an inherited socket or pipe, receives the same admission.

03

The operator can approve harm

A click or Touch ID proves the ceremony happened. It cannot make a poorly reviewed operation harmless.

04

MCP upstreams are trusted recipients

A remote server receives its configured API key or OAuth token. A local stdio child receives bound credentials and the app environment. Sallyport does not sandbox either server.

05

Catalog metadata is untrusted content

Initialization and tools/list bypass the invocation ladder and intent audit. Tool names, descriptions, and schemas remain arbitrary upstream-controlled content without credential-content filtering; documented size and description limits apply.

06

Traffic outside Sallyport is outside scope

The app cannot govern direct network calls, shell commands, other credential stores, or tools that bypass its MCP surface.

07

Executor results may contain sensitive data

HTTP, MCP, and SSH results and errors are not inspected or rewritten. A target can return credentials or other sensitive data, and SSH recordings preserve target output.

08

Audit previews can contain caller data

Sallyport does not add resolved credentials to approvals or audit rows, but caller-supplied commands and arguments appear in summaries and bounded previews. Treat decrypted audit data as sensitive.

09

This is an interactive Mac product

The supported deployment is a signed app on Apple Silicon macOS with local UI and Touch ID. There is no Linux, container, server, cloud-runner, or headless CI mode.

Inspect the implementation

The core is open source under Apache-2.0. Read the implementation and the trust model, or build it locally.

View source on GitHub