Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c281fb8
feat: init host key verification stratgey
manish-singh-bisht Nov 24, 2025
65ea4f0
chore: add comment
manish-singh-bisht Nov 24, 2025
689e6f4
feat: spec json
manish-singh-bisht Nov 24, 2025
570d561
feat: ui schema
manish-singh-bisht Nov 24, 2025
3d55c88
chore: remove trailing comma
manish-singh-bisht Nov 26, 2025
72eb3c1
chore: spec
manish-singh-bisht Nov 27, 2025
eb8b358
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Dec 2, 2025
5b9a04a
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Dec 5, 2025
2974c4a
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Dec 12, 2025
9bea0fb
fix: remove empty as verification method and fallback during validation
manish-singh-bisht Dec 14, 2025
ca0c079
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Dec 15, 2025
f2c6718
chore: Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Dec 16, 2025
4214120
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Dec 18, 2025
1eafc42
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Dec 20, 2025
2147d4c
Merge branch 'staging' into ssh_verification_strategy
vishalm0509 Dec 29, 2025
9403d81
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Jan 2, 2026
5764e54
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Jan 11, 2026
73b3e1e
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Jan 14, 2026
00ed24b
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Jan 20, 2026
b80424e
Merge branch 'staging' into ssh_verification_strategy
vaibhav-datazip Jan 20, 2026
0dac272
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Jan 20, 2026
37a2b6c
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Jan 21, 2026
408bd53
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Jan 22, 2026
1ed1c78
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Jan 29, 2026
da1a30a
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Feb 5, 2026
1863436
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Feb 9, 2026
3015512
Merge branch 'staging' into ssh_verification_strategy
manish-singh-bisht Mar 2, 2026
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
30 changes: 30 additions & 0 deletions drivers/mysql/resources/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,21 @@
"title": "SSH Passphrase",
"description": "Passphrase to decrypt the encrypted SSH private key",
"format": "password"
},
"host_key_verification_mode": {
"type": "string",
"title": "Host Key Verification Mode",
"description": "Mode for SSH host key verification. Use 'strict' to verify against known_hosts file, 'insecure' to skip verification, or leave empty for insecure (default)",
"enum": [
"strict",
"insecure"
],
"default": "insecure"
},
"known_hosts_file_path": {
"type": "string",
"title": "Known Hosts File Path",
"description": "Absolute path to the known_hosts file. Required when host_key_verification_mode is 'strict'"
}
},
"required": [
Expand Down Expand Up @@ -248,6 +263,21 @@
"description": "Password to authenticate with the SSH server",
"format": "password",
"minLength": 1
},
"host_key_verification_mode": {
"type": "string",
"title": "Host Key Verification Mode",
"description": "Mode for SSH host key verification. Use 'strict' to verify against known_hosts file, 'insecure' to skip verification, or leave empty for insecure (default)",
"enum": [
"strict",
"insecure"
],
"default": "insecure"
},
"known_hosts_file_path": {
"type": "string",
"title": "Known Hosts File Path",
"description": "Absolute path to the known_hosts file. Required when host_key_verification_mode is 'strict'"
}
},
"required": [
Expand Down
30 changes: 30 additions & 0 deletions drivers/postgres/resources/spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,21 @@
"title": "SSH Passphrase",
"description": "Passphrase to decrypt the encrypted SSH private key",
"format": "password"
},
"host_key_verification_mode": {
"type": "string",
"title": "Host Key Verification Mode",
"description": "Mode for SSH host key verification. Use 'strict' to verify against known_hosts file, 'insecure' to skip verification, or leave empty for insecure (default)",
"enum": [
"strict",
"insecure"
],
"default": "insecure"
},
"known_hosts_file_path": {
"type": "string",
"title": "Known Hosts File Path",
"description": "Absolute path to the known_hosts file. Required when host_key_verification_mode is 'strict'"
}
},
"required": [
Expand Down Expand Up @@ -199,6 +214,21 @@
"description": "Password to authenticate with the SSH server",
"format": "password",
"minLength": 1
},
"host_key_verification_mode": {
"type": "string",
"title": "Host Key Verification Mode",
"description": "Mode for SSH host key verification. Use 'strict' to verify against known_hosts file, 'insecure' to skip verification, or leave empty for insecure (default)",
"enum": [
"strict",
"insecure"
],
"default": "insecure"
},
"known_hosts_file_path": {
"type": "string",
"title": "Known Hosts File Path",
"description": "Absolute path to the known_hosts file. Required when host_key_verification_mode is 'strict'"
}
},
"required": [
Expand Down
32 changes: 32 additions & 0 deletions utils/spec/uischema.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,22 @@ const PostgresUISchema = `{
"ui:options": {
"rows": 1
}
},
"host_key_verification_mode": {
"ui:widget": "radio",
"ui:grid": [
{ "strict": 12, "insecure": 12}
],
"ui:options": {
"title": false,
"description": false
}
},
"known_hosts_file_path": {
"ui:widget": "text",
"ui:options": {
"placeholder": "Enter the path to the known_hosts file"
}
}
}
}`
Expand Down Expand Up @@ -156,6 +172,22 @@ const MySQLUISchema = `{
"ui:options": {
"rows": 1
}
},
"host_key_verification_mode": {
"ui:widget": "radio",
"ui:grid": [
{ "strict": 12, "insecure": 12}
],
"ui:options": {
"title": false,
"description": false
}
},
"known_hosts_file_path": {
"ui:widget": "text",
"ui:options": {
"placeholder": "Enter the path to the known_hosts file"
}
}
}
}`
Expand Down
72 changes: 61 additions & 11 deletions utils/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,25 @@ import (
"time"

"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/knownhosts"
)

type SSHConfig struct {
Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"`
Username string `json:"username,omitempty"`
PrivateKey string `json:"private_key,omitempty"`
Passphrase string `json:"passphrase,omitempty"`
Password string `json:"password,omitempty"`
Host string `json:"host,omitempty"`
Port int `json:"port,omitempty"`
Username string `json:"username,omitempty"`
PrivateKey string `json:"private_key,omitempty"`
Passphrase string `json:"passphrase,omitempty"`
Password string `json:"password,omitempty"`
HostKeyVerificationMode string `json:"host_key_verification_mode,omitempty"`
KnownHostsFilePath string `json:"known_hosts_file_path,omitempty"`
}

const (
StrictHostKeyVerification = "strict"
InsecureHostKeyVerification = "insecure"
)

func (c *SSHConfig) Validate() error {
if c.Host == "" {
return errors.New("ssh host is required")
Expand All @@ -36,9 +44,48 @@ func (c *SSHConfig) Validate() error {
return errors.New("private key or password is required")
}

if c.HostKeyVerificationMode == StrictHostKeyVerification {
if c.KnownHostsFilePath == "" {
return errors.New("known_hosts file path is required for strict verification")
}
}

if c.HostKeyVerificationMode == "" {
c.HostKeyVerificationMode = InsecureHostKeyVerification
}

return nil
}

func (c *SSHConfig) getHostKeyCallback() (ssh.HostKeyCallback, error) {
strictStrategy := func() (ssh.HostKeyCallback, error) {
// need an absolute path to the known_hosts file
if err := CheckIfFilesExists(c.KnownHostsFilePath); err != nil {
return nil, fmt.Errorf("known_hosts file validation failed: %w", err)
}

callback, err := knownhosts.New(c.KnownHostsFilePath)
if err != nil {
return nil, fmt.Errorf("failed to load known_hosts file: %w", err)
}

return callback, nil
}

insecureStrategy := func() (ssh.HostKeyCallback, error) {
return ssh.InsecureIgnoreHostKey(), nil // #nosec G106
}

switch c.HostKeyVerificationMode {
case InsecureHostKeyVerification:
return insecureStrategy()
case StrictHostKeyVerification:
return strictStrategy()
default:
return nil, fmt.Errorf("unknown host key verification strategy: %s", c.HostKeyVerificationMode)
}
}

func (c *SSHConfig) SetupSSHConnection() (*ssh.Client, error) {
err := c.Validate()
if err != nil {
Expand All @@ -58,12 +105,15 @@ func (c *SSHConfig) SetupSSHConnection() (*ssh.Client, error) {
authMethods = append(authMethods, ssh.PublicKeys(signer))
}

hostKeyCallback, err := c.getHostKeyCallback()
if err != nil {
return nil, fmt.Errorf("failed to get host key callback: %s", err)
}

sshCfg := &ssh.ClientConfig{
User: c.Username,
Auth: authMethods,
// Allows everyone to connect to the server without verifying the host key
// TODO: Add proper host key verification
HostKeyCallback: ssh.InsecureIgnoreHostKey(), // #nosec G106
User: c.Username,
Auth: authMethods,
HostKeyCallback: hostKeyCallback,
Timeout: 30 * time.Second,
}

Expand Down
Loading