feat: [#411] detect passphrase-protected SSH key and warn during create environment#421
Merged
josecelano merged 2 commits intotorrust:mainfrom Apr 7, 2026
Merged
Conversation
…ng create environment - Add is_passphrase_protected() in new src/adapters/ssh/key_inspector.rs - Detection uses byte inspection: bcrypt KDF scan for OpenSSH format, header check for legacy PEM (ENCRYPTED/Proc-Type: 4,ENCRYPTED) - Use base64 crate (already transitive, now direct) instead of inline decoder - Add ProgressReporter::warn() for advisory user-facing warnings - Emit non-blocking warning in CreateEnvironmentCommandController::execute() when the configured SSH private key appears passphrase-protected - Add encrypted ed25519 test fixture (fixtures/testing_ed25519_encrypted) - Add ADR: docs/decisions/ssh-key-passphrase-detection.md - Add user guide: docs/user-guide/ssh-keys.md - Update docs/user-guide/providers/hetzner.md with SSH key requirements - Update docs/user-guide/commands/create.md with passphrase warning note - Update docs/user-guide/README.md with ssh-keys link Closes torrust#411
Member
Author
|
ACK e688a7c |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #411
When a passphrase-protected SSH private key is configured in
ssh_credentials, the deployer previously failed silently duringprovisionwith a misleadingPermission denied (publickey,password)error. This PR adds an early non-blocking warning duringcreate environmentso users can make an informed decision before reachingprovision.Changes
Detection (
src/adapters/ssh/key_inspector.rs— new module)credentials.rsinto a dedicatedkey_inspectormodule (cleaner separation of concerns)is_passphrase_protected(path: &Path) -> bool— best-effort heuristic:BEGIN ENCRYPTED PRIVATE KEY/Proc-Type: 4,ENCRYPTEDheaderbcryptKDF markerbase64crate (now a direct dependency; was already transitive at v0.22.1) instead of an inline decoderWarning (
src/presentation/cli/views/progress/mod.rs,handler.rs)ProgressReporter::warn()for advisory user-facing messagesCreateEnvironmentCommandController::execute()callswarn_if_ssh_key_passphrase_protected()after config load — emits a detailed warning with 3 resolution options but does not block environment creationTest fixture
fixtures/testing_ed25519_encrypted— real ed25519 key protected with passphrase"password", used in unit testsADR
docs/decisions/ssh-key-passphrase-detection.md— documents the byte inspection approach and whyssh-keygen -yprobe was rejectedDocumentation
docs/user-guide/ssh-keys.md— new page covering SSH key requirements, 3 supported workflows, how to remove a passphrase, and security notesdocs/user-guide/providers/hetzner.md— added SSH Key Requirements section with warning calloutdocs/user-guide/commands/create.md— added passphrase warning subsection in Troubleshootingdocs/user-guide/README.md— added SSH Keys subsection under Security with linkTesting
All pre-commit checks pass:
cargo machete✅cargo run --bin linter all(clippy stable + nightly, rustfmt, cspell, shellcheck, markdownlint, yamllint, taplo) ✅cargo test(417 tests) ✅cargo doc✅