Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion docs/architecture/remote-workspace-transport.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,11 @@ to searching the controller filesystem.
## Authentication and secrets

Supported target methods are password, private key, private key plus OpenSSH
certificate, OpenSSH agent, and keyboard-interactive responses.
certificate, OpenSSH agent, keyboard-interactive responses, and the SSH `none`
method for endpoints whose transport is already authenticated (a Coder
workspace agent, for example). `none` is an explicit profile choice: it is
never tried as a fallback, and a rejected `none` profile never turns into a
credential prompt.

- Passwords use the existing encrypted password vault.
- Private-key paths, certificate paths, and auth method metadata may be saved.
Expand Down Expand Up @@ -504,6 +508,15 @@ Local Docker profiles may legitimately retain an empty legacy password
placeholder. Connection, testing, and local container discovery do not require
a password-vault entry for those profiles.

`SavedAuthType::None` is unknown to earlier builds, which parse
`ssh_connections.json` as one list and rewrite it from memory. Those profiles
therefore live in `ssh_connections_extended.json`, which earlier builds neither
read nor write; the primary file keeps the shape they understand. Loading merges
both files, and the primary entry wins when an earlier build recreated the same
ID. An earlier build does not list these profiles until the user upgrades again.
Peer controllers reject `None` before RPC unless the host advertises
`ssh_none_auth_v1`.

Startup recovery never deletes a profile or workspace merely because a
credential is unavailable, a connection times out, or a remote host is
temporarily offline. Destructive removal remains an explicit user action.
Expand Down
5 changes: 5 additions & 0 deletions docs/features/remote-workspaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ ssh-agent identity. Explicit password and keyboard-interactive challenge
responses are also supported, with configurable connection/authentication
timeouts, whole-chain retries, and challenge-round limits.

Choose **No authentication** only for endpoints that accept the SSH `none`
method because the tunnel is already authenticated, such as a Coder workspace
agent. OpenBitFun never falls back to it, and it never falls back from it to a
password or key.

## Docker targets

For **Remote host → Container → Through the Docker host**, OpenBitFun first establishes the SSH connection (and
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"digest": "fnv1a64:feb182159a7e227e",
"digest": "fnv1a64:33ad4ddb17680c30",
"retiredCommandPrefixes": [
{
"prefix": "lsp_",
Expand Down Expand Up @@ -51,6 +51,7 @@
"session_trajectory_v1",
"user_question_response",
"user_question_interaction_v1",
"ssh_none_auth_v1",
"terminal_cursor_replay_v1"
],
"desktop": [
Expand Down Expand Up @@ -95,7 +96,8 @@
"whole_session_copy_v1",
"session_trajectory_v1",
"user_question_response",
"user_question_interaction_v1"
"user_question_interaction_v1",
"ssh_none_auth_v1"
],
"cli": [
"model_routing_v1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ pub enum PeerHostCapability {
UserQuestionResponse,
/// First human interaction disables the unattended question timeout.
UserQuestionInteractionV1,
/// SSH profiles may use the `None` authentication method. A host without
/// this key cannot parse such a profile.
SshNoneAuthV1,
/// Terminal output is read as bounded `terminal_get_history` pages announced
/// on the `terminal-<id>` host stream instead of `terminal_event` fan-out.
/// This selects a delivery path, so only a host using that path advertises it.
Expand Down Expand Up @@ -158,6 +161,7 @@ impl PeerHostCapability {
Self::SessionTrajectoryV1,
Self::UserQuestionResponse,
Self::UserQuestionInteractionV1,
Self::SshNoneAuthV1,
Self::TerminalCursorReplayV1,
];

Expand Down Expand Up @@ -206,6 +210,7 @@ impl PeerHostCapability {
Self::WholeSessionCopyV1 => "whole_session_copy_v1",
Self::UserQuestionResponse => "user_question_response",
Self::UserQuestionInteractionV1 => "user_question_interaction_v1",
Self::SshNoneAuthV1 => "ssh_none_auth_v1",
Self::TerminalCursorReplayV1 => "terminal_cursor_replay_v1",
}
}
Expand Down Expand Up @@ -261,6 +266,7 @@ const DESKTOP_CAPABILITIES: &[PeerHostCapability] = &[
PeerHostCapability::SessionTrajectoryV1,
PeerHostCapability::UserQuestionResponse,
PeerHostCapability::UserQuestionInteractionV1,
PeerHostCapability::SshNoneAuthV1,
];

/// The CLI peer host has no MiniApp runtime, WSL or SSH connection setup,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,9 @@ pub enum SavedAuthTypeRecord {
fallback_key_path: Option<String>,
},
KeyboardInteractive,
/// Server accepts the connection without credentials; kept in sync with
/// `remote_ssh::types::SavedAuthType::None` so migrated profiles survive.
None,
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
Expand Down
Loading
Loading