- Consolidated documentation from Ralph Loop iterations - Archived 20+ outdated/superseded files to .archive/ - Kept essential docs: OIDC integration, mobile setup, quick start - Added operational scripts for health monitoring and backup - Research artifacts preserved in .tasks/artifacts/ Current state: - 3 VPS sites (fry, proton, photon) ONLINE in Pangolin - brn-home site pending for local services (Jellyfin, etc.) - Mobile access configuration pending Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
16 KiB
Apache Guacamole OIDC Integration with Authentik - Research Report
Research Task: RESEARCH-003 Date: 2026-01-20 Objective: Comprehensive research on Apache Guacamole OIDC integration with Authentik
1. Complete List of OPENID_ Environment Variables
Required Environment Variables
For Docker installations of Apache Guacamole, the following environment variables are required:
| Variable | Description | Example Value |
|---|---|---|
OPENID_AUTHORIZATION_ENDPOINT |
Authorization endpoint URI from IdP | https://sso.obr.sh/application/o/authorize/ |
OPENID_JWKS_ENDPOINT |
JWKS endpoint for validating ID tokens (JWTs) | https://sso.obr.sh/application/o/<slug>/jwks/ |
OPENID_ISSUER |
Expected issuer for all received ID tokens | https://sso.obr.sh/application/o/<slug>/ |
OPENID_CLIENT_ID |
OpenID client ID for your application | From Authentik provider configuration |
OPENID_REDIRECT_URI |
Full callback URL for Guacamole | https://remote.obr.sh/guacamole/api/auth/openid-connect/callback |
Optional Environment Variables
| Variable | Description | Default Value |
|---|---|---|
OPENID_ENABLED |
Explicitly enable the extension | true (or set any OPENID_ variable) |
OPENID_USERNAME_CLAIM_TYPE |
JWT claim for username | email |
OPENID_GROUPS_CLAIM_TYPE |
JWT claim for groups | groups |
OPENID_ATTRIBUTES_CLAIM_TYPE |
Comma-separated list of claims to expose as OIDC_* attributes |
(empty) |
OPENID_SCOPE |
OpenID scopes to request | openid email profile |
OPENID_ALLOWED_CLOCK_SKEW |
Clock skew tolerance for token validation | 30 (seconds) |
OPENID_MAX_TOKEN_VALIDITY |
Maximum token validity period | 300 (minutes/5 hours) |
OPENID_MAX_NONCE_VALIDITY |
Maximum nonce validity period | 10 (minutes) |
Extension Loading Control
| Variable | Description | Effect |
|---|---|---|
EXTENSION_PRIORITY |
Controls authentication flow | openid = auto-redirect to IdP |
*,openid = show login screen first |
Additional Configuration Requirement
For standalone installations (non-Docker), you must enable environment property evaluation:
# In /etc/guacamole/guacamole.properties
enable-environment-properties: true
2. Connection-Level Authentication Flow
User Authentication vs. Connection Authentication
Critical Finding: OIDC in Guacamole handles user authentication to the Guacamole web interface, NOT connection-level authentication to RDP/VNC/SSH hosts.
How It Works
- User logs into Guacamole via OIDC (SSO to Authentik)
- Guacamole creates a session for the authenticated user
- Connections are accessed based on permissions stored in the database extension (JDBC)
- Target system authentication happens separately using configured credentials
The Credential Passthrough Problem
With LDAP Authentication (Works)
User → LDAP login → Guacamole stores credentials → RDP connection
↓
${GUAC_USERNAME} and ${GUAC_PASSWORD} available
With OIDC Authentication (Does NOT Work)
User → OIDC login → Guacamole gets token only → RDP connection
↓
${GUAC_PASSWORD} is NOT available (password never sent to Guacamole)
Parameter Tokens Available
| Token | LDAP Auth | OIDC Auth | Notes |
|---|---|---|---|
${GUAC_USERNAME} |
✓ Available | ✓ Available | Username from claim |
${GUAC_PASSWORD} |
✓ Available | ✗ NOT Available | Password never leaves IdP |
OIDC Attribute Passthrough
The OPENID_ATTRIBUTES_CLAIM_TYPE variable allows exposing JWT claims as OIDC_* parameters:
# Example: Expose custom claims
OPENID_ATTRIBUTES_CLAIM_TYPE=workstationName,department,employeeId
This creates connection parameters:
${OIDC_workstationName}${OIDC_department}${OIDC_employeeId}
Use Case: Dynamic connection routing based on user attributes, NOT credential passthrough.
3. MFA Flow with TOTP Passthrough
Guacamole's TOTP Support
Apache Guacamole supports TOTP (Time-based One-Time Password) as a second authentication factor.
TOTP Authentication Flow
┌─────────────────────────────────────────────────────────────┐
│ 1. User attempts to log in │
│ ↓ │
│ 2. Primary authentication (OIDC/LDAP/Database) │
│ ↓ │
│ 3. If successful, TOTP extension checks for enrolled device │
│ ├─ Device enrolled: Prompt for TOTP code │
│ └─ No device: Force enrollment (QR code scan) │
│ ↓ │
│ 4. User enters 6-digit code from authenticator app │
│ ↓ │
│ 5. If code validates: Grant access │
│ └─ If code fails: Deny access │
└─────────────────────────────────────────────────────────────┘
TOTP Extension Configuration
Extension File: guacamole-auth-totp-*.jar
Environment Variables (Docker):
| Variable | Description | Default |
|---|---|---|
TOTP_ISSUER |
Issuer name shown in authenticator app | Apache Guacamole |
TOTP_DIGITS |
Number of digits in TOTP code | 6 |
TOTP_PERIOD |
Time period for code validity | 30 (seconds) |
TOTP_MODE |
TOTP generation mode | sha1 |
Layered Authentication: OIDC + TOTP
Prerequisites:
- Database authentication extension (JDBC) installed for key storage
- OIDC extension for primary authentication
- TOTP extension for second factor
Flow:
- User → Authentik (OIDC with MFA at IdP level) → Guacamole login
- Guacamole → TOTP challenge (separate from Authentik MFA)
- User → Enters TOTP code → Access granted
Important Limitation: Duo vs. TOTP with SSO
From official documentation:
"Guacamole's Duo support cannot currently be used alongside single sign-on (SSO). If you need both MFA and SSO, you must use your SSO provider's own Duo integration or use TOTP instead of Duo."
MFA Architecture Options
Option A: MFA at IdP Level (Authentik)
User → Authentik (with TOTP/WebAuthn) → Guacamole
Pros: Single MFA enforcement point, better UX
Cons: No Guacamole-level MFA control
Option B: MFA at Guacamole Level
User → Authentik (no MFA) → Guacamole TOTP → Access
Pros: Guacamole controls second factor
Cons: Users authenticate twice (SSO + TOTP)
Option C: Dual MFA (Most Secure)
User → Authentik (with MFA) → Guacamole TOTP → Access
Pros: Defense in depth, two independent factors
Cons: Potential user friction
4. RDP NLA Compatibility with SSO
What is RDP NLA?
Network Level Authentication (NLA) is a security feature in RDP that requires authentication before establishing a full remote desktop session.
The Fundamental Incompatibility
Critical Finding: OIDC SSO and RDP NLA have a credential passthrough problem.
Why It Doesn't Work
┌──────────────────────────────────────────────────────────┐
│ OIDC Flow (No Password to Guacamole) │
├──────────────────────────────────────────────────────────┤
│ User → Authentik → JWT Token → Guacamole │
│ │
│ RDP NLA Requirement (Needs Actual Password) │
│ │
│ Guacamole → Windows Server (NLA) → ??? No password ??? │
└──────────────────────────────────────────────────────────┘
The Problem:
- OIDC authentication means the user's password never reaches Guacamole
- RDP NLA requires a username/password for NTLM or Kerberos authentication
${GUAC_PASSWORD}token is empty when using OIDC
Confirmed by Community Evidence
From mailing list discussions:
"When using OpenID Connect (or SAML, or CAS without the ClearPass extension) for Guacamole login, the user's password is not shared between the Identity Provider (IdP) and Guacamole, meaning the
${GUAC_PASSWORD}variable will not be available for use in RDP connections."
Current Status of FreeRDP NLA Support
Guacamole uses FreeRDP for RDP connections. Key limitations:
- NTLM-only NLA: FreeRDP currently only supports NTLM variant of NLA
- No Kerberos NLA: Kerberos NLA support is in development
- Protected Users Group: Users in AD "Protected Users" group cannot authenticate via NTLM NLA
Workarounds and Solutions
Solution 1: Disable NLA on Target Systems
Pros: Simple, works immediately
Cons: Reduced security, Microsoft discourages this
Solution 2: Credential Prompting
Leave RDP username/password blank → User prompted during connection
Pros: Works with OIDC
Cons: Users log in twice (SSO + RDP prompt)
Solution 3: Pre-configured Shared Accounts
Store RDP credentials in Guacamole connection config
Pros: Single sign-on UX maintained
Cons: Shared accounts, loses per-user audit trail
Solution 4: Use LDAP Instead of OIDC (Not Recommended)
LDAP auth → ${GUAC_PASSWORD} available → RDP NLA works
Pros: Credential passthrough works
Cons: Loses SSO benefits, security regression
Solution 5: Custom Authentication Extension
Community Solution: guacamole-auth-header-password
# Example: Pass credentials via HTTP headers
http-username-header=OIDC_REMOTE_USER
http-password-header=OIDC_access_token # Not a real password
http-groups-header=OIDC_CLAIM_sdDesktopProjects
Note: This doesn't solve the password problem but shows extension architecture.
Solution 6: CAS with ClearPass (Alternative SSO)
Apache Guacamole 0.9.14+ includes CAS credential pass-through
using "ClearPass" which allows ${GUAC_USERNAME} and ${GUAC_PASSWORD}
tokens with SSO
Requires: CAS server instead of OIDC
Azure AD / Entra Joined Systems
Additional Complexity:
- Azure AD Joined (Entra-joined) systems may require web-based authentication
- Guacamole cannot pass through the web sign-in mechanism
- Hybrid joined (Azure AD + Domain joined) systems work better
From community reports:
"Hybrid joined systems with NLA enabled are working fine with Guacamole/RDP"
Recommended Approach for SSO + RDP NLA
Best Practice Architecture:
- Use OIDC for Guacamole authentication (SSO to Authentik)
- Configure RDP connections with one of:
- Option A: Dedicated service accounts (stored in connection config)
- Option B: Prompt users for RDP credentials (UX compromise)
- Option C: Disable NLA on internal trusted network segments only
- Implement connection-level access control via Authentik groups
- Enable audit logging to track connection access (even with shared accounts)
5. Authentik-Specific Configuration Notes
Authentik Provider Setup
Provider Type: OAuth2/OpenID Connect
Client Type: Confidential
Scopes: openid, email, profile
Critical Authentik Settings
-
Redirect URI:
https://remote.obr.sh/guacamole/api/auth/oidc/callback -
Token Validity:
Max 300 minutes (5 hours) - Guacamole limitation -
Signing Key:
authentik Self-signed Certificate
Username Claim Configuration
Two Options:
Option A: Use sub (Recommended)
OPENID_USERNAME_CLAIM_TYPE=sub
- Pros: Immutable, unique identifier
- Cons: Not human-readable (UUIDs)
- Important: Disable "Allow users to change username" in Authentik
Option B: Use preferred_username
OPENID_USERNAME_CLAIM_TYPE=preferred_username
- Pros: Human-readable usernames
- Cons: May change if user updates profile
- Requires: Custom property mapping in Authentik
Custom Property Mapping for Usernames
In Authentik: Create Scope Mapping to expose custom username attribute
# Example: Map custom field to preferred_username claim
{
"preferred_username": user.attributes.get("guacamole_username", user.username)
}
Pre-creating Admin User
Best Practice: Create admin user in Guacamole database before enabling OIDC
-- Insert user matching Authentik username
INSERT INTO guacamole_entity (name, type)
VALUES ('admin@example.com', 'USER');
-- Grant admin permissions
INSERT INTO guacamole_user_permission (entity_id, permission)
VALUES ((SELECT entity_id FROM guacamole_entity WHERE name='admin@example.com'), 'ADMINISTER');
6. Key Takeaways and Recommendations
Confirmed Capabilities
✓ OIDC authentication to Guacamole web interface works well with Authentik
✓ Username passthrough (${GUAC_USERNAME}) available with OIDC
✓ Custom JWT claims can be exposed as ${OIDC_*} parameters
✓ TOTP MFA can be layered on top of OIDC authentication
✓ Groups from Authentik can control connection access
Critical Limitations
✗ Password passthrough (${GUAC_PASSWORD}) does NOT work with OIDC
✗ RDP NLA requires passwords, creating incompatibility with OIDC SSO
✗ No per-connection SSO (OIDC only authenticates to Guacamole, not target systems)
✗ Duo MFA cannot be used with SSO (use TOTP instead)
Recommended Architecture
For Pangolin/Authentik/Guacamole Integration:
- Primary Authentication: OIDC to Authentik (SSO)
- MFA Strategy: MFA at Authentik level (TOTP/WebAuthn)
- RDP Authentication:
- Service accounts for automated access
- User prompting for per-user audit requirements
- NLA disabled on trusted internal segments (if acceptable)
- Database Extension: Required for connection storage and TOTP keys
- Group Mapping: Use
OPENID_GROUPS_CLAIM_TYPE=groupsto control access
Environment Variable Template for Pangolin
# Authentik OIDC Integration
OPENID_AUTHORIZATION_ENDPOINT=https://sso.obr.sh/application/o/authorize/
OPENID_JWKS_ENDPOINT=https://sso.obr.sh/application/o/guacamole/jwks/
OPENID_ISSUER=https://sso.obr.sh/application/o/guacamole/
OPENID_CLIENT_ID=<from_authentik_provider>
OPENID_REDIRECT_URI=https://remote.obr.sh/guacamole/api/auth/oidc/callback
# Claim Configuration
OPENID_USERNAME_CLAIM_TYPE=preferred_username
OPENID_GROUPS_CLAIM_TYPE=groups
OPENID_SCOPE=openid email profile
# Token Settings
OPENID_MAX_TOKEN_VALIDITY=300
OPENID_ALLOWED_CLOCK_SKEW=30
# Extension Loading
EXTENSION_PRIORITY=openid
OPENID_ENABLED=true
# Enable environment variables in guacamole.properties
enable-environment-properties: true
References
- Apache Guacamole Official Documentation: https://guacamole.apache.org/doc/gug/openid-auth.html
- Authentik Integration Guide: https://docs.goauthentik.io/integrations/services/apache-guacamole/
- Guacamole Mailing List Archives: https://www.mail-archive.com/user@guacamole.apache.org/
- FreeRDP NLA Limitations: Community reports on NTLM vs Kerberos support
- TOTP Extension Guide: https://guacamole.apache.org/doc/gug/totp-auth.html
Research Completed: 2026-01-20 Task: RESEARCH-003 Status: Complete