Files
rustguac/docs/credential-variables.md
T
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

4.0 KiB

Credential Variables

Credential variables let connections entries reference shared credentials by name instead of storing passwords directly. Users maintain their own credential values in Vault via the My Credentials dialog (gear menu). When a session launches, rustguac substitutes the variables from the user's saved values.

This gives a similar experience to LDAP credential passthrough in Apache Guacamole — users log in once and sessions just work — without rustguac needing to bind to LDAP. Credentials stay in Vault, never on disk or in the browser.

How it works

  1. Admin creates connections entries with variable references like $corp_username and $corp_password in the credential fields
  2. Users open My Credentials from the gear menu and fill in their values (stored per-user in Vault)
  3. At connect time, rustguac substitutes the variables. If all are set, the session launches silently. If any are missing, the user is prompted.

Variable naming

Variables start with $ and use the pattern $<domain>_<suffix>:

Pattern Purpose Input type
$<domain>_username Username Text
$<domain>_password Password Password (masked)
$<domain>_domain AD/Windows domain Text
$<domain>_key SSH private key Textarea

The <domain> is a logical name chosen by the admin to group related credentials — for example corp, jumpcloud, lab, or cloud-prod. Multiple entries can reference the same domain, so users only configure their credentials once.

Allowed characters: lowercase letters, numbers, underscores, and hyphens. For example: $corp_username, $jump-host_password, $cloud-prod_key.

Example

An admin creates two connections entries:

  • Production SSH — username: $corp_username, password: $corp_password
  • Staging SSH — username: $corp_username, password: $corp_password

Both reference the same corp domain. A user opens My Credentials, fills in their corp username and password once, and both entries work without further prompting.

An entry can also mix variables with static values. For example, an RDP entry might have a static hostname and port but use $ad_username, $ad_password, and $ad_domain for credentials.

My Credentials dialog

Access via the gear icon in the top-right corner of the connections page. The dialog:

  • Shows all credential variables used across entries the user has access to
  • Groups variables by domain prefix
  • Indicates how many entries use each variable
  • Masks password and key fields (saved values are not shown, but a placeholder confirms they exist)
  • Partial saves work — fill in what you have now, come back later for the rest

Graceful degradation

  • All variables set — session launches immediately, no prompting
  • Some missing — credential prompt appears with known values pre-filled; user only needs to fill gaps
  • None set — full credential prompt (same as entries without variables)

Vault storage

User credentials are stored in Vault KV v2 at:

<base_path>/users/<sanitized_email>

Each user gets a single Vault secret containing all their credential key-value pairs. Variable names are the keys, plaintext values are the values. The Vault policy must allow read/write to this path for authenticated users.

Required Vault policy

In addition to the existing connections policy, add:

# User credential variables (read/write own credentials)
path "secret/data/rustguac/users/*" {
  capabilities = ["create", "read", "update", "delete"]
}
path "secret/metadata/rustguac/users/*" {
  capabilities = ["list", "read", "delete"]
}

API endpoints

Method Path Role Description
GET /api/me/credentials operator+ List own saved variables (passwords masked)
PUT /api/me/credentials operator+ Save/update own variables
GET /api/credential-variables operator+ List all variables used across accessible entries