Skip to content

feat: Authenticate WebSocket provider connections to secured remote servers#2365

Open
dirkwa wants to merge 4 commits intoSignalK:masterfrom
dirkwa:fix-ws-provider-auth
Open

feat: Authenticate WebSocket provider connections to secured remote servers#2365
dirkwa wants to merge 4 commits intoSignalK:masterfrom
dirkwa:fix-ws-provider-auth

Conversation

@dirkwa
Copy link
Contributor

@dirkwa dirkwa commented Feb 25, 2026

Summary

  • Add token-based authentication for WebSocket provider (Data Connection) connections to remote Signal K servers
  • Token is sent on connect and verified via /signalk/v1/api/self on the remote server
  • Add proxy endpoints (testConnectionrequestAccesscheckAccessRequest) so the admin UI can interact with remote servers for token management
  • Add TokenInput UI component in R19 admin UI with manual token entry, "Request Access" and "Test Connection" buttons
  • Change default selfHandling from noSelf to useRemoteSelf
  • Add disconnect and error event handlers with status messages including auth hints
  • Include R19 admin UI corrections (Form.Select, expiration default, enabled on click, runDiscovery after delete)

Manual testing performed

  • Created device access request on secured remote server (192.168.0.147:3000) via API and approved it
  • Configured WS provider Data Connection on dev server (localhost:4000) with host, port, and device token
  • Verified authenticated WS connection established successfully — status shows "ws connection connected"
  • Verified deltas from remote server visible in Data Browser on local server
  • Fixed verifyRemoteToken — was using /skServer/loginStatus which returns notLoggedIn for valid device tokens; now uses /signalk/v1/api/self (200 = valid, 401 = invalid)
  • Verified R19 Access Requests UI renders correctly (Form.Select, NEVER expiration default)
  • Verified new Data Connection defaults to enabled
  • Verified runDiscovery triggers after provider delete

Fixes #2269

Copy link
Member

@tkurki tkurki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Authenticate WebSocket provider connections to secured remote servers" is a nice addition, but per the project's PR guidelines:

One logical change per PR. Refactoring and behavior changes belong in separate PRs. If changes would result in multiple changelog entries, they should be separate PRs.

This PR bundles several independent changes that should be split. Each of the following would have its own changelog entry and can be reviewed/reverted/bisected independently:


1. fix: Reject revoked tokens instead of downgrading to anonymous read-only

Files: src/tokensecurity.ts, src/interfaces/ws.js

This is a security behavior change where invalid tokens now get a 401 instead of silently falling through to anonymous readonly. It's independently valuable and already exists as a standalone commit (b24f0c7). Should be its own PR.

2. feat: Authenticate WebSocket provider connections to secured remote servers

Files: packages/streams/mdns-ws.js, packages/server-admin-ui/src/views/ServerConfig/BasicProvider.js (selfHandling default)

The core feature: sending the token over the WS connection, verifying it against /loginStatus, disconnecting on failure, and the selfHandling conditional logic + default change. This is the main PR topic.

3. feat: Add token management UI and backend endpoints for WS provider connections

Files: packages/server-admin-ui-react19/src/views/ServerConfig/BasicProvider.tsx (+319/-26), src/interfaces/providers.js (+171 lines)

Large UI feature (TokenInput, Request Access flow, Test Connection) with three new backend API endpoints (/testConnection, /requestAccess, /checkAccessRequest). This depends on #2 but is a substantial, separately reviewable addition.

4. feat: Show resolved IP address per mDNS discovery entry

Files: src/discovery.js

Completely unrelated to authentication. Changes the discovery ID format and adds the address field. Independent enhancement.

5. fix: Reconnect admin WebSocket after login/logout

Files: packages/server-admin-ui-react19/src/actions.ts, packages/server-admin-ui-react19/src/services/WebSocketService.ts

Standalone bug fix so admin event subscriptions (ACCESS_REQUEST, etc.) work after auth state changes. Also adds the RECEIVE_LOGIN_STATUS handler.

6. fix: Miscellaneous R19 admin UI corrections

Files: AccessRequests.tsx, Devices.tsx, ProvidersConfiguration.tsx, AccessRequests.js

Groups several unrelated small fixes that could even be further split:

  • Form.Control type="select"Form.Select (React Bootstrap 5 migration)
  • Default expiration '1y''NEVER' on access request approval (behavior change)
  • Set discovered & configured providers to enabled: true
  • Re-run discovery after deleting a provider

Suggested dependency chain

#1 (reject revoked tokens)
└─► #2 (WS provider auth)
└─► #3 (token management UI + endpoints)

#4 (mDNS discovery IPs) — independent
#5 (reconnect admin WS) — independent
#6 (misc UI fixes) — independent

Recommendation

Split this into at minimum 4 PRs:

  1. #1 — security fix for revoked tokens
  2. #2 + #3 combined if you prefer, since the UI is tightly coupled to the feature (though separating them would make review easier given the +345 line diff in BasicProvider.tsx)
  3. #4 — mDNS discovery enhancement
  4. #5 + #6 — admin UI fixes (these are at least all UI-layer, though the expiration default change touches behavior)

This makes each PR easier to review, safer to revert if needed, and produces cleaner, more human friendly release notes.

dirkwa added 2 commits March 4, 2026 11:07
…ervers

Add token-based authentication for outgoing WebSocket provider
connections. When a token is configured, the provider sends it upon
connecting and verifies it against the remote server's login status
endpoint. Invalid tokens trigger a disconnect with a clear error.

Add server-side proxy endpoints (testConnection, requestAccess,
checkAccessRequest) that let the admin UI interact with remote Signal K
servers for token management. Deduplicate mDNS discovery results and
change the default self-handling to useRemoteSelf for both admin UIs.
Add TokenInput component to the SignalK provider configuration form
with Request Access and Test Connection buttons. Request Access sends
an access request to the remote server and polls for approval, filling
in the token automatically when granted. Test Connection verifies
connectivity and authentication status.
@dirkwa dirkwa force-pushed the fix-ws-provider-auth branch from 6492af4 to e2a6d85 Compare March 3, 2026 23:11
dirkwa added 2 commits March 4, 2026 11:50
Fix Form.Control type=select to Form.Select (React Bootstrap 5) in
AccessRequests and Devices views. Default token expiration to NEVER
in both admin UIs to match the server-side default. Force discovered
providers to enabled when selected, and re-run discovery after
deleting a connection so it reappears without a page reload.
The /skServer/loginStatus endpoint returns notLoggedIn for device
tokens even when they are valid. Use /signalk/v1/api/self instead
which returns 200 for any authenticated request.
@dirkwa dirkwa changed the title Authenticate WebSocket provider connections to secured remote servers feat: Authenticate WebSocket provider connections to secured remote servers Mar 4, 2026
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.

Error: Missing access token at strategy.authorizeWS

2 participants