Skip to content

Security: sshKey-generate / sshKey-all / sshKey-one leak private keys through MCP responses #34

@marcfargas

Description

@marcfargas

Related to #26 (which covers GitHub App secrets leaking through compose-one / application-one). The SSH-key tools have the equivalent bug:

  • sshKey-generate returns the newly generated private key inline in its JSON response, alongside the public key. Because persistence requires a subsequent sshKey-create call that accepts privateKey as a parameter, the secret is forced to round-trip through the MCP client (i.e. through an LLM's conversation context, which is logged and often synced).
  • sshKey-all returns the full private key for every stored SSH key.
  • sshKey-one (by id) returns the private key for that key.

Impact

Any MCP client invoking these tools exposes Dokploy-managed SSH private keys to its own conversation transcript / logs. For a deploy-key used to clone a private repo, the blast radius is one repo's contents; for a general-purpose SSH key attached to infra provisioning flows, it's broader.

In practice this means the Dokploy web UI is the only safe path to generate and inspect SSH keys — the MCP equivalents cannot be used without leaking.

Requested changes

  1. sshKey-generate should persist the generated keypair server-side and return only { sshKeyId, publicKey, name }. No privateKey in the response.
  2. sshKey-all and sshKey-one should omit privateKey from the returned records by default.
  3. (Optional) A privileged read endpoint for operators who genuinely need to export the private key (rare), gated behind an explicit flag or a separate tool name like sshKey-exportPrivate, documented as dangerous.

Additional leak surface worth covering in the same audit

  • compose-one returns the full env block (plaintext env vars). compose-saveEnvironment is effectively write-only but the read counterpart dumps everything. Would be worth an explicit env filter or a redactSecrets: true default.
  • Any *-one / *-all tool that returns a record with env/secret fields.

Combined fix: document a redaction rule — any field that's ever written as a secret must be redacted (or omitted) in every read response, with export gated behind an explicit separate call.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions