OneLinersCommand workbench
Guides
Identity & Access / Incident Response & Troubleshooting

Fix SSH Permission denied (publickey) without weakening authentication

Trace the SSH user, host, selected key, agent, server policy, authorized_keys path, permissions, and authentication log before changing access controls.

35 min8 stepsChanges system stateRevision 1
Save or explore
Save to collectionCreate a collection in the sidebar first.
0 of 8 steps completed
Goal

Restore key-based SSH access for the intended account while keeping password login, host verification, and unrelated accounts unchanged.

Supported environments
  • OpenSSH client 9.x, 10.x
  • OpenSSH server 9.x, 10.x
Prerequisites
  • Fallback access Keep console access or a second authenticated session before editing server authorization files.
  • Expected identity Know the intended SSH username, hostname, port, and public-key fingerprint.
  • Server evidence Have permission to read effective sshd configuration and the authentication journal or log.
Operating boundary

OneLiners never runs these steps or stores secrets. Review placeholders, versions, current state, and change-control requirements before using a command.

Full guide

What you will build

System
  • A repeatable OpenSSH incident record that starts with the literal `Permission denied (publickey)` symptom and preserves the first useful failure instead of hiding it with an early restart or broad permission change.
  • A layer-by-layer decision path from client context through configuration and runtime evidence to one narrowly scoped remediation, followed by positive and negative verification.
  • A reusable evidence bundle containing commands, concrete example output, timestamps, identities, effective configuration, and stop conditions that another operator can review without access to the original terminal.
Observable outcome
  • You can identify which boundary failed, explain why competing hypotheses were rejected, and state what changed before declaring the incident resolved.
  • The repaired path succeeds under the intended identity while an unauthorized or incorrect path still fails, proving that the fix did not simply remove a security control.
  • The final evidence distinguishes a transient recovery from a durable repair by checking logs, counters, configuration provenance, and the original user-visible operation.

Architecture

How the parts fit together

OpenSSH troubleshooting is treated as an evidence pipeline rather than a list of guesses. The operator captures the symptom, resolves client and target context, inspects the first authoritative server-side failure, tests the smallest cause boundary, applies one reviewed change, and repeats the same observation path. This keeps a secondary error from replacing the primary cause and makes rollback possible.

Client contextProves the executable, identity, target, selected configuration, environment variables, and exact request that produced the visible error.
Transport and targetConfirms that the request reached the intended host, socket, service, repository, or upstream instead of a stale context or similarly named environment.
Authoritative evidenceUses effective configuration, service state, event records, and logs from the component that made the decision rather than relying on a client summary.
Controlled remediationChanges one demonstrated cause, retains a backup or previous reference, and avoids global permission, trust, timeout, or force settings.
Verification boundaryRepeats the original operation, exercises a negative case, and watches for recurrence long enough to distinguish a repair from a restart-only recovery.
  1. Copy the literal error and the command that produced it before retrying, restarting, pruning, resetting, or editing anything.
  2. Resolve the selected identity, configuration, target, and current runtime state so later commands inspect the same path the user exercised.
  3. Read the nearest authoritative log or effective configuration and align timestamps across the client and server evidence.
  4. Test one hypothesis with a read-only command; if evidence disagrees, return to the previous layer instead of stacking speculative changes.
  5. Back up the affected configuration or reference, apply the narrow repair, validate syntax, and reload only the component that owns the decision.
  6. Repeat the original action plus a negative control, record the outcome, and keep rollback material until the observation window is complete.

Assumptions

  • The host key has already been verified through a trusted channel; this tutorial does not bypass a changed-host-key warning.
  • The server is reachable and completes SSH transport negotiation, so the failure occurs during user authentication.
  • The intended private key remains local and readable only by its owner; only its public fingerprint is recorded in evidence.
  • Clocks are close enough that client and server timestamps can be correlated. If they are not, record the offset before comparing logs.
  • The operator has a recovery path that does not depend on the component being changed, such as console access, a second session, or a preserved remote reference.
  • Commands are first run in the affected environment with placeholders reviewed. OneLiners never executes them and does not know local policy, tenancy, or maintenance constraints.

Key concepts

Authentication user
The account name before the host in user@host; a correct key authorized for another user still fails.
Identity selection
The client chooses keys from explicit IdentityFile directives and an agent; IdentitiesOnly limits offers to reviewed identities.
authorized_keys
The server-side public-key list whose path, ownership, modes, restrictions, and content are evaluated for the target user.
StrictModes
An sshd check that rejects unsafe ownership or permissions on the user's home, .ssh directory, and authorization file.
Effective configuration
The final client or server settings after includes, host blocks, Match rules, command-line flags, and defaults are applied.
Set guide values0/4 ready

Fill these once. Every matching command and configuration block updates immediately; values stay in this page only.

Security and production boundaries

  • Treat access restoration as an identity change: prove the user, source, key fingerprint, and authorized scope before repair.
  • PasswordAuthentication and StrictHostKeyChecking must not be disabled as diagnostic shortcuts.
  • Do not paste private keys, tokens, complete environment dumps, authorization headers, or unredacted customer data into tickets or external analysis tools.
  • A successful operation after disabling authentication, trust, host verification, sandboxing, or least privilege is a security regression, not a valid repair.
  • Prefer effective configuration and narrow identity tests over recursive ownership changes, mode 777, global trust bypasses, or force options copied from unrelated incidents.

Stop before continuing if

  • Stop on any unexplained host-key change and verify the host out of band.
  • Stop if the intended account, key owner, or source network cannot be proven.
  • Stop if the target, account, environment, repository, or service instance cannot be identified unambiguously.
  • Stop before a destructive cleanup, force update, broad permission change, or production reload when backup and recovery evidence is missing.
  • Stop if the proposed action would conceal the first error or remove logs, failed objects, repository references, or configuration needed for diagnosis.
01

instruction

Freeze the symptom and define the incident boundary

read-only

Before changing OpenSSH, preserve the literal `Permission denied (publickey)` message, the exact action that produced it, the affected identity, target, UTC time, and expected result. Decide which production boundary is in scope and name the independent recovery path you will keep available.

Why this step matters

A retry, restart, cleanup, permission change, or configuration edit can replace the primary failure with a secondary one. A fixed starting record lets every later check answer a specific hypothesis.

What to understand

Record whether the problem affects one user or workload, one target, one host, or every comparable path; this determines whether to begin at the client, transport, or service boundary.

Write down the expected successful behavior in observable terms such as an exit status, HTTP response, remote object ID, authenticated principal, or stable service state.

Keep console access, a second session, an earlier configuration, or a recoverable reference independent of the component being diagnosed.

System changes

  • No persistent change. This step reads current configuration, identity, runtime state, or logs and records evidence for the incident timeline.
Example output / evidence
Incident scope
Tool: OpenSSH
Observed: `Permission denied (publickey)`
Affected target: production-app-01
Observed at: 2026-08-17T14:02:11Z
Expected: the reviewed operation completes without weakening an access or safety control
Recovery path: console session and last known-good configuration retained

Security notes

  • Redact secrets and customer data, but retain error text, timestamps, object IDs, modes, owners, and target names needed to reproduce the decision.

Alternatives

  • When direct production inspection is restricted, reproduce the same version and configuration boundary in an isolated environment and mark which evidence is illustrative.

Stop conditions

  • Stop before any mutation if the target, identity, affected environment, expected result, or recovery path is still ambiguous.
02

command

Capture the key offer and server decision

read-only

Run one verbose connection with an explicit user, port, and identity. Keep the lines around Offering public key, Server accepts key, and Authentications that can continue.

Why this step matters

Verbose client output proves which key was actually offered and whether the server rejected it, avoiding guesses based on filenames or agent contents.

What to understand

Use one explicit key so Too many authentication failures and agent ordering cannot obscure the result.

The absence of Offering public key means the problem is local selection or key readability; a rejection after offering moves the investigation server-side.

Record the command, UTC timestamp, exit status, and the exact output before moving to the next layer. A later successful command must not erase evidence of the original failure.

Interpret this result together with the previous checkpoint. One matching line is evidence for a hypothesis, not permission to apply every commonly suggested fix.

System changes

  • No persistent change. This step reads current configuration, identity, runtime state, or logs and records evidence for the incident timeline.

Syntax explained

-vvv
Emits protocol and authentication decisions without printing private-key material.
IdentitiesOnly=yes
Prevents unrelated agent keys from being offered for this controlled test.
-i / -p
Selects the reviewed identity file and service port explicitly.
Command
Fill variables0/4 ready

Values stay on this page and are never sent or saved.

ssh -vvv -o IdentitiesOnly=yes -i {{keyPath}} -p {{port}} {{user}}@{{host}} true
Example output / evidence
debug1: Offering public key: /home/alice/.ssh/id_ed25519_deploy ED25519 SHA256:4mY... explicit
debug1: Authentications that can continue: publickey
deploy@app01.example.net: Permission denied (publickey).

Checkpoint: Checkpoint: Capture the key offer and server decision

ssh -vvv -o IdentitiesOnly=yes -i {{keyPath}} -p {{port}} {{user}}@{{host}} true

Continue whenThe intended fingerprint is offered to the intended user and host; the exact rejection point is visible.

Stop whenThe host key is new or changed, the target address is unexpected, or the intended key is not the one offered.

If this step fails

The client reports Load key: invalid format or error in libcrypto.

Likely causeThe key file is damaged, is a public key passed as a private key, has altered line endings, or is in an unsupported format.

Safe checks
  • file {{keyPath}}
  • ssh-keygen -y -f {{keyPath}} >/dev/null

ResolutionRecover the original private key from a trusted source or issue a new key; do not edit key body lines manually.

Security notes

  • Verbose logs can expose usernames, hostnames, and paths; redact them before external sharing.

Alternatives

  • Use `ssh -G` first when policy forbids even a failed authentication attempt.

Stop conditions

  • The host key is new or changed, the target address is unexpected, or the intended key is not the one offered.
03

command

Resolve the effective SSH client configuration

read-only

Inspect the final hostname, user, port, identity files, proxy path, and authentication controls after all Host and Include rules are applied.

Why this step matters

Aliases, wildcard Host blocks, includes, and jump hosts frequently change the real destination or identity even when the typed command looks correct.

What to understand

Compare hostname and user with the server you can inspect; a ProxyJump means authentication may occur on more than one host.

Multiple IdentityFile rows are ordered inputs, not proof that a particular private key exists or was accepted.

Record the command, UTC timestamp, exit status, and the exact output before moving to the next layer. A later successful command must not erase evidence of the original failure.

Interpret this result together with the previous checkpoint. One matching line is evidence for a hypothesis, not permission to apply every commonly suggested fix.

System changes

  • No persistent change. This step reads current configuration, identity, runtime state, or logs and records evidence for the incident timeline.

Syntax explained

ssh -G
Prints evaluated client configuration without opening a network connection.
Command
Fill variables0/3 ready

Values stay on this page and are never sent or saved.

ssh -G -p {{port}} {{user}}@{{host}} | grep -E '^(hostname|user|port|identityfile|identitiesonly|proxyjump|proxycommand) '
Example output / evidence
hostname app01.example.net
user deploy
port 22
identityfile ~/.ssh/id_ed25519_deploy
identitiesonly yes

Checkpoint: Checkpoint: Resolve the effective SSH client configuration

ssh -G -p {{port}} {{user}}@{{host}} | grep -E '^(hostname|user|port|identityfile|identitiesonly|proxyjump|proxycommand) '

Continue whenThe effective destination, user, port, proxy, and identity match the intended access path.

Stop whenA proxy, hostname rewrite, unexpected user, or organization-managed include changes the target path.

If this step fails

The expected IdentityFile does not appear.

Likely causeA Host pattern does not match, an Include is missing, or a later command-line choice overrides configuration.

Safe checks
  • ssh -G {{host}} | grep '^identityfile '

ResolutionCorrect the narrow Host block or invoke the explicit identity; do not replace global client configuration.

Security notes

  • Do not remove host-key checking or ProxyJump policy to make the path simpler.

Alternatives

  • Use a temporary `-F` file containing only the reviewed host block for a controlled comparison.

Stop conditions

  • A proxy, hostname rewrite, unexpected user, or organization-managed include changes the target path.
04

command

Compare local, agent, and authorized fingerprints

read-only

Derive the public fingerprint from the private key, list agent identities, and compare only fingerprints with the authorized server entry.

Why this step matters

A filename, comment, or copied public-key label is not identity evidence; the cryptographic fingerprint must match across the client and server.

What to understand

`ssh-keygen -y` reads the private key and emits only its public half into the fingerprint command.

An agent may hold an older or unrelated key; the explicit-key test remains authoritative for this incident.

Record the command, UTC timestamp, exit status, and the exact output before moving to the next layer. A later successful command must not erase evidence of the original failure.

Interpret this result together with the previous checkpoint. One matching line is evidence for a hypothesis, not permission to apply every commonly suggested fix.

System changes

  • No persistent change. This step reads current configuration, identity, runtime state, or logs and records evidence for the incident timeline.

Syntax explained

ssh-keygen -y
Derives the public key from the private key without displaying private material.
ssh-keygen -lf -
Prints the fingerprint of the public key received on standard input.
ssh-add -l
Lists fingerprints currently offered by the authentication agent.
Command
Fill variables0/1 ready

Values stay on this page and are never sent or saved.

ssh-keygen -y -f {{keyPath}} | ssh-keygen -lf - && ssh-add -l
Example output / evidence
256 SHA256:4mYf8f0R... deploy@app01 (ED25519)
256 SHA256:pQ3cA7... workstation (ED25519)

Checkpoint: Checkpoint: Compare local, agent, and authorized fingerprints

ssh-keygen -y -f {{keyPath}} | ssh-keygen -lf - && ssh-add -l

Continue whenThe explicit private key has the expected public fingerprint; agent differences are understood.

Stop whenThe key cannot be read, its fingerprint is unknown, or it does not match the approved public key.

If this step fails

ssh-add reports that the agent has no identities.

Likely causeThe controlled path depends on an unloaded agent key instead of the explicit identity.

Safe checks
  • printf '%s ' "$SSH_AUTH_SOCK"
  • ssh-add -l

ResolutionUse the explicit reviewed key or load it into the correct session agent according to local policy.

Security notes

  • Never send the private key to the server or include it in evidence; fingerprints are sufficient.

Alternatives

  • Compare the `.pub` file fingerprint directly when private-key access is intentionally delegated to hardware.

Stop conditions

  • The key cannot be read, its fingerprint is unknown, or it does not match the approved public key.
05

command

Inspect effective sshd policy and authorization path

read-only

Evaluate sshd for the target user and inspect the home, .ssh directory, authorization file, ownership, modes, and matching public fingerprint.

Why this step matters

The server makes the authorization decision from effective Match-aware policy, path traversal permissions, file ownership, modes, and key options.

What to understand

Supply the real client address when Match Address rules exist; a placeholder address can produce the wrong effective policy.

`namei -l` exposes every parent component, which catches an unsafe or inaccessible home directory that a final-file `ls` misses.

Record the command, UTC timestamp, exit status, and the exact output before moving to the next layer. A later successful command must not erase evidence of the original failure.

Interpret this result together with the previous checkpoint. One matching line is evidence for a hypothesis, not permission to apply every commonly suggested fix.

System changes

  • No persistent change. This step reads current configuration, identity, runtime state, or logs and records evidence for the incident timeline.

Syntax explained

sshd -T -C
Prints effective server configuration for a simulated user, host, and client address.
namei -l
Shows ownership and mode for every path component.
ssh-keygen -lf authorized_keys
Lists fingerprints of authorized public keys without private data.
Command
Fill variables0/2 ready

Values stay on this page and are never sent or saved.

sudo sshd -T -C user={{user}},host={{host}},addr=192.0.2.10 | grep -E '^(pubkeyauthentication|authorizedkeysfile|strictmodes|authenticationmethods) ' && sudo namei -l /home/{{user}}/.ssh/authorized_keys && sudo ssh-keygen -lf /home/{{user}}/.ssh/authorized_keys
Example output / evidence
pubkeyauthentication yes
authorizedkeysfile .ssh/authorized_keys .ssh/authorized_keys2
strictmodes yes
f: /home/deploy/.ssh/authorized_keys
-rw------- deploy deploy authorized_keys
256 SHA256:4mYf8f0R... deploy@app01 (ED25519)

Checkpoint: Checkpoint: Inspect effective sshd policy and authorization path

sudo sshd -T -C user={{user}},host={{host}},addr=192.0.2.10 | grep -E '^(pubkeyauthentication|authorizedkeysfile|strictmodes|authenticationmethods) ' && sudo namei -l /home/{{user}}/.ssh/authorized_keys && sudo ssh-keygen -lf /home/{{user}}/.ssh/authorized_keys

Continue whenPublic-key authentication is enabled, the path is the expected one, modes pass StrictModes, and the intended fingerprint is present.

Stop whenA Match rule, centralized AuthorizedKeysCommand, unknown key restriction, or account policy owns authorization instead of the inspected file.

If this step fails

sshd -T reports an unsupported or invalid option.

Likely causeThe command is running against a different sshd build or configuration than the active service.

Safe checks
  • sudo sshd -t
  • systemctl cat sshd 2>/dev/null || systemctl cat ssh

ResolutionLocate the active daemon configuration and validate it before editing; do not reload a configuration that fails `sshd -t`.

Security notes

  • Preserve key restrictions such as `from=`, `command=`, or certificate-authority; they may be the intended control.

Alternatives

  • Inspect the configured AuthorizedKeysCommand output when authorization is centrally managed.

Stop conditions

  • A Match rule, centralized AuthorizedKeysCommand, unknown key restriction, or account policy owns authorization instead of the inspected file.
06

command

Read the authoritative authentication rejection

read-only

Correlate one controlled failed attempt with the SSH service journal and record the server reason, source address, target user, and key fingerprint when available.

Why this step matters

The client intentionally gives a generic denial, while the server log often identifies StrictModes, account state, key restrictions, algorithm policy, or lookup failures.

What to understand

Filter by the test timestamp, source address, and user; unrelated internet scans can otherwise dominate the log.

If the service logs elsewhere, inspect the configured facility or distribution authentication log without changing verbosity in production first.

Record the command, UTC timestamp, exit status, and the exact output before moving to the next layer. A later successful command must not erase evidence of the original failure.

Interpret this result together with the previous checkpoint. One matching line is evidence for a hypothesis, not permission to apply every commonly suggested fix.

System changes

  • No persistent change. This step reads current configuration, identity, runtime state, or logs and records evidence for the incident timeline.

Syntax explained

-u ssh.service -u sshd.service
Covers common Debian/Ubuntu and RHEL-family unit names.
--since
Bounds evidence to the controlled attempt.
Command
sudo journalctl -u ssh.service -u sshd.service --since '-10 minutes' --no-pager | tail -n 80
Example output / evidence
Aug 17 11:42:18 app01 sshd[18422]: Authentication refused: bad ownership or modes for file /home/deploy/.ssh/authorized_keys
Aug 17 11:42:18 app01 sshd[18422]: Connection closed by authenticating user deploy 192.0.2.10 port 51422 [preauth]

Checkpoint: Checkpoint: Read the authoritative authentication rejection

sudo journalctl -u ssh.service -u sshd.service --since '-10 minutes' --no-pager | tail -n 80

Continue whenOne server-side reason aligns with the controlled client attempt and the intended target account.

Stop whenNo matching attempt reaches the server, logs identify a different source/username, or centralized authentication is unavailable.

If this step fails

No authentication record appears.

Likely causeThe request reached another host/port, was blocked before sshd, or logs use another destination.

Safe checks
  • getent ahosts {{host}}
  • ssh -G {{host}} | grep -E '^(hostname|port|proxyjump) '

ResolutionRe-establish the real target path before changing server authorization.

Security notes

  • Authentication logs contain user and network identifiers; retain them according to incident policy.

Alternatives

  • Use the distribution authentication log when journald forwarding or unit filtering is not authoritative.

Stop conditions

  • No matching attempt reaches the server, logs identify a different source/username, or centralized authentication is unavailable.
07

decision

Repair one demonstrated cause and verify both boundaries

caution

Back up the authorization file, correct only the demonstrated ownership/mode or key entry, validate sshd, and test the intended key plus an unauthorized key from a second session.

Why this step matters

A narrow, backed-up repair preserves the key-only boundary and proves the intended identity rather than merely making an SSH prompt disappear.

What to understand

Apply ownership or mode changes only when the log proved StrictModes was the cause; otherwise repair the specific key, user, or Match policy.

Keep the fallback session open until `sshd -t`, positive login, negative login, and a fresh journal review all succeed.

Record the command, UTC timestamp, exit status, and the exact output before moving to the next layer. A later successful command must not erase evidence of the original failure.

Interpret this result together with the previous checkpoint. One matching line is evidence for a hypothesis, not permission to apply every commonly suggested fix.

System changes

  • Creates one rollback copy and may change ownership or mode of the target user's .ssh directory and authorization file; it does not enable passwords or reload sshd.

Syntax explained

cp -a
Preserves the prior authorization file and metadata for rollback.
chmod 700/600
Removes group/other access from the authorization directory and file.
sshd -t
Validates server configuration syntax before any reload is considered.
Command
Fill variables0/4 ready

Values stay on this page and are never sent or saved.

sudo cp -a /home/{{user}}/.ssh/authorized_keys /home/{{user}}/.ssh/authorized_keys.before-oneliners && sudo chown {{user}}:{{user}} /home/{{user}}/.ssh /home/{{user}}/.ssh/authorized_keys && sudo chmod 700 /home/{{user}}/.ssh && sudo chmod 600 /home/{{user}}/.ssh/authorized_keys && sudo sshd -t && ssh -o IdentitiesOnly=yes -i {{keyPath}} -p {{port}} {{user}}@{{host}} 'id && printf authorized'
Example output / evidence
uid=1002(deploy) gid=1002(deploy) groups=1002(deploy)
authorized

Checkpoint: Checkpoint: Repair one demonstrated cause and verify both boundaries

sudo cp -a /home/{{user}}/.ssh/authorized_keys /home/{{user}}/.ssh/authorized_keys.before-oneliners && sudo chown {{user}}:{{user}} /home/{{user}}/.ssh /home/{{user}}/.ssh/authorized_keys && sudo chmod 700 /home/{{user}}/.ssh && sudo chmod 600 /home/{{user}}/.ssh/authorized_keys && sudo sshd -t && ssh -o IdentitiesOnly=yes -i {{keyPath}} -p {{port}} {{user}}@{{host}} 'id && printf authorized'

Continue whenThe intended key logs in as the intended account, unauthorized keys remain denied, and the journal contains no policy bypass or new warning.

Stop whenOwnership is centrally managed, the home layout differs, the backup fails, sshd validation fails, or the negative test unexpectedly succeeds.

If this step fails

The intended key still fails after permissions are corrected.

Likely causeThe original cause was a user, key, Match, restriction, algorithm, account, or centralized lookup mismatch rather than StrictModes.

Safe checks
  • sudo sshd -T -C user={{user}},host={{host}},addr=192.0.2.10
  • sudo journalctl -u sshd --since '-5 minutes' --no-pager

ResolutionRestore the prior file if changed unnecessarily and continue from the new authoritative log reason.

Security notes

  • Never use recursive chown on the whole home or chmod 777; either can expose secrets and mask the actual policy boundary.

Alternatives

  • Issue a new restricted key through the organization's identity workflow when the approved key cannot be recovered.

Stop conditions

  • Ownership is centrally managed, the home layout differs, the backup fails, sshd validation fails, or the negative test unexpectedly succeeds.
08

verification

Observe for recurrence and close with evidence

read-only

After the original OpenSSH operation succeeds, repeat the same read-only observation path used at the start. Watch the relevant logs, counters, identities, and target state for a bounded period, then record the proven cause, exact change, verification result, rollback point, and remaining uncertainty.

Why this step matters

A single successful retry may be a transient recovery. Repeating the original checks and retaining the rollback point distinguishes a durable repair from a restart-only improvement.

What to understand

Use the same client identity, target, path, and configuration selection as the original failure so the positive result is comparable.

Include one negative or unauthorized control where safe; this proves the repair did not work by removing authentication, trust, isolation, or branch protection.

Keep the evidence concise enough for another operator to reproduce, but include software versions and exact object or configuration references.

System changes

  • No persistent change. This step reads current configuration, identity, runtime state, or logs and records evidence for the incident timeline.
Example output / evidence
Observation window: 15 minutes
Original operation: PASS
Original signature recurrences: 0
Negative control: PASS
Rollback point retained: yes
Cause and repair recorded: yes
Remaining uncertainty: none observed within the stated boundary

Checkpoint: Checkpoint: the repair remains valid

sudo cp -a /home/{{user}}/.ssh/authorized_keys /home/{{user}}/.ssh/authorized_keys.before-oneliners && sudo chown {{user}}:{{user}} /home/{{user}}/.ssh /home/{{user}}/.ssh/authorized_keys && sudo chmod 700 /home/{{user}}/.ssh && sudo chmod 600 /home/{{user}}/.ssh/authorized_keys && sudo sshd -t && ssh -o IdentitiesOnly=yes -i {{keyPath}} -p {{port}} {{user}}@{{host}} 'id && printf authorized'

Continue whenThe intended operation stays healthy, the original signature does not recur, and the negative control still enforces the expected boundary.

Stop whenThe result depends on an unexplained retry, disabled control, different target, or unrecorded manual state.

If this step fails

The error returns during the observation window.

Likely causeThe change treated a symptom, another instance still has the old state, or an automated process reverted or recreated the failing condition.

Safe checks
  • ssh -vvv -o IdentitiesOnly=yes -i {{keyPath}} -p {{port}} {{user}}@{{host}} true
  • sudo cp -a /home/{{user}}/.ssh/authorized_keys /home/{{user}}/.ssh/authorized_keys.before-oneliners && sudo chown {{user}}:{{user}} /home/{{user}}/.ssh /home/{{user}}/.ssh/authorized_keys && sudo chmod 700 /home/{{user}}/.ssh && sudo chmod 600 /home/{{user}}/.ssh/authorized_keys && sudo sshd -t && ssh -o IdentitiesOnly=yes -i {{keyPath}} -p {{port}} {{user}}@{{host}} 'id && printf authorized'

ResolutionPreserve the recurrence, compare it with the first evidence set, restore the known-good state if necessary, and reopen the unresolved layer instead of stacking another repair.

Security notes

  • Store only redacted operational evidence and remove temporary debug output according to local retention policy after review.

Alternatives

  • Use the service's approved monitoring or audit trail when an interactive observation window is not practical.

Stop conditions

  • Do not close the incident while the result is intermittent, the rollback point is missing, or a safety control remains weakened.

Finish line

Verification checklist

Original operation succeedssudo cp -a /home/{{user}}/.ssh/authorized_keys /home/{{user}}/.ssh/authorized_keys.before-oneliners && sudo chown {{user}}:{{user}} /home/{{user}}/.ssh /home/{{user}}/.ssh/authorized_keys && sudo chmod 700 /home/{{user}}/.ssh && sudo chmod 600 /home/{{user}}/.ssh/authorized_keys && sudo sshd -t && ssh -o IdentitiesOnly=yes -i {{keyPath}} -p {{port}} {{user}}@{{host}} 'id && printf authorized'The operation completes with exit status 0 and without the original error. The output identifies the intended host, service, repository, or endpoint.
Failure evidence stays absentssh -vvv -o IdentitiesOnly=yes -i {{keyPath}} -p {{port}} {{user}}@{{host}} trueA fresh diagnostic capture shows the healthy path and no recurrence of the original signature. Logs and counters remain stable during the observation window.

Recovery guidance

Common problems and safe checks

The client offers many keys and the server disconnects with Too many authentication failures.

Likely causeAn agent exhausts MaxAuthTries before the intended key is offered.

Safe checks
  • ssh-add -l
  • ssh -vvv -o IdentitiesOnly=yes -i {{keyPath}} {{user}}@{{host}}

ResolutionUse IdentitiesOnly for the host and configure the intended IdentityFile; do not raise MaxAuthTries globally.

The key is present but a `from=` restriction rejects the client.

Likely causeThe source address changed or traffic now exits through another gateway.

Safe checks
  • curl -4 https://ifconfig.co 2>/dev/null
  • sudo journalctl -u sshd --since '-10 minutes'

ResolutionVerify the new trusted source path and update the narrow restriction through change control if intended.

A hardware-backed key works interactively but not in automation.

Likely causeThe job lacks the agent, user presence, or FIDO capability required by the key.

Safe checks
  • ssh-add -L
  • ssh -Q key

ResolutionUse an automation-specific restricted credential or certificate rather than exporting the human private key.

After the procedure

Alternatives and next steps

Consider these alternatives

  • Use short-lived OpenSSH user certificates when centralized issuance and revocation are available.
  • Use console or an out-of-band management plane to repair server policy when no trusted SSH session remains.

Operate it safely

  • Add a controlled key-expiry and revocation process with fingerprint inventory.
  • Monitor authentication failures without alerting on unrelated internet scanning.
  • Turn the verified checks into a read-only health probe or alert using stable fields rather than matching a whole human-formatted line.
  • Record the cause, exact repair, rollback point, software version, and follow-up owner in the incident note so the same failure becomes cheaper to diagnose.
  • Review adjacent environments for the demonstrated cause, but apply changes only where the same evidence is present.

Reference

Frequently asked questions

Should I enable password login temporarily?

No. A public-key failure has a specific user, identity, policy, path, or permission cause. Enabling another method expands exposure and removes evidence that the key path was actually repaired.

Does chmod 600 always fix authorized_keys?

No. Parent ownership, home permissions, Match rules, key options, AuthorizedKeysCommand, account state, algorithms, and the selected username also affect authorization.

Why does the key work for one host alias but not another?

Host blocks and Includes can choose a different hostname, port, user, identity, proxy, or IdentitiesOnly value. Compare `ssh -G` output for both names.

Can I copy the private key to the server to test it?

No. Compare public fingerprints. The private key should remain at its approved client or hardware boundary.

Recovery

Rollback

Restore the backed-up authorization file and its original metadata from the open recovery session.

  1. Keep the fallback session open and restore `authorized_keys.before-oneliners` with `cp -a`.
  2. Restore documented owner and modes, run `sshd -t`, and repeat positive plus negative authentication tests.
  3. Remove the temporary backup only after the observation window and approval.

Evidence

Sources and review

Verified 2026-08-17Review due 2027-02-13
OpenSSH ssh client manualofficialOpenSSH sshd server manualofficialOpenSSH sshd_config manualofficial