16 Commits

Author SHA1 Message Date
Dave Kempe 627c05074b docs(oidc): document outbound HTTP proxy (Squid) egress 2026-07-06 20:12:44 +10:00
Dave Kempe 575d4ab798 docs(integrations): add Microsoft Entra ID setup guide
Covers the claim-vs-scope distinction that trips Entra setups when users
copy the Authentik example. Includes the AADSTS650053 error explainer
plus a troubleshooting section. Promised in #153.
2026-06-03 15:19:57 +10:00
Dave Kempe 70763932ca fix(drive): honour cleanup_on_close and retention_secs at session end
Closes #123 (parts 2 + 3 only; upload disconnect and drag-drop UX
postponed for further testing).

cleanup_browser hardcoded retention_secs=0 and never consulted
cleanup_on_close, so the [drive] config flags were dead code at
end-of-session teardown. This was visible to operators as
"cleanup_on_close = false has no effect" and "retention_secs = 0 wins
over cleanup_on_close = false" - the same root cause for both reports.

  - cleanup_browser now takes (cleanup_on_close, retention_secs) and
    only calls drive::cleanup_session_dir when cleanup_on_close = true,
    passing retention_secs through. session.drive_path is still cleared
    either way so subsequent reads don't think we still own the dir.
  - drive_cleanup_settings() centralises the resolution from the
    optional [drive] config; absent config uses the legacy "always
    wipe immediately" defaults so installs that never enabled drive
    keep prior behaviour.
  - All four cleanup_browser call sites updated (delete, complete,
    error, pending-timeout).
  - Three new unit tests covering the resolution helper.
  - Docs gain a "Cleanup behaviour" subsection in the Drive section
    explaining the precedence (retention_secs only matters when
    cleanup_on_close=true) and the per-session UUID subdir model that
    means files do not persist across sessions even with cleanup
    disabled. The cross-session "personal drive" model would be a
    separate feature.
2026-05-06 15:57:26 +10:00
Dave Kempe 4aa18e1f32 docs(authentik): add missing groups scope mapping step
Closes #122.

Authentik does not ship a `groups` scope mapping by default, so the
existing instruction "Add the `groups` scope" in the provider's Advanced
protocol settings has nothing to select. Operators following the guide
end up with rustguac unable to read group memberships, which silently
breaks group-to-role mapping.

Adds a new step 1 explaining how to create a Scope Mapping under
Customisation > Property Mappings with the standard
`request.user.ak_groups` expression, and updates the provider step to
reference the newly-created mapping by name. Subsequent steps renumbered.
2026-05-06 15:57:26 +10:00
Dave Kempe c7554fec1d docs: emphasise vault/openbao as a dependency, point at quickstart
The Connections UI is the main user-facing rustguac feature, and it does
not work without Vault or OpenBao. The previous docs framed this as
"recommended" or "optional Vault-backed connections", which understated
how much of rustguac depends on the secret store being there.

  - README.md gains a Requirements table listing guacd (bundled),
    vault/openbao (required for Connections), OIDC (optional), Docker
    (optional). The Features bullet now points at it.
  - docs/installation.md upgrades step 4 from "(Recommended)" to
    "(Required for connections)" with explicit "without one of these,
    the Connections UI is unavailable" wording. Includes the
    quickstart one-liner and a --local example.
  - docs/overview.md drops "optional" from the Vault-backed connections
    description and adds a follow-up paragraph pointing at the
    integrations doc and the quickstart script.
  - docs/integrations.md adds a Quickstart subsection above the manual
    walkthrough with a mode table, three example invocations, and the
    --local on-disk-unseal security caveat reiterated where it'll be
    seen by anyone reading the section.
2026-05-06 15:57:26 +10:00
Dave Kempe 542474dc3a v1.6.6 polish: OIDC error clarity, xrdp TLS perms, aurora default, reverse-proxy docs
### OIDC discovery error wrap

src/oidc.rs now reshapes the openidconnect crate's "unexpected issuer
URI `X` (expected `Y`)" validation error into something an operator
can act on without having to reason about which side is the config
and which is the provider. For the overwhelmingly common
trailing-slash case the message collapses to a single actionable
line; for the rarer case where the two URIs differ materially (wrong
tenant, copy-pasted authorise URL, Keycloak path change), it falls
back to a config/provider/fix three-liner. Raw Debug output is
preserved for any non-mismatch discovery failure. Works for any
OIDC provider, not just JumpCloud.

### xrdp TLS key permissions (contrib/setup-xrdp-gfx.sh)

After rebuilding xrdp from sid, the `adduser xrdp ssl-cert` step
from the Debian postinst doesn't always re-apply cleanly, leaving
the xrdp user unable to read /etc/xrdp/key.pem. xrdp then falls
back to "classic RDP security" and FreeRDP drops the connection
with a MAC checksum error. New Step 9 in Phase 3 explicitly adds
xrdp to ssl-cert and normalises the key's ownership/mode. Step
list in the help text renumbered to match.

### Aurora default when [theme] is absent

src/main.rs resolved the theme via ThemeConfig::resolve() only when
config.theme was Some(..), and otherwise fell through to a hardcoded
("dark", builtin_presets()[0].1.clone()) pair. That meant aurora
only kicked in when a [theme] section was present in config.toml,
even an empty one. ThemeConfig now derives Default (all fields
Option<String>, so zero-cost), and main.rs resolves via
config.theme.clone().unwrap_or_default().resolve() so absent and
empty [theme] behave identically. Regression test added.

### docs/reverse-proxies.md

New doc covering nginx, Caddy, Apache, and Traefik with per-proxy
configs and the %2F-decoding gotcha that causes 404s on nested
subfolder paths when a proxy normalises the URI before forwarding.
The issue was surfaced by @mauroparente in #105 — thanks for the
repro and the nginx config that made the root cause obvious.
deployment-guide.md Step 3 and integrations.md HAProxy section
both link to the new doc.
2026-04-25 15:40:08 +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 5a5bd8ff75 Document Vault KV v2 metadata policy requirement for deletes (#54)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:05:35 +11:00
Dave Kempe ac77bfab98 v0.6.1: Vault mTLS support, comprehensive test suite (87 tests)
Vault/OpenBao mTLS:
- Add ca_cert, client_cert, client_key fields to [vault] config
- Supports custom CA certificates and mutual TLS authentication
- Clear error messages for missing files, invalid PEM, missing key
- Fixes #48 (OpenBao requiring client certificates)

Test suite (8 → 87 tests):
- vault: 13 tests (TLS client builder, config deserialization, name validation)
- auth: 11 tests (role hierarchy, effective role capping, XFF/trusted proxy, has_role)
- session: 12 tests (CIDR network checks, autofill JSON parsing, placeholder substitution)
- browser: 8 tests (Chromium password encryption, Login Data SQLite, RangeAllocator)
- config: 8 tests (preset resolution, theme overrides, defaults, vault config)
- api: 6 tests (HTML escaping, recording name path traversal protection)
- db: 7 tests (SHA-256 hashing, key generation, user groups parsing)
- import: 12 tests (already existed, now wired into module tree)
- protocol: 8 tests (already existed)

Other:
- Wire import.rs into module tree (fixes orphaned tests)
- Document mTLS config in configuration.md and integrations.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:44:46 +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 d07d79c4f2 Add Kerberos NLA support for RDP and credential prompting
- Patch guacd with Kerberos NLA support (002-kerberos-nla.patch),
  based on upstream GUACAMOLE-2057 PR #581, adapted for FreeRDP 3.x
- Add per-entry auth_pkg, kdc_url, and prompt_credentials settings
  to the address book (configurable in admin UI)
- Frontend credential prompt for entries without stored credentials
  or with prompt_credentials enabled (never stored, session-only)
- Wire auth-pkg, kdc-url, kerberos-cache params through rustguac
  to the guacd RDP handshake
- Comprehensive Kerberos NLA docs: krb5.conf setup, KDC discovery
  options, FQDN requirements, troubleshooting guide

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 10:39:18 +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 292db1fa55 Update OIDC docs to prefer Authentik, add setup guide
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 09:52:23 +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