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
sshKey-generate should persist the generated keypair server-side and return only { sshKeyId, publicKey, name }. No privateKey in the response.
sshKey-all and sshKey-one should omit privateKey from the returned records by default.
- (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.
Related to #26 (which covers GitHub App secrets leaking through
compose-one/application-one). The SSH-key tools have the equivalent bug:sshKey-generatereturns the newly generated private key inline in its JSON response, alongside the public key. Because persistence requires a subsequentsshKey-createcall that acceptsprivateKeyas 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-allreturns 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
sshKey-generateshould persist the generated keypair server-side and return only{ sshKeyId, publicKey, name }. NoprivateKeyin the response.sshKey-allandsshKey-oneshould omitprivateKeyfrom the returned records by default.sshKey-exportPrivate, documented as dangerous.Additional leak surface worth covering in the same audit
compose-onereturns the fullenvblock (plaintext env vars).compose-saveEnvironmentis effectively write-only but the read counterpart dumps everything. Would be worth an explicitenvfilter or aredactSecrets: truedefault.*-one/*-alltool 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.