summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2021-12-04 00:03:14 +0000
committerGerrit Code Review <review@openstack.org>2021-12-04 00:03:14 +0000
commitf392df4bd5f77cf983efccb968d6cff8e916fe92 (patch)
treec9af29cf400eca2c0764c61c7bcdf30b3ae27c7c /doc
parent79e8264385b6f6f519931bb9b8ca8c580669d695 (diff)
parentd4e9b66fa0b47f03f12260b39ecb2d2ee6bbea38 (diff)
downloadzuul-f392df4bd5f77cf983efccb968d6cff8e916fe92.tar.gz
Merge "Add a keycloak tutorial"
Diffstat (limited to 'doc')
-rw-r--r--doc/source/examples/docker-compose.yaml33
-rw-r--r--doc/source/examples/keycloak/docker-compose.yaml31
-rw-r--r--doc/source/examples/keycloak/etc_zuul/main.yaml25
-rw-r--r--doc/source/examples/keycloak/etc_zuul/zuul.conf52
-rw-r--r--doc/source/examples/keycloak/keycloak/zuul-demo-data.json2224
-rw-r--r--doc/source/reference/developer/javascript.rst9
-rw-r--r--doc/source/tutorials/admin.rst1
-rw-r--r--doc/source/tutorials/keycloak.rst78
8 files changed, 2447 insertions, 6 deletions
diff --git a/doc/source/examples/docker-compose.yaml b/doc/source/examples/docker-compose.yaml
index 688d79721..93e2fc589 100644
--- a/doc/source/examples/docker-compose.yaml
+++ b/doc/source/examples/docker-compose.yaml
@@ -1,6 +1,4 @@
-# Version 2 is the latest that is supported by docker-compose in
-# Ubuntu Xenial.
-version: '2'
+version: '2.1'
services:
gerrit:
@@ -10,6 +8,8 @@ services:
- "29418:29418"
environment:
- CANONICAL_WEB_URL=http://localhost:8080/
+ networks:
+ - zuul
gerritconfig:
image: docker.io/zuul/zuul-executor
environment:
@@ -27,6 +27,8 @@ services:
# NOTE(pabelanger): Be sure to update this line each time we change the
# default version of ansible for Zuul.
command: "/usr/local/lib/zuul/ansible/2.9/bin/ansible-playbook /var/playbooks/setup.yaml"
+ networks:
+ - zuul
zk:
image: docker.io/zookeeper
hostname: examples_zk_1.examples_default
@@ -35,6 +37,8 @@ services:
- "certs:/var/certs:z"
- "./zoo.cfg:/conf/zoo.cfg:z"
command: "sh -c '/var/playbooks/wait-to-start-certs.sh && zkServer.sh start-foreground'"
+ networks:
+ - zuul
mysql:
image: docker.io/mariadb
environment:
@@ -44,6 +48,8 @@ services:
MYSQL_PASSWORD: secret
# Work around slow db startup when writing TZINFO data.
MYSQL_INITDB_SKIP_TZINFO: 1
+ networks:
+ - zuul
scheduler:
depends_on:
- gerritconfig
@@ -62,10 +68,12 @@ services:
# This needs to be changes such that ansible is not required for startup.
image: docker.io/zuul/zuul-scheduler
volumes:
- - "./etc_zuul/:/etc/zuul/:z"
+ - "${ZUUL_TUTORIAL_CONFIG:-./etc_zuul/}:/etc/zuul/:z"
- "./playbooks/:/var/playbooks/:z"
- "sshkey:/var/ssh:z"
- "certs:/var/certs:z"
+ networks:
+ - zuul
web:
command: |
sh -c '/var/playbooks/wait-to-start-certs.sh && \
@@ -80,9 +88,11 @@ services:
environment:
ZUUL_MYSQL_PASSWORD: secret
volumes:
- - "./etc_zuul/:/etc/zuul/:z"
+ - "${ZUUL_TUTORIAL_CONFIG:-./etc_zuul/}:/etc/zuul/:z"
- "./playbooks/:/var/playbooks/:z"
- "certs:/var/certs:z"
+ networks:
+ - zuul
executor:
privileged: true
environment:
@@ -94,12 +104,14 @@ services:
- scheduler
image: docker.io/zuul/zuul-executor
volumes:
- - "./etc_zuul/:/etc/zuul/:z"
+ - "${ZUUL_TUTORIAL_CONFIG:-./etc_zuul/}:/etc/zuul/:z"
- "./playbooks/:/var/playbooks/:z"
- "sshkey:/var/ssh:z"
- "logs:/srv/static/logs:z"
- "certs:/var/certs:z"
command: "sh -c '/var/playbooks/wait-to-start-certs.sh && zuul-executor -f'"
+ networks:
+ - zuul
node:
build:
dockerfile: node-Dockerfile
@@ -110,6 +122,8 @@ services:
no_proxy: "${no_proxy},gerrit"
volumes:
- "nodessh:/root/.ssh:z"
+ networks:
+ - zuul
launcher:
depends_on:
- zk
@@ -121,6 +135,8 @@ services:
ports:
- "8022:8022"
command: "sh -c '/var/playbooks/wait-to-start-certs.sh && nodepool-launcher -f'"
+ networks:
+ - zuul
logs:
build:
dockerfile: logs-Dockerfile
@@ -133,9 +149,14 @@ services:
- "8000:80"
volumes:
- "logs:/usr/local/apache2/htdocs:z"
+ networks:
+ - zuul
volumes:
sshkey:
nodessh:
logs:
certs:
+
+networks:
+ zuul:
diff --git a/doc/source/examples/keycloak/docker-compose.yaml b/doc/source/examples/keycloak/docker-compose.yaml
new file mode 100644
index 000000000..917c50231
--- /dev/null
+++ b/doc/source/examples/keycloak/docker-compose.yaml
@@ -0,0 +1,31 @@
+# Start the quickstart tutorial with `docker-compose -p zuul-tutorial
+# up` (as directed in the instructions) in order for the network to
+# have the expected name so that it can be shared with keycloak.
+
+# Version 2.1 is required to specify the network name
+version: '2.1'
+
+services:
+ keycloak:
+ image: docker.io/jboss/keycloak
+ environment:
+ - KEYCLOAK_USER=admin
+ - KEYCLOAK_PASSWORD=kcadmin
+ - DB_VENDOR=h2
+ - KEYCLOAK_IMPORT=/var/keycloak_import/zuul-demo-data.json
+ - JAVA_OPTS_APPEND="-Djboss.socket.binding.port-offset=2"
+ ports:
+ - "8082:8082"
+ volumes:
+ - "./keycloak/:/var/keycloak_import/:z"
+ entrypoint: |
+ /bin/sh -c '\
+ /opt/jboss/tools/docker-entrypoint.sh -b 0.0.0.0'
+ command: []
+ networks:
+ - zuul
+
+networks:
+ zuul:
+ external: true
+ name: zuul-tutorial_zuul
diff --git a/doc/source/examples/keycloak/etc_zuul/main.yaml b/doc/source/examples/keycloak/etc_zuul/main.yaml
new file mode 100644
index 000000000..9006399b6
--- /dev/null
+++ b/doc/source/examples/keycloak/etc_zuul/main.yaml
@@ -0,0 +1,25 @@
+- admin-rule:
+ name: tenant-group
+ conditions:
+ - groups: "{tenant.name}-admin"
+- admin-rule:
+ name: admin-user
+ conditions:
+ - preferred_username: admin
+- tenant:
+ name: example-tenant
+ admin-rules:
+ - tenant-group
+ - admin-user
+ source:
+ gerrit:
+ config-projects:
+ - zuul-config
+ untrusted-projects:
+ - test1
+ - test2
+ opendev.org:
+ untrusted-projects:
+ - zuul/zuul-jobs:
+ include:
+ - job
diff --git a/doc/source/examples/keycloak/etc_zuul/zuul.conf b/doc/source/examples/keycloak/etc_zuul/zuul.conf
new file mode 100644
index 000000000..dcbe5555a
--- /dev/null
+++ b/doc/source/examples/keycloak/etc_zuul/zuul.conf
@@ -0,0 +1,52 @@
+[gearman]
+server=scheduler
+
+[gearman_server]
+start=true
+
+[zookeeper]
+hosts=zk:2281
+tls_cert=/var/certs/certs/client.pem
+tls_key=/var/certs/keys/clientkey.pem
+tls_ca=/var/certs/certs/cacert.pem
+
+[keystore]
+password=secret
+
+[scheduler]
+tenant_config=/etc/zuul/main.yaml
+
+[auth keycloak]
+default=true
+driver=OpenIDConnect
+realm=zuul-demo
+issuer_id=http://keycloak:8082/auth/realms/zuul-demo
+client_id=zuul
+
+[connection "gerrit"]
+name=gerrit
+driver=gerrit
+server=gerrit
+sshkey=/var/ssh/zuul
+user=zuul
+password=secret
+baseurl=http://gerrit:8080
+auth_type=basic
+
+[connection "opendev.org"]
+name=opendev
+driver=git
+baseurl=https://opendev.org
+
+[database]
+dburi=mysql+pymysql://zuul:%(ZUUL_MYSQL_PASSWORD)s@mysql/zuul
+
+[web]
+listen_address=0.0.0.0
+port=9000
+root=http://localhost:9000
+
+[executor]
+private_key_file=/var/ssh/nodepool
+default_username=root
+trusted_rw_paths=/srv/static/logs
diff --git a/doc/source/examples/keycloak/keycloak/zuul-demo-data.json b/doc/source/examples/keycloak/keycloak/zuul-demo-data.json
new file mode 100644
index 000000000..448267eed
--- /dev/null
+++ b/doc/source/examples/keycloak/keycloak/zuul-demo-data.json
@@ -0,0 +1,2224 @@
+{
+ "id": "zuul-demo",
+ "realm": "zuul-demo",
+ "notBefore": 0,
+ "revokeRefreshToken": false,
+ "refreshTokenMaxReuse": 0,
+ "accessTokenLifespan": 300,
+ "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,
+ "enabled": true,
+ "sslRequired": "external",
+ "registrationAllowed": true,
+ "registrationEmailAsUsername": false,
+ "rememberMe": false,
+ "verifyEmail": false,
+ "loginWithEmailAllowed": true,
+ "duplicateEmailsAllowed": false,
+ "resetPasswordAllowed": false,
+ "editUsernameAllowed": false,
+ "bruteForceProtected": false,
+ "permanentLockout": false,
+ "maxFailureWaitSeconds": 900,
+ "minimumQuickLoginWaitSeconds": 60,
+ "waitIncrementSeconds": 60,
+ "quickLoginCheckMilliSeconds": 1000,
+ "maxDeltaTimeSeconds": 43200,
+ "failureFactor": 30,
+ "roles": {
+ "realm": [
+ {
+ "id": "b295f2e1-c823-4f30-84b4-c534676c3ded",
+ "name": "uma_authorization",
+ "composite": false,
+ "clientRole": false,
+ "containerId": "zuul-demo",
+ "attributes": {}
+ },
+ {
+ "id": "047a5001-b3fe-452a-8fd3-985d82f7df31",
+ "name": "offline_access",
+ "description": "${role_offline-access}",
+ "composite": false,
+ "clientRole": false,
+ "containerId": "zuul-demo",
+ "attributes": {}
+ }
+ ],
+ "client": {
+ "realm-management": [
+ {
+ "id": "7e18128e-7a99-4403-8107-5a90ac0b952c",
+ "name": "view-identity-providers",
+ "description": "${role_view-identity-providers}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "95f5f229-415e-48ba-8bfc-ff0a750f119e",
+ "name": "view-users",
+ "description": "${role_view-users}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "query-groups",
+ "query-users"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "7cffdbb0-ced3-4fb0-98de-6b1d8506dbe4",
+ "name": "manage-identity-providers",
+ "description": "${role_manage-identity-providers}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "08729d50-a31e-42fd-ad81-120cdee3b1b9",
+ "name": "query-clients",
+ "description": "${role_query-clients}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "69ffc663-32cb-4f4e-a9af-669bd23b4edc",
+ "name": "query-groups",
+ "description": "${role_query-groups}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "2a9f4d72-35bb-4072-b8aa-3fe7f1ab7f26",
+ "name": "view-clients",
+ "description": "${role_view-clients}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "query-clients"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "16c74fae-7feb-446d-9d42-08b31583ddf5",
+ "name": "manage-events",
+ "description": "${role_manage-events}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "30cc0071-f914-446a-9aa3-a3372d9f45c0",
+ "name": "manage-authorization",
+ "description": "${role_manage-authorization}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "d3d32a6d-f1da-410f-8c52-62d1b2ac7abc",
+ "name": "query-realms",
+ "description": "${role_query-realms}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "1f7afd46-36a8-46e8-abc1-8949836ec532",
+ "name": "view-authorization",
+ "description": "${role_view-authorization}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "6384baeb-1ec0-4e69-a5c2-7b632c3bfda5",
+ "name": "impersonation",
+ "description": "${role_impersonation}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "eefc7ff0-e2f2-4381-b034-c96d0bae3769",
+ "name": "realm-admin",
+ "description": "${role_realm-admin}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "realm-management": [
+ "view-identity-providers",
+ "view-users",
+ "manage-identity-providers",
+ "query-clients",
+ "query-groups",
+ "view-clients",
+ "manage-events",
+ "view-authorization",
+ "manage-authorization",
+ "query-realms",
+ "impersonation",
+ "create-client",
+ "manage-clients",
+ "manage-users",
+ "manage-realm",
+ "view-events",
+ "view-realm",
+ "query-users"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "1c104476-dc65-4df5-9f0e-3f9086a75813",
+ "name": "create-client",
+ "description": "${role_create-client}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "f0893b2a-770e-4b21-a430-1a9974ecc01a",
+ "name": "manage-clients",
+ "description": "${role_manage-clients}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "dfddee2e-682a-47ea-924c-59699f338e0c",
+ "name": "manage-users",
+ "description": "${role_manage-users}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "a8198df9-d3cd-460f-a48f-ccede56e08a9",
+ "name": "manage-realm",
+ "description": "${role_manage-realm}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "657b4b26-98c5-4963-a353-db26453f5dd2",
+ "name": "view-events",
+ "description": "${role_view-events}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "693093ae-6004-48be-bb22-8804f61af1c0",
+ "name": "view-realm",
+ "description": "${role_view-realm}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ },
+ {
+ "id": "418abb16-fdc3-402e-8125-52800990445b",
+ "name": "query-users",
+ "description": "${role_query-users}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "attributes": {}
+ }
+ ],
+ "security-admin-console": [],
+ "admin-cli": [],
+ "account-console": [],
+ "zuul": [],
+ "broker": [],
+ "account": [
+ {
+ "id": "b839cd34-f23d-4c14-8060-ed635e708b87",
+ "name": "view-consent",
+ "description": "${role_view-consent}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6fd2abe1-4aeb-4834-8a9e-e3f499d64a03",
+ "attributes": {}
+ },
+ {
+ "id": "a98bcb3b-1584-45ab-afa8-e431ddfed5e7",
+ "name": "view-applications",
+ "description": "${role_view-applications}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6fd2abe1-4aeb-4834-8a9e-e3f499d64a03",
+ "attributes": {}
+ },
+ {
+ "id": "471d721c-872c-4004-bb76-e6399f5e1fd0",
+ "name": "delete-account",
+ "description": "${role_delete-account}",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6fd2abe1-4aeb-4834-8a9e-e3f499d64a03",
+ "attributes": {}
+ },
+ {
+ "id": "e5a0f953-bdcb-4136-bfbf-0c311797e57f",
+ "name": "manage-account",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6fd2abe1-4aeb-4834-8a9e-e3f499d64a03",
+ "attributes": {}
+ },
+ {
+ "id": "c8726cd0-6447-4131-9731-717897ff167a",
+ "name": "manage-consent",
+ "description": "${role_manage-consent}",
+ "composite": true,
+ "composites": {
+ "client": {
+ "account": [
+ "view-consent"
+ ]
+ }
+ },
+ "clientRole": true,
+ "containerId": "6fd2abe1-4aeb-4834-8a9e-e3f499d64a03",
+ "attributes": {}
+ },
+ {
+ "id": "eb6c2340-cecf-4095-bdc7-d14f38a9aee6",
+ "name": "view-profile",
+ "composite": false,
+ "clientRole": true,
+ "containerId": "6fd2abe1-4aeb-4834-8a9e-e3f499d64a03",
+ "attributes": {}
+ }
+ ],
+ }
+ },
+ "groups": [
+ {
+ "id": "d372cb0e-f3c8-40be-8527-73775d1f7e47",
+ "name": "example-tenant-admin",
+ "path": "/example-tenant-admin",
+ "attributes": {},
+ "realmRoles": [],
+ "clientRoles": {},
+ "subGroups": []
+ }
+ ],
+ "defaultRoles": [
+ "uma_authorization",
+ "offline_access"
+ ],
+ "requiredCredentials": [
+ "password"
+ ],
+ "otpPolicyType": "totp",
+ "otpPolicyAlgorithm": "HmacSHA1",
+ "otpPolicyInitialCounter": 0,
+ "otpPolicyDigits": 6,
+ "otpPolicyLookAheadWindow": 1,
+ "otpPolicyPeriod": 30,
+ "otpSupportedApplications": [
+ "FreeOTP",
+ "Google Authenticator"
+ ],
+ "webAuthnPolicyRpEntityName": "keycloak",
+ "webAuthnPolicySignatureAlgorithms": [
+ "ES256"
+ ],
+ "webAuthnPolicyRpId": "",
+ "webAuthnPolicyAttestationConveyancePreference": "not specified",
+ "webAuthnPolicyAuthenticatorAttachment": "not specified",
+ "webAuthnPolicyRequireResidentKey": "not specified",
+ "webAuthnPolicyUserVerificationRequirement": "not specified",
+ "webAuthnPolicyCreateTimeout": 0,
+ "webAuthnPolicyAvoidSameAuthenticatorRegister": false,
+ "webAuthnPolicyAcceptableAaguids": [],
+ "webAuthnPolicyPasswordlessRpEntityName": "keycloak",
+ "webAuthnPolicyPasswordlessSignatureAlgorithms": [
+ "ES256"
+ ],
+ "webAuthnPolicyPasswordlessRpId": "",
+ "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified",
+ "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified",
+ "webAuthnPolicyPasswordlessRequireResidentKey": "not specified",
+ "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified",
+ "webAuthnPolicyPasswordlessCreateTimeout": 0,
+ "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false,
+ "webAuthnPolicyPasswordlessAcceptableAaguids": [],
+ "users": [
+ {
+ "id": "3defcf9c-a89d-496e-9769-526bc65b6db6",
+ "createdTimestamp": 1609929909934,
+ "username": "admin",
+ "enabled": true,
+ "totp": false,
+ "emailVerified": false,
+ "firstName": "Zuul",
+ "lastName": "Administrator",
+ "email": "admin@example.com",
+ "credentials": [
+ {
+ "id": "1a05a791-be4d-4060-ae6b-e117c6c8de70",
+ "type": "password",
+ "createdDate": 1609929922393,
+ "secretData": "{\"value\":\"BtE429Fzy8ygtLLD+eEHHY5DzJr3pzDf5wBwR8ZD4HFRPPn6NldxGTy+0AEJBGAQt+dZ0eEqVV8edytNR8PwMw==\",\"salt\":\"jL8euyHG4ZQy2BUMY/LpIg==\",\"additionalParameters\":{}}",
+ "credentialData": "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+ }
+ ],
+ "disableableCredentialTypes": [],
+ "requiredActions": [],
+ "realmRoles": [
+ "uma_authorization",
+ "offline_access"
+ ],
+ "clientRoles": {
+ "account": [
+ "manage-account",
+ "view-profile"
+ ]
+ },
+ "notBefore": 0,
+ "groups": []
+ },
+ {
+ "id": "091fbeb0-ac10-47eb-a113-88fbb0a7988f",
+ "createdTimestamp": 1609929807691,
+ "username": "user1",
+ "enabled": true,
+ "totp": false,
+ "emailVerified": false,
+ "firstName": "User",
+ "lastName": "One",
+ "email": "user1@example.com",
+ "credentials": [
+ {
+ "id": "caec7277-9620-4232-b07f-10076ae32e17",
+ "type": "password",
+ "createdDate": 1609929824753,
+ "secretData": "{\"value\":\"XbD+O1HUVhvqMg2xP36il/haxbzS65GjV2YYwqJWGfJuztQCn2G5ArmeWcqMxEd6BEBnPjZCjM3tpaBSFluLvg==\",\"salt\":\"8dXWJvuUtbqZuBw3ZUL4zA==\",\"additionalParameters\":{}}",
+ "credentialData": "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+ }
+ ],
+ "disableableCredentialTypes": [],
+ "requiredActions": [],
+ "realmRoles": [
+ "uma_authorization",
+ "offline_access"
+ ],
+ "clientRoles": {
+ "account": [
+ "manage-account",
+ "view-profile"
+ ]
+ },
+ "notBefore": 0,
+ "groups": [
+ "/example-tenant-admin"
+ ]
+ },
+ {
+ "id": "633cbfcd-43d9-4588-9c74-7af4ea007dda",
+ "createdTimestamp": 1609929870956,
+ "username": "user2",
+ "enabled": true,
+ "totp": false,
+ "emailVerified": false,
+ "firstName": "User",
+ "lastName": "Two",
+ "email": "user2@example.com",
+ "credentials": [
+ {
+ "id": "1975173e-f07c-4223-9bf6-fa44dcd27cf0",
+ "type": "password",
+ "createdDate": 1609929881586,
+ "secretData": "{\"value\":\"SZ0ESXObiHfCOo4m9afbnpNaZ52H0k0VVuHe2PecmUZ4FxpAXbCsUimNNsz5VVRdqhAqWJi2AcExCoKFSJzeug==\",\"salt\":\"+pc2TGNg/CjypsBPjH0YJg==\",\"additionalParameters\":{}}",
+ "credentialData": "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+ }
+ ],
+ "disableableCredentialTypes": [],
+ "requiredActions": [],
+ "realmRoles": [
+ "uma_authorization",
+ "offline_access"
+ ],
+ "clientRoles": {
+ "account": [
+ "manage-account",
+ "view-profile"
+ ]
+ },
+ "notBefore": 0,
+ "groups": []
+ }
+ ],
+ "scopeMappings": [
+ {
+ "clientScope": "offline_access",
+ "roles": [
+ "offline_access"
+ ]
+ }
+ ],
+ "clientScopeMappings": {
+ "account": [
+ {
+ "client": "account-console",
+ "roles": [
+ "manage-account"
+ ]
+ }
+ ]
+ },
+ "clients": [
+ {
+ "id": "6fd2abe1-4aeb-4834-8a9e-e3f499d64a03",
+ "clientId": "account",
+ "name": "${client_account}",
+ "rootUrl": "${authBaseUrl}",
+ "baseUrl": "/realms/zuul-demo/account/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "**********",
+ "defaultRoles": [
+ "manage-account",
+ "view-profile"
+ ],
+ "redirectUris": [
+ "/realms/zuul-demo/account/*"
+ ],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "role_list",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "1958e9b1-c3ce-4bec-89bd-3b0050a4dacf",
+ "clientId": "account-console",
+ "name": "${client_account-console}",
+ "rootUrl": "${authBaseUrl}",
+ "baseUrl": "/realms/zuul-demo/account/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "e555a236-3a76-4ac9-a55a-48f81a00535f",
+ "redirectUris": [
+ "/realms/zuul-demo/account/*"
+ ],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "pkce.code.challenge.method": "S256"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "protocolMappers": [
+ {
+ "id": "5a075254-4849-43dc-b036-53c606571988",
+ "name": "audience resolve",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-resolve-mapper",
+ "consentRequired": false,
+ "config": {}
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "role_list",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "3e59f406-d6b9-45bd-b072-ef1650233625",
+ "clientId": "admin-cli",
+ "name": "${client_admin-cli}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "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": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "role_list",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "b607307d-dde7-4563-9e70-a7fa9223c229",
+ "clientId": "broker",
+ "name": "${client_broker}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "**********",
+ "redirectUris": [],
+ "webOrigins": [],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": false,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "role_list",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "63ae0908-5213-436d-b3d6-5a611eb24216",
+ "clientId": "realm-management",
+ "name": "${client_realm-management}",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "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": {},
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "defaultClientScopes": [
+ "web-origins",
+ "role_list",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "26cb8208-4182-478b-903e-6abe9b555680",
+ "clientId": "security-admin-console",
+ "name": "${client_security-admin-console}",
+ "rootUrl": "${authAdminUrl}",
+ "baseUrl": "/admin/zuul-demo/console/",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "**********",
+ "redirectUris": [
+ "/admin/zuul-demo/console/*"
+ ],
+ "webOrigins": [
+ "+"
+ ],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": false,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "pkce.code.challenge.method": "S256"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": false,
+ "nodeReRegistrationTimeout": 0,
+ "protocolMappers": [
+ {
+ "id": "9077bfa3-32f2-4690-a1f4-fdb2726a6ef2",
+ "name": "locale",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "locale",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "locale",
+ "jsonType.label": "String"
+ }
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "role_list",
+ "profile",
+ "roles",
+ "email"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ },
+ {
+ "id": "118b61cd-e410-414a-a4ee-64e5722725b7",
+ "clientId": "zuul",
+ "description": "zuul oauth client",
+ "rootUrl": "http://localhost:9000",
+ "adminUrl": "http://localhost:9000",
+ "surrogateAuthRequired": false,
+ "enabled": true,
+ "alwaysDisplayInConsole": false,
+ "clientAuthenticatorType": "client-secret",
+ "secret": "**********",
+ "redirectUris": [
+ "http://127.0.0.1:9000/*",
+ "http://localhost:9000/*",
+ "http://127.0.0.1:3000/*",
+ "http://localhost:3000/*"
+ ],
+ "webOrigins": [
+ "http://localhost:9000",
+ "http://localhost:3000"
+ ],
+ "notBefore": 0,
+ "bearerOnly": false,
+ "consentRequired": false,
+ "standardFlowEnabled": true,
+ "implicitFlowEnabled": true,
+ "directAccessGrantsEnabled": false,
+ "serviceAccountsEnabled": false,
+ "publicClient": true,
+ "frontchannelLogout": false,
+ "protocol": "openid-connect",
+ "attributes": {
+ "saml.assertion.signature": "false",
+ "saml.force.post.binding": "false",
+ "saml.multivalued.roles": "false",
+ "saml.encrypt": "false",
+ "saml.server.signature": "false",
+ "saml.server.signature.keyinfo.ext": "false",
+ "exclude.session.state.from.auth.response": "true",
+ "saml_force_name_id_format": "false",
+ "saml.client.signature": "false",
+ "tls.client.certificate.bound.access.tokens": "false",
+ "saml.authnstatement": "false",
+ "display.on.consent.screen": "false",
+ "saml.onetimeuse.condition": "false"
+ },
+ "authenticationFlowBindingOverrides": {},
+ "fullScopeAllowed": true,
+ "nodeReRegistrationTimeout": -1,
+ "protocolMappers": [
+ {
+ "id": "2389430c-5b5e-4185-a116-a89fe9b2cbe0",
+ "name": "groups",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-group-membership-mapper",
+ "consentRequired": false,
+ "config": {
+ "full.path": "false",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "groups",
+ "userinfo.token.claim": "true"
+ }
+ }
+ ],
+ "defaultClientScopes": [
+ "web-origins",
+ "role_list",
+ "profile",
+ "roles",
+ "email",
+ "zuul_audience"
+ ],
+ "optionalClientScopes": [
+ "address",
+ "phone",
+ "offline_access",
+ "microprofile-jwt"
+ ]
+ }
+ ],
+ "clientScopes": [
+ {
+ "id": "a8ff8d15-7e18-46a7-afe9-cb4b51317f21",
+ "name": "address",
+ "description": "OpenID Connect built-in scope: address",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${addressScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "2fb91b25-bf0f-4d30-8c32-8da4d6e2e14a",
+ "name": "address",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-address-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute.formatted": "formatted",
+ "user.attribute.country": "country",
+ "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": "2491f163-0678-4222-974b-42851cb8bbea",
+ "name": "email",
+ "description": "OpenID Connect built-in scope: email",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${emailScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "247ada79-fd01-4e62-9231-46e09f2de990",
+ "name": "email",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "email",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "email",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "6a89efdc-4a19-4059-943f-fbf4b0c80fbc",
+ "name": "email verified",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "emailVerified",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "email_verified",
+ "jsonType.label": "boolean"
+ }
+ }
+ ]
+ },
+ {
+ "id": "77dc1544-6890-4714-acb5-bce0d34c15d5",
+ "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": "f1cc4b3b-6f0d-4564-b157-8e7790764643",
+ "name": "groups",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-realm-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "multivalued": "true",
+ "userinfo.token.claim": "true",
+ "user.attribute": "foo",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "groups",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "e9382111-9f81-455b-805a-9252c4c3db24",
+ "name": "upn",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "username",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "upn",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "7652d555-2c47-4312-85bb-b33e3f6d53ac",
+ "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": "e0d29ae8-b246-4d7c-bb0e-9b1f3b2fb95c",
+ "name": "phone",
+ "description": "OpenID Connect built-in scope: phone",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${phoneScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "b68bd653-6780-4cd7-a588-31073e2cc88b",
+ "name": "phone number verified",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "phoneNumberVerified",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "phone_number_verified",
+ "jsonType.label": "boolean"
+ }
+ },
+ {
+ "id": "08a83a89-6029-4c5d-9fe1-3aaaed3a1579",
+ "name": "phone number",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "phoneNumber",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "phone_number",
+ "jsonType.label": "String"
+ }
+ }
+ ]
+ },
+ {
+ "id": "2890097c-f60f-4690-a964-005272790b26",
+ "name": "profile",
+ "description": "OpenID Connect built-in scope: profile",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${profileScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "c7fa5831-9380-42d8-929a-a31e89b0dca5",
+ "name": "given name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "firstName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "given_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "fcb6f43b-0dfd-42c4-8f96-2b25078be8cf",
+ "name": "middle name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "middleName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "middle_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "15cc1330-fc07-4852-bd72-746ea7c70fc1",
+ "name": "locale",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "locale",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "locale",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "59e8530c-0630-46e3-b1db-629bd8bafa78",
+ "name": "birthdate",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "birthdate",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "birthdate",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "42a077a7-5a55-4838-b952-33f049fb5fc3",
+ "name": "family name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "lastName",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "family_name",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "bdc4888d-48ae-4d56-b1cd-d256c50d9b64",
+ "name": "nickname",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "nickname",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "nickname",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "97fb10c8-ff6e-4ccc-a25a-cfae87e783ef",
+ "name": "profile",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "profile",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "profile",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "adb8eb09-943b-4e6f-a7ee-bc531a55e359",
+ "name": "gender",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "gender",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "gender",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "c2260f1f-eb68-4186-b86c-74c23a450151",
+ "name": "zoneinfo",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "zoneinfo",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "zoneinfo",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "e618b191-1c20-466d-a412-9b59a221d587",
+ "name": "updated at",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "updatedAt",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "updated_at",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "bf72e820-32b2-41ff-a812-7349dbc97dc1",
+ "name": "website",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "website",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "website",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "00ec085d-5cdc-4009-968a-bc03843e0418",
+ "name": "username",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-property-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "username",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "preferred_username",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "e7f8706d-04b2-4ceb-97e0-d6c50f268653",
+ "name": "picture",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-attribute-mapper",
+ "consentRequired": false,
+ "config": {
+ "userinfo.token.claim": "true",
+ "user.attribute": "picture",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "claim.name": "picture",
+ "jsonType.label": "String"
+ }
+ },
+ {
+ "id": "dc881508-6029-4af0-9ab4-bc84613d0bfe",
+ "name": "full name",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-full-name-mapper",
+ "consentRequired": false,
+ "config": {
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "userinfo.token.claim": "true"
+ }
+ }
+ ]
+ },
+ {
+ "id": "a45a99e9-3413-4dbe-a1bf-da76d82c6887",
+ "name": "role_list",
+ "description": "SAML role list",
+ "protocol": "saml",
+ "attributes": {
+ "consent.screen.text": "${samlRoleListScopeConsentText}",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "8fdf3fb9-4eeb-4e14-986e-7c9711838ca5",
+ "name": "role list",
+ "protocol": "saml",
+ "protocolMapper": "saml-role-list-mapper",
+ "consentRequired": false,
+ "config": {
+ "single": "false",
+ "attribute.nameformat": "Basic",
+ "attribute.name": "Role"
+ }
+ }
+ ]
+ },
+ {
+ "id": "cf8edb74-1db4-4cc0-89fa-ec2a9ef19565",
+ "name": "roles",
+ "description": "OpenID Connect scope for add user roles to the access token",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "false",
+ "display.on.consent.screen": "true",
+ "consent.screen.text": "${rolesScopeConsentText}"
+ },
+ "protocolMappers": [
+ {
+ "id": "67629d5f-39aa-4521-b936-91964357e630",
+ "name": "audience resolve",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-resolve-mapper",
+ "consentRequired": false,
+ "config": {}
+ },
+ {
+ "id": "75458c67-6f8c-4646-a851-c3a5f6c9c6e1",
+ "name": "client roles",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-client-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "foo",
+ "access.token.claim": "true",
+ "claim.name": "resource_access.${client_id}.roles",
+ "jsonType.label": "String",
+ "multivalued": "true"
+ }
+ },
+ {
+ "id": "059aa66a-7d91-4116-8b4e-51f5ab57424c",
+ "name": "realm roles",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-usermodel-realm-role-mapper",
+ "consentRequired": false,
+ "config": {
+ "user.attribute": "foo",
+ "access.token.claim": "true",
+ "claim.name": "realm_access.roles",
+ "jsonType.label": "String",
+ "multivalued": "true"
+ }
+ }
+ ]
+ },
+ {
+ "id": "2637f0c2-5d96-4057-a032-ce8f11477048",
+ "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",
+ "display.on.consent.screen": "false",
+ "consent.screen.text": ""
+ },
+ "protocolMappers": [
+ {
+ "id": "33cbf353-644c-4801-91c1-b6ca677f65d2",
+ "name": "allowed web origins",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-allowed-origins-mapper",
+ "consentRequired": false,
+ "config": {}
+ }
+ ]
+ },
+ {
+ "id": "ace09ede-6cf1-4e36-9557-91beb58ce557",
+ "name": "zuul_audience",
+ "description": "fix audience claim for Zuul",
+ "protocol": "openid-connect",
+ "attributes": {
+ "include.in.token.scope": "true",
+ "display.on.consent.screen": "true"
+ },
+ "protocolMappers": [
+ {
+ "id": "9a1029e7-f142-4ff1-ba47-50ca6bb24073",
+ "name": "zuul_audience_mapper",
+ "protocol": "openid-connect",
+ "protocolMapper": "oidc-audience-mapper",
+ "consentRequired": false,
+ "config": {
+ "included.client.audience": "zuul",
+ "id.token.claim": "true",
+ "access.token.claim": "true",
+ "userinfo.token.claim": "true"
+ }
+ }
+ ]
+ }
+ ],
+ "defaultDefaultClientScopes": [
+ "email",
+ "web-origins",
+ "profile",
+ "role_list",
+ "roles"
+ ],
+ "defaultOptionalClientScopes": [
+ "offline_access",
+ "microprofile-jwt",
+ "address",
+ "phone"
+ ],
+ "browserSecurityHeaders": {
+ "contentSecurityPolicyReportOnly": "",
+ "xContentTypeOptions": "nosniff",
+ "xRobotsTag": "none",
+ "xFrameOptions": "SAMEORIGIN",
+ "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
+ "xXSSProtection": "1; mode=block",
+ "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": "909674c7-fb40-458b-af37-8372300725b1",
+ "name": "Max Clients Limit",
+ "providerId": "max-clients",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "max-clients": [
+ "200"
+ ]
+ }
+ },
+ {
+ "id": "b350d08d-4298-4d76-bd94-e120b1aadd28",
+ "name": "Allowed Client Scopes",
+ "providerId": "allowed-client-templates",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "allow-default-scopes": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "4c1d186e-250d-497b-ac28-b7dffd021c19",
+ "name": "Allowed Protocol Mapper Types",
+ "providerId": "allowed-protocol-mappers",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "allowed-protocol-mapper-types": [
+ "oidc-address-mapper",
+ "oidc-sha256-pairwise-sub-mapper",
+ "saml-user-attribute-mapper",
+ "oidc-full-name-mapper",
+ "oidc-usermodel-attribute-mapper",
+ "saml-user-property-mapper",
+ "oidc-usermodel-property-mapper",
+ "saml-role-list-mapper"
+ ]
+ }
+ },
+ {
+ "id": "74a38dd7-41bf-414e-9858-f4f287c8caf3",
+ "name": "Full Scope Disabled",
+ "providerId": "scope",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {}
+ },
+ {
+ "id": "19082549-290b-4e93-bd77-6ce5cc386b63",
+ "name": "Allowed Protocol Mapper Types",
+ "providerId": "allowed-protocol-mappers",
+ "subType": "authenticated",
+ "subComponents": {},
+ "config": {
+ "allowed-protocol-mapper-types": [
+ "saml-user-property-mapper",
+ "oidc-usermodel-attribute-mapper",
+ "oidc-address-mapper",
+ "oidc-usermodel-property-mapper",
+ "saml-role-list-mapper",
+ "saml-user-attribute-mapper",
+ "oidc-full-name-mapper",
+ "oidc-sha256-pairwise-sub-mapper"
+ ]
+ }
+ },
+ {
+ "id": "62c50eea-fc15-40f1-a3c0-9923dcb8a8c7",
+ "name": "Trusted Hosts",
+ "providerId": "trusted-hosts",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {
+ "host-sending-registration-request-must-match": [
+ "true"
+ ],
+ "client-uris-must-match": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "21095085-2c9b-45ea-99d3-9ce962ab2020",
+ "name": "Allowed Client Scopes",
+ "providerId": "allowed-client-templates",
+ "subType": "authenticated",
+ "subComponents": {},
+ "config": {
+ "allow-default-scopes": [
+ "true"
+ ]
+ }
+ },
+ {
+ "id": "36577457-a002-4b44-8029-9a599f2395a5",
+ "name": "Consent Required",
+ "providerId": "consent-required",
+ "subType": "anonymous",
+ "subComponents": {},
+ "config": {}
+ }
+ ],
+ "org.keycloak.keys.KeyProvider": [
+ {
+ "id": "0a6a397a-6eb1-46ab-8c6d-a3d4ea47f085",
+ "name": "rsa-generated",
+ "providerId": "rsa-generated",
+ "subComponents": {},
+ "config": {
+ "privateKey": [
+ "MIIEpQIBAAKCAQEA3q7PYMrX38XUpUScjbEn/4oyv5AI5TsyoFEPhgCFHzGEkeXWop3PNhh3OgFpz2Tn6qEqs9vRWi/8VDVC73lOZJWn70qfCDlr9Acmm1eKhrWkyHH6ONyg7qPj/PSsjapSsto5rVp1tdaOfObgWaLvg9dsOmbF+P6vUT6ggUD1p73KHySdDKiKHUTbaxaOVgDVTzeptDRg2iFaz+E0ETBsFKcJgXuPVd4IlxaXogDFLTKo6j2ITtnU8hw4wlqY3pkLI5OHP9EKmkV94fzmfYIoMxv4vLkwWRdz24hB459OCeDH0su25+JNnA0WA5SPRTUepeAsuZIFletYw2Mq/BFN5QIDAQABAoIBAQCX9e043VOxtjwlyAuZueJUxUdaaH1ZiStEMe0JAgPWRKF2OsVc1ZpZDRsXr204hWCqQe91K7XS+NoV0P7rkvmHNIWUi3S5VQ4xSkvzSCsVQJHB493gvdbo41iq/4Fdb3Td7oPbo9aeD1vPKnLBWKpgazrFI+tHvu1+4OEBM4YwP9KPXK4QOlxKFjzwGIeSgyMd3KnHbC6b9C8rlrf7b9Uj4UPVpGtNuPqTJyOeBTHh8CNJzYWYN0BPHk8DCMPaFkMXx42gSLsAAVOO1Kczby31Ac2IUIVDn/Z5kBmgxd6BWoVDSh1NpAlAYhK2A+LNUzveetE60CC80k387/N0JdlFAoGBAPr1v/e3rlD2pS3YA8UNQTcJjTJAvAuUw9kPXxYQd6G3UtuGwYNRw9DgZSA2E3eojzs6hLuS4W0mIVkmGwa/6SXD5TVbdaWbGO8C+x/Kxz0doRoM2AhA64uMy6zUNMwqIjroNuVn9vj8n5lMND4qqhMifYYuv9CQvyYOlXOSaFZTAoGBAOMnriWZQJqnLcd9zjr3DLxbrp/XCSLVvYRRVEleLkB+tahIFMNez50JHdTJb/TctDRfAFlZT2o0XI+FrHSqFI81UZes/cH2uqaIo+CgwRS4WY7f+Sp/ao6y+WZl2+Ip+Ao/QwjOvQ6u2jL+rCmZrPzoKoQHJaT+7WlHV2zZh9PnAoGBAOfquyCdakX/6N3YxoMPoLjP5uAN2rmJHQQ2pFSrmyKjW7rraWGF6kPZWxrNXmgyKUs+5PLC5fgMSL0t7cPrDfaMdgE9KBeGoSAfzRqwNjdQblS4kdvuwr4PuxlYcgJK3Z86gaC21xF5w7PTLGRW4R0VvpKGGVUQrtTonUxUfH9pAoGBALezd1pgvaZUXOlgDFATSvFpE6egN3s8b696Nje/Ophd4HrfECuPmUbeAIn8/dWARxuzWIzpdRfmkJRg/j667TWDYSDQfcdGyVu0VRNr7bnb/FFXQCHmOT597sOozFHyru1ai9OrnakqLrveyUw7Q3KkLv3m6cKth0IEt+cHZJkxAoGAHIGs8zI/Bp2U4Z4yHedyQ/tGF8Vk+ZehIsaHhOGEp3Cps4af5LBA5bstkArFsz+NJ7oDrxVBMUUNNypyUX4UF6EDcyZ+2vwBeill9fZqKR7BBBdC2AS6mT52gcCbFqBiGMHd+tYQj0tYnsann5e2a0ssqdXTYUn9YJO6iWh8EGY="
+ ],
+ "certificate": [
+ "MIICoTCCAYkCBgF210UjOTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAl6dXVsLWRlbW8wHhcNMjEwMTA2MTAzNTAxWhcNMzEwMTA2MTAzNjQxWjAUMRIwEAYDVQQDDAl6dXVsLWRlbW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDers9gytffxdSlRJyNsSf/ijK/kAjlOzKgUQ+GAIUfMYSR5dainc82GHc6AWnPZOfqoSqz29FaL/xUNULveU5klafvSp8IOWv0ByabV4qGtaTIcfo43KDuo+P89KyNqlKy2jmtWnW11o585uBZou+D12w6ZsX4/q9RPqCBQPWnvcofJJ0MqIodRNtrFo5WANVPN6m0NGDaIVrP4TQRMGwUpwmBe49V3giXFpeiAMUtMqjqPYhO2dTyHDjCWpjemQsjk4c/0QqaRX3h/OZ9gigzG/i8uTBZF3PbiEHjn04J4MfSy7bn4k2cDRYDlI9FNR6l4Cy5kgWV61jDYyr8EU3lAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEFDFCBBNEtzOuAs46BRNBzGO2QCvLXsBASKSDFTsv2AMaFJIlc9l5U16wMcrZMTvsPY5MQxuaZvIDyAQH7NaxuRW7siZFBMRtwPmSrPHb/XqGh5OO4lXLX+Vpnx/JuMt9dOgyr9hTIYZ2UCFYxdC7ht21XSlRU6dZfEO8lTu+XEPQil42sZ/aB2efKfgWHieNvzTx3RLfG9lbsP4Dhg7FX+rGDz3Ql8PCl0Puai4pDwMjvvpZcZBjEzonw9pQ1rlSyGx0DLSJxMPMlQ33auVwLYD3MYIrgJplnScA0aKelOYJrnbSFMOlb/DwKxQNvM77banJQGq5Lpn617r2FmHNk="
+ ],
+ "priority": [
+ "100"
+ ]
+ }
+ },
+ {
+ "id": "78880d4c-8ff2-4619-82b4-02a8fbd4a624",
+ "name": "hmac-generated",
+ "providerId": "hmac-generated",
+ "subComponents": {},
+ "config": {
+ "kid": [
+ "a23a2cdc-8d85-4754-b885-fc14a9e1a7bc"
+ ],
+ "secret": [
+ "k5rhshjW9QaQvYnfC4nZUzQRkLZHKJlW524t125u63s9nza8ptFhPkLl7C3AGYSS6vD3tKSfOvkGuxubsRIJKg"
+ ],
+ "priority": [
+ "100"
+ ],
+ "algorithm": [
+ "HS256"
+ ]
+ }
+ },
+ {
+ "id": "96281deb-af4d-49f8-a35c-10993007c7df",
+ "name": "aes-generated",
+ "providerId": "aes-generated",
+ "subComponents": {},
+ "config": {
+ "kid": [
+ "074f1951-9f97-40ff-8f0a-4219353d6f3d"
+ ],
+ "secret": [
+ "Csz6nXZD0tf117pBKkJ7qw"
+ ],
+ "priority": [
+ "100"
+ ]
+ }
+ }
+ ]
+ },
+ "internationalizationEnabled": false,
+ "supportedLocales": [],
+ "authenticationFlows": [
+ {
+ "id": "3e95c1d5-2e16-40ad-89d3-cc13bd514fee",
+ "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",
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "flowAlias": "Verify Existing Account by Re-authentication",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "7143f715-1076-4c59-a039-34c5ec30d7e8",
+ "alias": "Authentication Options",
+ "description": "Authentication options.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "basic-auth",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "basic-auth-otp",
+ "requirement": "DISABLED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "auth-spnego",
+ "requirement": "DISABLED",
+ "priority": 30,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "e3804922-4ffa-4e53-aa28-e982730f96a5",
+ "alias": "Browser - 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",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "auth-otp-form",
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "e5ba2a92-70f1-4559-b31a-968363222c72",
+ "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",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "direct-grant-validate-otp",
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "617c8570-c7aa-4b4a-8b52-3bb94dc7ba04",
+ "alias": "First broker login - 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",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "auth-otp-form",
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "7bf3d19b-f551-4c1f-9188-850923a403b1",
+ "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",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "flowAlias": "Account verification options",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "ff1dd822-547c-4e25-8c9e-5b7a3dd30504",
+ "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",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "reset-otp",
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "3b586469-9250-4bbf-9af0-f3ad81ce2eaa",
+ "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",
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "flowAlias": "Handle Existing Account",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "80831f25-c4ab-4ad8-ad6c-f1d7b570d919",
+ "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",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "requirement": "CONDITIONAL",
+ "priority": 20,
+ "flowAlias": "First broker login - Conditional OTP",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "dec78792-6cf8-4752-9833-18c1386423df",
+ "alias": "browser",
+ "description": "browser based authentication",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "auth-cookie",
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "auth-spnego",
+ "requirement": "DISABLED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "identity-provider-redirector",
+ "requirement": "ALTERNATIVE",
+ "priority": 25,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "requirement": "ALTERNATIVE",
+ "priority": 30,
+ "flowAlias": "forms",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "14c06286-51e3-4abc-af50-8554c57c9f8f",
+ "alias": "clients",
+ "description": "Base authentication for clients",
+ "providerId": "client-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "client-secret",
+ "requirement": "ALTERNATIVE",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "client-jwt",
+ "requirement": "ALTERNATIVE",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "client-secret-jwt",
+ "requirement": "ALTERNATIVE",
+ "priority": 30,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "client-x509",
+ "requirement": "ALTERNATIVE",
+ "priority": 40,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "54d29594-0183-486f-abb2-c1998d4e45c5",
+ "alias": "direct grant",
+ "description": "OpenID Connect Resource Owner Grant",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "direct-grant-validate-username",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "direct-grant-validate-password",
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "requirement": "CONDITIONAL",
+ "priority": 30,
+ "flowAlias": "Direct Grant - Conditional OTP",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "e6734c68-8029-4b27-bf56-7eccb2202903",
+ "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",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "0e26f9c0-bc34-4d38-b3fe-472580bff946",
+ "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",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "flowAlias": "User creation or linking",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "6f56d749-5f06-4e2a-a043-cd4103383899",
+ "alias": "forms",
+ "description": "Username, password, otp and other auth forms.",
+ "providerId": "basic-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "auth-username-password-form",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "requirement": "CONDITIONAL",
+ "priority": 20,
+ "flowAlias": "Browser - Conditional OTP",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "4a95b320-312e-468a-978e-215747302385",
+ "alias": "http challenge",
+ "description": "An authentication flow based on challenge-response HTTP Authentication Schemes",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "no-cookie-redirect",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "flowAlias": "Authentication Options",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "17678e79-9819-47f8-bbfe-3b68efb92f3d",
+ "alias": "registration",
+ "description": "registration flow",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "registration-page-form",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "flowAlias": "registration form",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "7c23bfaa-420a-4975-a547-254bb0873457",
+ "alias": "registration form",
+ "description": "registration form",
+ "providerId": "form-flow",
+ "topLevel": false,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "registration-user-creation",
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "registration-profile-action",
+ "requirement": "REQUIRED",
+ "priority": 40,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "registration-password-action",
+ "requirement": "REQUIRED",
+ "priority": 50,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "registration-recaptcha-action",
+ "requirement": "DISABLED",
+ "priority": 60,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ },
+ {
+ "id": "ef21d1d8-4afd-4baf-a44d-34d657f673a4",
+ "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",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "reset-credential-email",
+ "requirement": "REQUIRED",
+ "priority": 20,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "authenticator": "reset-password",
+ "requirement": "REQUIRED",
+ "priority": 30,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ },
+ {
+ "requirement": "CONDITIONAL",
+ "priority": 40,
+ "flowAlias": "Reset - Conditional OTP",
+ "userSetupAllowed": false,
+ "autheticatorFlow": true
+ }
+ ]
+ },
+ {
+ "id": "21fea2f5-c4e3-46af-a573-54f36aa25b4b",
+ "alias": "saml ecp",
+ "description": "SAML ECP Profile Authentication Flow",
+ "providerId": "basic-flow",
+ "topLevel": true,
+ "builtIn": true,
+ "authenticationExecutions": [
+ {
+ "authenticator": "http-basic-authenticator",
+ "requirement": "REQUIRED",
+ "priority": 10,
+ "userSetupAllowed": false,
+ "autheticatorFlow": false
+ }
+ ]
+ }
+ ],
+ "authenticatorConfig": [
+ {
+ "id": "d093ee16-2996-4916-ba26-827877401a45",
+ "alias": "create unique user config",
+ "config": {
+ "require.password.update.after.registration": "false"
+ }
+ },
+ {
+ "id": "9cf393f2-4659-473a-a1d8-2318e107fcfe",
+ "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": "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",
+ "attributes": {
+ "clientOfflineSessionMaxLifespan": "0",
+ "clientSessionIdleTimeout": "0",
+ "clientSessionMaxLifespan": "0",
+ "clientOfflineSessionIdleTimeout": "0"
+ },
+ "keycloakVersion": "12.0.1",
+ "userManagedAccessAllowed": false
+}
diff --git a/doc/source/reference/developer/javascript.rst b/doc/source/reference/developer/javascript.rst
index 4d7af91a7..d06af5f41 100644
--- a/doc/source/reference/developer/javascript.rst
+++ b/doc/source/reference/developer/javascript.rst
@@ -202,6 +202,15 @@ To run eslint tests locally:
yarn lint
+Authentication
+~~~~~~~~~~~~~~
+
+The docker-compose file in ``doc/source/examples/keycloak`` can be
+used to run a Keycloak server for use with a development build of the
+web app. The default values in that file are already set up for the
+web app running on localhost. See the Keycloak tutorial for details.
+
+
Deploying
---------
diff --git a/doc/source/tutorials/admin.rst b/doc/source/tutorials/admin.rst
index 826d56062..0b1c98c97 100644
--- a/doc/source/tutorials/admin.rst
+++ b/doc/source/tutorials/admin.rst
@@ -5,3 +5,4 @@ Admin Tutorials
:maxdepth: 1
quick-start
+ keycloak
diff --git a/doc/source/tutorials/keycloak.rst b/doc/source/tutorials/keycloak.rst
new file mode 100644
index 000000000..cc209ebd0
--- /dev/null
+++ b/doc/source/tutorials/keycloak.rst
@@ -0,0 +1,78 @@
+Keycloak Tutorial
+=================
+
+Zuul supports an authenticated API accessible via its web app which
+can be used to perform some administrative actions. To see this in
+action, first run the :ref:`quick_start` and then follow the steps in
+this tutorial to add a Keycloak server.
+
+Zuul supports any identity provider that can supply a JWT using OpenID
+Connect. Keycloak is used here because it is entirely self-contained.
+Google authentication is one additional option described elsewhere in
+the documentation.
+
+Gerrit can be updated to use the same authentication system as Zuul,
+but this tutorial does not address that.
+
+Update /etc/hosts
+-----------------
+
+The Zuul containers will use the internal docker network to connect to
+keycloak, but you will use a mapped port to access it in your web
+browser. There is no way to have Zuul use the internal hostname when
+it validates the token yet redirect your browser to `localhost` to
+obtain the token, therefore you will need to add a matching host entry
+to `/etc/hosts`. Make sure you have a line that looks like this:
+
+.. code-block::
+
+ 127.0.0.1 localhost keycloak
+
+Restart Zuul Containers
+-----------------------
+
+After completing the initial tutorial, stop the Zuul containers so
+that we can update Zuul's configuration to add authentication.
+
+.. code-block:: shell
+
+ cd zuul/doc/source/examples
+ sudo -E docker-compose -p zuul-tutorial down
+
+Restart the containers with a new Zuul configuration.
+
+.. code-block:: shell
+
+ cd zuul/doc/source/examples
+ ZUUL_TUTORIAL_CONFIG="./keycloak/etc_zuul/" sudo -E docker-compose -p zuul-tutorial up -d
+
+This tells docker-compose to use these Zuul `config files
+<https://opendev.org/zuul/zuul/src/branch/master/doc/source/examples/keycloak>`_.
+
+Start Keycloak
+--------------
+
+A separate docker-compose file is supplied to run Keycloak. Start it
+with this command:
+
+.. code-block:: shell
+
+ cd zuul/doc/source/examples/keycloak
+ sudo -E docker-compose -p zuul-tutorial-keycloak up -d
+
+Once Keycloak is running, you can visit the web interface at
+http://localhost:8082/
+
+The Keycloak administrative user is `admin` with a password of
+`kcadmin`.
+
+Log Into Zuul
+-------------
+
+Visit http://localhost:9000/t/example-tenant/autoholds and click the
+login icon on the top right. You will be directed to Keycloak, where
+you can log into the Zuul realm with the user `admin` and password
+`admin`.
+
+Once you return to Zuul, you should see the option to create an
+autohold -- an admin-only option.