Skip to content

feat(ssh): add configurable client authentication methods#1637

Merged
Eugeny merged 7 commits intowarp-tech:mainfrom
liebermantodd:feature/ssh-client-auth-config
Jan 27, 2026
Merged

feat(ssh): add configurable client authentication methods#1637
Eugeny merged 7 commits intowarp-tech:mainfrom
liebermantodd:feature/ssh-client-auth-config

Conversation

@liebermantodd
Copy link
Copy Markdown
Contributor

Hey folks! First off, thanks for Warpgate - it's been great for managing SSH access to my infrastructure.

The Problem

I've been running Warpgate exposed on port 2222 and getting absolutely hammered by SSH brute-force attacks. Even with Fail2Ban, the sheer volume of password auth attempts was filling up my SQLite database (got up to 2 million log entries, 600MB, eventually corrupted).

I wanted to do what I do with regular sshd - just disable password auth entirely so attackers aren't even offered it as an option. But I noticed the auth methods are hardcoded in run_server:

methods: MethodSet::from(&[
    MethodKind::PublicKey,
    MethodKind::Password,
    MethodKind::KeyboardInteractive,
][..])

The Fix

Added three config options to SshConfig:

ssh:
  client_auth_publickey: true
  client_auth_password: false      # this is what I needed
  client_auth_keyboard_interactive: true

All default to true so existing configs work unchanged. When you start up you'll see:

INFO warpgate_protocol_ssh::server: SSH authentication methods enabled: publickey=true, password=false, keyboard_interactive=true

Testing

I followed your existing test patterns and added test_ssh_client_auth_config.py with:

  • TestSshClientAuthPasswordDisabled - password rejected, pubkey still works
  • TestSshClientAuthPublickeyDisabled - pubkey rejected, password still works
  • TestSshClientAuthAllMethodsDisabled - nothing works when all disabled
  • TestSshClientAuthDefaultConfig - default config allows everything (backward compat)

Would love if you could run the test suite against this. I tested manually on my own Warpgate instance and it's working well - brute force attackers now get immediately rejected instead of being able to spam password attempts.

Let me know if you'd like any changes to the approach or if I should adjust how the config options are named/structured.

Closes #1561

@Eugeny
Copy link
Copy Markdown
Member

Eugeny commented Jan 1, 2026

Thank you for the contribution! However this needs a few changes:

  • I'd like to avoid introducing new config options - instead, these should go into the Parameters database model
  • They'll need their own checkboxes in Parameters.svelte
  • Disabling authentication methods should affect the options shown in AuthPolicyEditor.svelte correspondingly

liebermantodd added a commit to liebermantodd/warpgate that referenced this pull request Jan 18, 2026
…ers UI

Move SSH authentication method configuration from YAML config to the
Parameters database model, as requested by maintainer.

Changes:
- Add ssh_client_auth_publickey, ssh_client_auth_password, and
  ssh_client_auth_keyboard_interactive fields to Parameters entity
- Add database migration (m00025_ssh_client_auth)
- SSH server now reads auth settings from Parameters and builds
  MethodSet dynamically at startup
- Add "SSH Authentication Methods" section to Parameters.svelte with
  toggle switches for each auth method
- AuthPolicyEditor now filters credential options based on enabled
  SSH auth methods (e.g., hides Password option when password auth
  is disabled globally)

This addresses the reviewer feedback on PR warp-tech#1637 to avoid introducing
new config options and instead use the Parameters database model.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
liebermantodd added a commit to liebermantodd/warpgate that referenced this pull request Jan 19, 2026
…ers UI

Move SSH authentication method configuration from YAML config to the
Parameters database model, as requested by maintainer.

Changes:
- Add ssh_client_auth_publickey, ssh_client_auth_password, and
  ssh_client_auth_keyboard_interactive fields to Parameters entity
- Add database migration (m00025_ssh_client_auth)
- SSH server now reads auth settings from Parameters and builds
  MethodSet dynamically at startup
- Add "SSH Authentication Methods" section to Parameters.svelte with
  toggle switches for each auth method
- AuthPolicyEditor now filters credential options based on enabled
  SSH auth methods (e.g., hides Password option when password auth
  is disabled globally)

This addresses the reviewer feedback on PR warp-tech#1637 to avoid introducing
new config options and instead use the Parameters database model.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@liebermantodd
Copy link
Copy Markdown
Contributor Author

Hi @Eugeny, I've updated the PR to address your feedback:

Changes made:

  1. Moved from YAML config to Parameters database - Settings are now stored in the Parameters model and persisted to DB
  2. Added UI toggles in Parameters.svelte - Admins can enable/disable each SSH auth method (publickey, password, keyboard-interactive)
  3. Updated CredentialEditor.svelte - When an auth method is disabled globally, the corresponding credential options are hidden from the user policy editor
  4. Added fallback safety - If all methods are disabled, all are enabled by default (with warning logged)
  5. Added info text in UI explaining the fallback behavior
  6. Added comprehensive E2E tests (8 tests covering API + actual SSH auth enforcement)

Files changed (9):

  • warpgate-admin/src/api/parameters.rs - API endpoint
  • warpgate-db-entities/src/Parameters.rs - DB entity
  • warpgate-db-migrations/ - Migration for new columns
  • warpgate-protocol-ssh/src/server/mod.rs - SSH auth method enforcement
  • warpgate-web/src/admin/config/Parameters.svelte - UI toggles
  • warpgate-web/src/admin/CredentialEditor.svelte - Policy editor filtering
  • warpgate-web/src/admin/lib/openapi-schema.json - API schema
  • tests/test_ssh_client_auth_config.py - E2E tests

Tested on a live deployment - password auth is properly blocked when disabled.

liebermantodd and others added 3 commits January 22, 2026 05:23
…ers UI

Move SSH authentication method configuration from YAML config to the
Parameters database model, as requested by maintainer.

Changes:
- Add ssh_client_auth_publickey, ssh_client_auth_password, and
  ssh_client_auth_keyboard_interactive fields to Parameters entity
- Add database migration (m00025_ssh_client_auth)
- SSH server now reads auth settings from Parameters and builds
  MethodSet dynamically at startup
- Add "SSH Authentication Methods" section to Parameters.svelte with
  toggle switches for each auth method
- AuthPolicyEditor now filters credential options based on enabled
  SSH auth methods (e.g., hides Password option when password auth
  is disabled globally)

This addresses the reviewer feedback on PR warp-tech#1637 to avoid introducing
new config options and instead use the Parameters database model.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Update openapi-schema.json with SSH client auth parameter fields
- Add comprehensive E2E tests for SSH authentication method configuration:
  - API tests for get/update parameters
  - E2E tests verifying password auth disabled blocks password login
  - E2E tests verifying pubkey auth disabled blocks pubkey login
  - E2E tests verifying enabled methods work correctly
  - E2E tests verifying fallback when all methods disabled

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Inform admins that if all SSH authentication methods are disabled,
all will be enabled by default as a safety fallback.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@liebermantodd liebermantodd force-pushed the feature/ssh-client-auth-config branch from 249b292 to 7adbd3e Compare January 22, 2026 05:55
Ensures errors from updateParameters are properly propagated
rather than silently ignored.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@liebermantodd
Copy link
Copy Markdown
Contributor Author

Also added a small fix: await the api.updateParameters() call in Parameters.svelte to ensure errors are properly propagated rather than silently ignored.

@Eugeny
Copy link
Copy Markdown
Member

Eugeny commented Jan 26, 2026

Thanks! I've updated the PR to apply options without a server restart as well as added checks to actually reject auth attempts since config.methods only affects what the server is advertising.

Note that I've removed the fallback when all options are disabled since it's a bit counterintuitive to the user

@Eugeny Eugeny merged commit d45dbe5 into warp-tech:main Jan 27, 2026
15 checks passed
@Eugeny
Copy link
Copy Markdown
Member

Eugeny commented Jan 27, 2026

@all-contributors add @liebermantodd for code

@allcontributors
Copy link
Copy Markdown
Contributor

@Eugeny

I've put up a pull request to add @liebermantodd! 🎉

Eugeny pushed a commit that referenced this pull request Jan 28, 2026
Adds @liebermantodd as a contributor for code.

This was requested by Eugeny [in this
comment](#1637 (comment))

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No login attempts limiting could be a security risk

2 participants