Authentication

SSHAuthentication is the auth method picker. Each case is constructed with the inputs it needs.

Password

let auth: SSHAuthentication = .password("hunter2")

Private key file

let auth: SSHAuthentication = .privateKeyFile(
    path: ("~/.ssh/id_ed25519" as NSString).expandingTildeInPath,
    passphrase: nil
)

Pass an OpenSSH PEM path. If the key is encrypted, supply the passphrase; otherwise pass nil (the default).

Keyboard-interactive

let auth: SSHAuthentication = .keyboardInteractive { name, instruction, prompts in
    // Return one response per prompt, in order.
    // `echo == false` indicates a sensitive input that should not be shown.
    prompts.map { prompt in
        prompt.echo ? "deploy" : ""
    }
}

The responder is @Sendable and runs off the worker queue when the server issues a challenge.

SSH agent

// Default agent (SSH_AUTH_SOCK):
let auth: SSHAuthentication = .agent()

// Pin a specific agent socket:
let pinned: SSHAuthentication = .agent(SSHAgentConfiguration(socketPath: "/tmp/agent.sock"))

Discovery

Some flows want to ask the server which methods it accepts before attempting credentials. SSHClient.discoverAuthenticationMethods performs the auth banner exchange without authenticating.

let discovery = try await SSHClient.discoverAuthenticationMethods(
    configuration: configuration
)
if discovery.methods.contains(.publicKey) {
    // route to private-key auth
}
print(discovery.issueBanner ?? "")

Generate deploy keys

SSHKeyGenerator emits OpenSSH-format key pairs without shelling out.

let pair = try SSHKeyGenerator.generateOpenSSHKeyPair(
    type: .ed25519,
    comment: "deploy@laptop",
    passphrase: nil
)
print(pair.authorizedKey)     // append to ~/.ssh/authorized_keys on the server
print(pair.privateKeyOpenSSH) // store securely (e.g. in SSHKeychainCredentialStore)

Available types: .ed25519, .rsa(bits:) (default 3072), .ecdsaP256, .ecdsaP384, .ecdsaP521.