Commit Graph

10 Commits

Author SHA1 Message Date
Dave Kempe f2cd9119d3 sessions: owner-only first connection, optional read-only joins
The first WebSocket to a pending session takes its guacd stream, already
logged in to the target. Any operator could claim another user's pending
session that way, and session ids are visible in reports. Now only the
session's creator may make that connection, with no admin bypass: an admin
"shadowing" a pending session used to silently become its owner and lock
the real owner out, so shadow now refuses sessions that have not started
(409). handle_ws only takes the stream when the owner check passed at
upgrade time.

POST /api/sessions accepts an admin-only `owner` field so a backend using
an API key can create a session for a user who then connects with their
own login. That user is recorded as the creator.

Share links and shadow tokens gain an optional read-only mode; the default
stays read/write. Each shareable session gets a second token
(share_url_readonly), and shadow takes {"read_only": true}. guacd enforces
it per joining user via the read-only connect arg, which was previously
hardcoded to false. The Share dialog offers both links, the Sessions page
offers watch and shadow, and docs no longer claim a read-only mode that
did not exist.
2026-10-01 21:21:35 +10:00
Dave Kempe 0d69e8fed4 Rename Address Book → Connections; allowed_groups picker; session privacy (#102)
Three pieces of v1.6.0 work that happened together and are easier to
review as one save point.

Rename: Address Book → Connections
- static/addressbook.html renamed to static/connections.html
- Nav links, page titles, empty states, onboarding, and prose updated
  across all 8 static pages (connections, admin, docs, index,
  recordings, reports, sessions, tokens).
- README, CLAUDE.md, and every file under docs/ updated.
- src/main.rs: connections.html added to the branded-page map and
  route list; /addressbook.html returns a 308 permanent redirect so
  existing bookmarks keep working.
- Backend API paths, Rust types, and Vault storage paths are
  deliberately unchanged — internal only.

Folder allowed_groups picker
- New SQLite table `seen_groups` tracks OIDC groups observed in any
  user login; OIDC callback upserts after extracting groups.
- `GET /api/auth/known-groups` (admin-only) returns the union of
  group_role_mappings and seen_groups.
- `GET /api/addressbook/folders/{scope}/{folder}/config` adds the
  missing endpoint the frontend was already calling — existing
  allowed_groups now prefill the edit-folder modal.
- Folder modal swaps the free-text comma-separated input for a chip
  picker with a themed combobox dropdown: autocomplete over known
  groups, keyboard nav, "+ add custom" row for unlisted groups.

Active session visibility (GitHub #102)
- `GET /api/sessions` scopes to the caller's own sessions by default;
  `?all=true` lets admins opt in (used by the Sessions page).
- `GET /api/sessions/{id}` and the thumbnail GET/PUT endpoints are
  now owner-or-admin, returning 404 for other callers so session
  existence isn't leaked.
- Connections' Active Sessions strip is now always owner-scoped —
  admins still manage everyone via the Sessions page.
2026-04-18 21:56:20 +10:00
Dave Kempe 0c98aba190 v0.7.0: Banner field, automation UI, fix CDP policy, login script filtering
- Add optional `banner` field to address book entries (shown before session
  starts, user must click Continue). No longer auto-populates from display_name.
- Restructure web entry form: username, password, login script, and autofill
  collapsed under a collapsible "Automation" section.
- Filter login scripts dropdown to .js/.sh/.py files only (skip package.json etc.)
- Fix CDP/login scripts: change DeveloperToolsAvailability policy from 2 (disabled)
  to 0. DevTools UI remains blocked by chrome://* URLBlocklist. Fixes login script
  automation that was silently broken by the v0.6.0 security hardening.
- Update Dockerfile, debian/postinst, install.sh with corrected policy.
- Update docs/security.md and docs/web-sessions.md.
2026-03-11 23:01:22 +11:00
Dave Kempe df402944f3 v0.6.2: Fix mTLS identity parsing (#51), decouple server/guacd TLS (#49)
- Rewrite Vault mTLS client to build rustls ClientConfig directly,
  bypassing reqwest::Identity::from_pem() which fails with rustls
  backend for PKCS#8 keys from OpenBao/Vault PKI
- Make cert_path/key_path optional in [tls] — guacd TLS now works
  independently of server HTTPS (for reverse proxy setups)
- Add webpki-roots direct dependency for custom TLS config
- Add mTLS tests: PKCS#8 key, fullchain cert, tls_skip_verify
- Update docs: configuration.md, security.md

Closes #51, closes #49

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 07:37:45 +11:00
Dave Kempe b5d31b13ce Add dedicated web sessions doc, fix credential docs, global policy warning
- New docs/web-sessions.md: comprehensive guide with autofill, domain
  allowlisting, login scripts (Playwright + shell examples), clipboard
  control, API reference, and troubleshooting
- Fix integrations.md: web sessions DO use credentials (for autofill
  and login scripts)
- Add global Chromium policy warning to security.md and web-sessions.md
- Add web-sessions.md to in-app docs (build.rs)
- Condense overview.md web section to link to new dedicated doc

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 07:30:09 +11:00
Dave Kempe 99d79fe05d v0.6.0: Web autofill, domain allowlisting, clipboard control, Guacamole import
New features:
- Native Chromium autofill: pre-populate Login Data SQLite before launch,
  zero external deps (no Node.js/Playwright needed for simple login flows)
- Per-entry domain allowlisting: restrict which domains Chromium can reach
  via --host-rules (separate from server-side web_allowed_networks CIDR)
- Per-entry clipboard control: disable-copy and disable-paste for all
  session types (SSH, RDP, VNC, Web) via guacd native parameters
- Guacamole import: `rustguac import-guacamole` parses mysqldump SQL and
  writes entries to Vault address book

Security hardening:
- Comprehensive Chromium managed policy deployed via install.sh, Dockerfile,
  and debian/postinst (blocks DevTools, downloads, file dialogs, extensions,
  dangerous URL schemes)
- Profile isolation: each web session gets a unique UUID-based profile dir
- Autofill credentials encrypted with Chromium's native os_crypt (AES-128-CBC)

Documentation:
- Updated README, docs/api.md, docs/security.md, docs/configuration.md,
  docs/overview.md, docs/integrations.md with all new features
- Clarified two-layer domain restriction (web_allowed_networks vs allowed_domains)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 00:54:26 +11:00
Dave Kempe 76c93bc502 Add multi-hop SSH tunnels, VNC sessions, and web session tunnel support
Multi-hop SSH tunnel chains allow routing any session type through
multiple bastion hosts. VNC is now a first-class session type.
Web browser sessions can tunnel through jump hosts with automatic
URL rewriting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 08:22:34 +11:00
Dave Kempe a94b743d6c Add user API tokens with role-based access and audit logging
User API tokens allow OIDC users to authenticate via bearer token for
automation and scripting. Powerusers and admins can create their own
tokens; admins can create tokens for operators. Tokens use SHA-256
hashing, optional max_role caps, optional expiry, and full audit
logging of create/revoke operations with client IPs.

- DB schema: user_api_tokens and token_audit_log tables
- Auth middleware: validates user tokens as fallback after admin keys
- API: 7 new endpoints (self-service + admin token management)
- UI: tokens.html (self-service) + admin.html token/audit sections
- Nav: Tokens link added to all pages (visible for operator+)
- Docs: API reference, security model, roles/access control updated
- Background cleanup: expired tokens + 90-day audit log retention

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:02:54 +11:00
Dave Kempe 466ffd2d44 Upgrade openidconnect v3 -> v4, remove JumpCloud references
- openidconnect 3.5.0 -> 4.0.1 (oauth2 4 -> 5)
- Eliminates duplicate reqwest/hyper/http dependency chains
- 386 -> 355 crate dependencies
- Resolves rustls-pemfile 1.0.4 unmaintained warning
- HTTP client now uses stateful reqwest::Client (no-redirect policy)
- exchange_code returns Result for EndpointMaybeSet token URLs
- Remove JumpCloud from provider examples, prefer Authentik

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 10:39:24 +11:00
Dave Kempe 67101e27ce Initial public release
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 14:38:53 +11:00