From 6dcd7e9367024381eedfe94119e8cf1c23127374 Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh <26975142+ZohebShaikh@users.noreply.github.com> Date: Fri, 28 Nov 2025 12:09:47 +0000 Subject: [PATCH 1/9] Update to use a startup script for keycloak-oidc --- example_configs/keycloak_oidc/compose.yaml | 8 +- .../keycloak_oidc/keycloak_config/startup.sh | 25 + .../keycloak_config/tiled-cli.json | 65 + .../keycloak_oidc/keycloak_config/tiled.json | 73 + .../keycloak_oidc/oauth2-alpha.yaml | 1 + .../keycloak_oidc/realm-export.json | 2694 ----------------- 6 files changed, 169 insertions(+), 2697 deletions(-) create mode 100644 example_configs/keycloak_oidc/keycloak_config/startup.sh create mode 100644 example_configs/keycloak_oidc/keycloak_config/tiled-cli.json create mode 100644 example_configs/keycloak_oidc/keycloak_config/tiled.json delete mode 100644 example_configs/keycloak_oidc/realm-export.json diff --git a/example_configs/keycloak_oidc/compose.yaml b/example_configs/keycloak_oidc/compose.yaml index bc1207020..ba4a3d789 100644 --- a/example_configs/keycloak_oidc/compose.yaml +++ b/example_configs/keycloak_oidc/compose.yaml @@ -9,9 +9,11 @@ services: - KC_BOOTSTRAP_ADMIN_USERNAME=admin - KC_HEALTH_ENABLED=true - KC_METRICS_ENABLED=true - command: ["start-dev", "--import-realm"] + command: ["start-dev"] volumes: - - ./realm-export.json:/opt/keycloak/data/import/realm-export.json + - ./keycloak_config/:/mnt + post_start: + - command: bash /mnt/startup.sh ports: - 8080:8080 - 9000:9000 @@ -24,7 +26,7 @@ services: oauth2-proxy: network_mode: host - image: "quay.io/oauth2-proxy/oauth2-proxy" + image: "quay.io/oauth2-proxy/oauth2-proxy:v7.13.0-amd64" volumes: - ./oauth2-proxy.cfg:/opt/oauth2-proxy.cfg - ./oauth2-alpha.yaml:/opt/oauth2-alpha.yaml diff --git a/example_configs/keycloak_oidc/keycloak_config/startup.sh b/example_configs/keycloak_oidc/keycloak_config/startup.sh new file mode 100644 index 000000000..dd8637eaa --- /dev/null +++ b/example_configs/keycloak_oidc/keycloak_config/startup.sh @@ -0,0 +1,25 @@ +#!/bin/bash +export PATH=$PATH:/opt/keycloak/bin + +sleep 2 +while ! kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin --password admin; do + sleep 1 +done + +# Add users to Keycloak +for user in alice bob carol oscar; do + kcadm.sh create users -r master -s username="$user" -s enabled=true + kcadm.sh set-password -r master --username "$user" --new-password "$user" +done + +allowed_protocol_mappers=$(kcadm.sh get components -q name="Allowed Protocol Mapper Types" --fields id --format csv --noquotes) + +for i in $allowed_protocol_mappers;do + kcadm.sh update components/$i -s 'config.allowed-protocol-mapper-types=[ "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-audience-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ]' +done + +kcreg.sh config credentials --server http://localhost:8080 --realm master --user admin --password admin + +for client in tiled-cli.json tiled.json; do + kcreg.sh create --file "/mnt/$client" +done diff --git a/example_configs/keycloak_oidc/keycloak_config/tiled-cli.json b/example_configs/keycloak_oidc/keycloak_config/tiled-cli.json new file mode 100644 index 000000000..2132f4ae4 --- /dev/null +++ b/example_configs/keycloak_oidc/keycloak_config/tiled-cli.json @@ -0,0 +1,65 @@ +{ + "id" : "194bca53-a569-4411-925e-217d8d6d21cf", + "clientId" : "tiled-cli", + "name" : "", + "description" : "Tiled client for Device flow login ", + "rootUrl" : "", + "adminUrl" : "", + "baseUrl" : "", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "defaultRoles" : [ ], + "redirectUris" : [ "/*" ], + "webOrigins" : [ "/*" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : true, + "frontchannelLogout" : true, + "protocol" : "openid-connect", + "attributes" : { + "standard.token.exchange.enabled" : "false", + "frontchannel.logout.session.required" : "true", + "post.logout.redirect.uris" : "+", + "oauth2.device.authorization.grant.enabled" : "true", + "backchannel.logout.revoke.offline.tokens" : "false", + "use.refresh.tokens" : "true", + "realm_client" : "false", + "oidc.ciba.grant.enabled" : "false", + "client.use.lightweight.access.token.enabled" : "false", + "backchannel.logout.session.required" : "true", + "client_credentials.use_refresh_token" : "false", + "tls.client.certificate.bound.access.tokens" : "false", + "require.pushed.authorization.requests" : "false", + "acr.loa.map" : "{}", + "display.on.consent.screen" : "false", + "token.response.type.bearer.lower-case" : "false" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : -1, + "protocolMappers" : [ { + "id" : "3a57ab6a-332e-4831-8583-820ae22cb830", + "name" : "tiled_aud", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "false", + "lightweight.claim" : "false", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "included.custom.audience" : "tiled_aud", + "userinfo.token.claim" : "false" + } + } + ], + "defaultClientScopes" : [ "web-origins", "acr", "offline_access", "roles", "profile", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "microprofile-jwt" ] +} diff --git a/example_configs/keycloak_oidc/keycloak_config/tiled.json b/example_configs/keycloak_oidc/keycloak_config/tiled.json new file mode 100644 index 000000000..b7ce77df7 --- /dev/null +++ b/example_configs/keycloak_oidc/keycloak_config/tiled.json @@ -0,0 +1,73 @@ +{ + "id" : "96265cb5-8046-4e06-9095-37ecf65d5bf6", + "clientId" : "tiled", + "name" : "Tiled", + "description" : "Standard flow client used for tiled authentication using oauth2-proxy", + "rootUrl" : "http://localhost:4180", + "adminUrl" : "http://localhost:4180", + "baseUrl" : "http://localhost:4180", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "secret" : "o8b7mIuYmzybNPVS8SSduhMdeqM8NDLp", + "defaultRoles" : [ ], + "redirectUris" : [ "http://localhost:4180/*" ], + "webOrigins" : [ "http://localhost:4180/*" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : true, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : false, + "publicClient" : false, + "frontchannelLogout" : true, + "protocol" : "openid-connect", + "attributes" : { + "client.secret.creation.time" : "1756805685", + "request.object.signature.alg" : "any", + "request.object.encryption.alg" : "any", + "client.introspection.response.allow.jwt.claim.enabled" : "false", + "standard.token.exchange.enabled" : "false", + "post.logout.redirect.uris" : "http://localhost:4180/*", + "frontchannel.logout.session.required" : "true", + "oauth2.device.authorization.grant.enabled" : "false", + "use.jwks.url" : "false", + "backchannel.logout.revoke.offline.tokens" : "false", + "use.refresh.tokens" : "true", + "realm_client" : "false", + "oidc.ciba.grant.enabled" : "false", + "client.use.lightweight.access.token.enabled" : "false", + "backchannel.logout.session.required" : "true", + "request.object.required" : "not required", + "client_credentials.use_refresh_token" : "false", + "access.token.header.type.rfc9068" : "false", + "tls.client.certificate.bound.access.tokens" : "false", + "require.pushed.authorization.requests" : "false", + "acr.loa.map" : "{}", + "display.on.consent.screen" : "false", + "request.object.encryption.enc" : "any", + "token.response.type.bearer.lower-case" : "false" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : -1, + "protocolMappers" : [ { + "id" : "af58bf06-d7d3-4046-80eb-f58d5ae35aca", + "name" : "tiled_aud", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-audience-mapper", + "consentRequired" : false, + "config" : { + "id.token.claim" : "false", + "lightweight.claim" : "false", + "introspection.token.claim" : "true", + "access.token.claim" : "true", + "included.custom.audience" : "tiled_aud", + "userinfo.token.claim" : "false" + } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "basic", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] +} diff --git a/example_configs/keycloak_oidc/oauth2-alpha.yaml b/example_configs/keycloak_oidc/oauth2-alpha.yaml index ba1840dac..b9f1a2796 100644 --- a/example_configs/keycloak_oidc/oauth2-alpha.yaml +++ b/example_configs/keycloak_oidc/oauth2-alpha.yaml @@ -13,6 +13,7 @@ providers: extraAudiences: ["tiled_aud"] emailClaim: sub insecureAllowUnverifiedEmail: true + insecureSkipNonce: true issuerURL: http://localhost:8080/realms/master server: BindAddress: localhost:4180 diff --git a/example_configs/keycloak_oidc/realm-export.json b/example_configs/keycloak_oidc/realm-export.json deleted file mode 100644 index 9136415c1..000000000 --- a/example_configs/keycloak_oidc/realm-export.json +++ /dev/null @@ -1,2694 +0,0 @@ -{ - "id": "6278a8cf-7257-46e9-a12c-8f30ffd8318a", - "realm": "master", - "displayName": "Keycloak", - "displayNameHtml": "
Keycloak
", - "notBefore": 0, - "defaultSignatureAlgorithm": "RS256", - "revokeRefreshToken": false, - "refreshTokenMaxReuse": 0, - "accessTokenLifespan": 60, - "accessTokenLifespanForImplicitFlow": 900, - "ssoSessionIdleTimeout": 1800, - "ssoSessionMaxLifespan": 36000, - "ssoSessionIdleTimeoutRememberMe": 0, - "ssoSessionMaxLifespanRememberMe": 0, - "offlineSessionIdleTimeout": 2592000, - "offlineSessionMaxLifespanEnabled": false, - "offlineSessionMaxLifespan": 5184000, - "clientSessionIdleTimeout": 0, - "clientSessionMaxLifespan": 0, - "clientOfflineSessionIdleTimeout": 0, - "clientOfflineSessionMaxLifespan": 0, - "accessCodeLifespan": 60, - "accessCodeLifespanUserAction": 300, - "accessCodeLifespanLogin": 1800, - "actionTokenGeneratedByAdminLifespan": 43200, - "actionTokenGeneratedByUserLifespan": 300, - "oauth2DeviceCodeLifespan": 600, - "oauth2DevicePollingInterval": 5, - "enabled": true, - "sslRequired": "external", - "registrationAllowed": false, - "registrationEmailAsUsername": false, - "rememberMe": false, - "verifyEmail": false, - "loginWithEmailAllowed": true, - "duplicateEmailsAllowed": false, - "resetPasswordAllowed": false, - "editUsernameAllowed": false, - "bruteForceProtected": false, - "permanentLockout": false, - "maxTemporaryLockouts": 0, - "bruteForceStrategy": "MULTIPLE", - "maxFailureWaitSeconds": 900, - "minimumQuickLoginWaitSeconds": 60, - "waitIncrementSeconds": 60, - "quickLoginCheckMilliSeconds": 1000, - "maxDeltaTimeSeconds": 43200, - "failureFactor": 30, - "roles": { - "realm": [ - { - "id": "d3df8c51-4a04-476b-80c8-a21114299cbd", - "name": "offline_access", - "description": "${role_offline-access}", - "composite": false, - "clientRole": false, - "containerId": "6278a8cf-7257-46e9-a12c-8f30ffd8318a", - "attributes": {} - }, - { - "id": "c6ab7502-68c3-4d67-9fcb-89ed5763e232", - "name": "uma_authorization", - "description": "${role_uma_authorization}", - "composite": false, - "clientRole": false, - "containerId": "6278a8cf-7257-46e9-a12c-8f30ffd8318a", - "attributes": {} - }, - { - "id": "6a4ec6b3-b261-49c5-9011-9bb4a71bb3dd", - "name": "admin", - "description": "${role_admin}", - "composite": true, - "composites": { - "realm": [ - "create-realm" - ], - "client": { - "master-realm": [ - "view-identity-providers", - "view-realm", - "view-clients", - "query-users", - "query-realms", - "create-client", - "manage-clients", - "query-clients", - "manage-authorization", - "manage-identity-providers", - "manage-events", - "manage-realm", - "query-groups", - "view-events", - "view-authorization", - "impersonation", - "view-users", - "manage-users" - ] - } - }, - "clientRole": false, - "containerId": "6278a8cf-7257-46e9-a12c-8f30ffd8318a", - "attributes": {} - }, - { - "id": "b89d1f5b-43e0-4ab1-bbd2-c5d888f88918", - "name": "default-roles-master", - "description": "${role_default-roles}", - "composite": true, - "composites": { - "realm": [ - "offline_access", - "uma_authorization" - ], - "client": { - "account": [ - "view-profile", - "manage-account" - ] - } - }, - "clientRole": false, - "containerId": "6278a8cf-7257-46e9-a12c-8f30ffd8318a", - "attributes": {} - }, - { - "id": "71af5829-ee0e-447a-8af8-b013cce4f910", - "name": "create-realm", - "description": "${role_create-realm}", - "composite": false, - "clientRole": false, - "containerId": "6278a8cf-7257-46e9-a12c-8f30ffd8318a", - "attributes": {} - } - ], - "client": { - "tiled": [], - "security-admin-console": [], - "tiled-cli": [], - "admin-cli": [], - "account-console": [], - "broker": [ - { - "id": "ca29c74a-8be2-4d54-89ab-561e47231e74", - "name": "read-token", - "description": "${role_read-token}", - "composite": false, - "clientRole": true, - "containerId": "75ab6c83-7302-4523-9460-e8bfd0bbebbf", - "attributes": {} - } - ], - "master-realm": [ - { - "id": "51b72dea-44e2-4f4f-bdff-ee70122faf3b", - "name": "view-identity-providers", - "description": "${role_view-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "a207974a-a87c-4a7a-9930-9c0cb04a132b", - "name": "view-realm", - "description": "${role_view-realm}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "69e12f75-d262-4ac8-8e55-669f202983a5", - "name": "query-users", - "description": "${role_query-users}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "5f9cbd8d-5b57-4362-a843-d57ebf2a2192", - "name": "view-clients", - "description": "${role_view-clients}", - "composite": true, - "composites": { - "client": { - "master-realm": [ - "query-clients" - ] - } - }, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "a34c5e31-8397-4ea4-864c-5e50b58607d5", - "name": "query-realms", - "description": "${role_query-realms}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "8eb99d43-9e7c-4415-b871-481cad44e7c1", - "name": "create-client", - "description": "${role_create-client}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "d10dbb9a-200f-45cd-92c0-b55fbb97be03", - "name": "manage-clients", - "description": "${role_manage-clients}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "7535bb22-5653-4e53-a0ee-4f411e816758", - "name": "query-clients", - "description": "${role_query-clients}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "7ca0a05a-cc02-41dd-a8a9-d1f486e01bc5", - "name": "manage-authorization", - "description": "${role_manage-authorization}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "b23483e1-f1b7-4626-96cd-a4088e6fbe5c", - "name": "manage-events", - "description": "${role_manage-events}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "65b0c925-c8d8-49a9-9119-6dc04dfbad7e", - "name": "manage-identity-providers", - "description": "${role_manage-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "ba5b4ac9-2b17-4d9f-8318-385ef1247e75", - "name": "manage-realm", - "description": "${role_manage-realm}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "f8b158bf-758f-4a66-8d0d-05b1641de5ed", - "name": "query-groups", - "description": "${role_query-groups}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "b37096cd-beb4-4ff7-b210-aef3de32144e", - "name": "impersonation", - "description": "${role_impersonation}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "b1e7485e-5f27-44b0-9584-7fb24ed9c051", - "name": "view-authorization", - "description": "${role_view-authorization}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "14e71462-939f-4e71-a1d6-2b1812f4801a", - "name": "view-events", - "description": "${role_view-events}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "1e5d778f-aa0c-46be-95e1-37a04ef8c781", - "name": "view-users", - "description": "${role_view-users}", - "composite": true, - "composites": { - "client": { - "master-realm": [ - "query-groups", - "query-users" - ] - } - }, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - }, - { - "id": "30af24b3-ad88-4b9e-b266-d2235e91760f", - "name": "manage-users", - "description": "${role_manage-users}", - "composite": false, - "clientRole": true, - "containerId": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "attributes": {} - } - ], - "account": [ - { - "id": "6986892a-019b-4fbd-94f5-443c0230afa6", - "name": "manage-account-links", - "description": "${role_manage-account-links}", - "composite": false, - "clientRole": true, - "containerId": "f0ced306-efcb-480a-9c81-7d6c83227c06", - "attributes": {} - }, - { - "id": "d159fedb-6df0-4b21-aef4-01f667eb664b", - "name": "view-profile", - "description": "${role_view-profile}", - "composite": false, - "clientRole": true, - "containerId": "f0ced306-efcb-480a-9c81-7d6c83227c06", - "attributes": {} - }, - { - "id": "e8f2b892-7641-4146-81bc-aaef3966fd46", - "name": "view-groups", - "description": "${role_view-groups}", - "composite": false, - "clientRole": true, - "containerId": "f0ced306-efcb-480a-9c81-7d6c83227c06", - "attributes": {} - }, - { - "id": "f479fd08-3b0a-48c8-8308-3bbdc6b22370", - "name": "manage-consent", - "description": "${role_manage-consent}", - "composite": true, - "composites": { - "client": { - "account": [ - "view-consent" - ] - } - }, - "clientRole": true, - "containerId": "f0ced306-efcb-480a-9c81-7d6c83227c06", - "attributes": {} - }, - { - "id": "6c1b81f9-5d28-48c7-aaf1-5e53d5d6851f", - "name": "view-consent", - "description": "${role_view-consent}", - "composite": false, - "clientRole": true, - "containerId": "f0ced306-efcb-480a-9c81-7d6c83227c06", - "attributes": {} - }, - { - "id": "74884ad7-2f16-4d1b-9a77-9a0670ca8e40", - "name": "delete-account", - "description": "${role_delete-account}", - "composite": false, - "clientRole": true, - "containerId": "f0ced306-efcb-480a-9c81-7d6c83227c06", - "attributes": {} - }, - { - "id": "06398c01-5e31-4565-a92c-0516582a5923", - "name": "manage-account", - "description": "${role_manage-account}", - "composite": true, - "composites": { - "client": { - "account": [ - "manage-account-links" - ] - } - }, - "clientRole": true, - "containerId": "f0ced306-efcb-480a-9c81-7d6c83227c06", - "attributes": {} - }, - { - "id": "33199cb2-f8fd-4403-a5f6-5ed03c3155ea", - "name": "view-applications", - "description": "${role_view-applications}", - "composite": false, - "clientRole": true, - "containerId": "f0ced306-efcb-480a-9c81-7d6c83227c06", - "attributes": {} - } - ] - } - }, - "groups": [], - "defaultRole": { - "id": "b89d1f5b-43e0-4ab1-bbd2-c5d888f88918", - "name": "default-roles-master", - "description": "${role_default-roles}", - "composite": true, - "clientRole": false, - "containerId": "6278a8cf-7257-46e9-a12c-8f30ffd8318a" - }, - "requiredCredentials": [ - "password" - ], - "otpPolicyType": "totp", - "otpPolicyAlgorithm": "HmacSHA1", - "otpPolicyInitialCounter": 0, - "otpPolicyDigits": 6, - "otpPolicyLookAheadWindow": 1, - "otpPolicyPeriod": 30, - "otpPolicyCodeReusable": false, - "otpSupportedApplications": [ - "totpAppFreeOTPName", - "totpAppGoogleName", - "totpAppMicrosoftAuthenticatorName" - ], - "localizationTexts": {}, - "webAuthnPolicyRpEntityName": "keycloak", - "webAuthnPolicySignatureAlgorithms": [ - "ES256", - "RS256" - ], - "webAuthnPolicyRpId": "", - "webAuthnPolicyAttestationConveyancePreference": "not specified", - "webAuthnPolicyAuthenticatorAttachment": "not specified", - "webAuthnPolicyRequireResidentKey": "not specified", - "webAuthnPolicyUserVerificationRequirement": "not specified", - "webAuthnPolicyCreateTimeout": 0, - "webAuthnPolicyAvoidSameAuthenticatorRegister": false, - "webAuthnPolicyAcceptableAaguids": [], - "webAuthnPolicyExtraOrigins": [], - "webAuthnPolicyPasswordlessRpEntityName": "keycloak", - "webAuthnPolicyPasswordlessSignatureAlgorithms": [ - "ES256", - "RS256" - ], - "webAuthnPolicyPasswordlessRpId": "", - "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", - "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", - "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", - "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", - "webAuthnPolicyPasswordlessCreateTimeout": 0, - "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, - "webAuthnPolicyPasswordlessAcceptableAaguids": [], - "webAuthnPolicyPasswordlessExtraOrigins": [], - "scopeMappings": [ - { - "clientScope": "offline_access", - "roles": [ - "offline_access" - ] - } - ], - "clientScopeMappings": { - "account": [ - { - "client": "account-console", - "roles": [ - "manage-account", - "view-groups" - ] - } - ] - }, - "clients": [ - { - "id": "f0ced306-efcb-480a-9c81-7d6c83227c06", - "clientId": "account", - "name": "${client_account}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/master/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "/realms/master/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "realm_client": "false", - "post.logout.redirect.uris": "+" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "basic", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "organization", - "microprofile-jwt" - ] - }, - { - "id": "50e64d69-434d-43b7-b37d-1679578c1cb0", - "clientId": "account-console", - "name": "${client_account-console}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/master/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "/realms/master/account/*" - ], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "realm_client": "false", - "post.logout.redirect.uris": "+", - "pkce.code.challenge.method": "S256" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - "id": "272c57c8-151d-44fb-abac-5966705b7b74", - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": {} - } - ], - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "basic", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "organization", - "microprofile-jwt" - ] - }, - { - "id": "edf1f045-fa15-4cf6-879d-03fc54ee613b", - "clientId": "admin-cli", - "name": "${client_admin-cli}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": false, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "realm_client": "false", - "client.use.lightweight.access.token.enabled": "true", - "post.logout.redirect.uris": "+" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "basic", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "organization", - "microprofile-jwt" - ] - }, - { - "id": "75ab6c83-7302-4523-9460-e8bfd0bbebbf", - "clientId": "broker", - "name": "${client_broker}", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": true, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "realm_client": "true", - "post.logout.redirect.uris": "+" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "basic", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "organization", - "microprofile-jwt" - ] - }, - { - "id": "1cf34671-a09a-4797-b668-fa115c7a6b44", - "clientId": "master-realm", - "name": "master Realm", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [], - "webOrigins": [], - "notBefore": 0, - "bearerOnly": true, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "realm_client": "true", - "post.logout.redirect.uris": "+" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": false, - "nodeReRegistrationTimeout": 0, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "basic", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "organization", - "microprofile-jwt" - ] - }, - { - "id": "60eb52b3-59bf-48ee-b9c4-df2d32057125", - "clientId": "security-admin-console", - "name": "${client_security-admin-console}", - "rootUrl": "${authAdminUrl}", - "baseUrl": "/admin/master/console/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "/admin/master/console/*" - ], - "webOrigins": [ - "+" - ], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": false, - "protocol": "openid-connect", - "attributes": { - "realm_client": "false", - "client.use.lightweight.access.token.enabled": "true", - "post.logout.redirect.uris": "+", - "pkce.code.challenge.method": "S256" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": 0, - "protocolMappers": [ - { - "id": "d0cbd944-76dd-48ca-af3a-87d344150740", - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "basic", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "organization", - "microprofile-jwt" - ] - }, - { - "id": "96265cb5-8046-4e06-9095-37ecf65d5bf6", - "clientId": "tiled", - "name": "Tiled", - "description": "Standard flow client used for tiled authentication using oauth2-proxy", - "rootUrl": "http://localhost:4180", - "adminUrl": "http://localhost:4180", - "baseUrl": "http://localhost:4180", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "secret": "o8b7mIuYmzybNPVS8SSduhMdeqM8NDLp", - "redirectUris": [ - "http://localhost:4180/*" - ], - "webOrigins": [ - "http://localhost:4180/*" - ], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": true, - "protocol": "openid-connect", - "attributes": { - "client.secret.creation.time": "1756805685", - "request.object.signature.alg": "any", - "request.object.encryption.alg": "any", - "client.introspection.response.allow.jwt.claim.enabled": "false", - "standard.token.exchange.enabled": "false", - "post.logout.redirect.uris": "http://localhost:4180/*", - "frontchannel.logout.session.required": "true", - "oauth2.device.authorization.grant.enabled": "false", - "use.jwks.url": "false", - "backchannel.logout.revoke.offline.tokens": "false", - "use.refresh.tokens": "true", - "realm_client": "false", - "oidc.ciba.grant.enabled": "false", - "client.use.lightweight.access.token.enabled": "false", - "backchannel.logout.session.required": "true", - "request.object.required": "not required", - "client_credentials.use_refresh_token": "false", - "access.token.header.type.rfc9068": "false", - "tls.client.certificate.bound.access.tokens": "false", - "require.pushed.authorization.requests": "false", - "acr.loa.map": "{}", - "display.on.consent.screen": "false", - "request.object.encryption.enc": "any", - "token.response.type.bearer.lower-case": "false" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "protocolMappers": [ - { - "id": "72c90cf1-f71c-434c-bf8b-6135bc5e0f81", - "name": "email", - "protocol": "cas", - "protocolMapper": "cas-usermodel-property-mapper", - "consentRequired": false, - "config": { - "claim.name": "mail", - "user.attribute": "email", - "jsonType.label": "String" - } - }, - { - "id": "31d9504c-c1e2-4c12-bba5-abea888500e5", - "name": "full name", - "protocol": "cas", - "protocolMapper": "cas-full-name-mapper", - "consentRequired": false, - "config": { - "claim.name": "cn", - "jsonType.label": "String" - } - }, - { - "id": "ed4bb39b-8a8b-4e67-bcdc-6e1f2bbbc10f", - "name": "given name", - "protocol": "cas", - "protocolMapper": "cas-usermodel-property-mapper", - "consentRequired": false, - "config": { - "claim.name": "givenName", - "user.attribute": "firstName", - "jsonType.label": "String" - } - }, - { - "id": "bf2af61b-7c02-4a8e-9217-e89e113e6541", - "name": "tiled", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "false", - "lightweight.claim": "false", - "introspection.token.claim": "true", - "access.token.claim": "true", - "included.custom.audience": "tiled_aud", - "userinfo.token.claim": "false" - } - }, - { - "id": "092ef6ba-cd44-4391-a365-3a28e1287f9c", - "name": "family name", - "protocol": "cas", - "protocolMapper": "cas-usermodel-property-mapper", - "consentRequired": false, - "config": { - "claim.name": "sn", - "user.attribute": "lastName", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "acr", - "read:metadata", - "roles", - "profile", - "basic", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - }, - { - "id": "194bca53-a569-4411-925e-217d8d6d21cf", - "clientId": "tiled-cli", - "name": "", - "description": "Tiled client for Device flow login ", - "rootUrl": "", - "adminUrl": "", - "baseUrl": "", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "/*" - ], - "webOrigins": [ - "/*" - ], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": false, - "implicitFlowEnabled": false, - "directAccessGrantsEnabled": false, - "serviceAccountsEnabled": false, - "publicClient": true, - "frontchannelLogout": true, - "protocol": "openid-connect", - "attributes": { - "standard.token.exchange.enabled": "false", - "frontchannel.logout.session.required": "true", - "oauth2.device.authorization.grant.enabled": "true", - "backchannel.logout.revoke.offline.tokens": "false", - "use.refresh.tokens": "true", - "realm_client": "false", - "oidc.ciba.grant.enabled": "false", - "client.use.lightweight.access.token.enabled": "false", - "backchannel.logout.session.required": "true", - "client_credentials.use_refresh_token": "false", - "tls.client.certificate.bound.access.tokens": "false", - "require.pushed.authorization.requests": "false", - "acr.loa.map": "{}", - "display.on.consent.screen": "false", - "token.response.type.bearer.lower-case": "false" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "protocolMappers": [ - { - "id": "3a57ab6a-332e-4831-8583-820ae22cb830", - "name": "tiled_aud", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "false", - "lightweight.claim": "false", - "access.token.claim": "true", - "introspection.token.claim": "true" - } - }, - { - "id": "4a3f3517-a0b2-4cf8-ab3e-8855ffa3af90", - "name": "family name", - "protocol": "cas", - "protocolMapper": "cas-usermodel-property-mapper", - "consentRequired": false, - "config": { - "claim.name": "sn", - "user.attribute": "lastName", - "jsonType.label": "String" - } - }, - { - "id": "c201d7bd-bb10-430b-b08c-044e2d4f35e7", - "name": "given name", - "protocol": "cas", - "protocolMapper": "cas-usermodel-property-mapper", - "consentRequired": false, - "config": { - "claim.name": "givenName", - "user.attribute": "firstName", - "jsonType.label": "String" - } - }, - { - "id": "f39feb3d-9da7-4658-a527-2ab9c5d24762", - "name": "full name", - "protocol": "cas", - "protocolMapper": "cas-full-name-mapper", - "consentRequired": false, - "config": { - "claim.name": "cn", - "jsonType.label": "String" - } - }, - { - "id": "022b6c9a-6f70-4d4d-abfb-1bbb593d1fdd", - "name": "email", - "protocol": "cas", - "protocolMapper": "cas-usermodel-property-mapper", - "consentRequired": false, - "config": { - "claim.name": "mail", - "user.attribute": "email", - "jsonType.label": "String" - } - } - ], - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "basic", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "read:metadata", - "offline_access", - "microprofile-jwt" - ] - } - ], - "clientScopes": [ - { - "id": "90bbd137-0809-4703-9d42-200229b11e0e", - "name": "offline_access", - "description": "OpenID Connect built-in scope: offline_access", - "protocol": "openid-connect", - "attributes": { - "consent.screen.text": "${offlineAccessScopeConsentText}", - "display.on.consent.screen": "true" - } - }, - { - "id": "737da562-613b-4620-8340-4e5de5e8df25", - "name": "address", - "description": "OpenID Connect built-in scope: address", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "consent.screen.text": "${addressScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "9c0cc611-d9b0-4453-b450-474f0e835010", - "name": "address", - "protocol": "openid-connect", - "protocolMapper": "oidc-address-mapper", - "consentRequired": false, - "config": { - "user.attribute.formatted": "formatted", - "user.attribute.country": "country", - "introspection.token.claim": "true", - "user.attribute.postal_code": "postal_code", - "userinfo.token.claim": "true", - "user.attribute.street": "street", - "id.token.claim": "true", - "user.attribute.region": "region", - "access.token.claim": "true", - "user.attribute.locality": "locality" - } - } - ] - }, - { - "id": "22eecf2d-9969-4a1c-845b-9057069d6e25", - "name": "service_account", - "description": "Specific scope for a client enabled for service accounts", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - "id": "7ce370c7-daa4-44a2-83db-819d564c053f", - "name": "Client ID", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "client_id", - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "client_id", - "jsonType.label": "String" - } - }, - { - "id": "f0777bd8-f718-4fbb-9cfa-fe7e7e6d4628", - "name": "Client IP Address", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientAddress", - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientAddress", - "jsonType.label": "String" - } - }, - { - "id": "3f69d16b-bb19-4ce9-b6ab-9d5d78f41b7c", - "name": "Client Host", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "clientHost", - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "clientHost", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "6c4942a0-b6b2-463d-af07-112460cfabfd", - "name": "email", - "description": "OpenID Connect built-in scope: email", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "consent.screen.text": "${emailScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "c7bb16bf-1547-4a55-841d-0d725581abba", - "name": "email", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "email", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email", - "jsonType.label": "String" - } - }, - { - "id": "1c1e76ae-074d-45ab-b697-e255ab1aaa77", - "name": "email verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-property-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "emailVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "email_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - "id": "e5500e08-4b0c-47ae-b115-c70efb062a90", - "name": "saml_organization", - "description": "Organization Membership", - "protocol": "saml", - "attributes": { - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - "id": "ecc22c36-1ea5-4531-8d6b-42becb089012", - "name": "organization", - "protocol": "saml", - "protocolMapper": "saml-organization-membership-mapper", - "consentRequired": false, - "config": {} - } - ] - }, - { - "id": "d4e46adb-ff2c-4df9-9155-3e6712953c8a", - "name": "organization", - "description": "Additional claims about the organization a subject belongs to", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "consent.screen.text": "${organizationScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "ca1aefac-1ced-45cd-bb64-0bf2d41b74f5", - "name": "organization", - "protocol": "openid-connect", - "protocolMapper": "oidc-organization-membership-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "multivalued": "true", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "organization", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "99edc589-3832-4293-a135-5e66de7e6865", - "name": "profile", - "description": "OpenID Connect built-in scope: profile", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "consent.screen.text": "${profileScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "867335c2-3919-41b3-8d35-826ed3284428", - "name": "zoneinfo", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "zoneinfo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "zoneinfo", - "jsonType.label": "String" - } - }, - { - "id": "bdc89abb-2c25-4cb8-8885-e82cbe18a28d", - "name": "birthdate", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "birthdate", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "birthdate", - "jsonType.label": "String" - } - }, - { - "id": "5444d279-061d-446f-8778-1e6248f2111d", - "name": "website", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "website", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "website", - "jsonType.label": "String" - } - }, - { - "id": "c3aa5b11-287b-4334-ade4-3b6dadab1530", - "name": "picture", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "picture", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "picture", - "jsonType.label": "String" - } - }, - { - "id": "ba288d13-9d60-44f0-b08a-b36dfdc2f054", - "name": "username", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "preferred_username", - "jsonType.label": "String" - } - }, - { - "id": "5b0b28e5-6971-4cfd-9f2d-bd8c60800802", - "name": "profile", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "profile", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "profile", - "jsonType.label": "String" - } - }, - { - "id": "057fe855-e19e-487b-8601-a888aa11e837", - "name": "middle name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "middleName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "middle_name", - "jsonType.label": "String" - } - }, - { - "id": "422328c3-c4ef-4539-bb6e-c45905640967", - "name": "nickname", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "nickname", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "nickname", - "jsonType.label": "String" - } - }, - { - "id": "d4775fd5-3e64-43a3-a293-3136b3deb049", - "name": "updated at", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "updatedAt", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "updated_at", - "jsonType.label": "long" - } - }, - { - "id": "12a70184-0b33-479f-9752-9db5da2fc73f", - "name": "gender", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "gender", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "gender", - "jsonType.label": "String" - } - }, - { - "id": "47f88de5-6f5c-4291-a552-619a78502349", - "name": "given name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "firstName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "given_name", - "jsonType.label": "String" - } - }, - { - "id": "c299c787-15d3-4d68-b660-9e4d166cedb8", - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "true", - "introspection.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" - } - }, - { - "id": "74d72e51-e0e1-4481-8ee8-2a84ae3c3215", - "name": "locale", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "locale", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "locale", - "jsonType.label": "String" - } - }, - { - "id": "4b02529b-a43a-4ab4-9a2a-785aec79e703", - "name": "family name", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "lastName", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "family_name", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "74389689-75c7-43a2-813a-6fbfb5ef5488", - "name": "phone", - "description": "OpenID Connect built-in scope: phone", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "consent.screen.text": "${phoneScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "cf49f43f-8ba8-4633-9f2c-22ba27ac020f", - "name": "phone number", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "phoneNumber", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number", - "jsonType.label": "String" - } - }, - { - "id": "1846cc22-0c62-48a1-8117-d08a3e4a2418", - "name": "phone number verified", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "phoneNumberVerified", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "phone_number_verified", - "jsonType.label": "boolean" - } - } - ] - }, - { - "id": "2e3f6da4-daed-417a-9426-51d0a0400598", - "name": "web-origins", - "description": "OpenID Connect scope for add allowed web origins to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "consent.screen.text": "", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - "id": "c7e89e0b-dc40-4ada-b174-365878904481", - "name": "allowed web origins", - "protocol": "openid-connect", - "protocolMapper": "oidc-allowed-origins-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "access.token.claim": "true" - } - } - ] - }, - { - "id": "6763c283-05b4-4495-b467-2f7c094b50e5", - "name": "role_list", - "description": "SAML role list", - "protocol": "saml", - "attributes": { - "consent.screen.text": "${samlRoleListScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "ad5ac3c4-a2f2-4625-a15c-e9b55f4ad202", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - } - ] - }, - { - "id": "9bcd3ca6-6663-4fb9-a76a-b996a0ce15c1", - "name": "acr", - "description": "OpenID Connect scope for add acr (authentication context class reference) to the token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - "id": "9e24b9f2-157f-4725-a6aa-dca1b2b0e5bf", - "name": "acr loa level", - "protocol": "openid-connect", - "protocolMapper": "oidc-acr-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "true", - "introspection.token.claim": "true", - "access.token.claim": "true", - "userinfo.token.claim": "true" - } - } - ] - }, - { - "id": "79798be6-8c60-4d26-beeb-56e8fdedabfe", - "name": "roles", - "description": "OpenID Connect scope for add user roles to the access token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "consent.screen.text": "${rolesScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "c2fcc9fa-312f-4cb3-b74d-d3f49ab0b692", - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "access.token.claim": "true" - } - }, - { - "id": "d950ad5b-3c70-4bec-b79c-4cc637d2c096", - "name": "realm roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "introspection.token.claim": "true", - "access.token.claim": "true", - "claim.name": "realm_access.roles", - "jsonType.label": "String", - "multivalued": "true" - } - }, - { - "id": "4d9f40ce-b711-4e13-a76b-f4708f9a6117", - "name": "client roles", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-client-role-mapper", - "consentRequired": false, - "config": { - "user.attribute": "foo", - "introspection.token.claim": "true", - "access.token.claim": "true", - "claim.name": "resource_access.${client_id}.roles", - "jsonType.label": "String", - "multivalued": "true" - } - } - ] - }, - { - "id": "22ee0979-063e-4ea6-8b7f-329b955b046e", - "name": "microprofile-jwt", - "description": "Microprofile - JWT built-in scope", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - "id": "8cdc0cac-c612-4ce7-a6d3-229558af7624", - "name": "upn", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-attribute-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "user.attribute": "username", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "upn", - "jsonType.label": "String" - } - }, - { - "id": "6bd925ba-57e1-4b83-9c30-03c7d390cf32", - "name": "groups", - "protocol": "openid-connect", - "protocolMapper": "oidc-usermodel-realm-role-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "multivalued": "true", - "userinfo.token.claim": "true", - "user.attribute": "foo", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "groups", - "jsonType.label": "String" - } - } - ] - }, - { - "id": "283a37d2-8682-4458-a266-73aacef4f167", - "name": "read:metadata", - "description": "", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "true", - "display.on.consent.screen": "true", - "gui.order": "", - "consent.screen.text": "" - } - }, - { - "id": "3daa4f68-97a7-456b-92cd-7becc153e990", - "name": "basic", - "description": "OpenID Connect scope for add all basic claims to the token", - "protocol": "openid-connect", - "attributes": { - "include.in.token.scope": "false", - "display.on.consent.screen": "false" - }, - "protocolMappers": [ - { - "id": "7e3a2c2b-df17-4349-a2d9-5c88728c8c08", - "name": "auth_time", - "protocol": "openid-connect", - "protocolMapper": "oidc-usersessionmodel-note-mapper", - "consentRequired": false, - "config": { - "user.session.note": "AUTH_TIME", - "introspection.token.claim": "true", - "userinfo.token.claim": "true", - "id.token.claim": "true", - "access.token.claim": "true", - "claim.name": "auth_time", - "jsonType.label": "long" - } - }, - { - "id": "931ac6bf-91a1-4abc-834f-7ca1b6ea6651", - "name": "sub", - "protocol": "openid-connect", - "protocolMapper": "oidc-sub-mapper", - "consentRequired": false, - "config": { - "introspection.token.claim": "true", - "access.token.claim": "true" - } - } - ] - } - ], - "defaultDefaultClientScopes": [ - "role_list", - "saml_organization", - "profile", - "email", - "roles", - "web-origins", - "acr", - "basic" - ], - "defaultOptionalClientScopes": [ - "offline_access", - "address", - "phone", - "microprofile-jwt", - "organization" - ], - "browserSecurityHeaders": { - "contentSecurityPolicyReportOnly": "", - "xContentTypeOptions": "nosniff", - "referrerPolicy": "no-referrer", - "xRobotsTag": "none", - "xFrameOptions": "SAMEORIGIN", - "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", - "strictTransportSecurity": "max-age=31536000; includeSubDomains" - }, - "smtpServer": {}, - "eventsEnabled": false, - "eventsListeners": [ - "jboss-logging" - ], - "enabledEventTypes": [], - "adminEventsEnabled": false, - "adminEventsDetailsEnabled": false, - "identityProviders": [], - "identityProviderMappers": [], - "components": { - "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ - { - "id": "70bf01b0-aade-4519-9e11-8cc4e55089db", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-usermodel-property-mapper", - "oidc-address-mapper", - "saml-user-attribute-mapper", - "oidc-full-name-mapper", - "saml-user-property-mapper", - "saml-role-list-mapper", - "oidc-sha256-pairwise-sub-mapper", - "oidc-usermodel-attribute-mapper" - ] - } - }, - { - "id": "5f1f50be-9f90-4c59-9694-a2f2c97b5667", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-sha256-pairwise-sub-mapper", - "oidc-usermodel-attribute-mapper", - "saml-user-attribute-mapper", - "oidc-address-mapper", - "oidc-usermodel-property-mapper", - "saml-user-property-mapper", - "oidc-full-name-mapper", - "saml-role-list-mapper" - ] - } - }, - { - "id": "39dae9f4-4eae-461f-b834-368e9f685b28", - "name": "Trusted Hosts", - "providerId": "trusted-hosts", - "subType": "anonymous", - "subComponents": {}, - "config": { - "host-sending-registration-request-must-match": [ - "true" - ], - "client-uris-must-match": [ - "true" - ] - } - }, - { - "id": "53f4ae4d-b266-41fd-9123-53daccdd1268", - "name": "Consent Required", - "providerId": "consent-required", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, - { - "id": "5c91d2df-33b6-4de7-a38a-9ff7fcc61c6d", - "name": "Max Clients Limit", - "providerId": "max-clients", - "subType": "anonymous", - "subComponents": {}, - "config": { - "max-clients": [ - "200" - ] - } - }, - { - "id": "243301cd-2c46-47b8-ad26-8013e80240d6", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "25691816-5454-41d3-832a-4f1a3fa3a279", - "name": "Full Scope Disabled", - "providerId": "scope", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, - { - "id": "e80333e8-b3cc-40af-b4ad-64688f5d89f4", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - } - ], - "org.keycloak.userprofile.UserProfileProvider": [ - { - "id": "5dfc1ba0-1d29-4410-96cd-40485c3d767a", - "providerId": "declarative-user-profile", - "subComponents": {}, - "config": { - "kc.user.profile.config": [ - "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}]}" - ] - } - } - ], - "org.keycloak.keys.KeyProvider": [ - { - "id": "82042f16-e7bc-4728-8cd4-e2c9340c23b7", - "name": "hmac-generated-hs512", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS512" - ] - } - }, - { - "id": "4a0572b6-aa08-42d0-9f79-d1a6eac9e29d", - "name": "rsa-enc-generated", - "providerId": "rsa-enc-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "RSA-OAEP" - ] - } - }, - { - "id": "6d2166e8-76ce-4785-8052-4ad1aa2d0830", - "name": "aes-generated", - "providerId": "aes-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "5ba5816b-821b-46b1-8b38-0863aa4c00ce", - "name": "rsa-generated", - "providerId": "rsa-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - } - ] - }, - "internationalizationEnabled": false, - "authenticationFlows": [ - { - "id": "9fb31182-0ea7-400e-b2d7-a1ba7009b443", - "alias": "Account verification options", - "description": "Method with which to verity the existing account", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-email-verification", - "authenticatorFlow": false, - "requirement": "ALTERNATIVE", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticatorFlow": true, - "requirement": "ALTERNATIVE", - "priority": 20, - "autheticatorFlow": true, - "flowAlias": "Verify Existing Account by Re-authentication", - "userSetupAllowed": false - } - ] - }, - { - "id": "4165dae9-0a90-49e2-887d-a7014a0549d2", - "alias": "Browser - Conditional 2FA", - "description": "Flow to determine if any 2FA is required for the authentication", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "auth-otp-form", - "authenticatorFlow": false, - "requirement": "ALTERNATIVE", - "priority": 20, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "webauthn-authenticator", - "authenticatorFlow": false, - "requirement": "DISABLED", - "priority": 30, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "auth-recovery-authn-code-form", - "authenticatorFlow": false, - "requirement": "DISABLED", - "priority": 40, - "autheticatorFlow": false, - "userSetupAllowed": false - } - ] - }, - { - "id": "1c371709-f249-4b70-bc3c-2eca07d58cdd", - "alias": "Direct Grant - Conditional OTP", - "description": "Flow to determine if the OTP is required for the authentication", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "direct-grant-validate-otp", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 20, - "autheticatorFlow": false, - "userSetupAllowed": false - } - ] - }, - { - "id": "ec24fa2c-e0e2-4d8d-963e-302c195337e6", - "alias": "First broker login - Conditional 2FA", - "description": "Flow to determine if any 2FA is required for the authentication", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "auth-otp-form", - "authenticatorFlow": false, - "requirement": "ALTERNATIVE", - "priority": 20, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "webauthn-authenticator", - "authenticatorFlow": false, - "requirement": "DISABLED", - "priority": 30, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "auth-recovery-authn-code-form", - "authenticatorFlow": false, - "requirement": "DISABLED", - "priority": 40, - "autheticatorFlow": false, - "userSetupAllowed": false - } - ] - }, - { - "id": "ace965c6-cb60-4482-be4c-a43f95c414b0", - "alias": "Handle Existing Account", - "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-confirm-link", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticatorFlow": true, - "requirement": "REQUIRED", - "priority": 20, - "autheticatorFlow": true, - "flowAlias": "Account verification options", - "userSetupAllowed": false - } - ] - }, - { - "id": "70cd5853-5bc5-401a-ba6c-e10c40126f99", - "alias": "Reset - Conditional OTP", - "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "conditional-user-configured", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "reset-otp", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 20, - "autheticatorFlow": false, - "userSetupAllowed": false - } - ] - }, - { - "id": "cad7f273-cfc1-40fe-aa4e-b069c4f1916f", - "alias": "User creation or linking", - "description": "Flow for the existing/non-existing user alternatives", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "create unique user config", - "authenticator": "idp-create-user-if-unique", - "authenticatorFlow": false, - "requirement": "ALTERNATIVE", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticatorFlow": true, - "requirement": "ALTERNATIVE", - "priority": 20, - "autheticatorFlow": true, - "flowAlias": "Handle Existing Account", - "userSetupAllowed": false - } - ] - }, - { - "id": "16caeaff-e0ab-43cf-8384-fbec58c7096f", - "alias": "Verify Existing Account by Re-authentication", - "description": "Reauthentication of existing account", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "idp-username-password-form", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticatorFlow": true, - "requirement": "CONDITIONAL", - "priority": 20, - "autheticatorFlow": true, - "flowAlias": "First broker login - Conditional 2FA", - "userSetupAllowed": false - } - ] - }, - { - "id": "4c780115-35a4-412c-977b-15d87bbe824d", - "alias": "browser", - "description": "Browser based authentication", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-cookie", - "authenticatorFlow": false, - "requirement": "ALTERNATIVE", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "auth-spnego", - "authenticatorFlow": false, - "requirement": "DISABLED", - "priority": 20, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "identity-provider-redirector", - "authenticatorFlow": false, - "requirement": "ALTERNATIVE", - "priority": 25, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticatorFlow": true, - "requirement": "ALTERNATIVE", - "priority": 30, - "autheticatorFlow": true, - "flowAlias": "forms", - "userSetupAllowed": false - } - ] - }, - { - "id": "91ab8faf-893d-4d6a-9cb6-465e481b51df", - "alias": "clients", - "description": "Base authentication for clients", - "providerId": "client-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "client-secret", - "authenticatorFlow": false, - "requirement": "ALTERNATIVE", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "client-jwt", - "authenticatorFlow": false, - "requirement": "ALTERNATIVE", - "priority": 20, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "client-secret-jwt", - "authenticatorFlow": false, - "requirement": "ALTERNATIVE", - "priority": 30, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "client-x509", - "authenticatorFlow": false, - "requirement": "ALTERNATIVE", - "priority": 40, - "autheticatorFlow": false, - "userSetupAllowed": false - } - ] - }, - { - "id": "bd4c2d5d-a3c7-4188-8c2a-455799d4e727", - "alias": "direct grant", - "description": "OpenID Connect Resource Owner Grant", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "direct-grant-validate-username", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "direct-grant-validate-password", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 20, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticatorFlow": true, - "requirement": "CONDITIONAL", - "priority": 30, - "autheticatorFlow": true, - "flowAlias": "Direct Grant - Conditional OTP", - "userSetupAllowed": false - } - ] - }, - { - "id": "f5d07caa-8c28-48cd-a638-58fefcbd79dc", - "alias": "docker auth", - "description": "Used by Docker clients to authenticate against the IDP", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "docker-http-basic-authenticator", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - } - ] - }, - { - "id": "4d5cd782-25a2-4b2f-bc04-cb298e0d6399", - "alias": "first broker login", - "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticatorConfig": "review profile config", - "authenticator": "idp-review-profile", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticatorFlow": true, - "requirement": "REQUIRED", - "priority": 20, - "autheticatorFlow": true, - "flowAlias": "User creation or linking", - "userSetupAllowed": false - } - ] - }, - { - "id": "2f5bdcdb-ee4f-4e2a-8ca9-43806170673a", - "alias": "forms", - "description": "Username, password, otp and other auth forms.", - "providerId": "basic-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "auth-username-password-form", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticatorFlow": true, - "requirement": "CONDITIONAL", - "priority": 20, - "autheticatorFlow": true, - "flowAlias": "Browser - Conditional 2FA", - "userSetupAllowed": false - } - ] - }, - { - "id": "b377c069-ba3e-4539-9384-96500f159b38", - "alias": "registration", - "description": "Registration flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-page-form", - "authenticatorFlow": true, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": true, - "flowAlias": "registration form", - "userSetupAllowed": false - } - ] - }, - { - "id": "09c14b3f-624e-4644-8575-0cdaa0136c81", - "alias": "registration form", - "description": "Registration form", - "providerId": "form-flow", - "topLevel": false, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "registration-user-creation", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 20, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "registration-password-action", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 50, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "registration-recaptcha-action", - "authenticatorFlow": false, - "requirement": "DISABLED", - "priority": 60, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "registration-terms-and-conditions", - "authenticatorFlow": false, - "requirement": "DISABLED", - "priority": 70, - "autheticatorFlow": false, - "userSetupAllowed": false - } - ] - }, - { - "id": "bb025b69-6cc9-4f78-8d3c-52c2c3f950a6", - "alias": "reset credentials", - "description": "Reset credentials for a user if they forgot their password or something", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "reset-credentials-choose-user", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "reset-credential-email", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 20, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticator": "reset-password", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 30, - "autheticatorFlow": false, - "userSetupAllowed": false - }, - { - "authenticatorFlow": true, - "requirement": "CONDITIONAL", - "priority": 40, - "autheticatorFlow": true, - "flowAlias": "Reset - Conditional OTP", - "userSetupAllowed": false - } - ] - }, - { - "id": "04c20ba3-1ca7-4154-a4d8-2a757bcd8bf4", - "alias": "saml ecp", - "description": "SAML ECP Profile Authentication Flow", - "providerId": "basic-flow", - "topLevel": true, - "builtIn": true, - "authenticationExecutions": [ - { - "authenticator": "http-basic-authenticator", - "authenticatorFlow": false, - "requirement": "REQUIRED", - "priority": 10, - "autheticatorFlow": false, - "userSetupAllowed": false - } - ] - } - ], - "authenticatorConfig": [ - { - "id": "f2226ef0-fffb-4dd2-ace2-e416abcc1626", - "alias": "create unique user config", - "config": { - "require.password.update.after.registration": "false" - } - }, - { - "id": "90417eb9-4152-4b12-afc1-a6fb33f7e404", - "alias": "review profile config", - "config": { - "update.profile.on.first.login": "missing" - } - } - ], - "requiredActions": [ - { - "alias": "CONFIGURE_TOTP", - "name": "Configure OTP", - "providerId": "CONFIGURE_TOTP", - "enabled": true, - "defaultAction": false, - "priority": 10, - "config": {} - }, - { - "alias": "TERMS_AND_CONDITIONS", - "name": "Terms and Conditions", - "providerId": "TERMS_AND_CONDITIONS", - "enabled": false, - "defaultAction": false, - "priority": 20, - "config": {} - }, - { - "alias": "UPDATE_PASSWORD", - "name": "Update Password", - "providerId": "UPDATE_PASSWORD", - "enabled": true, - "defaultAction": false, - "priority": 30, - "config": {} - }, - { - "alias": "UPDATE_PROFILE", - "name": "Update Profile", - "providerId": "UPDATE_PROFILE", - "enabled": true, - "defaultAction": false, - "priority": 40, - "config": {} - }, - { - "alias": "VERIFY_EMAIL", - "name": "Verify Email", - "providerId": "VERIFY_EMAIL", - "enabled": true, - "defaultAction": false, - "priority": 50, - "config": {} - }, - { - "alias": "delete_account", - "name": "Delete Account", - "providerId": "delete_account", - "enabled": false, - "defaultAction": false, - "priority": 60, - "config": {} - }, - { - "alias": "webauthn-register", - "name": "Webauthn Register", - "providerId": "webauthn-register", - "enabled": true, - "defaultAction": false, - "priority": 70, - "config": {} - }, - { - "alias": "webauthn-register-passwordless", - "name": "Webauthn Register Passwordless", - "providerId": "webauthn-register-passwordless", - "enabled": true, - "defaultAction": false, - "priority": 80, - "config": {} - }, - { - "alias": "VERIFY_PROFILE", - "name": "Verify Profile", - "providerId": "VERIFY_PROFILE", - "enabled": true, - "defaultAction": false, - "priority": 90, - "config": {} - }, - { - "alias": "delete_credential", - "name": "Delete Credential", - "providerId": "delete_credential", - "enabled": true, - "defaultAction": false, - "priority": 100, - "config": {} - }, - { - "alias": "idp_link", - "name": "Linking Identity Provider", - "providerId": "idp_link", - "enabled": true, - "defaultAction": false, - "priority": 110, - "config": {} - }, - { - "alias": "CONFIGURE_RECOVERY_AUTHN_CODES", - "name": "Recovery Authentication Codes", - "providerId": "CONFIGURE_RECOVERY_AUTHN_CODES", - "enabled": true, - "defaultAction": false, - "priority": 120, - "config": {} - }, - { - "alias": "update_user_locale", - "name": "Update User Locale", - "providerId": "update_user_locale", - "enabled": true, - "defaultAction": false, - "priority": 1000, - "config": {} - } - ], - "browserFlow": "browser", - "registrationFlow": "registration", - "directGrantFlow": "direct grant", - "resetCredentialsFlow": "reset credentials", - "clientAuthenticationFlow": "clients", - "dockerAuthenticationFlow": "docker auth", - "firstBrokerLoginFlow": "first broker login", - "attributes": { - "cibaBackchannelTokenDeliveryMode": "poll", - "cibaExpiresIn": "120", - "cibaAuthRequestedUserHint": "login_hint", - "oauth2DeviceCodeLifespan": "600", - "clientOfflineSessionMaxLifespan": "0", - "oauth2DevicePollingInterval": "5", - "clientSessionIdleTimeout": "0", - "parRequestUriLifespan": "60", - "clientSessionMaxLifespan": "0", - "clientOfflineSessionIdleTimeout": "0", - "cibaInterval": "5", - "realmReusableOtpCode": "false" - }, - "keycloakVersion": "26.3.3", - "userManagedAccessAllowed": false, - "organizationsEnabled": false, - "verifiableCredentialsEnabled": false, - "adminPermissionsEnabled": false, - "clientProfiles": { - "profiles": [] - }, - "clientPolicies": { - "policies": [] - } -} From 7cb2ea129ac2e81c7e9894e275ff4087cb98a79b Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh <26975142+ZohebShaikh@users.noreply.github.com> Date: Fri, 28 Nov 2025 12:44:04 +0000 Subject: [PATCH 2/9] Update health check for keycloak --- example_configs/keycloak_oidc/Dockerfile | 8 -------- example_configs/keycloak_oidc/compose.yaml | 9 ++------- 2 files changed, 2 insertions(+), 15 deletions(-) delete mode 100644 example_configs/keycloak_oidc/Dockerfile diff --git a/example_configs/keycloak_oidc/Dockerfile b/example_configs/keycloak_oidc/Dockerfile deleted file mode 100644 index 8e5628d39..000000000 --- a/example_configs/keycloak_oidc/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM registry.access.redhat.com/ubi9 AS ubi-micro-build -RUN mkdir -p /mnt/rootfs -RUN dnf install --installroot /mnt/rootfs curl --releasever 9 --setopt install_weak_deps=false --nodocs -y && \ - dnf --installroot /mnt/rootfs clean all && \ - rpm --root /mnt/rootfs -e --nodeps setup - -FROM quay.io/keycloak/keycloak -COPY --from=ubi-micro-build /mnt/rootfs / diff --git a/example_configs/keycloak_oidc/compose.yaml b/example_configs/keycloak_oidc/compose.yaml index ba4a3d789..904fa454f 100644 --- a/example_configs/keycloak_oidc/compose.yaml +++ b/example_configs/keycloak_oidc/compose.yaml @@ -1,14 +1,10 @@ services: keycloak: - build: - context: . - dockerfile: Dockerfile + image: keycloak/keycloak:26.4 environment: - KC_BOOTSTRAP_ADMIN_PASSWORD=admin - KC_BOOTSTRAP_ADMIN_USERNAME=admin - - KC_HEALTH_ENABLED=true - - KC_METRICS_ENABLED=true command: ["start-dev"] volumes: - ./keycloak_config/:/mnt @@ -16,9 +12,8 @@ services: - command: bash /mnt/startup.sh ports: - 8080:8080 - - 9000:9000 healthcheck: - test: "curl --head -fsS http://localhost:9000/health/ready" + test: /opt/keycloak/bin/kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin --password admin interval: 5s timeout: 5s retries: 10 From 07bdc1595674ec8c4c38417f96fb692a5fecbe52 Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh <26975142+ZohebShaikh@users.noreply.github.com> Date: Fri, 28 Nov 2025 15:14:52 +0000 Subject: [PATCH 3/9] Increase sleep time for keycloak --- example_configs/keycloak_oidc/keycloak_config/startup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example_configs/keycloak_oidc/keycloak_config/startup.sh b/example_configs/keycloak_oidc/keycloak_config/startup.sh index dd8637eaa..10b7e0e22 100644 --- a/example_configs/keycloak_oidc/keycloak_config/startup.sh +++ b/example_configs/keycloak_oidc/keycloak_config/startup.sh @@ -1,7 +1,7 @@ #!/bin/bash export PATH=$PATH:/opt/keycloak/bin -sleep 2 +sleep 30 while ! kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin --password admin; do sleep 1 done From ab694f3f4ee2630ed567310fcb676897c45f8f03 Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh <26975142+ZohebShaikh@users.noreply.github.com> Date: Wed, 3 Dec 2025 11:53:30 +0000 Subject: [PATCH 4/9] Update the startup time for compose yaml --- example_configs/keycloak_oidc/compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example_configs/keycloak_oidc/compose.yaml b/example_configs/keycloak_oidc/compose.yaml index 904fa454f..3435a88c1 100644 --- a/example_configs/keycloak_oidc/compose.yaml +++ b/example_configs/keycloak_oidc/compose.yaml @@ -17,7 +17,7 @@ services: interval: 5s timeout: 5s retries: 10 - start_period: 12s + start_period: 30s oauth2-proxy: network_mode: host From 1e1185c993eeafe6f6aa4d2175166a7f06219ab0 Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh <26975142+ZohebShaikh@users.noreply.github.com> Date: Tue, 9 Dec 2025 12:28:47 +0000 Subject: [PATCH 5/9] Update client secret to secret --- example_configs/keycloak_oidc/keycloak_config/tiled.json | 2 +- example_configs/keycloak_oidc/oauth2-alpha.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/example_configs/keycloak_oidc/keycloak_config/tiled.json b/example_configs/keycloak_oidc/keycloak_config/tiled.json index b7ce77df7..9fb109c0f 100644 --- a/example_configs/keycloak_oidc/keycloak_config/tiled.json +++ b/example_configs/keycloak_oidc/keycloak_config/tiled.json @@ -10,7 +10,7 @@ "enabled" : true, "alwaysDisplayInConsole" : false, "clientAuthenticatorType" : "client-secret", - "secret" : "o8b7mIuYmzybNPVS8SSduhMdeqM8NDLp", + "secret" : "secret", "defaultRoles" : [ ], "redirectUris" : [ "http://localhost:4180/*" ], "webOrigins" : [ "http://localhost:4180/*" ], diff --git a/example_configs/keycloak_oidc/oauth2-alpha.yaml b/example_configs/keycloak_oidc/oauth2-alpha.yaml index b9f1a2796..017b4f92a 100644 --- a/example_configs/keycloak_oidc/oauth2-alpha.yaml +++ b/example_configs/keycloak_oidc/oauth2-alpha.yaml @@ -6,7 +6,7 @@ injectRequestHeaders: providers: - provider: oidc clientID: tiled - clientSecret: o8b7mIuYmzybNPVS8SSduhMdeqM8NDLp + clientSecret: secret id: authn oidcConfig: audienceClaims: ["aud"] From 5676c7071f62573a0c28f48dc9a8aa73721b10ce Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh <26975142+ZohebShaikh@users.noreply.github.com> Date: Wed, 10 Dec 2025 11:41:49 +0000 Subject: [PATCH 6/9] Add comments --- example_configs/keycloak_oidc/README.md | 4 ++++ .../keycloak_oidc/keycloak_config/startup.sh | 13 ++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/example_configs/keycloak_oidc/README.md b/example_configs/keycloak_oidc/README.md index 53fab39e0..c648c58d2 100644 --- a/example_configs/keycloak_oidc/README.md +++ b/example_configs/keycloak_oidc/README.md @@ -10,5 +10,9 @@ This will start three services defined in the Docker Compose file: 3. Open your browser and go to [http://localhost:4180](http://localhost:4180) (served by oauth2-proxy). You will be prompted to log in. Use `admin` for both the username and password. 4. After logging in as `admin`, you will have access to all resources. +Additionally, three test users are created at startup: +- **alice** (password: alice) +- **bob** (password: bob) +- **carol** (password: carol) > **Note:** This configuration exposes all secrets and passwords to make it easier to use as an example. **Do not use this setup in production.** diff --git a/example_configs/keycloak_oidc/keycloak_config/startup.sh b/example_configs/keycloak_oidc/keycloak_config/startup.sh index 10b7e0e22..ef095df6f 100644 --- a/example_configs/keycloak_oidc/keycloak_config/startup.sh +++ b/example_configs/keycloak_oidc/keycloak_config/startup.sh @@ -1,25 +1,28 @@ #!/bin/bash export PATH=$PATH:/opt/keycloak/bin +# Wait for Keycloak to start up sleep 30 while ! kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin --password admin; do sleep 1 done # Add users to Keycloak -for user in alice bob carol oscar; do +for user in alice bob carol; do kcadm.sh create users -r master -s username="$user" -s enabled=true kcadm.sh set-password -r master --username "$user" --new-password "$user" done +# Retrieve all allowed protocol mappers for client registration allowed_protocol_mappers=$(kcadm.sh get components -q name="Allowed Protocol Mapper Types" --fields id --format csv --noquotes) -for i in $allowed_protocol_mappers;do - kcadm.sh update components/$i -s 'config.allowed-protocol-mapper-types=[ "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-audience-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ]' +# Enable oidc-audience-mapper for all allowed protocol mappers to support tiled client registration +for mapper_id in $allowed_protocol_mappers; do + kcadm.sh update components/$mapper_id -s 'config.allowed-protocol-mapper-types=[ "saml-user-attribute-mapper", "saml-user-property-mapper", "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "oidc-address-mapper", "oidc-audience-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper" ]' done kcreg.sh config credentials --server http://localhost:8080 --realm master --user admin --password admin -for client in tiled-cli.json tiled.json; do - kcreg.sh create --file "/mnt/$client" +for client in tiled-cli tiled; do + kcreg.sh get $client >/dev/null 2>&1 || kcreg.sh create --file "/mnt/$client.json" done From fa2cb27ecfc2a277c10c51ffcb3c493ffb3d9e71 Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh <26975142+ZohebShaikh@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:29:55 +0000 Subject: [PATCH 7/9] Add more documentation --- example_configs/keycloak_oidc/README.md | 83 ++++++++++++++++++---- example_configs/keycloak_oidc/compose.yaml | 2 +- 2 files changed, 72 insertions(+), 13 deletions(-) diff --git a/example_configs/keycloak_oidc/README.md b/example_configs/keycloak_oidc/README.md index c648c58d2..18a9fd76f 100644 --- a/example_configs/keycloak_oidc/README.md +++ b/example_configs/keycloak_oidc/README.md @@ -1,18 +1,77 @@ # Running a Local Keycloak Instance for Authentication -1. In this directory, run `docker compose up`. +This example demonstrates how to set up authentication using Keycloak (or any OAuth2-compliant provider). Two clients require authentication: +1. Tiled CLI (command-line client) +2. Tiled Web UI (FastAPI server and frontend) -This will start three services defined in the Docker Compose file: -- **Keycloak**: Handles authentication. -- **oauth2-proxy**: Acts as a proxy to authenticate users. +## Tiled CLI Authentication -2. Start the Tiled server using the configuration file located at `example_configs/keycloak_oidc/config.yaml`. -3. Open your browser and go to [http://localhost:4180](http://localhost:4180) (served by oauth2-proxy). You will be prompted to log in. Use `admin` for both the username and password. +The Tiled CLI uses the [device authorization flow](https://auth0.com/docs/get-started/authentication-and-authorization-flow/device-authorization-flow): -4. After logging in as `admin`, you will have access to all resources. -Additionally, three test users are created at startup: -- **alice** (password: alice) -- **bob** (password: bob) -- **carol** (password: carol) +```mermaid +sequenceDiagram + actor User + participant CLI as Tiled CLI + participant Server as Tiled Server + participant IdP as Keycloak -> **Note:** This configuration exposes all secrets and passwords to make it easier to use as an example. **Do not use this setup in production.** + User->>CLI: run "tiled login" + CLI->>Server: Request auth configuration (/api/v1) + Server-->>CLI: Device flow endpoints (client_id, auth-endpoint, token_endpoint) + CLI->>IdP: POST /device (client_id, scopes) + IdP-->>CLI: device_code, user_code, verification_uri, interval + CLI->>User: "Visit verification URL and enter user code" + + par User Authentication + User->>IdP: Open verification URL and authenticate + IdP-->>User: Login successful + and CLI Polling + CLI->>IdP: Poll /token with device_code + IdP-->>CLI: "authorization_pending" (repeat until login) + end + + IdP-->>CLI: access_token, refresh_token + CLI->>CLI: Store tokens (~/.cache/tiled) + CLI-->>User: "You have logged in with Proxied OIDC as external user." +``` + +After login, subsequent requests include the access token in the Authorization header. When the token expires (1-minute validity), the CLI automatically refreshes it. You must create a public client in Keycloak with OAuth 2.0 Device Authorization Grant enabled (named `tiled-cli` in this example). + +## Tiled Web UI Authentication + +The web server uses a simpler flow with a confidential Keycloak client (named `tiled` in this example) and OAuth2 Proxy: + +```mermaid +sequenceDiagram + actor User + participant OAuth2Proxy as OAuth2 Proxy + participant Keycloak + participant Tiled + + User->>OAuth2Proxy: Request access to application + OAuth2Proxy->>Keycloak: Redirect user for authentication + activate Keycloak + Keycloak-->>OAuth2Proxy: Return JWT Access Token + deactivate Keycloak + OAuth2Proxy->>Tiled: Forward request with JWT Access Token + Tiled->>User: Provide resources if authenticated +``` + +## Getting Started + +1. Run `docker compose up` in this directory. This starts: + - **Keycloak**: Authentication provider + - **oauth2-proxy**: Authentication proxy + +2. Start the Tiled server with `example_configs/keycloak_oidc/config.yaml`. + +3. Open [http://localhost:4180](http://localhost:4180) in your browser and log in with: + - Username: `admin` + - Password: `admin` + +4. After authentication, you'll access all resources. Three additional test users are available: + - **alice** (password: alice) + - **bob** (password: bob) + - **carol** (password: carol) + +> **Note:** This example exposes secrets and passwords for demonstration only. **Do not use in production.** diff --git a/example_configs/keycloak_oidc/compose.yaml b/example_configs/keycloak_oidc/compose.yaml index 3435a88c1..9f7a52b02 100644 --- a/example_configs/keycloak_oidc/compose.yaml +++ b/example_configs/keycloak_oidc/compose.yaml @@ -21,7 +21,7 @@ services: oauth2-proxy: network_mode: host - image: "quay.io/oauth2-proxy/oauth2-proxy:v7.13.0-amd64" + image: "quay.io/oauth2-proxy/oauth2-proxy:v7.13.0" volumes: - ./oauth2-proxy.cfg:/opt/oauth2-proxy.cfg - ./oauth2-alpha.yaml:/opt/oauth2-alpha.yaml From ce5898e3d746063b25d90da0d0742b5a6fbbbccb Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh <26975142+ZohebShaikh@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:56:40 +0000 Subject: [PATCH 8/9] Add docs for logout --- example_configs/keycloak_oidc/README.md | 29 +++++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/example_configs/keycloak_oidc/README.md b/example_configs/keycloak_oidc/README.md index 18a9fd76f..f488fc174 100644 --- a/example_configs/keycloak_oidc/README.md +++ b/example_configs/keycloak_oidc/README.md @@ -15,13 +15,13 @@ sequenceDiagram participant Server as Tiled Server participant IdP as Keycloak - User->>CLI: run "tiled login" + User->>CLI: client.login() CLI->>Server: Request auth configuration (/api/v1) Server-->>CLI: Device flow endpoints (client_id, auth-endpoint, token_endpoint) CLI->>IdP: POST /device (client_id, scopes) IdP-->>CLI: device_code, user_code, verification_uri, interval CLI->>User: "Visit verification URL and enter user code" - + par User Authentication User->>IdP: Open verification URL and authenticate IdP-->>User: Login successful @@ -29,7 +29,7 @@ sequenceDiagram CLI->>IdP: Poll /token with device_code IdP-->>CLI: "authorization_pending" (repeat until login) end - + IdP-->>CLI: access_token, refresh_token CLI->>CLI: Store tokens (~/.cache/tiled) CLI-->>User: "You have logged in with Proxied OIDC as external user." @@ -39,7 +39,22 @@ After login, subsequent requests include the access token in the Authorization h ## Tiled Web UI Authentication -The web server uses a simpler flow with a confidential Keycloak client (named `tiled` in this example) and OAuth2 Proxy: +The Tiled Web UI uses [OAuth2 Proxy](https://oauth2-proxy.github.io/oauth2-proxy/) as a reverse proxy to the Tiled server. OAuth2 Proxy handles all session management, including login, logout, and access token refresh. +The web server uses a confidential Keycloak client (named `tiled` in this example). +To logout, users are redirected to the Keycloak end_session_endpoint via OAuth2 Proxy's sign-out handler: + +``` +http://localhost:4180/oauth2/sign_out?rd=http%3A%2F%2Flocalhost%3A8080%2Frealms%2Fmaster%2Fprotocol%2Fopenid-connect%2Flogout + +# The logout URL can be build as follow:- +end_session_endpoint = "http://localhost:8080/realms/master/protocol/openid-connect/logout" +# end_session_endpoint can be found at http://localhost:8080/realms/master/.well-known/openid-configuration +encoded_url = urllib.parse.quote_plus(end_session_endpoint) + +logout_url= "http://localhost:4180" + "oauth2/sign_out?rd=" + encoded_url +``` + +For better user experience, you can configure a `/logout` endpoint to redirect to this URL automatically. ```mermaid sequenceDiagram @@ -63,13 +78,13 @@ sequenceDiagram - **Keycloak**: Authentication provider - **oauth2-proxy**: Authentication proxy -2. Start the Tiled server with `example_configs/keycloak_oidc/config.yaml`. +2. Start the Tiled server with `tiled server config example_configs/keycloak_oidc/config.yaml`. -3. Open [http://localhost:4180](http://localhost:4180) in your browser and log in with: +3. Open http://localhost:4180 (Oauth2 proxy address) in your browser and log in with: - Username: `admin` - Password: `admin` -4. After authentication, you'll access all resources. Three additional test users are available: +4. After authentication, you'll access all resources. Three additional test users are also available: - **alice** (password: alice) - **bob** (password: bob) - **carol** (password: carol) From 6edce906e8535a3edb7424083e6698b436de93db Mon Sep 17 00:00:00 2001 From: Zoheb Shaikh <26975142+ZohebShaikh@users.noreply.github.com> Date: Wed, 10 Dec 2025 16:04:41 +0000 Subject: [PATCH 9/9] Add proper name for keycloak --- example_configs/keycloak_oidc/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/example_configs/keycloak_oidc/README.md b/example_configs/keycloak_oidc/README.md index f488fc174..dd857b5f6 100644 --- a/example_configs/keycloak_oidc/README.md +++ b/example_configs/keycloak_oidc/README.md @@ -75,12 +75,12 @@ sequenceDiagram ## Getting Started 1. Run `docker compose up` in this directory. This starts: - - **Keycloak**: Authentication provider - - **oauth2-proxy**: Authentication proxy + - **Keycloak**: Identity Provider (IdP) + - **OAuth2-proxy**: Reverse-proxy to access OAuth2 secured Tiled -2. Start the Tiled server with `tiled server config example_configs/keycloak_oidc/config.yaml`. +2. Start the Tiled server with `tiled server config example_configs/keycloak_oidc/config.yaml`. Tiled will make a call to Keycloak at startup to get the .well-known/openid-configuration. -3. Open http://localhost:4180 (Oauth2 proxy address) in your browser and log in with: +3. Open http://localhost:4180 (OAuth2 proxy address) in your browser and log in with: - Username: `admin` - Password: `admin`