Overview
When a user configures a passphrase-protected SSH private key in ssh_credentials, the deployer fails silently during provision with a misleading Permission denied (publickey,password) error. The root cause — that the key is encrypted and cannot be decrypted without a passphrase in an unattended environment — is never surfaced to the user.
This was triggered during the Hetzner demo deployment (#405) where a fresh deployment key was created with a passphrase. In an interactive terminal session the OS SSH agent transparently decrypts the key, so the error only appears when running the deployer in an automated context (Docker container, CI/CD pipeline) where no agent is available.
There is no blocking code fix required — passphrase-protected keys are valid in some workflows (e.g. with SSH agent forwarding). The two actions needed are:
- Early warning in
create environment — detect passphrase-protected keys and notify the user before they reach provision
- Documentation — add a user guide section on SSH key handling and the supported workflows
Specification
See detailed specification: docs/issues/411-bug-ssh-key-passphrase-breaks-automated-deployment.md
Implementation Plan
Phase 1: Detection and warning (code change)
Phase 2: Documentation
Phase 3: Linting and pre-commit
Acceptance Criteria
Note for Contributors: These criteria define what the PR reviewer will check. Use this as your pre-review checklist before submitting the PR to minimize back-and-forth iterations.
Quality Checks:
Task-Specific Criteria:
Related
Overview
When a user configures a passphrase-protected SSH private key in
ssh_credentials, the deployer fails silently duringprovisionwith a misleadingPermission denied (publickey,password)error. The root cause — that the key is encrypted and cannot be decrypted without a passphrase in an unattended environment — is never surfaced to the user.This was triggered during the Hetzner demo deployment (#405) where a fresh deployment key was created with a passphrase. In an interactive terminal session the OS SSH agent transparently decrypts the key, so the error only appears when running the deployer in an automated context (Docker container, CI/CD pipeline) where no agent is available.
There is no blocking code fix required — passphrase-protected keys are valid in some workflows (e.g. with SSH agent forwarding). The two actions needed are:
create environment— detect passphrase-protected keys and notify the user before they reachprovisionSpecification
See detailed specification: docs/issues/411-bug-ssh-key-passphrase-breaks-automated-deployment.md
Implementation Plan
Phase 1: Detection and warning (code change)
is_passphrase_protected(path: &Path) -> boolinsrc/adapters/ssh/ssh/credentials.rs(or a newkey_inspector.rsmodule)ENCRYPTEDin PEM header (legacy format)bcryptnear the start of the decoded OpenSSH bodyfalseon any I/O or parse errorcreate environmenthandler (handler.rs): afterLoadConfiguration, call the detection function and emit a warning viauser_outputif the key appears to be passphrase-protectedit_detects_passphrase_protected_keyPhase 2: Documentation
docs/user-guide/ssh-keys.mdcovering all workflows and security notesdocs/user-guide/providers/hetzner.mdwith an SSH key requirements notedocs/user-guide/commands/create.mdto mention the passphrase warningdocs/user-guide/README.mdto link to the newssh-keys.mdpagePhase 3: Linting and pre-commit
cargo run --bin linter all./scripts/pre-commit.shAcceptance Criteria
Quality Checks:
./scripts/pre-commit.shTask-Specific Criteria:
create environmentemits a visible warning (not an error) when the configured private key file is passphrase-protectedcreate environmentstill succeeds (environment is created) even when the warning is emitted — the user is not blockedcreate environmentemits no warning when the key is unencrypteddocs/user-guide/ssh-keys.mdexists and covers key requirements, workflows, and security notesdocs/user-guide/providers/hetzner.mdreferences the SSH key requirementsRelated