--- # Was a plain ConfigMap with client_secret hardcoded in plaintext - found # and fixed 2026-08-20. Same story as argocd-blueprint.yaml: the value # was already Vault's source of truth on the app side (secret/ # guacamole-oauth), this blueprint just had its own separate hardcoded # plaintext copy. apiVersion: external-secrets.io/v1 kind: ExternalSecret metadata: name: authentik-blueprints-guacamole namespace: authentik spec: refreshInterval: 1h secretStoreRef: kind: ClusterSecretStore name: vault-backend target: name: authentik-blueprints-guacamole creationPolicy: Owner template: metadata: labels: goauthentik.io/blueprint: "true" data: guacamole.yaml: |- version: 1 metadata: name: guacamole-oidc labels: blueprints.goauthentik.io/instantiate: "true" entries: # ============================================================================ # GUACAMOLE OAUTH2 PROVIDER # ============================================================================ # This creates the OAuth2 provider that Guacamole will use for authentication. # The client_id and client_secret must match what's configured in Guacamole. # ============================================================================ # ============================================================================ # GROUPS SCOPE MAPPING # ============================================================================ # Custom scope mapping that includes user's group names in the OIDC token. # ============================================================================ - model: authentik_providers_oauth2.scopemapping id: guacamole-groups-scope identifiers: managed: goauthentik.io/providers/oauth2/guacamole-groups attrs: name: "Guacamole Groups Scope" scope_name: groups expression: | return { "groups": [group.name for group in request.user.ak_groups.all()], } - model: authentik_providers_oauth2.oauth2provider id: guacamole-provider identifiers: name: guacamole attrs: name: Guacamole client_id: a55cbe3c6d2ae30c05c86385802ffcfd76a972c22c8d039f000281d4a149fd44 client_secret: "{{ .clientSecret }}" authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]] authentication_flow: !Find [authentik_flows.flow, [slug, default-authentication-flow]] invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]] redirect_uris: - url: "https://guacamole.kube.huskypup.net/" matching_mode: strict - url: "https://guacamole.kube.huskypup.net/guacamole/" matching_mode: strict property_mappings: - !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]] - !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]] - !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]] - !KeyOf guacamole-groups-scope client_type: confidential access_code_validity: "minutes=10" access_token_validity: "hours=1" refresh_token_validity: "days=30" signing_key: !Find [authentik_crypto.certificatekeypair, [name, "Lets Encrypt K8s Cert"]] # ============================================================================ # GUACAMOLE APPLICATION # ============================================================================ # This creates the application entry that users will see in Authentik. # ============================================================================ - model: authentik_core.application id: guacamole-application identifiers: slug: guacamole attrs: name: Guacamole slug: guacamole policy_engine_mode: any provider: !KeyOf guacamole-provider data: - secretKey: clientSecret remoteRef: key: guacamole-oauth property: client-secret