Skip to content

Security hardening#19

Open
gorlitzer wants to merge 17 commits intostoops-io:mainfrom
gorlitzer:security-hardening
Open

Security hardening#19
gorlitzer wants to merge 17 commits intostoops-io:mainfrom
gorlitzer:security-hardening

Conversation

@gorlitzer
Copy link

This pull request introduces several important improvements to authentication, security, and usability in the project. The most significant changes include a switch to using Authorization: Bearer tokens for all API requests, the addition of token expiration and pruning logic, enhanced documentation for secure usage and network access, and new CLI options for exposing the server and customizing CORS origins. There are also minor improvements to error handling and developer experience.

Security and Authentication Improvements:

  • All API requests now use Authorization: Bearer <token> headers instead of passing tokens in the request body or query parameters, improving security and aligning with best practices. (src/agent/remote-room-data-source.ts, src/cli/join.ts) [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]
  • The TokenManager class now tracks creation and expiration times for both session and share tokens, enforcing 24-hour and 1-hour TTLs respectively. Expired tokens are automatically pruned and cannot be used. (src/cli/auth.ts)
  • Added methods to TokenManager for rotating session tokens and sweeping expired tokens, further improving session management and security. (src/cli/auth.ts)

Documentation and Usability Enhancements:

  • Updated README.md with new sections on running over a private network, security best practices, and clear instructions for running from source. Also clarified the minimum required Node.js version (now 20+). [1] [2] [3]
  • Added CLI options for --expose (to bind the server to all interfaces) and --cors-origin (to customize allowed CORS origins), improving flexibility for different deployment scenarios. (src/cli/index.ts, README.md) [1] [2] [3]
  • Added a start script to package.json for easier development and running from source. (package.json)

Error Handling:

  • Improved error logging in the join flow to provide more informative messages when the server is unreachable. (src/cli/join.ts)

These changes collectively make the project more secure, easier to use in real-world environments, and more robust for both end users and developers.

gorlitzer and others added 17 commits March 14, 2026 13:20
Prevents the server from being accessible on the network by default.
Use --expose to opt in to binding on all interfaces.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Clamp count params to safe ranges (/messages [1,100], /events/history
[1,200], /search [1,50]). Reject messages exceeding 50k chars.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Validate that save/load paths end with .json and are under cwd or
tmpdir. Defense-in-depth check also added to FileBackedStorage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove Access-Control-Allow-Origin: * and validate origins against an
allowlist (localhost, tunnel URL, --cors-origin values). Add OPTIONS
preflight handler.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add extractSessionToken() helper on server that checks Authorization:
Bearer first, falls back to query param/body for backward compat.
Update all clients (join.ts, remote-room-data-source.ts, runtime-setup.ts)
to send tokens via Authorization header. POST /join accepts body.shareToken
with body.token as deprecated alias.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show first 4 + last 4 chars of tokens in the TUI banner instead of
raw values. Headless JSON keeps raw tokens for machine consumption
but prints a warning to stderr.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Session tokens expire after 24h, share tokens after 1h (configurable).
Add rotateSessionToken() and pruneExpired() to TokenManager. Add POST
/rotate-token endpoint. Run pruning sweep every 5 minutes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rate limits: /join 10/min per IP, /message 30/min per session, /share
10/min per session, GET 60/min per session, SSE 5/min per IP. Returns
429 with Retry-After header when exceeded.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Migrate all integration test helpers and inline fetch calls to use
Authorization headers. Add tests/security.test.ts covering token
expiry, rotation, pruning, integer bounds, message length, rate
limiting, backward compat, and bind address.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The DTS build fails when @langchain/* packages aren't installed because
TypeScript can't resolve types for the dynamic imports. These stub
declarations provide minimal ambient types so the build succeeds
regardless of whether the optional packages are present.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When --expose binds the server to 0.0.0.0, share links were still
generated with 127.0.0.1, making them unusable from other machines.
Now resolves the first non-internal IPv4 address for the serverUrl.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The catch-all was hiding the real failure reason (e.g. 403, network
errors) behind a generic "Cannot reach server" message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Node 18 doesn't support the /v regex flag used by string-width.
Added default port and firewall hint to the private network section.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sends a :heartbeat comment every 30s to keep connections alive
through proxies, firewalls, and OS-level TCP idle timeouts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.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.

1 participant