diff --git a/keycloak/data/test-realm.json b/keycloak/data/test-realm.json
new file mode 100644
index 00000000..78115de2
--- /dev/null
+++ b/keycloak/data/test-realm.json
@@ -0,0 +1,2328 @@
+{
+  "id" : "f74c917b-fd69-4c6d-9afa-d9f6774e9d7d",
+  "realm" : "test",
+  "notBefore" : 0,
+  "defaultSignatureAlgorithm" : "RS256",
+  "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,
+  "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,
+  "maxFailureWaitSeconds" : 900,
+  "minimumQuickLoginWaitSeconds" : 60,
+  "waitIncrementSeconds" : 60,
+  "quickLoginCheckMilliSeconds" : 1000,
+  "maxDeltaTimeSeconds" : 43200,
+  "failureFactor" : 30,
+  "roles" : {
+    "realm" : [ {
+      "id" : "28c07910-21e3-460d-98f3-18bdb430ffe1",
+      "name" : "default-roles-test",
+      "description" : "${role_default-roles}",
+      "composite" : true,
+      "composites" : {
+        "realm" : [ "offline_access", "uma_authorization" ],
+        "client" : {
+          "account" : [ "view-profile", "manage-account" ]
+        }
+      },
+      "clientRole" : false,
+      "containerId" : "f74c917b-fd69-4c6d-9afa-d9f6774e9d7d",
+      "attributes" : { }
+    }, {
+      "id" : "a3d84717-84c9-4d08-a90c-01b4d913b919",
+      "name" : "offline_access",
+      "description" : "${role_offline-access}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "f74c917b-fd69-4c6d-9afa-d9f6774e9d7d",
+      "attributes" : { }
+    }, {
+      "id" : "50173816-9726-4655-8a65-13b0d0c23729",
+      "name" : "uma_authorization",
+      "description" : "${role_uma_authorization}",
+      "composite" : false,
+      "clientRole" : false,
+      "containerId" : "f74c917b-fd69-4c6d-9afa-d9f6774e9d7d",
+      "attributes" : { }
+    } ],
+    "client" : {
+      "realm-management" : [ {
+        "id" : "0c16a480-bbf3-49ad-8843-d4055cc83100",
+        "name" : "query-groups",
+        "description" : "${role_query-groups}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "e2fa2cdd-feb7-42b1-a0f9-c6653e62d578",
+        "name" : "manage-clients",
+        "description" : "${role_manage-clients}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "6d0c5def-b4d0-43b6-87c6-9cf6d6f9f2fb",
+        "name" : "realm-admin",
+        "description" : "${role_realm-admin}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "realm-management" : [ "query-groups", "manage-clients", "view-identity-providers", "query-clients", "view-authorization", "view-clients", "manage-events", "manage-users", "manage-identity-providers", "query-users", "create-client", "impersonation", "query-realms", "manage-authorization", "view-events", "manage-realm", "view-realm", "view-users" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "7d602068-73ae-4d83-bd9a-994a8dbf24b6",
+        "name" : "view-identity-providers",
+        "description" : "${role_view-identity-providers}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "670970ae-e6b0-44f8-bd0e-c6945d41cacf",
+        "name" : "query-clients",
+        "description" : "${role_query-clients}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "931ad9f0-c8ad-456a-a69d-d6c08abbe42a",
+        "name" : "view-authorization",
+        "description" : "${role_view-authorization}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "3015f5e3-f9b4-4938-bae2-c2e1415b01c3",
+        "name" : "view-clients",
+        "description" : "${role_view-clients}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "realm-management" : [ "query-clients" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "9648682e-3b89-4fa7-83e0-bd673d4d3119",
+        "name" : "manage-events",
+        "description" : "${role_manage-events}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "baa8f313-386c-4ade-832f-0d2a7da6a2bc",
+        "name" : "manage-users",
+        "description" : "${role_manage-users}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "f59ed8c2-772a-4faf-87a8-04e9e1f0a032",
+        "name" : "manage-identity-providers",
+        "description" : "${role_manage-identity-providers}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "3a950e7f-4762-4306-8d42-63fdd90aa212",
+        "name" : "query-users",
+        "description" : "${role_query-users}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "ab1e85d0-4e35-42ac-acc3-4fde650a1b9f",
+        "name" : "create-client",
+        "description" : "${role_create-client}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "f517cd55-5d1e-4baa-bedb-35fbb7135b24",
+        "name" : "impersonation",
+        "description" : "${role_impersonation}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "7c437eed-ebd0-41fe-a5f2-c569724b71e9",
+        "name" : "query-realms",
+        "description" : "${role_query-realms}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "8ec7b657-c507-4548-9a88-0c018350bdb9",
+        "name" : "manage-authorization",
+        "description" : "${role_manage-authorization}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "bfec4ce4-563a-4f9c-a678-f5cda9f554c4",
+        "name" : "view-events",
+        "description" : "${role_view-events}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "08ab5b1c-0d0c-4789-a595-81dcac9d4b5a",
+        "name" : "manage-realm",
+        "description" : "${role_manage-realm}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "fbfe356d-f049-475c-a7f3-35276f12173b",
+        "name" : "view-realm",
+        "description" : "${role_view-realm}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      }, {
+        "id" : "42c2f2c5-eb42-49e3-93a0-a6c352af85c5",
+        "name" : "view-users",
+        "description" : "${role_view-users}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "realm-management" : [ "query-users", "query-groups" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+        "attributes" : { }
+      } ],
+      "security-admin-console" : [ ],
+      "test-userinfo-jwt" : [ ],
+      "admin-cli" : [ ],
+      "testid" : [ ],
+      "account-console" : [ ],
+      "broker" : [ {
+        "id" : "b740a3c9-82ad-4b74-8a83-46c7d1d69441",
+        "name" : "read-token",
+        "description" : "${role_read-token}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "0263ec51-8f33-4f73-952b-8cdb1712028c",
+        "attributes" : { }
+      } ],
+      "account" : [ {
+        "id" : "70072e4f-0600-42d1-b490-92de314f63bb",
+        "name" : "view-groups",
+        "description" : "${role_view-groups}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "89fbc9e2-7a6c-4600-8ee8-f028644297fa",
+        "attributes" : { }
+      }, {
+        "id" : "87ffa29a-0a89-443b-bcf9-d26350bf74f8",
+        "name" : "view-applications",
+        "description" : "${role_view-applications}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "89fbc9e2-7a6c-4600-8ee8-f028644297fa",
+        "attributes" : { }
+      }, {
+        "id" : "f6d0fe38-c146-4aab-924e-24b2d63ed95f",
+        "name" : "view-profile",
+        "description" : "${role_view-profile}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "89fbc9e2-7a6c-4600-8ee8-f028644297fa",
+        "attributes" : { }
+      }, {
+        "id" : "0a6283c0-8c43-41e6-b6be-de81d6927b35",
+        "name" : "delete-account",
+        "description" : "${role_delete-account}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "89fbc9e2-7a6c-4600-8ee8-f028644297fa",
+        "attributes" : { }
+      }, {
+        "id" : "f45f95f0-6a9e-4e98-ae9b-75e9b41023a6",
+        "name" : "view-consent",
+        "description" : "${role_view-consent}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "89fbc9e2-7a6c-4600-8ee8-f028644297fa",
+        "attributes" : { }
+      }, {
+        "id" : "c21366ff-5003-4a3d-936d-925de4c347ae",
+        "name" : "manage-account-links",
+        "description" : "${role_manage-account-links}",
+        "composite" : false,
+        "clientRole" : true,
+        "containerId" : "89fbc9e2-7a6c-4600-8ee8-f028644297fa",
+        "attributes" : { }
+      }, {
+        "id" : "79e03b78-c3b2-4bcc-a04f-a58bba9a67a7",
+        "name" : "manage-account",
+        "description" : "${role_manage-account}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "account" : [ "manage-account-links" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "89fbc9e2-7a6c-4600-8ee8-f028644297fa",
+        "attributes" : { }
+      }, {
+        "id" : "9fd80770-e9cc-4393-aded-ce9969067b35",
+        "name" : "manage-consent",
+        "description" : "${role_manage-consent}",
+        "composite" : true,
+        "composites" : {
+          "client" : {
+            "account" : [ "view-consent" ]
+          }
+        },
+        "clientRole" : true,
+        "containerId" : "89fbc9e2-7a6c-4600-8ee8-f028644297fa",
+        "attributes" : { }
+      } ]
+    }
+  },
+  "groups" : [ {
+    "id" : "54b1af7e-173d-4319-85e0-d0848a106095",
+    "name" : "Registreerders",
+    "path" : "/Registreerders",
+    "subGroups" : [ ],
+    "attributes" : { },
+    "realmRoles" : [ ],
+    "clientRoles" : { }
+  } ],
+  "defaultRole" : {
+    "id" : "28c07910-21e3-460d-98f3-18bdb430ffe1",
+    "name" : "default-roles-test",
+    "description" : "${role_default-roles}",
+    "composite" : true,
+    "clientRole" : false,
+    "containerId" : "f74c917b-fd69-4c6d-9afa-d9f6774e9d7d"
+  },
+  "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" ],
+  "webAuthnPolicyRpId" : "",
+  "webAuthnPolicyAttestationConveyancePreference" : "not specified",
+  "webAuthnPolicyAuthenticatorAttachment" : "not specified",
+  "webAuthnPolicyRequireResidentKey" : "not specified",
+  "webAuthnPolicyUserVerificationRequirement" : "not specified",
+  "webAuthnPolicyCreateTimeout" : 0,
+  "webAuthnPolicyAvoidSameAuthenticatorRegister" : false,
+  "webAuthnPolicyAcceptableAaguids" : [ ],
+  "webAuthnPolicyExtraOrigins" : [ ],
+  "webAuthnPolicyPasswordlessRpEntityName" : "keycloak",
+  "webAuthnPolicyPasswordlessSignatureAlgorithms" : [ "ES256" ],
+  "webAuthnPolicyPasswordlessRpId" : "",
+  "webAuthnPolicyPasswordlessAttestationConveyancePreference" : "not specified",
+  "webAuthnPolicyPasswordlessAuthenticatorAttachment" : "not specified",
+  "webAuthnPolicyPasswordlessRequireResidentKey" : "not specified",
+  "webAuthnPolicyPasswordlessUserVerificationRequirement" : "not specified",
+  "webAuthnPolicyPasswordlessCreateTimeout" : 0,
+  "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister" : false,
+  "webAuthnPolicyPasswordlessAcceptableAaguids" : [ ],
+  "webAuthnPolicyPasswordlessExtraOrigins" : [ ],
+  "users" : [ {
+    "id" : "6db2db87-de31-4e30-9f25-cefe5da8b154",
+    "createdTimestamp" : 1716466774675,
+    "username" : "admin",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : true,
+    "email" : "admin@example.com",
+    "credentials" : [ {
+      "id" : "3f77857f-70ba-43d2-9333-c996ba0f7f25",
+      "type" : "password",
+      "userLabel" : "My password",
+      "createdDate" : 1716466894356,
+      "secretData" : "{\"value\":\"kxBJkhnwzRk2nb9aLM026KH+53AoV9Jv3vbW0KM/k1E=\",\"salt\":\"mbXY7a8/tk0m9xKflh+ZhA==\",\"additionalParameters\":{}}",
+      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+    } ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-test" ],
+    "notBefore" : 0,
+    "groups" : [ "/Registreerders" ]
+  }, {
+    "id" : "ec5a1f70-3d10-48a8-a18b-2d13c925cd92",
+    "createdTimestamp" : 1716388011747,
+    "username" : "digid-machtigen",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : false,
+    "attributes" : {
+      "gemachtigde.bsn" : [ "999999999" ],
+      "aanvrager.bsn" : [ "000000000" ],
+      "service_id" : [ "b18dd73f-3dca-4b67-a4fb-06cb4ebbe2eb" ]
+    },
+    "credentials" : [ {
+      "id" : "5dde1609-96d7-44e0-be78-ac32b9d55736",
+      "type" : "password",
+      "userLabel" : "My password",
+      "createdDate" : 1716388020934,
+      "secretData" : "{\"value\":\"fCYy0OCCW1dVleqekfMpt7hkrQg+e2AeY3pJ14eLKdU=\",\"salt\":\"+TVXeVVZ4RudZj0nUVZsYA==\",\"additionalParameters\":{}}",
+      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+    } ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-test" ],
+    "notBefore" : 0,
+    "groups" : [ ]
+  }, {
+    "id" : "646e27c6-1b42-4e11-a5c6-d9fae4c3cea6",
+    "createdTimestamp" : 1716392361705,
+    "username" : "eherkenning-bewindvoering",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : false,
+    "attributes" : {
+      "service_uuid" : [ "81216fa4-80a1-4686-a8ac-5c8e5c030c93" ],
+      "representeeBSN" : [ "000000000" ],
+      "legalSubjectID" : [ "12345678" ],
+      "actingSubjectID" : [ "4B75A0EA107B3D36" ],
+      "service_id" : [ "urn:etoegang:DV:00000001002308836000:services:9113" ],
+      "aanvrager.kvk" : [ "12345678" ],
+      "name_qualifier" : [ "urn:etoegang:1.9:EntityConcernedID:KvKnr" ],
+      "gemachtigde.pseudoID" : [ "4B75A0EA107B3D36" ]
+    },
+    "credentials" : [ {
+      "id" : "8d284b91-21db-4bc7-8163-b35fac289108",
+      "type" : "password",
+      "userLabel" : "My password",
+      "createdDate" : 1716393311799,
+      "secretData" : "{\"value\":\"c7ugclHPaUkxdiBzUaUKQscFGSp2ioE3z6Ipvcmwfag=\",\"salt\":\"UHMZypw/YcFH0m0/4YnnjA==\",\"additionalParameters\":{}}",
+      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+    } ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-test" ],
+    "notBefore" : 0,
+    "groups" : [ ]
+  }, {
+    "id" : "44be45f6-a7ae-42c2-9486-30f078cf5b39",
+    "createdTimestamp" : 1719999585061,
+    "username" : "eherkenning-vestiging",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : false,
+    "attributes" : {
+      "service_uuid" : [ "81216fa4-80a1-4686-a8ac-5c8e5c030c93" ],
+      "representeeBSN" : [ "000000000" ],
+      "legalSubjectID" : [ "12345678" ],
+      "actingSubjectID" : [ "4B75A0EA107B3D36" ],
+      "service_id" : [ "urn:etoegang:DV:00000001002308836000:services:9113" ],
+      "name_qualifier" : [ "urn:etoegang:1.9:EntityConcernedID:KvKnr" ],
+      "vestiging" : [ "123456789012" ]
+    },
+    "credentials" : [ {
+      "id" : "5e4a5b82-f5b1-48b6-9335-e25d3b417cef",
+      "type" : "password",
+      "userLabel" : "My password",
+      "createdDate" : 1719999593682,
+      "secretData" : "{\"value\":\"etDGywOL01Nr9RD1tG2x95/A37HEsf0zk2Kol8GNIJ0=\",\"salt\":\"pnnxOICMkQRoCM/ywGSOww==\",\"additionalParameters\":{}}",
+      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+    } ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-test" ],
+    "notBefore" : 0,
+    "groups" : [ ]
+  }, {
+    "id" : "a28aac19-6ac5-4ce5-bbe3-b6c24051914a",
+    "createdTimestamp" : 1707141299906,
+    "username" : "service-account-testid",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : false,
+    "serviceAccountClientId" : "testid",
+    "credentials" : [ ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-test" ],
+    "notBefore" : 0,
+    "groups" : [ ]
+  }, {
+    "id" : "aa10cfc7-2c4d-41f6-8fac-7bf405c572c4",
+    "createdTimestamp" : 1707141446005,
+    "username" : "testuser",
+    "enabled" : true,
+    "totp" : false,
+    "emailVerified" : false,
+    "attributes" : {
+      "name_qualifier" : [ "urn:etoegang:1.9:EntityConcernedID:KvKnr" ],
+      "kvk" : [ "012345678" ],
+      "bsn" : [ "000000000" ],
+      "legalSubjectID" : [ "12345678" ],
+      "actingSubjectID" : [ "4B75A0EA107B3D36" ]
+    },
+    "credentials" : [ {
+      "id" : "7592b843-a7ab-4372-a133-d4d984ae687c",
+      "type" : "password",
+      "userLabel" : "My password",
+      "createdDate" : 1707141485838,
+      "secretData" : "{\"value\":\"s9LcIc++9CRM7/wgifxyz0jUFYfmn2VuNpLP3NwUcDw=\",\"salt\":\"JReLfJs5YgTCeB+7u0tgfA==\",\"additionalParameters\":{}}",
+      "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+    } ],
+    "disableableCredentialTypes" : [ ],
+    "requiredActions" : [ ],
+    "realmRoles" : [ "default-roles-test" ],
+    "notBefore" : 0,
+    "groups" : [ ]
+  } ],
+  "scopeMappings" : [ {
+    "clientScope" : "offline_access",
+    "roles" : [ "offline_access" ]
+  } ],
+  "clientScopeMappings" : {
+    "account" : [ {
+      "client" : "account-console",
+      "roles" : [ "manage-account", "view-groups" ]
+    } ]
+  },
+  "clients" : [ {
+    "id" : "89fbc9e2-7a6c-4600-8ee8-f028644297fa",
+    "clientId" : "account",
+    "name" : "${client_account}",
+    "rootUrl" : "${authBaseUrl}",
+    "baseUrl" : "/realms/test/account/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/realms/test/account/*" ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "post.logout.redirect.uris" : "+"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "6030fa07-5521-4c89-ad5f-0055bac6a47f",
+    "clientId" : "account-console",
+    "name" : "${client_account-console}",
+    "rootUrl" : "${authBaseUrl}",
+    "baseUrl" : "/realms/test/account/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/realms/test/account/*" ],
+    "webOrigins" : [ ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "post.logout.redirect.uris" : "+",
+      "pkce.code.challenge.method" : "S256"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "protocolMappers" : [ {
+      "id" : "675a1d8e-030c-4be6-bc22-bbcff46771b4",
+      "name" : "audience resolve",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-audience-resolve-mapper",
+      "consentRequired" : false,
+      "config" : { }
+    } ],
+    "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "0ba5f086-39ea-4545-a237-639bcfbb6d20",
+    "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" : {
+      "post.logout.redirect.uris" : "+"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "0263ec51-8f33-4f73-952b-8cdb1712028c",
+    "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" : {
+      "post.logout.redirect.uris" : "+"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "b61c6592-3036-4e48-8c90-b0818f63576c",
+    "clientId" : "realm-management",
+    "name" : "${client_realm-management}",
+    "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" : {
+      "post.logout.redirect.uris" : "+"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "defaultClientScopes" : [ "web-origins", "acr", "roles", "profile", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "d20d5fd5-e7aa-4641-8c83-c6a2fa0acfe2",
+    "clientId" : "security-admin-console",
+    "name" : "${client_security-admin-console}",
+    "rootUrl" : "${authAdminUrl}",
+    "baseUrl" : "/admin/test/console/",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "redirectUris" : [ "/admin/test/console/*" ],
+    "webOrigins" : [ "+" ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : false,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : true,
+    "frontchannelLogout" : false,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "post.logout.redirect.uris" : "+",
+      "pkce.code.challenge.method" : "S256"
+    },
+    "authenticationFlowBindingOverrides" : { },
+    "fullScopeAllowed" : false,
+    "nodeReRegistrationTimeout" : 0,
+    "protocolMappers" : [ {
+      "id" : "2c68a174-10c2-464e-bbc4-d8d414053fd6",
+      "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", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "42a22604-c3d9-48a7-9186-e8ef84e05223",
+    "clientId" : "test-userinfo-jwt",
+    "name" : "",
+    "description" : "",
+    "rootUrl" : "",
+    "adminUrl" : "",
+    "baseUrl" : "",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "secret" : "ktGlGUELd1FR7dTXc84L7dJzUTjCtw9S",
+    "redirectUris" : [ "http://testserver/*", "http://127.0.0.1:8000/*", "http://localhost:8000/*" ],
+    "webOrigins" : [ "http://127.0.0.1:8000" ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : true,
+    "serviceAccountsEnabled" : false,
+    "publicClient" : false,
+    "frontchannelLogout" : true,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "client.secret.creation.time" : "1707218309",
+      "user.info.response.signature.alg" : "RS256",
+      "post.logout.redirect.uris" : "+",
+      "oauth2.device.authorization.grant.enabled" : "false",
+      "backchannel.logout.revoke.offline.tokens" : "false",
+      "use.refresh.tokens" : "true",
+      "oidc.ciba.grant.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,
+    "defaultClientScopes" : [ "web-origins", "kvk", "acr", "roles", "profile", "bsn", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  }, {
+    "id" : "adf4ad83-4550-4619-9231-73bd8d700f45",
+    "clientId" : "testid",
+    "name" : "",
+    "description" : "",
+    "rootUrl" : "",
+    "adminUrl" : "",
+    "baseUrl" : "",
+    "surrogateAuthRequired" : false,
+    "enabled" : true,
+    "alwaysDisplayInConsole" : false,
+    "clientAuthenticatorType" : "client-secret",
+    "secret" : "7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I",
+    "redirectUris" : [ "http://testserver/*", "http://127.0.0.1:8000/*", "http://example.com/*", "http://localhost:8000/*" ],
+    "webOrigins" : [ "http://127.0.0.1:8000" ],
+    "notBefore" : 0,
+    "bearerOnly" : false,
+    "consentRequired" : false,
+    "standardFlowEnabled" : true,
+    "implicitFlowEnabled" : false,
+    "directAccessGrantsEnabled" : true,
+    "serviceAccountsEnabled" : true,
+    "publicClient" : false,
+    "frontchannelLogout" : true,
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "client.secret.creation.time" : "1707141299",
+      "user.info.response.signature.alg" : "RS256",
+      "post.logout.redirect.uris" : "+",
+      "oauth2.device.authorization.grant.enabled" : "false",
+      "backchannel.logout.revoke.offline.tokens" : "false",
+      "use.refresh.tokens" : "true",
+      "oidc.ciba.grant.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" : "e62c9c9b-3a85-41a3-8529-42483cc285f1",
+      "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" : "c283ef6b-0be7-4ce0-a5dc-622b6ca88dc9",
+      "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" : "68d1ac80-7066-45c3-af1b-48fd1bb52f25",
+      "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"
+      }
+    } ],
+    "defaultClientScopes" : [ "web-origins", "kvk", "acr", "roles", "profile", "groups", "bsn", "email" ],
+    "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+  } ],
+  "clientScopes" : [ {
+    "id" : "cbee953a-f6cc-47d0-9417-bde0ade67c28",
+    "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" : "895028b7-75e6-4d1e-ab98-74e8fd83688c",
+      "name" : "realm roles",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "multivalued" : "true",
+        "user.attribute" : "foo",
+        "access.token.claim" : "true",
+        "claim.name" : "realm_access.roles",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "7a9b8a8d-b221-4748-941a-5b465036b01e",
+      "name" : "client roles",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-client-role-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "multivalued" : "true",
+        "user.attribute" : "foo",
+        "access.token.claim" : "true",
+        "claim.name" : "resource_access.${client_id}.roles",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "0066ba3c-8feb-40ae-a8c4-f82e556b7001",
+      "name" : "audience resolve",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-audience-resolve-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "access.token.claim" : "true"
+      }
+    } ]
+  }, {
+    "id" : "626b8bbf-e0f7-4b59-93c7-80e875d48f75",
+    "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" : "f153d49f-b2eb-4631-b5d4-d994b1a5c1b1",
+      "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" : "d225930c-582f-456e-b286-b95d8c4dd916",
+      "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" : "593033e2-5011-46b1-be8f-df036dee32b2",
+    "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" : "ab90bd48-a6c3-4b47-bab6-1d993c010404",
+      "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" : "33f67e40-80d4-4e10-951c-0c08d1051969",
+      "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" : "56f353fd-546e-48e4-8344-73332df31d3a",
+      "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" : "f78c250d-df76-4e1e-904f-c8d2d60aeb04",
+      "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" : "ab97273d-18bd-426f-a3f7-61e45309500d",
+      "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" : "82effad5-1147-4b1d-bcc7-bda7e9c61760",
+      "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" : "40d6f0ed-f41e-4a3c-acce-5f536fe91fcd",
+      "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" : "c4d1ee91-ce3c-4f75-ba38-3a9c8def5b04",
+      "name" : "groups",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-realm-role-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "multivalued" : "true",
+        "user.attribute" : "foo",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "groups",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "07c6a4b7-4a27-4d1b-872d-4a726169c641",
+      "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" : "df1e7c2d-e8e8-4176-8da9-628985e9cb51",
+      "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" : "20e3fa91-8afc-4735-977c-5de3d486a50d",
+      "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" : "3e525255-568d-40df-9c46-a4f25823ff7e",
+      "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" : "b7cc3936-ca28-4aa5-9eed-7811ed2d6215",
+      "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" : "4ef08463-2a21-44bf-8e5e-6f4783aacf95",
+      "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" : "15a35ab1-e602-445d-81bb-5a5a997a83dc",
+      "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" : "cdf790bc-c9d4-450c-9088-ef0435d0c7fb",
+    "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" : "3d18951b-0124-4daf-aad5-c8f6bebbb54b",
+      "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" : "9071e077-8fe3-4ea4-a2a8-51d8c8929329",
+    "name" : "bsn",
+    "description" : "",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "true",
+      "gui.order" : "",
+      "consent.screen.text" : ""
+    },
+    "protocolMappers" : [ {
+      "id" : "65bb02a6-160e-4cd0-9cc8-41123b1f8207",
+      "name" : "aanvrager.bsn",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "aggregate.attrs" : "false",
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "multivalued" : "false",
+        "user.attribute" : "aanvrager.bsn",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "aanvrager\\.bsn",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "e9a645fb-f731-43a0-bcca-c0a40070727a",
+      "name" : "bsn",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "bsn",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "bsn",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "a4c9d555-0beb-44da-9356-b417f37fd7a8",
+      "name" : "aanvrager.kvk",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "aanvrager.kvk",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "aanvrager\\.kvk",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "edd8c9d6-d4f0-43a5-b7ff-747d12007856",
+      "name" : "service_uuid",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "service_uuid",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "service_uuid",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "c6e49a67-cdbe-436b-ad47-c6dc3a8bf5be",
+      "name" : "representeeBSN",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "representeeBSN",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "representeeBSN",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "2bc83ef0-a719-48e4-8142-6bfdcbe77ab2",
+      "name" : "gemachtigde.bsn",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "aggregate.attrs" : "false",
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "multivalued" : "false",
+        "user.attribute" : "gemachtigde.bsn",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "gemachtigde\\.bsn",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "5cca44aa-84b0-45f3-9381-7239cf37d04e",
+      "name" : "gemachtigde.pseudoID",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "gemachtigde.pseudoID",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "gemachtigde\\.pseudoID",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "a815d8d5-48c5-4dad-bb2f-1fba89582fcf",
+      "name" : "actingSubjectID",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "actingSubjectID",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "actingSubjectID",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "cb90396c-deea-4d38-bf2b-117a3ce2b194",
+      "name" : "service_id",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "service_id",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "service_id",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "5ba6ed6e-e6c5-4c74-9049-185c875df8ad",
+      "name" : "vestiging",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "vestiging",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "vestiging",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "e12f9cee-121e-4b29-be63-0eda4cc0e8ba",
+      "name" : "legalSubjectID",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "legalSubjectID",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "legalSubjectID",
+        "jsonType.label" : "String"
+      }
+    }, {
+      "id" : "ebef48ea-cf2d-4865-9a3b-0589fd00f486",
+      "name" : "name_qualifier",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "name_qualifier",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "name_qualifier",
+        "jsonType.label" : "String"
+      }
+    } ]
+  }, {
+    "id" : "f32301bc-3922-491a-89c3-9764356d9d17",
+    "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" : "7d845a9b-b76e-4b9f-890b-ef313f9c2e5d",
+      "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" : "e939e96f-9eec-4cc3-9a8e-137760c65b7a",
+      "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" : "68c885a8-6cc4-4e18-8213-d69e80f9deef",
+    "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" : "f328d8ca-8da7-4d0c-a8d4-35a8e0912649",
+      "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" : "2a595631-0f05-4e03-9bf7-d0a86743f246",
+    "name" : "role_list",
+    "description" : "SAML role list",
+    "protocol" : "saml",
+    "attributes" : {
+      "consent.screen.text" : "${samlRoleListScopeConsentText}",
+      "display.on.consent.screen" : "true"
+    },
+    "protocolMappers" : [ {
+      "id" : "7e2ae83b-388d-4f10-ab1f-37b84ebde9d6",
+      "name" : "role list",
+      "protocol" : "saml",
+      "protocolMapper" : "saml-role-list-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "single" : "false",
+        "attribute.nameformat" : "Basic",
+        "attribute.name" : "Role"
+      }
+    } ]
+  }, {
+    "id" : "036a72a9-c46f-40e8-8324-c30ba3ea671c",
+    "name" : "kvk",
+    "description" : "",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "true",
+      "gui.order" : "",
+      "consent.screen.text" : ""
+    },
+    "protocolMappers" : [ {
+      "id" : "8cbdcd7a-239f-4f8c-ae19-6896a04bb680",
+      "name" : "kvk",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-usermodel-attribute-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "user.attribute" : "kvk",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "kvk",
+        "jsonType.label" : "String"
+      }
+    } ]
+  }, {
+    "id" : "b906f0fd-71de-43e6-959d-201c9a0d8cef",
+    "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" : "11c0d4eb-482e-4b8a-946d-63b268bf7fc9",
+      "name" : "allowed web origins",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-allowed-origins-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "introspection.token.claim" : "true",
+        "access.token.claim" : "true"
+      }
+    } ]
+  }, {
+    "id" : "89a1f6aa-a02f-48b6-b6ed-13d7521427d5",
+    "name" : "groups",
+    "description" : "Keycloak user groups",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "include.in.token.scope" : "true",
+      "display.on.consent.screen" : "false",
+      "gui.order" : "",
+      "consent.screen.text" : ""
+    },
+    "protocolMappers" : [ {
+      "id" : "4436cbb5-1460-447e-b0a8-ebe80ef7e873",
+      "name" : "groups",
+      "protocol" : "openid-connect",
+      "protocolMapper" : "oidc-group-membership-mapper",
+      "consentRequired" : false,
+      "config" : {
+        "full.path" : "false",
+        "introspection.token.claim" : "true",
+        "userinfo.token.claim" : "true",
+        "id.token.claim" : "true",
+        "access.token.claim" : "true",
+        "claim.name" : "groups"
+      }
+    } ]
+  }, {
+    "id" : "0a26b3ef-c0eb-418c-85ca-6030c13e4182",
+    "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" : "13f9f62d-8be7-40bb-9507-f4fd9dd4168f",
+      "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" : "51caccb7-1d50-4347-94d4-41ae1af2cea6",
+      "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" : "a1de3cd0-4499-4b82-86da-45c2f1c2eb5e",
+    "name" : "offline_access",
+    "description" : "OpenID Connect built-in scope: offline_access",
+    "protocol" : "openid-connect",
+    "attributes" : {
+      "consent.screen.text" : "${offlineAccessScopeConsentText}",
+      "display.on.consent.screen" : "true"
+    }
+  } ],
+  "defaultDefaultClientScopes" : [ "role_list", "profile", "email", "roles", "web-origins", "acr" ],
+  "defaultOptionalClientScopes" : [ "offline_access", "address", "phone", "microprofile-jwt" ],
+  "browserSecurityHeaders" : {
+    "contentSecurityPolicyReportOnly" : "",
+    "xContentTypeOptions" : "nosniff",
+    "referrerPolicy" : "no-referrer",
+    "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" : "c47d8d87-0dda-4a91-a778-1ff4953d0c72",
+      "name" : "Max Clients Limit",
+      "providerId" : "max-clients",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "max-clients" : [ "200" ]
+      }
+    }, {
+      "id" : "2e42c404-90e4-4d4f-aae9-5de838dcf012",
+      "name" : "Trusted Hosts",
+      "providerId" : "trusted-hosts",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "host-sending-registration-request-must-match" : [ "true" ],
+        "client-uris-must-match" : [ "true" ]
+      }
+    }, {
+      "id" : "9545949f-87fd-4416-8f3b-a2be3203b43b",
+      "name" : "Full Scope Disabled",
+      "providerId" : "scope",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : { }
+    }, {
+      "id" : "d7ed32b7-9bc0-4c22-af63-95e605fa571c",
+      "name" : "Allowed Protocol Mapper Types",
+      "providerId" : "allowed-protocol-mappers",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "allowed-protocol-mapper-types" : [ "saml-user-property-mapper", "oidc-address-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", "saml-user-attribute-mapper", "oidc-full-name-mapper", "oidc-sha256-pairwise-sub-mapper" ]
+      }
+    }, {
+      "id" : "c6b13ddf-1676-4e33-85d7-c778891156b3",
+      "name" : "Consent Required",
+      "providerId" : "consent-required",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : { }
+    }, {
+      "id" : "28c52629-450d-4e79-a7ba-c4a28d1f9e7c",
+      "name" : "Allowed Client Scopes",
+      "providerId" : "allowed-client-templates",
+      "subType" : "authenticated",
+      "subComponents" : { },
+      "config" : {
+        "allow-default-scopes" : [ "true" ]
+      }
+    }, {
+      "id" : "1e4a85fd-6412-470d-9edf-562a8b8021b2",
+      "name" : "Allowed Protocol Mapper Types",
+      "providerId" : "allowed-protocol-mappers",
+      "subType" : "authenticated",
+      "subComponents" : { },
+      "config" : {
+        "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-usermodel-property-mapper", "oidc-full-name-mapper", "saml-role-list-mapper", "oidc-address-mapper" ]
+      }
+    }, {
+      "id" : "9557d357-cc12-443e-bba6-a89e89b22c2e",
+      "name" : "Allowed Client Scopes",
+      "providerId" : "allowed-client-templates",
+      "subType" : "anonymous",
+      "subComponents" : { },
+      "config" : {
+        "allow-default-scopes" : [ "true" ]
+      }
+    } ],
+    "org.keycloak.keys.KeyProvider" : [ {
+      "id" : "8b83b45b-d80d-49c7-ae04-c3f4618c7514",
+      "name" : "aes-generated",
+      "providerId" : "aes-generated",
+      "subComponents" : { },
+      "config" : {
+        "kid" : [ "d993f461-f278-47ef-8c93-70488711ebfd" ],
+        "secret" : [ "o3i6s9I3iiVzLyDPxclUkg" ],
+        "priority" : [ "100" ]
+      }
+    }, {
+      "id" : "4a08d0a0-4d74-4b42-b18a-e06e27fc062b",
+      "name" : "hmac-generated",
+      "providerId" : "hmac-generated",
+      "subComponents" : { },
+      "config" : {
+        "kid" : [ "e715e051-6cdb-48cc-b4f4-f0722c81f9d3" ],
+        "secret" : [ "sR5n-Ep98RcqFydPbvUYTqdnwIB7742D09yUYMiB-OTsqTzoH5op0_KkVqNy9EYg-ibOR3QkvtcauTyjhaK7uw" ],
+        "priority" : [ "100" ],
+        "algorithm" : [ "HS256" ]
+      }
+    }, {
+      "id" : "4d6e8de3-aecf-4209-9922-a890eafa9691",
+      "name" : "rsa-generated",
+      "providerId" : "rsa-generated",
+      "subComponents" : { },
+      "config" : {
+        "privateKey" : [ "MIIEpAIBAAKCAQEA2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF++2lIS7vNV/PbsVVznPAAMqVrNG+8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5//ttJdxPfIBT5+2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB+ORKDTUIQwGZM5mSCy+cY3cHvvZfZVgaUUy5NvujPRXTMje4n/hG0KfEV+40G9qC2/Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ/zbrF4B9dmS6Zli5rBvbox9Hh45wIDAQABAoIBAGshgp7zVbFgWdq6eGr9z0P1qHnnAtR3RvXs91pQHGaHLlkqaJw2yrqwWCu1bA7e23eQG2D9Q/aLSV+FQZUjyHVyhc4oIjRC3qWfQuIiXxQLEe72LQq/xx4ULYgmqZy9QSFzdyK6RHIDffww+CHXyG/yxP5SyP/tLAbb17f/TjBYLMoVcdDmn/wl4UWZMR7ZqFeGOGJWmFpHmeB3HBPU2TyzsTLF9ECgCw298qIKwH0kD3rvGZ+fXPRCX8bLqDkVNL/jDLT5Z/ITGmIUWaBAT/MFoMeuKvOG8NC82edNb7RukoHoXxVgVywbd9Cdlrzu5S0TAgg8qhTlAAx7PuLqyNECgYEA9zqS5smIu1iDwczqYbGxXab3wEVhfAZ/rHa2zB0/tMyZBWJjWlw3jrcNouWnRlxWXoUrcVe/NavKkRBMjlhITZ+nPA7kOQaZIpujulN6euKVgf57zcfhxc4SUeyxYwnOGQFErorP8UnuDYC8rK8tloPVyp3B+sXyZpHOjTtH0RcCgYEA39850L18FfqSN1oDRe01BCJNF0/OM++CFka+OyPkTI7GpmeeEobhY2VsTJuPGMw07uB9OWHOrfsxNbd3R5QO4Rd0svlfBpz8XtUCgWaHV3pNm+zprAf3Fq06Gk3KfO9QMO116fd7RS/RmsFhGIqFGRZ+IP0Tl02mA+ri7wQ3WLECgYAp8Ofm+x2VGskPYaIJfMmoJ6E0HxEQp1GVgnY0XmnmVCdJgI12UNqj/W30ypz8FMIaOuFJ0yb/BevRfEBgjZ2GfaUzTRtuiS4Fbv3xqCPJIRNYAEIkgNpOYk09VLgrIwixuUNbkPUB7BbUd5iKexVyyV7FhsnXrykWOXoe/4WJdQKBgQC03JDG1O50izSpRy0xxwt3xYZmePDsAGkmOgzhloOQXiCau0d3TES2mm++DEa1D/ULr407WIsy/6an8QqKZ1EGBH8hQFnG6/jvXENj60MYJxSgDexSMTUrutMgAQy/lk9A1/bVCD0sjg9WaThaLT6OIB/R4uN67x5aN98SnmNgYQKBgQClIzFFq6Ks2sqxn4PguvL1B4vnqetR4WJc9RvoKp+WAHcJD372B3N4i25n0kv7xyWgYUp25qj1SJL11NTsbiPdFzc4IYBEOwf7/y4l+ZRg2PSF96wZmuQdK3mwzUj9OiYkPUeYd6mtNVbgsCZLrr3Tvgd6NZMSeigFMfESiIpo6w==" ],
+        "keyUse" : [ "SIG" ],
+        "certificate" : [ "MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag==" ],
+        "priority" : [ "100" ]
+      }
+    }, {
+      "id" : "d50865f3-256c-4fe2-b426-f8fe01b21381",
+      "name" : "rsa-enc-generated",
+      "providerId" : "rsa-enc-generated",
+      "subComponents" : { },
+      "config" : {
+        "privateKey" : [ "MIIEpAIBAAKCAQEApNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6/ny1CYfoaxTV2iDpRUw8/f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2/nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C/ZAUzkXC+l3oQ+BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61/Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc/Lv33EwykscLznKWZY2Mbs3Iz/rFNv3sVX/vHpH4DHWlKu7QIDAQABAoIBAAn84YwiHaBm4/Jj/S9Q3z9iwYhcCNrEBXvHJhLPfbZdyrYwzq54FTEIqT6Lgeu+wR8i8k7ZrzzL6M5bUvOvV8a80tNg1lIRimzITzYLXg5TdGnX7lhRe2W4hEI7wR7DLBDzShurcZ5UbMWO234CkKIdddPdoy41FpfHAoly5P4S48ZYqoEcx3V2g3S7XJ4pz2JE9bCF6c9PAiYWimIW6yJgopqjslMrkFxbyWhQir7tuulGSsLaHvX2wuHlKJ0GqNUQiVAd1xapmTleJstJ0OHFnfxn+2gHqiBc08c1IjNDpDmH/54nA8MQhMR8qMRIBO1OMzu7do5HKiSf25FfRacCgYEA6HUpKuo2k/2SjxSnYaHAozGiXdmCFf6mNuT0sCQdDu5ZxMmS2QLTLeH0BbFIXf98EXfFeqwBcA00PXpfc5Fo7fudxnMl/lVyqN+gGO/Sfo7sM+Ds/iXDvucE+vGpgcLEpMvvnFphs0ScPyE0mbbAbYVukKz5YrUgeL+d+I+Z938CgYEAtY4PKsvgRy1sD5WCZqoCRpoY2H3/MuLxDQUu8EAlU4ALyxBkEmaMAcXx+fIDT0X8ldCEoLcyy7800UdgxRbdKflT/lRTEW4CC/1slYpg1jPkkhYaCpsQG9G92dcAUaJWtCbLG0/9I3KFUOAhozKkvmz4gIyARw9bW28BY5Ym75MCgYEApHkRMb4Z88f8hKQWcivigxVBTqnxMuLEdB63SlGjBcd7WJNPBaDMDrDK2aRAEdIM1McrwMonEkMlbUJCeyCtX4UicyFSBowq3nWrbzlwc/9n/KTuyjuqLk6C5ZNLXfaS8A8jcDs62X54FurFruTxbgx02ISqxz5kxUq+2Pmx9L0CgYEArQtu92qFJTJs+dmWBcZrDuIXZlmJYPYfrTpQh9uL+C9mjjDcQRGOxq3lukbq0qcxXZX2o7yZZMulSweOe6wUNsqXPSUgW8+PkeAFm+7d56xkYr1AKvWq/+kE3FnpyuVBYMpM8oZmD2A7I1/Nj+BYV8xDezrvlUtU1yxRlZrrF5MCgYBUMysubXkyp2nqor+x8VExN0BIlDG+0I4XwcGrI47Sb8bNaVd39XuF4GSnLGxxJ7phSOzmlNGq20ssL6h9b8czq6l5l04q0g6w0IQiWvXiFT5fQ5B2NL3jiC1feqBhXppP6Ew60a0eK7LA+/QqQLvZHkbKW72L//8B/kFACcx69Q==" ],
+        "keyUse" : [ "ENC" ],
+        "certificate" : [ "MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA==" ],
+        "priority" : [ "100" ],
+        "algorithm" : [ "RSA-OAEP" ]
+      }
+    } ]
+  },
+  "internationalizationEnabled" : false,
+  "supportedLocales" : [ ],
+  "authenticationFlows" : [ {
+    "id" : "eade39e3-8a2f-4e07-a459-24085849cc7b",
+    "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" : "4ba9c174-71c9-4c41-9c4f-c0c0961c2e60",
+    "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",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "auth-otp-form",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "3c863e05-422e-4048-b5df-8db9f407265c",
+    "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" : "195520f1-5683-4d15-8512-722882436cb6",
+    "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",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 10,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    }, {
+      "authenticator" : "auth-otp-form",
+      "authenticatorFlow" : false,
+      "requirement" : "REQUIRED",
+      "priority" : 20,
+      "autheticatorFlow" : false,
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "ffb0fb4e-a5b3-47d2-a695-b458f0ae98e6",
+    "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" : "13083de7-5ca7-4090-a325-fac79ad8974a",
+    "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" : "2c726272-8443-4bb3-aede-e853348de93d",
+    "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" : "8c368b22-beaf-460f-852c-ed22a9f634e0",
+    "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 OTP",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "a513e259-143c-4ca5-8453-7b40b3adaca2",
+    "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" : "567fabf9-3a81-4994-82f2-32265b469f0a",
+    "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" : "9138d835-7470-40b8-bd87-9dea7dddf38b",
+    "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" : "27ebb1ca-e8b7-44ac-b012-8d580a323249",
+    "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" : "1dfada24-8a57-4790-8e9b-537d5325f304",
+    "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" : "abdd8910-0519-418d-9bf6-d74350116737",
+    "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 OTP",
+      "userSetupAllowed" : false
+    } ]
+  }, {
+    "id" : "1d657342-0a34-43b2-88a9-de018c0f2f3e",
+    "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" : "e26131b1-5820-405b-98b5-5dd1ff5d146e",
+    "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
+    } ]
+  }, {
+    "id" : "d7de4f38-5c54-434b-b429-109bc617d88e",
+    "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" : "8a5af7f0-4be1-4a71-82e6-53b998ab9996",
+    "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" : "ad975f49-59a4-4091-9591-a533e4a9b162",
+    "alias" : "create unique user config",
+    "config" : {
+      "require.password.update.after.registration" : "false"
+    }
+  }, {
+    "id" : "f0a940bd-6086-461e-89c2-18dcebdc8f57",
+    "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" : "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" : {
+    "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" : "23.0.7",
+  "userManagedAccessAllowed" : false,
+  "clientProfiles" : {
+    "profiles" : [ ]
+  },
+  "clientPolicies" : {
+    "policies" : [ ]
+  }
+}
diff --git a/keycloak/docker-compose.keycloak.yml b/keycloak/docker-compose.keycloak.yml
new file mode 100644
index 00000000..f0b8e79b
--- /dev/null
+++ b/keycloak/docker-compose.keycloak.yml
@@ -0,0 +1,36 @@
+# Config taken from https://stackoverflow.com/a/77257732
+#
+# This docker-compose is for development and test purposes. Tests are recorded with
+# VCR against this instance.
+#
+#   Log in to http://localhost:8080/admin/master/console/ with `admin`/`admin`
+#   credentials.
+#
+# DO NOT USE THIS IN PRODUCTION.
+#
+# Start a Keycloak instance in your local environment from the parent directory:
+# 
+#     docker compose -f docker-compose.keycloak.yml up -d
+# 
+
+version: '3'
+
+services:
+  keycloak:
+    image: quay.io/keycloak/keycloak:23.0
+    command: start-dev --import-realm
+    environment:
+      - KEYCLOAK_ADMIN=admin
+      - KEYCLOAK_ADMIN_PASSWORD=admin
+    volumes:
+      - ./data:/opt/keycloak/data/import
+    ports:
+      - 8080:8080
+    networks:
+      objects-dev:
+        aliases:
+          - keycloak.objects.local
+
+networks:
+  objects-dev:
+    name: objects-dev
diff --git a/package-lock.json b/package-lock.json
index 92e002e1..8cb0d4c5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6,7 +6,7 @@
   "packages": {
     "": {
       "name": "objects",
-      "version": "2.3.0",
+      "version": "2.4.0",
       "license": "UNLICENSED",
       "dependencies": {
         "microscope-sass": "latest",
@@ -2882,11 +2882,11 @@
       }
     },
     "node_modules/braces": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
-      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
       "dependencies": {
-        "fill-range": "^7.0.1"
+        "fill-range": "^7.1.1"
       },
       "engines": {
         "node": ">=8"
@@ -4014,9 +4014,9 @@
       }
     },
     "node_modules/engine.io": {
-      "version": "6.5.4",
-      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.4.tgz",
-      "integrity": "sha512-KdVSDKhVKyOi+r5uEabrDLZw2qXStVvCsEB/LN3mw4WFi6Gx50jTyuxYVCwAAC0U46FdnzP/ScKRBTXb/NiEOg==",
+      "version": "6.5.5",
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz",
+      "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==",
       "dev": true,
       "dependencies": {
         "@types/cookie": "^0.4.1",
@@ -4028,7 +4028,7 @@
         "cors": "~2.8.5",
         "debug": "~4.3.1",
         "engine.io-parser": "~5.2.1",
-        "ws": "~8.11.0"
+        "ws": "~8.17.1"
       },
       "engines": {
         "node": ">=10.2.0"
@@ -4264,17 +4264,17 @@
       }
     },
     "node_modules/express": {
-      "version": "4.18.2",
-      "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
-      "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+      "version": "4.19.2",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
+      "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
       "dev": true,
       "dependencies": {
         "accepts": "~1.3.8",
         "array-flatten": "1.1.1",
-        "body-parser": "1.20.1",
+        "body-parser": "1.20.2",
         "content-disposition": "0.5.4",
         "content-type": "~1.0.4",
-        "cookie": "0.5.0",
+        "cookie": "0.6.0",
         "cookie-signature": "1.0.6",
         "debug": "2.6.9",
         "depd": "2.0.0",
@@ -4305,34 +4305,10 @@
         "node": ">= 0.10.0"
       }
     },
-    "node_modules/express/node_modules/body-parser": {
-      "version": "1.20.1",
-      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
-      "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
-      "dev": true,
-      "dependencies": {
-        "bytes": "3.1.2",
-        "content-type": "~1.0.4",
-        "debug": "2.6.9",
-        "depd": "2.0.0",
-        "destroy": "1.2.0",
-        "http-errors": "2.0.0",
-        "iconv-lite": "0.4.24",
-        "on-finished": "2.4.1",
-        "qs": "6.11.0",
-        "raw-body": "2.5.1",
-        "type-is": "~1.6.18",
-        "unpipe": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8",
-        "npm": "1.2.8000 || >= 1.4.16"
-      }
-    },
     "node_modules/express/node_modules/cookie": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
-      "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
+      "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
       "dev": true,
       "engines": {
         "node": ">= 0.6"
@@ -4377,21 +4353,6 @@
       "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
       "dev": true
     },
-    "node_modules/express/node_modules/raw-body": {
-      "version": "2.5.1",
-      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
-      "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
-      "dev": true,
-      "dependencies": {
-        "bytes": "3.1.2",
-        "http-errors": "2.0.0",
-        "iconv-lite": "0.4.24",
-        "unpipe": "1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/express/node_modules/safe-buffer": {
       "version": "5.2.1",
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -4537,9 +4498,9 @@
       }
     },
     "node_modules/fill-range": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
-      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
       "dependencies": {
         "to-regex-range": "^5.0.1"
       },
@@ -4640,9 +4601,9 @@
       "dev": true
     },
     "node_modules/follow-redirects": {
-      "version": "1.15.5",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
-      "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==",
+      "version": "1.15.6",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+      "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
       "dev": true,
       "funding": [
         {
@@ -8592,12 +8553,13 @@
       }
     },
     "node_modules/socket.io-adapter": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz",
-      "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==",
+      "version": "2.5.5",
+      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz",
+      "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==",
       "dev": true,
       "dependencies": {
-        "ws": "~8.11.0"
+        "debug": "~4.3.4",
+        "ws": "~8.17.1"
       }
     },
     "node_modules/socket.io-parser": {
@@ -9521,9 +9483,9 @@
       }
     },
     "node_modules/webpack-dev-middleware": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz",
-      "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==",
+      "version": "5.3.4",
+      "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz",
+      "integrity": "sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==",
       "dev": true,
       "dependencies": {
         "colorette": "^2.0.10",
@@ -9602,27 +9564,6 @@
         }
       }
     },
-    "node_modules/webpack-dev-server/node_modules/ws": {
-      "version": "8.16.0",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz",
-      "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=10.0.0"
-      },
-      "peerDependencies": {
-        "bufferutil": "^4.0.1",
-        "utf-8-validate": ">=5.0.2"
-      },
-      "peerDependenciesMeta": {
-        "bufferutil": {
-          "optional": true
-        },
-        "utf-8-validate": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/webpack-merge": {
       "version": "4.2.2",
       "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz",
@@ -9809,16 +9750,16 @@
       "dev": true
     },
     "node_modules/ws": {
-      "version": "8.11.0",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
-      "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
+      "version": "8.17.1",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
+      "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
       "dev": true,
       "engines": {
         "node": ">=10.0.0"
       },
       "peerDependencies": {
         "bufferutil": "^4.0.1",
-        "utf-8-validate": "^5.0.2"
+        "utf-8-validate": ">=5.0.2"
       },
       "peerDependenciesMeta": {
         "bufferutil": {
diff --git a/requirements/base.txt b/requirements/base.txt
index 04225b7d..b7ab97df 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -1,5 +1,5 @@
 #
-# This file is autogenerated by pip-compile with Python 3.10
+# This file is autogenerated by pip-compile with Python 3.11
 # by the following command:
 #
 #    pip-compile --no-emit-index-url requirements/base.in
@@ -9,6 +9,7 @@ amqp==5.2.0
 asgiref==3.7.2
     # via
     #   django
+    #   django-axes
     #   django-cors-headers
 asn1crypto==1.5.1
     # via webauthn
@@ -16,7 +17,7 @@ attrs==20.3.0
     # via
     #   glom
     #   jsonschema
-billiard==3.6.4.0
+billiard==4.2.0
     # via celery
 bleach==6.1.0
     # via open-api-framework
@@ -24,14 +25,14 @@ boltons==21.0.0
     # via
     #   face
     #   glom
-cbor2==5.6.1
+cbor2==5.6.2
     # via webauthn
-celery==5.2.7
+celery==5.4.0
     # via
     #   flower
     #   notifications-api-common
     #   open-api-framework
-certifi==2020.12.5
+certifi==2023.7.22
     # via
     #   django-simple-certmanager
     #   elastic-apm
@@ -66,7 +67,7 @@ cryptography==41.0.7
     #   mozilla-django-oidc
     #   pyopenssl
     #   webauthn
-django==4.2.11
+django==4.2.15
     # via
     #   commonground-api-common
     #   django-admin-index
@@ -104,17 +105,17 @@ django-admin-index==3.1.0
     # via open-api-framework
 django-appconf==1.0.6
     # via django-log-outgoing-requests
-django-axes==6.3.0
+django-axes==6.5.1
     # via open-api-framework
-django-cors-headers==4.3.1
+django-cors-headers==4.4.0
     # via open-api-framework
-django-filter==23.5
+django-filter==24.2
     # via
     #   commonground-api-common
     #   open-api-framework
 django-formtools==2.3
     # via django-two-factor-auth
-django-jsonform==2.21.4
+django-jsonform==2.22.0
     # via
     #   mozilla-django-oidc-db
     #   open-api-framework
@@ -151,7 +152,7 @@ django-solo==2.2.0
     #   zgw-consumers
 django-two-factor-auth[phonenumberslite,webauthn]==1.16.0
     # via maykin-2fa
-djangorestframework==3.14.0
+djangorestframework==3.15.2
     # via
     #   commonground-api-common
     #   djangorestframework-gis
@@ -171,13 +172,13 @@ djangorestframework-inclusions==1.2.0
     # via open-api-framework
 drf-nested-routers==0.93.3
     # via commonground-api-common
-drf-spectacular==0.27.0
+drf-spectacular==0.27.2
     # via open-api-framework
 drf-yasg==1.21.7
     # via commonground-api-common
 ecs-logging==2.1.0
     # via elastic-apm
-elastic-apm==6.20.0
+elastic-apm==6.23.0
     # via open-api-framework
 face==20.1.1
     # via glom
@@ -198,7 +199,7 @@ glom==23.5.0
     #   mozilla-django-oidc-db
 humanize==4.9.0
     # via flower
-idna==2.10
+idna==3.7
     # via requests
 inflection==0.5.1
     # via
@@ -210,7 +211,7 @@ isodate==0.6.0
     # via commonground-api-common
 itypes==1.2.0
     # via coreapi
-jinja2==3.1.3
+jinja2==3.1.4
     # via coreschema
 josepy==1.9.0
     # via mozilla-django-oidc
@@ -222,17 +223,17 @@ kombu==5.3.5
     # via celery
 markupsafe==2.1.3
     # via jinja2
-maykin-2fa==1.0.0
+maykin-2fa==1.0.1
     # via open-api-framework
 mozilla-django-oidc==4.0.0
     # via mozilla-django-oidc-db
-mozilla-django-oidc-db==0.14.1
+mozilla-django-oidc-db==0.19.0
     # via open-api-framework
 notifications-api-common==0.2.2
     # via
     #   -r requirements/base.in
     #   commonground-api-common
-open-api-framework==0.5.0
+open-api-framework==0.6.1
     # via -r requirements/base.in
 orderedmultidict==1.0.1
     # via furl
@@ -262,8 +263,9 @@ pyopenssl==23.3.0
     #   zgw-consumers
 pyrsistent==0.17.3
     # via jsonschema
-python-dateutil==2.8.1
+python-dateutil==2.9.0.post0
     # via
+    #   celery
     #   django-relativedelta
     #   faker
 python-decouple==3.8
@@ -272,8 +274,6 @@ python-dotenv==1.0.0
     # via open-api-framework
 pytz==2024.1
     # via
-    #   celery
-    #   djangorestframework
     #   drf-yasg
     #   flower
 pyyaml==6.0.1
@@ -286,7 +286,7 @@ qrcode==6.1
     # via django-two-factor-auth
 redis==3.5.3
     # via django-redis
-requests==2.31.0
+requests==2.32.3
     # via
     #   commonground-api-common
     #   coreapi
@@ -298,7 +298,7 @@ requests==2.31.0
     #   zgw-consumers
 requests-mock==1.8.0
     # via zgw-consumers
-sentry-sdk==1.39.2
+sentry-sdk==2.12.0
     # via open-api-framework
 six==1.16.0
     # via
@@ -309,20 +309,22 @@ six==1.16.0
     #   python-dateutil
     #   qrcode
     #   requests-mock
-sqlparse==0.4.2
+sqlparse==0.5.0
     # via django
 text-unidecode==1.3
     # via faker
-tornado==6.4
+tornado==6.4.1
     # via flower
 typing-extensions==4.9.0
-    # via asgiref
+    # via mozilla-django-oidc-db
+tzdata==2024.1
+    # via celery
 uritemplate==3.0.1
     # via
     #   coreapi
     #   drf-spectacular
     #   drf-yasg
-urllib3==2.2.1
+urllib3==2.2.2
     # via
     #   elastic-apm
     #   requests
diff --git a/requirements/ci.txt b/requirements/ci.txt
index 7be57728..06c91880 100644
--- a/requirements/ci.txt
+++ b/requirements/ci.txt
@@ -1,5 +1,5 @@
 #
-# This file is autogenerated by pip-compile with Python 3.10
+# This file is autogenerated by pip-compile with Python 3.11
 # by the following command:
 #
 #    pip-compile --no-emit-index-url --output-file=requirements/ci.txt requirements/base.txt requirements/test-tools.in
@@ -12,6 +12,7 @@ asgiref==3.7.2
     # via
     #   -r requirements/base.txt
     #   django
+    #   django-axes
     #   django-cors-headers
 asn1crypto==1.5.1
     # via
@@ -24,7 +25,7 @@ attrs==20.3.0
     #   jsonschema
 beautifulsoup4==4.9.3
     # via webtest
-billiard==3.6.4.0
+billiard==4.2.0
     # via
     #   -r requirements/base.txt
     #   celery
@@ -37,17 +38,17 @@ boltons==21.0.0
     #   -r requirements/base.txt
     #   face
     #   glom
-cbor2==5.6.1
+cbor2==5.6.2
     # via
     #   -r requirements/base.txt
     #   webauthn
-celery==5.2.7
+celery==5.4.0
     # via
     #   -r requirements/base.txt
     #   flower
     #   notifications-api-common
     #   open-api-framework
-certifi==2020.12.5
+certifi==2023.7.22
     # via
     #   -r requirements/base.txt
     #   django-simple-certmanager
@@ -105,7 +106,7 @@ cryptography==41.0.7
     #   webauthn
 cssselect==1.1.0
     # via pyquery
-django==4.2.11
+django==4.2.15
     # via
     #   -r requirements/base.txt
     #   commonground-api-common
@@ -148,15 +149,15 @@ django-appconf==1.0.6
     # via
     #   -r requirements/base.txt
     #   django-log-outgoing-requests
-django-axes==6.3.0
+django-axes==6.5.1
     # via
     #   -r requirements/base.txt
     #   open-api-framework
-django-cors-headers==4.3.1
+django-cors-headers==4.4.0
     # via
     #   -r requirements/base.txt
     #   open-api-framework
-django-filter==23.5
+django-filter==24.2
     # via
     #   -r requirements/base.txt
     #   commonground-api-common
@@ -165,7 +166,7 @@ django-formtools==2.3
     # via
     #   -r requirements/base.txt
     #   django-two-factor-auth
-django-jsonform==2.21.4
+django-jsonform==2.22.0
     # via
     #   -r requirements/base.txt
     #   mozilla-django-oidc-db
@@ -229,11 +230,10 @@ django-solo==2.2.0
 django-two-factor-auth[phonenumberslite,webauthn]==1.16.0
     # via
     #   -r requirements/base.txt
-    #   django-two-factor-auth
     #   maykin-2fa
 django-webtest==1.9.7
     # via -r requirements/test-tools.in
-djangorestframework==3.14.0
+djangorestframework==3.15.2
     # via
     #   -r requirements/base.txt
     #   commonground-api-common
@@ -261,7 +261,7 @@ drf-nested-routers==0.93.3
     # via
     #   -r requirements/base.txt
     #   commonground-api-common
-drf-spectacular==0.27.0
+drf-spectacular==0.27.2
     # via
     #   -r requirements/base.txt
     #   open-api-framework
@@ -273,7 +273,7 @@ ecs-logging==2.1.0
     # via
     #   -r requirements/base.txt
     #   elastic-apm
-elastic-apm==6.20.0
+elastic-apm==6.23.0
     # via
     #   -r requirements/base.txt
     #   open-api-framework
@@ -310,10 +310,11 @@ humanize==4.9.0
     # via
     #   -r requirements/base.txt
     #   flower
-idna==2.10
+idna==3.7
     # via
     #   -r requirements/base.txt
     #   requests
+    #   yarl
 inflection==0.5.1
     # via
     #   -r requirements/base.txt
@@ -331,7 +332,7 @@ itypes==1.2.0
     # via
     #   -r requirements/base.txt
     #   coreapi
-jinja2==3.1.3
+jinja2==3.1.4
     # via
     #   -r requirements/base.txt
     #   coreschema
@@ -353,7 +354,7 @@ markupsafe==2.1.3
     # via
     #   -r requirements/base.txt
     #   jinja2
-maykin-2fa==1.0.0
+maykin-2fa==1.0.1
     # via
     #   -r requirements/base.txt
     #   open-api-framework
@@ -361,15 +362,17 @@ mozilla-django-oidc==4.0.0
     # via
     #   -r requirements/base.txt
     #   mozilla-django-oidc-db
-mozilla-django-oidc-db==0.14.1
+mozilla-django-oidc-db==0.19.0
     # via
     #   -r requirements/base.txt
     #   open-api-framework
+multidict==6.0.5
+    # via yarl
 notifications-api-common==0.2.2
     # via
     #   -r requirements/base.txt
     #   commonground-api-common
-open-api-framework==0.5.0
+open-api-framework==0.6.1
     # via -r requirements/base.txt
 orderedmultidict==1.0.1
     # via
@@ -421,9 +424,10 @@ pyrsistent==0.17.3
     # via
     #   -r requirements/base.txt
     #   jsonschema
-python-dateutil==2.8.1
+python-dateutil==2.9.0.post0
     # via
     #   -r requirements/base.txt
+    #   celery
     #   django-relativedelta
     #   faker
     #   freezegun
@@ -438,8 +442,6 @@ python-dotenv==1.0.0
 pytz==2024.1
     # via
     #   -r requirements/base.txt
-    #   celery
-    #   djangorestframework
     #   drf-yasg
     #   flower
 pyyaml==6.0.1
@@ -449,6 +451,7 @@ pyyaml==6.0.1
     #   drf-yasg
     #   gemma-zds-client
     #   oyaml
+    #   vcrpy
 qrcode==6.1
     # via
     #   -r requirements/base.txt
@@ -457,7 +460,7 @@ redis==3.5.3
     # via
     #   -r requirements/base.txt
     #   django-redis
-requests==2.31.0
+requests==2.32.3
     # via
     #   -r requirements/base.txt
     #   commonground-api-common
@@ -473,7 +476,7 @@ requests-mock==1.8.0
     #   -r requirements/base.txt
     #   -r requirements/test-tools.in
     #   zgw-consumers
-sentry-sdk==1.39.2
+sentry-sdk==2.12.0
     # via
     #   -r requirements/base.txt
     #   open-api-framework
@@ -490,7 +493,7 @@ six==1.16.0
     #   webtest
 soupsieve==2.2.1
     # via beautifulsoup4
-sqlparse==0.4.2
+sqlparse==0.5.0
     # via
     #   -r requirements/base.txt
     #   django
@@ -500,21 +503,25 @@ text-unidecode==1.3
     # via
     #   -r requirements/base.txt
     #   faker
-tornado==6.4
+tornado==6.4.1
     # via
     #   -r requirements/base.txt
     #   flower
 typing-extensions==4.9.0
     # via
     #   -r requirements/base.txt
-    #   asgiref
+    #   mozilla-django-oidc-db
+tzdata==2024.1
+    # via
+    #   -r requirements/base.txt
+    #   celery
 uritemplate==3.0.1
     # via
     #   -r requirements/base.txt
     #   coreapi
     #   drf-spectacular
     #   drf-yasg
-urllib3==2.2.1
+urllib3==2.2.2
     # via
     #   -r requirements/base.txt
     #   elastic-apm
@@ -524,13 +531,15 @@ uwsgi==2.0.23
     # via
     #   -r requirements/base.txt
     #   open-api-framework
+vcrpy==6.0.1
+    # via -r requirements/test-tools.in
 vine==5.1.0
     # via
     #   -r requirements/base.txt
     #   amqp
     #   celery
     #   kombu
-waitress==2.1.1
+waitress==2.1.2
     # via webtest
 wcwidth==0.2.13
     # via
@@ -552,6 +561,9 @@ wrapt==1.14.1
     # via
     #   -r requirements/base.txt
     #   elastic-apm
+    #   vcrpy
+yarl==1.9.4
+    # via vcrpy
 zgw-consumers==0.27.0
     # via
     #   -r requirements/base.txt
diff --git a/requirements/dev.txt b/requirements/dev.txt
index fc78f832..b1d05ca6 100644
--- a/requirements/dev.txt
+++ b/requirements/dev.txt
@@ -1,5 +1,5 @@
 #
-# This file is autogenerated by pip-compile with Python 3.10
+# This file is autogenerated by pip-compile with Python 3.11
 # by the following command:
 #
 #    pip-compile --no-emit-index-url --output-file=requirements/dev.txt requirements/ci.txt requirements/dev.in
@@ -14,6 +14,7 @@ asgiref==3.7.2
     # via
     #   -r requirements/ci.txt
     #   django
+    #   django-axes
     #   django-cors-headers
 asn1crypto==1.5.1
     # via
@@ -30,11 +31,11 @@ beautifulsoup4==4.9.3
     # via
     #   -r requirements/ci.txt
     #   webtest
-billiard==3.6.4.0
+billiard==4.2.0
     # via
     #   -r requirements/ci.txt
     #   celery
-black==23.12.1
+black==24.3.0
     # via -r requirements/dev.in
 bleach==6.1.0
     # via
@@ -51,17 +52,17 @@ bump2version==1.0.1
     # via bumpversion
 bumpversion==0.6.0
     # via -r requirements/dev.in
-cbor2==5.6.1
+cbor2==5.6.2
     # via
     #   -r requirements/ci.txt
     #   webauthn
-celery==5.2.7
+celery==5.4.0
     # via
     #   -r requirements/ci.txt
     #   flower
     #   notifications-api-common
     #   open-api-framework
-certifi==2020.12.5
+certifi==2023.7.22
     # via
     #   -r requirements/ci.txt
     #   django-simple-certmanager
@@ -125,7 +126,7 @@ cssselect==1.1.0
     # via
     #   -r requirements/ci.txt
     #   pyquery
-django==4.2.11
+django==4.2.15
     # via
     #   -r requirements/ci.txt
     #   commonground-api-common
@@ -170,11 +171,11 @@ django-appconf==1.0.6
     # via
     #   -r requirements/ci.txt
     #   django-log-outgoing-requests
-django-axes==6.3.0
+django-axes==6.5.1
     # via
     #   -r requirements/ci.txt
     #   open-api-framework
-django-cors-headers==4.3.1
+django-cors-headers==4.4.0
     # via
     #   -r requirements/ci.txt
     #   open-api-framework
@@ -182,7 +183,7 @@ django-debug-toolbar==4.2.0
     # via -r requirements/dev.in
 django-extensions==3.2.3
     # via -r requirements/dev.in
-django-filter==23.5
+django-filter==24.2
     # via
     #   -r requirements/ci.txt
     #   commonground-api-common
@@ -191,7 +192,7 @@ django-formtools==2.3
     # via
     #   -r requirements/ci.txt
     #   django-two-factor-auth
-django-jsonform==2.21.4
+django-jsonform==2.22.0
     # via
     #   -r requirements/ci.txt
     #   mozilla-django-oidc-db
@@ -255,11 +256,10 @@ django-solo==2.2.0
 django-two-factor-auth[phonenumberslite,webauthn]==1.16.0
     # via
     #   -r requirements/ci.txt
-    #   django-two-factor-auth
     #   maykin-2fa
 django-webtest==1.9.7
     # via -r requirements/ci.txt
-djangorestframework==3.14.0
+djangorestframework==3.15.2
     # via
     #   -r requirements/ci.txt
     #   commonground-api-common
@@ -293,7 +293,7 @@ drf-nested-routers==0.93.3
     # via
     #   -r requirements/ci.txt
     #   commonground-api-common
-drf-spectacular==0.27.0
+drf-spectacular==0.27.2
     # via
     #   -r requirements/ci.txt
     #   open-api-framework
@@ -305,7 +305,7 @@ ecs-logging==2.1.0
     # via
     #   -r requirements/ci.txt
     #   elastic-apm
-elastic-apm==6.20.0
+elastic-apm==6.23.0
     # via
     #   -r requirements/ci.txt
     #   open-api-framework
@@ -344,10 +344,11 @@ humanize==4.9.0
     # via
     #   -r requirements/ci.txt
     #   flower
-idna==2.10
+idna==3.7
     # via
     #   -r requirements/ci.txt
     #   requests
+    #   yarl
 imagesize==1.4.1
     # via sphinx
 inflection==0.5.1
@@ -369,7 +370,7 @@ itypes==1.2.0
     # via
     #   -r requirements/ci.txt
     #   coreapi
-jinja2==3.1.3
+jinja2==3.1.4
     # via
     #   -r requirements/ci.txt
     #   coreschema
@@ -394,7 +395,7 @@ markupsafe==2.1.3
     # via
     #   -r requirements/ci.txt
     #   jinja2
-maykin-2fa==1.0.0
+maykin-2fa==1.0.1
     # via
     #   -r requirements/ci.txt
     #   open-api-framework
@@ -404,17 +405,21 @@ mozilla-django-oidc==4.0.0
     # via
     #   -r requirements/ci.txt
     #   mozilla-django-oidc-db
-mozilla-django-oidc-db==0.14.1
+mozilla-django-oidc-db==0.19.0
     # via
     #   -r requirements/ci.txt
     #   open-api-framework
+multidict==6.0.5
+    # via
+    #   -r requirements/ci.txt
+    #   yarl
 mypy-extensions==0.4.3
     # via black
 notifications-api-common==0.2.2
     # via
     #   -r requirements/ci.txt
     #   commonground-api-common
-open-api-framework==0.5.0
+open-api-framework==0.6.1
     # via -r requirements/ci.txt
 orderedmultidict==1.0.1
     # via
@@ -485,9 +490,10 @@ pyrsistent==0.17.3
     # via
     #   -r requirements/ci.txt
     #   jsonschema
-python-dateutil==2.8.1
+python-dateutil==2.9.0.post0
     # via
     #   -r requirements/ci.txt
+    #   celery
     #   django-relativedelta
     #   faker
     #   freezegun
@@ -503,8 +509,6 @@ pytz==2024.1
     # via
     #   -r requirements/ci.txt
     #   babel
-    #   celery
-    #   djangorestframework
     #   drf-yasg
     #   flower
 pyyaml==6.0.1
@@ -514,6 +518,7 @@ pyyaml==6.0.1
     #   drf-yasg
     #   gemma-zds-client
     #   oyaml
+    #   vcrpy
 qrcode==6.1
     # via
     #   -r requirements/ci.txt
@@ -524,7 +529,7 @@ redis==3.5.3
     # via
     #   -r requirements/ci.txt
     #   django-redis
-requests==2.31.0
+requests==2.32.3
     # via
     #   -r requirements/ci.txt
     #   commonground-api-common
@@ -540,7 +545,7 @@ requests-mock==1.8.0
     # via
     #   -r requirements/ci.txt
     #   zgw-consumers
-sentry-sdk==1.39.2
+sentry-sdk==2.12.0
     # via
     #   -r requirements/ci.txt
     #   open-api-framework
@@ -586,7 +591,7 @@ sphinxcontrib-qthelp==1.0.3
     # via sphinx
 sphinxcontrib-serializinghtml==1.1.5
     # via sphinx
-sqlparse==0.4.2
+sqlparse==0.5.0
     # via
     #   -r requirements/ci.txt
     #   django
@@ -597,28 +602,25 @@ text-unidecode==1.3
     # via
     #   -r requirements/ci.txt
     #   faker
-tomli==2.0.1
-    # via
-    #   black
-    #   build
-    #   pip-tools
-    #   pyproject-hooks
-tornado==6.4
+tornado==6.4.1
     # via
     #   -r requirements/ci.txt
     #   flower
 typing-extensions==4.9.0
     # via
     #   -r requirements/ci.txt
-    #   asgiref
-    #   black
+    #   mozilla-django-oidc-db
+tzdata==2024.1
+    # via
+    #   -r requirements/ci.txt
+    #   celery
 uritemplate==3.0.1
     # via
     #   -r requirements/ci.txt
     #   coreapi
     #   drf-spectacular
     #   drf-yasg
-urllib3==2.2.1
+urllib3==2.2.2
     # via
     #   -r requirements/ci.txt
     #   elastic-apm
@@ -628,13 +630,15 @@ uwsgi==2.0.23
     # via
     #   -r requirements/ci.txt
     #   open-api-framework
+vcrpy==6.0.1
+    # via -r requirements/ci.txt
 vine==5.1.0
     # via
     #   -r requirements/ci.txt
     #   amqp
     #   celery
     #   kombu
-waitress==2.1.1
+waitress==2.1.2
     # via
     #   -r requirements/ci.txt
     #   webtest
@@ -664,6 +668,11 @@ wrapt==1.14.1
     # via
     #   -r requirements/ci.txt
     #   elastic-apm
+    #   vcrpy
+yarl==1.9.4
+    # via
+    #   -r requirements/ci.txt
+    #   vcrpy
 zgw-consumers==0.27.0
     # via
     #   -r requirements/ci.txt
diff --git a/requirements/test-tools.in b/requirements/test-tools.in
index f6f5c01d..e9d49af0 100644
--- a/requirements/test-tools.in
+++ b/requirements/test-tools.in
@@ -6,3 +6,4 @@ freezegun
 pyquery  # integrates with webtest
 requests-mock
 tblib
+vcrpy
diff --git a/src/objects/accounts/tests/factories.py b/src/objects/accounts/tests/factories.py
index 5b8130b1..843f3953 100644
--- a/src/objects/accounts/tests/factories.py
+++ b/src/objects/accounts/tests/factories.py
@@ -1,8 +1,26 @@
-import factory.fuzzy
+from django.contrib.auth import get_user_model
 
+import factory
+from factory.django import DjangoModelFactory
 
-class UserFactory(factory.django.DjangoModelFactory):
+User = get_user_model()
+
+
+class UserFactory(DjangoModelFactory):
     username = factory.Sequence(lambda n: f"user-{n}")
+    first_name = factory.Faker("first_name")
+    last_name = factory.Faker("last_name")
+    password = factory.PostGenerationMethodCall("set_password", "password")
 
     class Meta:
-        model = "accounts.User"
+        model = User
+
+    class Params:
+        superuser = factory.Trait(
+            is_staff=True,
+            is_superuser=True,
+        )
+
+
+class StaffUserFactory(UserFactory):
+    is_staff = True
diff --git a/src/objects/accounts/tests/keycloak_cassets/duplicate_email.yaml b/src/objects/accounts/tests/keycloak_cassets/duplicate_email.yaml
new file mode 100644
index 00000000..a96dbc44
--- /dev/null
+++ b/src/objects/accounts/tests/keycloak_cassets/duplicate_email.yaml
@@ -0,0 +1,314 @@
+interactions:
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/auth?response_type=code&scope=openid&client_id=testid&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F&state=not-a-random-string&nonce=not-a-random-string
+  response:
+    body:
+      string: "<!DOCTYPE html>\n<html class=\"login-pf\">\n\n<head>\n    <meta charset=\"utf-8\">\n
+        \   <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"
+        />\n    <meta name=\"robots\" content=\"noindex, nofollow\">\n\n            <meta
+        name=\"viewport\" content=\"width=device-width,initial-scale=1\"/>\n    <title>Sign
+        in to test</title>\n    <link rel=\"icon\" href=\"/resources/25wg7/login/keycloak/img/favicon.ico\"
+        />\n            <link href=\"/resources/25wg7/common/keycloak/node_modules/@patternfly/patternfly/patternfly.min.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/common/keycloak/node_modules/patternfly/dist/css/patternfly.min.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/common/keycloak/node_modules/patternfly/dist/css/patternfly-additions.min.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/common/keycloak/lib/pficon/pficon.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/login/keycloak/css/login.css\"
+        rel=\"stylesheet\" />\n        <script type=\"module\">\n            import
+        { checkCookiesAndSetTimer } from \"/resources/25wg7/login/keycloak/js/authChecker.js\";\n\n
+        \           checkCookiesAndSetTimer(\n              \"27b136e6-b724-4aa4-98ad-bd87c311ea49\",\n
+        \             \"70a2_sn6uUo\",\n              \"/realms/test/login-actions/restart?client_id=testid&tab_id=70a2_sn6uUo&skip_logout=true\"\n
+        \           );\n        </script>\n</head>\n\n<body class=\"\">\n<div class=\"login-pf-page\">\n
+        \   <div id=\"kc-header\" class=\"login-pf-page-header\">\n        <div id=\"kc-header-wrapper\"\n
+        \            class=\"\">test</div>\n    </div>\n    <div class=\"card-pf\">\n
+        \       <header class=\"login-pf-header\">\n                <h1 id=\"kc-page-title\">
+        \       Sign in to your account\n\n</h1>\n      </header>\n      <div id=\"kc-content\">\n
+        \       <div id=\"kc-content-wrapper\">\n\n\n        <div id=\"kc-form\">\n
+        \         <div id=\"kc-form-wrapper\">\n                <form id=\"kc-form-login\"
+        onsubmit=\"login.disabled = true; return true;\" action=\"http://localhost:8080/realms/test/login-actions/authenticate?session_code=EcKoQAvb9_URRFfxUE3VM0d5MovzoPEtv39_igRTN3c&amp;execution=b29f5dd7-8ad1-412a-8026-f37f60fa4bc5&amp;client_id=testid&amp;tab_id=70a2_sn6uUo\"
+        method=\"post\">\n                        <div class=\"form-group\">\n                            <label
+        for=\"username\" class=\"pf-c-form__label pf-c-form__label-text\">Username
+        or email</label>\n\n                            <input tabindex=\"1\" id=\"username\"
+        class=\"pf-c-form-control\" name=\"username\" value=\"\"  type=\"text\" autofocus
+        autocomplete=\"off\"\n                                   aria-invalid=\"\"\n
+        \                           />\n\n\n                        </div>\n\n                    <div
+        class=\"form-group\">\n                        <label for=\"password\" class=\"pf-c-form__label
+        pf-c-form__label-text\">Password</label>\n\n                        <div class=\"pf-c-input-group\">\n
+        \                           <input tabindex=\"2\" id=\"password\" class=\"pf-c-form-control\"
+        name=\"password\" type=\"password\" autocomplete=\"off\"\n                                   aria-invalid=\"\"\n
+        \                           />\n                            <button class=\"pf-c-button
+        pf-m-control\" type=\"button\" aria-label=\"Show password\"\n                                    aria-controls=\"password\"
+        \ data-password-toggle\n                                    data-icon-show=\"fa
+        fa-eye\" data-icon-hide=\"fa fa-eye-slash\"\n                                    data-label-show=\"Show
+        password\" data-label-hide=\"Hide password\">\n                                <i
+        class=\"fa fa-eye\" aria-hidden=\"true\"></i>\n                            </button>\n
+        \                       </div>\n\n\n                    </div>\n\n                    <div
+        class=\"form-group login-pf-settings\">\n                        <div id=\"kc-form-options\">\n
+        \                           </div>\n                            <div class=\"\">\n
+        \                           </div>\n\n                      </div>\n\n                      <div
+        id=\"kc-form-buttons\" class=\"form-group\">\n                          <input
+        type=\"hidden\" id=\"id-hidden-input\" name=\"credentialId\" />\n                          <input
+        tabindex=\"4\" class=\"pf-c-button pf-m-primary pf-m-block btn-lg\" name=\"login\"
+        id=\"kc-login\" type=\"submit\" value=\"Sign In\"/>\n                      </div>\n
+        \               </form>\n            </div>\n        </div>\n        <script
+        type=\"module\" src=\"/resources/25wg7/login/keycloak/js/passwordVisibility.js\"></script>\n\n\n\n\n\n
+        \       </div>\n      </div>\n\n    </div>\n  </div>\n</body>\n</html>\n"
+    headers:
+      Cache-Control:
+      - no-store, must-revalidate, max-age=0
+      Content-Language:
+      - en
+      Content-Security-Policy:
+      - frame-src 'self'; frame-ancestors 'self'; object-src 'none';
+      Content-Type:
+      - text/html;charset=utf-8
+      Referrer-Policy:
+      - no-referrer
+      Set-Cookie:
+      - AUTH_SESSION_ID=27b136e6-b724-4aa4-98ad-bd87c311ea49; Version=1; Path=/realms/test/;
+        SameSite=None; Secure; HttpOnly
+      - AUTH_SESSION_ID_LEGACY=27b136e6-b724-4aa4-98ad-bd87c311ea49; Version=1; Path=/realms/test/;
+        HttpOnly
+      - KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI;
+        Version=1; Path=/realms/test/; HttpOnly
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-Robots-Tag:
+      - none
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '4466'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: username=admin&password=admin&credentialId=&login=Sign+In
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '57'
+      Content-Type:
+      - application/x-www-form-urlencoded
+      Cookie:
+      - AUTH_SESSION_ID_LEGACY=27b136e6-b724-4aa4-98ad-bd87c311ea49; KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI
+      User-Agent:
+      - python-requests/2.32.3
+    method: POST
+    uri: http://localhost:8080/realms/test/login-actions/authenticate?session_code=EcKoQAvb9_URRFfxUE3VM0d5MovzoPEtv39_igRTN3c&execution=b29f5dd7-8ad1-412a-8026-f37f60fa4bc5&client_id=testid&tab_id=70a2_sn6uUo
+  response:
+    body:
+      string: ''
+    headers:
+      Cache-Control:
+      - no-store, must-revalidate, max-age=0
+      Content-Security-Policy:
+      - frame-src 'self'; frame-ancestors 'self'; object-src 'none';
+      Location:
+      - http://testserver/oidc/callback/?state=not-a-random-string&session_state=27b136e6-b724-4aa4-98ad-bd87c311ea49&iss=http%3A%2F%2Flocalhost%3A8080%2Frealms%2Ftest&code=822a2a28-23ee-459f-8cf4-f277c152ee74.27b136e6-b724-4aa4-98ad-bd87c311ea49.adf4ad83-4550-4619-9231-73bd8d700f45
+      Referrer-Policy:
+      - no-referrer
+      Set-Cookie:
+      - KEYCLOAK_LOCALE=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970
+        00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly
+      - KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0;
+        Path=/realms/test/; HttpOnly
+      - KC_AUTH_STATE=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0;
+        Path=/realms/test/
+      - KEYCLOAK_IDENTITY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjMyNTAzMjgsImlhdCI6MTcyMzIxNDMyOCwianRpIjoiZTgwYWM1ZWMtOGU2Ny00NzI1LThmOGYtNzVmNzM0MGMyNWE1IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiIyN2IxMzZlNi1iNzI0LTRhYTQtOThhZC1iZDg3YzMxMWVhNDkiLCJzaWQiOiIyN2IxMzZlNi1iNzI0LTRhYTQtOThhZC1iZDg3YzMxMWVhNDkiLCJzdGF0ZV9jaGVja2VyIjoidmRiRXdoVzNWRFZNMTVIbVg4bnVxNjZ4eXpCWUZaNk9rcFlhZ2Z4VGo3dyJ9.X535OlODkas3T89AuYG4FPigeqd7wRtIwwPRX6SucY0;
+        Version=1; Path=/realms/test/; SameSite=None; Secure; HttpOnly
+      - KEYCLOAK_IDENTITY_LEGACY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjMyNTAzMjgsImlhdCI6MTcyMzIxNDMyOCwianRpIjoiZTgwYWM1ZWMtOGU2Ny00NzI1LThmOGYtNzVmNzM0MGMyNWE1IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiIyN2IxMzZlNi1iNzI0LTRhYTQtOThhZC1iZDg3YzMxMWVhNDkiLCJzaWQiOiIyN2IxMzZlNi1iNzI0LTRhYTQtOThhZC1iZDg3YzMxMWVhNDkiLCJzdGF0ZV9jaGVja2VyIjoidmRiRXdoVzNWRFZNMTVIbVg4bnVxNjZ4eXpCWUZaNk9rcFlhZ2Z4VGo3dyJ9.X535OlODkas3T89AuYG4FPigeqd7wRtIwwPRX6SucY0;
+        Version=1; Path=/realms/test/; HttpOnly
+      - KEYCLOAK_SESSION=test/6db2db87-de31-4e30-9f25-cefe5da8b154/27b136e6-b724-4aa4-98ad-bd87c311ea49;
+        Version=1; Expires=Sat, 10-Aug-2024 00:38:48 GMT; Max-Age=36000; Path=/realms/test/;
+        SameSite=None; Secure
+      - KEYCLOAK_SESSION_LEGACY=test/6db2db87-de31-4e30-9f25-cefe5da8b154/27b136e6-b724-4aa4-98ad-bd87c311ea49;
+        Version=1; Expires=Sat, 10-Aug-2024 00:38:48 GMT; Max-Age=36000; Path=/realms/test/
+      - KEYCLOAK_REMEMBER_ME=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970
+        00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-Robots-Tag:
+      - none
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '0'
+    status:
+      code: 302
+      message: Found
+- request:
+    body: client_id=testid&client_secret=7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I&grant_type=authorization_code&code=822a2a28-23ee-459f-8cf4-f277c152ee74.27b136e6-b724-4aa4-98ad-bd87c311ea49.adf4ad83-4550-4619-9231-73bd8d700f45&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '267'
+      Content-Type:
+      - application/x-www-form-urlencoded
+      User-Agent:
+      - python-requests/2.32.3
+    method: POST
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/token
+  response:
+    body:
+      string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjMyMTQ2MjgsImlhdCI6MTcyMzIxNDMyOCwiYXV0aF90aW1lIjoxNzIzMjE0MzI4LCJqdGkiOiI0NDI5NWYzZS03YzM0LTQ0ZmUtOWEyMi05ZWIzNjgzMWI2NWQiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6IjI3YjEzNmU2LWI3MjQtNGFhNC05OGFkLWJkODdjMzExZWE0OSIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgZ3JvdXBzIGJzbiIsInNpZCI6IjI3YjEzNmU2LWI3MjQtNGFhNC05OGFkLWJkODdjMzExZWE0OSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiUmVnaXN0cmVlcmRlcnMiLCJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSJ9.FOJ2lKA6rW9CAdBnT31TkWJmtORtwDm7YJxLeYEPeOUM6zbQBJTH9ha-9WDFNOHFvLa3_iyM2OPsuO5jkUMPhxOK1bzYvbhoYfzSv2OV1MQ4xrXOX3G2rmctyTeVJSn_glDCU5T2Uin6wWQULlfL-p6tZEBV4t0O83yh975X9LE9olL_Pl4JKt0_axl_I1jivKWw4u9blN_jfjNZHUppUENSKr4bz4j5OziP7ivQ-TbK27381gh-lbwkYC-ONxY-xp6z-SxnrEKf5rhypCOaD3lJ471F4gjdKbYFMQOqKtBdH8gqoham8rNZgjQKOepKtEkSvbVhVwloT55VrAULnQ","expires_in":300,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjMyMTYxMjgsImlhdCI6MTcyMzIxNDMyOCwianRpIjoiNzlhMWVlMGQtN2Y4Yy00OGUyLWFlNDMtN2JhMTRhZjIzZmFlIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiIyN2IxMzZlNi1iNzI0LTRhYTQtOThhZC1iZDg3YzMxMWVhNDkiLCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIGt2ayBncm91cHMgYnNuIiwic2lkIjoiMjdiMTM2ZTYtYjcyNC00YWE0LTk4YWQtYmQ4N2MzMTFlYTQ5In0.50p-PnvW0f7UvA7-f8dF4G7fx3HA1Xfwe6ce2Lmxin8","token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjMyMTQ2MjgsImlhdCI6MTcyMzIxNDMyOCwiYXV0aF90aW1lIjoxNzIzMjE0MzI4LCJqdGkiOiJmNmE2YTVlYy01NDJlLTQ0ZTMtYmVkOS1hZWFkODk2M2MwZjUiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJ0ZXN0aWQiLCJzdWIiOiI2ZGIyZGI4Ny1kZTMxLTRlMzAtOWYyNS1jZWZlNWRhOGIxNTQiLCJ0eXAiOiJJRCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiIyN2IxMzZlNi1iNzI0LTRhYTQtOThhZC1iZDg3YzMxMWVhNDkiLCJhdF9oYXNoIjoiSnEzclh1UU9LUmktWkQwZWdsczhudyIsImFjciI6IjEiLCJzaWQiOiIyN2IxMzZlNi1iNzI0LTRhYTQtOThhZC1iZDg3YzMxMWVhNDkiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ3JvdXBzIjpbIlJlZ2lzdHJlZXJkZXJzIiwiZGVmYXVsdC1yb2xlcy10ZXN0Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20ifQ.egzD-aTo5dQfsRRyH9GqT_BEP0teK3OLAdVpnZVCkpOXQ8qWquP35E_zB1EXRmRN26Cyrc6rfQKnrCsvGop03V7ctleMRTbCOvvbrtWZ910MCt4SCW9VmUg2dfdlLKhcGYa6E9b2j-srE5_T8PsKZ-7tA3ylXZq_gd9WNaoLs9h1tp0OVZj9E7xCeD936C68be0mTuVelqDydH3_V4MNpvj1TkPIpS4hN8u8cwFOMLbKt1SIE6zRUpxPfV7_2s843m9oOw5F_5VA2i2UxjRJzup2AmrikBtfhFiefJKBmofMfiRvCkii9e5qA9Y8FNMKGZ8A7d_4KEd-_qVOhPDzOA","not-before-policy":0,"session_state":"27b136e6-b724-4aa4-98ad-bd87c311ea49","scope":"openid
+        email profile kvk groups bsn"}'
+    headers:
+      Cache-Control:
+      - no-store
+      Content-Type:
+      - application/json
+      Pragma:
+      - no-cache
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '3698'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/certs
+  response:
+    body:
+      string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}'
+    headers:
+      Cache-Control:
+      - no-cache
+      Content-Type:
+      - application/json;charset=UTF-8
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '2909'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Authorization:
+      - Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjMyMTQ2MjgsImlhdCI6MTcyMzIxNDMyOCwiYXV0aF90aW1lIjoxNzIzMjE0MzI4LCJqdGkiOiI0NDI5NWYzZS03YzM0LTQ0ZmUtOWEyMi05ZWIzNjgzMWI2NWQiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6IjI3YjEzNmU2LWI3MjQtNGFhNC05OGFkLWJkODdjMzExZWE0OSIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgZ3JvdXBzIGJzbiIsInNpZCI6IjI3YjEzNmU2LWI3MjQtNGFhNC05OGFkLWJkODdjMzExZWE0OSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiUmVnaXN0cmVlcmRlcnMiLCJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSJ9.FOJ2lKA6rW9CAdBnT31TkWJmtORtwDm7YJxLeYEPeOUM6zbQBJTH9ha-9WDFNOHFvLa3_iyM2OPsuO5jkUMPhxOK1bzYvbhoYfzSv2OV1MQ4xrXOX3G2rmctyTeVJSn_glDCU5T2Uin6wWQULlfL-p6tZEBV4t0O83yh975X9LE9olL_Pl4JKt0_axl_I1jivKWw4u9blN_jfjNZHUppUENSKr4bz4j5OziP7ivQ-TbK27381gh-lbwkYC-ONxY-xp6z-SxnrEKf5rhypCOaD3lJ471F4gjdKbYFMQOqKtBdH8gqoham8rNZgjQKOepKtEkSvbVhVwloT55VrAULnQ
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
+  response:
+    body:
+      string: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJzdWIiOiI2ZGIyZGI4Ny1kZTMxLTRlMzAtOWYyNS1jZWZlNWRhOGIxNTQiLCJhdWQiOiJ0ZXN0aWQiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiZ3JvdXBzIjpbIlJlZ2lzdHJlZXJkZXJzIiwiZGVmYXVsdC1yb2xlcy10ZXN0Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20ifQ.vx4dCJ-Y-PEzjy8p7CNPB3yy0TyV_QugOHRbiV6UY3qHtZUnZqSsJD991QUostcYECuyTHefqfRtdCbvSJcPWI4ucosY65vshUMBtQeahsFOgNwWp2BvCkALJmEya4H_gh63vVlVZ2ZOSpWpah6eV2PNhiiYWD-Y9qEuLMzwngNvp5hna30BiRKAEsStB7izjE5pGECqkQm7pxCeZWHU81Lbh5fSo_2XvcGZ1Z-tf6DN95Oz4ers9YrG6dKSuh-HciY1zhv7mcee_tlJaeKjITue6r06163oKdjsYKRpiR4bLQ9256KafoxmU6O0IIlpkQhmtXrmaFSg0XyBYU8qcQ
+    headers:
+      Cache-Control:
+      - no-cache
+      Content-Type:
+      - application/jwt
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '813'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/certs
+  response:
+    body:
+      string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}'
+    headers:
+      Cache-Control:
+      - no-cache
+      Content-Type:
+      - application/json;charset=UTF-8
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '2909'
+    status:
+      code: 200
+      message: OK
+version: 1
diff --git a/src/objects/accounts/tests/keycloak_cassets/happy_flow.yaml b/src/objects/accounts/tests/keycloak_cassets/happy_flow.yaml
new file mode 100644
index 00000000..d748a607
--- /dev/null
+++ b/src/objects/accounts/tests/keycloak_cassets/happy_flow.yaml
@@ -0,0 +1,314 @@
+interactions:
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/auth?response_type=code&scope=openid&client_id=testid&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F&state=not-a-random-string&nonce=not-a-random-string
+  response:
+    body:
+      string: "<!DOCTYPE html>\n<html class=\"login-pf\">\n\n<head>\n    <meta charset=\"utf-8\">\n
+        \   <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"
+        />\n    <meta name=\"robots\" content=\"noindex, nofollow\">\n\n            <meta
+        name=\"viewport\" content=\"width=device-width,initial-scale=1\"/>\n    <title>Sign
+        in to test</title>\n    <link rel=\"icon\" href=\"/resources/25wg7/login/keycloak/img/favicon.ico\"
+        />\n            <link href=\"/resources/25wg7/common/keycloak/node_modules/@patternfly/patternfly/patternfly.min.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/common/keycloak/node_modules/patternfly/dist/css/patternfly.min.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/common/keycloak/node_modules/patternfly/dist/css/patternfly-additions.min.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/common/keycloak/lib/pficon/pficon.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/login/keycloak/css/login.css\"
+        rel=\"stylesheet\" />\n        <script type=\"module\">\n            import
+        { checkCookiesAndSetTimer } from \"/resources/25wg7/login/keycloak/js/authChecker.js\";\n\n
+        \           checkCookiesAndSetTimer(\n              \"deb831a3-3338-4d32-8d8a-3c9ef74c246f\",\n
+        \             \"907AcvLHmCo\",\n              \"/realms/test/login-actions/restart?client_id=testid&tab_id=907AcvLHmCo&skip_logout=true\"\n
+        \           );\n        </script>\n</head>\n\n<body class=\"\">\n<div class=\"login-pf-page\">\n
+        \   <div id=\"kc-header\" class=\"login-pf-page-header\">\n        <div id=\"kc-header-wrapper\"\n
+        \            class=\"\">test</div>\n    </div>\n    <div class=\"card-pf\">\n
+        \       <header class=\"login-pf-header\">\n                <h1 id=\"kc-page-title\">
+        \       Sign in to your account\n\n</h1>\n      </header>\n      <div id=\"kc-content\">\n
+        \       <div id=\"kc-content-wrapper\">\n\n\n        <div id=\"kc-form\">\n
+        \         <div id=\"kc-form-wrapper\">\n                <form id=\"kc-form-login\"
+        onsubmit=\"login.disabled = true; return true;\" action=\"http://localhost:8080/realms/test/login-actions/authenticate?session_code=pdtcFJfZrjAJKls5sSGX3K6lSlkRq0XiiVACVcmc3l0&amp;execution=b29f5dd7-8ad1-412a-8026-f37f60fa4bc5&amp;client_id=testid&amp;tab_id=907AcvLHmCo\"
+        method=\"post\">\n                        <div class=\"form-group\">\n                            <label
+        for=\"username\" class=\"pf-c-form__label pf-c-form__label-text\">Username
+        or email</label>\n\n                            <input tabindex=\"1\" id=\"username\"
+        class=\"pf-c-form-control\" name=\"username\" value=\"\"  type=\"text\" autofocus
+        autocomplete=\"off\"\n                                   aria-invalid=\"\"\n
+        \                           />\n\n\n                        </div>\n\n                    <div
+        class=\"form-group\">\n                        <label for=\"password\" class=\"pf-c-form__label
+        pf-c-form__label-text\">Password</label>\n\n                        <div class=\"pf-c-input-group\">\n
+        \                           <input tabindex=\"2\" id=\"password\" class=\"pf-c-form-control\"
+        name=\"password\" type=\"password\" autocomplete=\"off\"\n                                   aria-invalid=\"\"\n
+        \                           />\n                            <button class=\"pf-c-button
+        pf-m-control\" type=\"button\" aria-label=\"Show password\"\n                                    aria-controls=\"password\"
+        \ data-password-toggle\n                                    data-icon-show=\"fa
+        fa-eye\" data-icon-hide=\"fa fa-eye-slash\"\n                                    data-label-show=\"Show
+        password\" data-label-hide=\"Hide password\">\n                                <i
+        class=\"fa fa-eye\" aria-hidden=\"true\"></i>\n                            </button>\n
+        \                       </div>\n\n\n                    </div>\n\n                    <div
+        class=\"form-group login-pf-settings\">\n                        <div id=\"kc-form-options\">\n
+        \                           </div>\n                            <div class=\"\">\n
+        \                           </div>\n\n                      </div>\n\n                      <div
+        id=\"kc-form-buttons\" class=\"form-group\">\n                          <input
+        type=\"hidden\" id=\"id-hidden-input\" name=\"credentialId\" />\n                          <input
+        tabindex=\"4\" class=\"pf-c-button pf-m-primary pf-m-block btn-lg\" name=\"login\"
+        id=\"kc-login\" type=\"submit\" value=\"Sign In\"/>\n                      </div>\n
+        \               </form>\n            </div>\n        </div>\n        <script
+        type=\"module\" src=\"/resources/25wg7/login/keycloak/js/passwordVisibility.js\"></script>\n\n\n\n\n\n
+        \       </div>\n      </div>\n\n    </div>\n  </div>\n</body>\n</html>\n"
+    headers:
+      Cache-Control:
+      - no-store, must-revalidate, max-age=0
+      Content-Language:
+      - en
+      Content-Security-Policy:
+      - frame-src 'self'; frame-ancestors 'self'; object-src 'none';
+      Content-Type:
+      - text/html;charset=utf-8
+      Referrer-Policy:
+      - no-referrer
+      Set-Cookie:
+      - AUTH_SESSION_ID=deb831a3-3338-4d32-8d8a-3c9ef74c246f; Version=1; Path=/realms/test/;
+        SameSite=None; Secure; HttpOnly
+      - AUTH_SESSION_ID_LEGACY=deb831a3-3338-4d32-8d8a-3c9ef74c246f; Version=1; Path=/realms/test/;
+        HttpOnly
+      - KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI;
+        Version=1; Path=/realms/test/; HttpOnly
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-Robots-Tag:
+      - none
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '4466'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: username=admin&password=admin&credentialId=&login=Sign+In
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '57'
+      Content-Type:
+      - application/x-www-form-urlencoded
+      Cookie:
+      - AUTH_SESSION_ID_LEGACY=deb831a3-3338-4d32-8d8a-3c9ef74c246f; KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI
+      User-Agent:
+      - python-requests/2.32.3
+    method: POST
+    uri: http://localhost:8080/realms/test/login-actions/authenticate?session_code=pdtcFJfZrjAJKls5sSGX3K6lSlkRq0XiiVACVcmc3l0&execution=b29f5dd7-8ad1-412a-8026-f37f60fa4bc5&client_id=testid&tab_id=907AcvLHmCo
+  response:
+    body:
+      string: ''
+    headers:
+      Cache-Control:
+      - no-store, must-revalidate, max-age=0
+      Content-Security-Policy:
+      - frame-src 'self'; frame-ancestors 'self'; object-src 'none';
+      Location:
+      - http://testserver/oidc/callback/?state=not-a-random-string&session_state=deb831a3-3338-4d32-8d8a-3c9ef74c246f&iss=http%3A%2F%2Flocalhost%3A8080%2Frealms%2Ftest&code=ae60a86a-9dc0-48a1-b4e9-3562e3e2ea92.deb831a3-3338-4d32-8d8a-3c9ef74c246f.adf4ad83-4550-4619-9231-73bd8d700f45
+      Referrer-Policy:
+      - no-referrer
+      Set-Cookie:
+      - KEYCLOAK_LOCALE=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970
+        00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly
+      - KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0;
+        Path=/realms/test/; HttpOnly
+      - KC_AUTH_STATE=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0;
+        Path=/realms/test/
+      - KEYCLOAK_IDENTITY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjMyNTAzMjgsImlhdCI6MTcyMzIxNDMyOCwianRpIjoiN2Y1YWM5OTgtNzI0NC00YTRkLTk5M2ItODVhOWVhZmYyYmQwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiJkZWI4MzFhMy0zMzM4LTRkMzItOGQ4YS0zYzllZjc0YzI0NmYiLCJzaWQiOiJkZWI4MzFhMy0zMzM4LTRkMzItOGQ4YS0zYzllZjc0YzI0NmYiLCJzdGF0ZV9jaGVja2VyIjoiUDl0NmlKbnp0QTBERmptWkR4LXBYd3drdEdfNkY1dlpqZDJPWmZNajlhNCJ9.N8DOiIpRb6feWa5yKohNqr09Z4cfe3H_xyK3jzwo5cQ;
+        Version=1; Path=/realms/test/; SameSite=None; Secure; HttpOnly
+      - KEYCLOAK_IDENTITY_LEGACY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjMyNTAzMjgsImlhdCI6MTcyMzIxNDMyOCwianRpIjoiN2Y1YWM5OTgtNzI0NC00YTRkLTk5M2ItODVhOWVhZmYyYmQwIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiJkZWI4MzFhMy0zMzM4LTRkMzItOGQ4YS0zYzllZjc0YzI0NmYiLCJzaWQiOiJkZWI4MzFhMy0zMzM4LTRkMzItOGQ4YS0zYzllZjc0YzI0NmYiLCJzdGF0ZV9jaGVja2VyIjoiUDl0NmlKbnp0QTBERmptWkR4LXBYd3drdEdfNkY1dlpqZDJPWmZNajlhNCJ9.N8DOiIpRb6feWa5yKohNqr09Z4cfe3H_xyK3jzwo5cQ;
+        Version=1; Path=/realms/test/; HttpOnly
+      - KEYCLOAK_SESSION=test/6db2db87-de31-4e30-9f25-cefe5da8b154/deb831a3-3338-4d32-8d8a-3c9ef74c246f;
+        Version=1; Expires=Sat, 10-Aug-2024 00:38:48 GMT; Max-Age=36000; Path=/realms/test/;
+        SameSite=None; Secure
+      - KEYCLOAK_SESSION_LEGACY=test/6db2db87-de31-4e30-9f25-cefe5da8b154/deb831a3-3338-4d32-8d8a-3c9ef74c246f;
+        Version=1; Expires=Sat, 10-Aug-2024 00:38:48 GMT; Max-Age=36000; Path=/realms/test/
+      - KEYCLOAK_REMEMBER_ME=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970
+        00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-Robots-Tag:
+      - none
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '0'
+    status:
+      code: 302
+      message: Found
+- request:
+    body: client_id=testid&client_secret=7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I&grant_type=authorization_code&code=ae60a86a-9dc0-48a1-b4e9-3562e3e2ea92.deb831a3-3338-4d32-8d8a-3c9ef74c246f.adf4ad83-4550-4619-9231-73bd8d700f45&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '267'
+      Content-Type:
+      - application/x-www-form-urlencoded
+      User-Agent:
+      - python-requests/2.32.3
+    method: POST
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/token
+  response:
+    body:
+      string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjMyMTQ2MjksImlhdCI6MTcyMzIxNDMyOSwiYXV0aF90aW1lIjoxNzIzMjE0MzI4LCJqdGkiOiJiYTI4MjY5MC1hZDQwLTQzYTQtYmNiZS1iZWRmMDNkYWFjZWYiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6ImRlYjgzMWEzLTMzMzgtNGQzMi04ZDhhLTNjOWVmNzRjMjQ2ZiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgZ3JvdXBzIGJzbiIsInNpZCI6ImRlYjgzMWEzLTMzMzgtNGQzMi04ZDhhLTNjOWVmNzRjMjQ2ZiIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiUmVnaXN0cmVlcmRlcnMiLCJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSJ9.1GquRLpb9qkWW6VXI8R4wkG9hQvnbKnbCZaNWXpChRL6OSgO-qTtBXNG96VqN24_BDj9VkXBiRlc1M867aN2yJYdKtdlg0P7qS-CwgfNDnDTkTZwxGgYvumnP5iLb9aX_nq_1kuSB_Din2e6HR4KpSUslUa7IK4tjbyts4gz4KEOhgYn0pkv_MhdljumFIaRgcY8pKQTZ9uJH0S--Cu_P2z135f_9p45RkB-F7Zx8pmcHEyx2v3EKhnsI1y_N0S6OqLCDN9s2U65CgAM4BOpY0SZrZqwXy0J6jYuoM5c5HKlhEHpIltMxY_ShooQ-Tqgucbb5p-x_L9INldgQnE2Dw","expires_in":300,"refresh_expires_in":1799,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjMyMTYxMjgsImlhdCI6MTcyMzIxNDMyOSwianRpIjoiZmU3YmUzNjAtODdlMy00NmVkLWJmOTAtOTBmMzU5MDE1NDJhIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiJkZWI4MzFhMy0zMzM4LTRkMzItOGQ4YS0zYzllZjc0YzI0NmYiLCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIGt2ayBncm91cHMgYnNuIiwic2lkIjoiZGViODMxYTMtMzMzOC00ZDMyLThkOGEtM2M5ZWY3NGMyNDZmIn0.wGP_SexEm3EskBgKbYaigT7VTrx-tXRJfRc4wFQQev0","token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjMyMTQ2MjksImlhdCI6MTcyMzIxNDMyOSwiYXV0aF90aW1lIjoxNzIzMjE0MzI4LCJqdGkiOiI2OTg5MDIzZS1iNDgwLTQ5NWUtOTc3ZC1hMDc1OGVhNTQ3OTQiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJ0ZXN0aWQiLCJzdWIiOiI2ZGIyZGI4Ny1kZTMxLTRlMzAtOWYyNS1jZWZlNWRhOGIxNTQiLCJ0eXAiOiJJRCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiJkZWI4MzFhMy0zMzM4LTRkMzItOGQ4YS0zYzllZjc0YzI0NmYiLCJhdF9oYXNoIjoibkZ2bWNRV21zSFJoYU9ncUdrMVRDUSIsImFjciI6IjEiLCJzaWQiOiJkZWI4MzFhMy0zMzM4LTRkMzItOGQ4YS0zYzllZjc0YzI0NmYiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ3JvdXBzIjpbIlJlZ2lzdHJlZXJkZXJzIiwiZGVmYXVsdC1yb2xlcy10ZXN0Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20ifQ.adtoUqYLr3_chQbuarVP13TmUdm0qRupoS-0_mq3ldrNGJ7tZzuRiqzF1QIHNWdugsumU-xstxvjpitKfR2xUuvlOcr3RJlVnkwuihhx96ykU0xkn2WXbsO_Hwe8BrXLiATavcecgWsQqnh3-gG_Dt72qB4jNuvITx5256zyrsT5rmq2NW8_H6uEMwYu_eaIiWNRrHxWOoKKsVcaz3UXu0pG_pfMGVktL9KhzwVth2Or-r_4YeIlNFPqJGE4wzRSL5AgtFz-V7eEjSXU2O1gA4WQu0i0b5RcA2e5lAzx1Rfcn5RKwzJIs7BCa1Ae5UUc24PEQ682CfMIBgpGibKhqg","not-before-policy":0,"session_state":"deb831a3-3338-4d32-8d8a-3c9ef74c246f","scope":"openid
+        email profile kvk groups bsn"}'
+    headers:
+      Cache-Control:
+      - no-store
+      Content-Type:
+      - application/json
+      Pragma:
+      - no-cache
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '3698'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/certs
+  response:
+    body:
+      string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}'
+    headers:
+      Cache-Control:
+      - no-cache
+      Content-Type:
+      - application/json;charset=UTF-8
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '2909'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Authorization:
+      - Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjMyMTQ2MjksImlhdCI6MTcyMzIxNDMyOSwiYXV0aF90aW1lIjoxNzIzMjE0MzI4LCJqdGkiOiJiYTI4MjY5MC1hZDQwLTQzYTQtYmNiZS1iZWRmMDNkYWFjZWYiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6ImRlYjgzMWEzLTMzMzgtNGQzMi04ZDhhLTNjOWVmNzRjMjQ2ZiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgZ3JvdXBzIGJzbiIsInNpZCI6ImRlYjgzMWEzLTMzMzgtNGQzMi04ZDhhLTNjOWVmNzRjMjQ2ZiIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiUmVnaXN0cmVlcmRlcnMiLCJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSJ9.1GquRLpb9qkWW6VXI8R4wkG9hQvnbKnbCZaNWXpChRL6OSgO-qTtBXNG96VqN24_BDj9VkXBiRlc1M867aN2yJYdKtdlg0P7qS-CwgfNDnDTkTZwxGgYvumnP5iLb9aX_nq_1kuSB_Din2e6HR4KpSUslUa7IK4tjbyts4gz4KEOhgYn0pkv_MhdljumFIaRgcY8pKQTZ9uJH0S--Cu_P2z135f_9p45RkB-F7Zx8pmcHEyx2v3EKhnsI1y_N0S6OqLCDN9s2U65CgAM4BOpY0SZrZqwXy0J6jYuoM5c5HKlhEHpIltMxY_ShooQ-Tqgucbb5p-x_L9INldgQnE2Dw
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
+  response:
+    body:
+      string: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJzdWIiOiI2ZGIyZGI4Ny1kZTMxLTRlMzAtOWYyNS1jZWZlNWRhOGIxNTQiLCJhdWQiOiJ0ZXN0aWQiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiZ3JvdXBzIjpbIlJlZ2lzdHJlZXJkZXJzIiwiZGVmYXVsdC1yb2xlcy10ZXN0Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20ifQ.vx4dCJ-Y-PEzjy8p7CNPB3yy0TyV_QugOHRbiV6UY3qHtZUnZqSsJD991QUostcYECuyTHefqfRtdCbvSJcPWI4ucosY65vshUMBtQeahsFOgNwWp2BvCkALJmEya4H_gh63vVlVZ2ZOSpWpah6eV2PNhiiYWD-Y9qEuLMzwngNvp5hna30BiRKAEsStB7izjE5pGECqkQm7pxCeZWHU81Lbh5fSo_2XvcGZ1Z-tf6DN95Oz4ers9YrG6dKSuh-HciY1zhv7mcee_tlJaeKjITue6r06163oKdjsYKRpiR4bLQ9256KafoxmU6O0IIlpkQhmtXrmaFSg0XyBYU8qcQ
+    headers:
+      Cache-Control:
+      - no-cache
+      Content-Type:
+      - application/jwt
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '813'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/certs
+  response:
+    body:
+      string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}'
+    headers:
+      Cache-Control:
+      - no-cache
+      Content-Type:
+      - application/json;charset=UTF-8
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '2909'
+    status:
+      code: 200
+      message: OK
+version: 1
diff --git a/src/objects/accounts/tests/keycloak_cassets/happy_flow_existing_user.yaml b/src/objects/accounts/tests/keycloak_cassets/happy_flow_existing_user.yaml
new file mode 100644
index 00000000..71fe183a
--- /dev/null
+++ b/src/objects/accounts/tests/keycloak_cassets/happy_flow_existing_user.yaml
@@ -0,0 +1,314 @@
+interactions:
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/auth?response_type=code&scope=openid&client_id=testid&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F&state=not-a-random-string&nonce=not-a-random-string
+  response:
+    body:
+      string: "<!DOCTYPE html>\n<html class=\"login-pf\">\n\n<head>\n    <meta charset=\"utf-8\">\n
+        \   <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"
+        />\n    <meta name=\"robots\" content=\"noindex, nofollow\">\n\n            <meta
+        name=\"viewport\" content=\"width=device-width,initial-scale=1\"/>\n    <title>Sign
+        in to test</title>\n    <link rel=\"icon\" href=\"/resources/25wg7/login/keycloak/img/favicon.ico\"
+        />\n            <link href=\"/resources/25wg7/common/keycloak/node_modules/@patternfly/patternfly/patternfly.min.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/common/keycloak/node_modules/patternfly/dist/css/patternfly.min.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/common/keycloak/node_modules/patternfly/dist/css/patternfly-additions.min.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/common/keycloak/lib/pficon/pficon.css\"
+        rel=\"stylesheet\" />\n            <link href=\"/resources/25wg7/login/keycloak/css/login.css\"
+        rel=\"stylesheet\" />\n        <script type=\"module\">\n            import
+        { checkCookiesAndSetTimer } from \"/resources/25wg7/login/keycloak/js/authChecker.js\";\n\n
+        \           checkCookiesAndSetTimer(\n              \"7f0abf13-cea9-405a-a50d-fd395b443218\",\n
+        \             \"P27-52WztMI\",\n              \"/realms/test/login-actions/restart?client_id=testid&tab_id=P27-52WztMI&skip_logout=true\"\n
+        \           );\n        </script>\n</head>\n\n<body class=\"\">\n<div class=\"login-pf-page\">\n
+        \   <div id=\"kc-header\" class=\"login-pf-page-header\">\n        <div id=\"kc-header-wrapper\"\n
+        \            class=\"\">test</div>\n    </div>\n    <div class=\"card-pf\">\n
+        \       <header class=\"login-pf-header\">\n                <h1 id=\"kc-page-title\">
+        \       Sign in to your account\n\n</h1>\n      </header>\n      <div id=\"kc-content\">\n
+        \       <div id=\"kc-content-wrapper\">\n\n\n        <div id=\"kc-form\">\n
+        \         <div id=\"kc-form-wrapper\">\n                <form id=\"kc-form-login\"
+        onsubmit=\"login.disabled = true; return true;\" action=\"http://localhost:8080/realms/test/login-actions/authenticate?session_code=caDvxOGVJp-PrUkU4rZT9OD6SIdO6Cs7J8ybFZaQ2qQ&amp;execution=b29f5dd7-8ad1-412a-8026-f37f60fa4bc5&amp;client_id=testid&amp;tab_id=P27-52WztMI\"
+        method=\"post\">\n                        <div class=\"form-group\">\n                            <label
+        for=\"username\" class=\"pf-c-form__label pf-c-form__label-text\">Username
+        or email</label>\n\n                            <input tabindex=\"1\" id=\"username\"
+        class=\"pf-c-form-control\" name=\"username\" value=\"\"  type=\"text\" autofocus
+        autocomplete=\"off\"\n                                   aria-invalid=\"\"\n
+        \                           />\n\n\n                        </div>\n\n                    <div
+        class=\"form-group\">\n                        <label for=\"password\" class=\"pf-c-form__label
+        pf-c-form__label-text\">Password</label>\n\n                        <div class=\"pf-c-input-group\">\n
+        \                           <input tabindex=\"2\" id=\"password\" class=\"pf-c-form-control\"
+        name=\"password\" type=\"password\" autocomplete=\"off\"\n                                   aria-invalid=\"\"\n
+        \                           />\n                            <button class=\"pf-c-button
+        pf-m-control\" type=\"button\" aria-label=\"Show password\"\n                                    aria-controls=\"password\"
+        \ data-password-toggle\n                                    data-icon-show=\"fa
+        fa-eye\" data-icon-hide=\"fa fa-eye-slash\"\n                                    data-label-show=\"Show
+        password\" data-label-hide=\"Hide password\">\n                                <i
+        class=\"fa fa-eye\" aria-hidden=\"true\"></i>\n                            </button>\n
+        \                       </div>\n\n\n                    </div>\n\n                    <div
+        class=\"form-group login-pf-settings\">\n                        <div id=\"kc-form-options\">\n
+        \                           </div>\n                            <div class=\"\">\n
+        \                           </div>\n\n                      </div>\n\n                      <div
+        id=\"kc-form-buttons\" class=\"form-group\">\n                          <input
+        type=\"hidden\" id=\"id-hidden-input\" name=\"credentialId\" />\n                          <input
+        tabindex=\"4\" class=\"pf-c-button pf-m-primary pf-m-block btn-lg\" name=\"login\"
+        id=\"kc-login\" type=\"submit\" value=\"Sign In\"/>\n                      </div>\n
+        \               </form>\n            </div>\n        </div>\n        <script
+        type=\"module\" src=\"/resources/25wg7/login/keycloak/js/passwordVisibility.js\"></script>\n\n\n\n\n\n
+        \       </div>\n      </div>\n\n    </div>\n  </div>\n</body>\n</html>\n"
+    headers:
+      Cache-Control:
+      - no-store, must-revalidate, max-age=0
+      Content-Language:
+      - en
+      Content-Security-Policy:
+      - frame-src 'self'; frame-ancestors 'self'; object-src 'none';
+      Content-Type:
+      - text/html;charset=utf-8
+      Referrer-Policy:
+      - no-referrer
+      Set-Cookie:
+      - AUTH_SESSION_ID=7f0abf13-cea9-405a-a50d-fd395b443218; Version=1; Path=/realms/test/;
+        SameSite=None; Secure; HttpOnly
+      - AUTH_SESSION_ID_LEGACY=7f0abf13-cea9-405a-a50d-fd395b443218; Version=1; Path=/realms/test/;
+        HttpOnly
+      - KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI;
+        Version=1; Path=/realms/test/; HttpOnly
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-Robots-Tag:
+      - none
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '4466'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: username=admin&password=admin&credentialId=&login=Sign+In
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '57'
+      Content-Type:
+      - application/x-www-form-urlencoded
+      Cookie:
+      - AUTH_SESSION_ID_LEGACY=7f0abf13-cea9-405a-a50d-fd395b443218; KC_RESTART=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJjaWQiOiJ0ZXN0aWQiLCJwdHkiOiJvcGVuaWQtY29ubmVjdCIsInJ1cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsImFjdCI6IkFVVEhFTlRJQ0FURSIsIm5vdGVzIjp7InNjb3BlIjoib3BlbmlkIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwicmVzcG9uc2VfdHlwZSI6ImNvZGUiLCJyZWRpcmVjdF91cmkiOiJodHRwOi8vdGVzdHNlcnZlci9vaWRjL2NhbGxiYWNrLyIsInN0YXRlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyJ9fQ.f7ZABGR0O48xm61gDKLOR_LjWH9a59wtTbGXUfm78sI
+      User-Agent:
+      - python-requests/2.32.3
+    method: POST
+    uri: http://localhost:8080/realms/test/login-actions/authenticate?session_code=caDvxOGVJp-PrUkU4rZT9OD6SIdO6Cs7J8ybFZaQ2qQ&execution=b29f5dd7-8ad1-412a-8026-f37f60fa4bc5&client_id=testid&tab_id=P27-52WztMI
+  response:
+    body:
+      string: ''
+    headers:
+      Cache-Control:
+      - no-store, must-revalidate, max-age=0
+      Content-Security-Policy:
+      - frame-src 'self'; frame-ancestors 'self'; object-src 'none';
+      Location:
+      - http://testserver/oidc/callback/?state=not-a-random-string&session_state=7f0abf13-cea9-405a-a50d-fd395b443218&iss=http%3A%2F%2Flocalhost%3A8080%2Frealms%2Ftest&code=257f97ce-9bd4-45c9-a993-cd78fb143917.7f0abf13-cea9-405a-a50d-fd395b443218.adf4ad83-4550-4619-9231-73bd8d700f45
+      Referrer-Policy:
+      - no-referrer
+      Set-Cookie:
+      - KEYCLOAK_LOCALE=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970
+        00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly
+      - KC_RESTART=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0;
+        Path=/realms/test/; HttpOnly
+      - KC_AUTH_STATE=; Version=1; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=0;
+        Path=/realms/test/
+      - KEYCLOAK_IDENTITY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjMyNTAzMjksImlhdCI6MTcyMzIxNDMyOSwianRpIjoiZjViMTQ2MTYtZjE4OC00MTZmLTk3OGEtM2U5ZGQ1N2E5YTJiIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiI3ZjBhYmYxMy1jZWE5LTQwNWEtYTUwZC1mZDM5NWI0NDMyMTgiLCJzaWQiOiI3ZjBhYmYxMy1jZWE5LTQwNWEtYTUwZC1mZDM5NWI0NDMyMTgiLCJzdGF0ZV9jaGVja2VyIjoiU2ZFcVBQcTBTQXNVM0VwT2tRaUpydmdBVHZGX0N2aVR5RFNtTW9FdnJTSSJ9.CVanGRl3av9oFTE8Pu_e3Wmm0fNUbtZA51J2nCB7MIA;
+        Version=1; Path=/realms/test/; SameSite=None; Secure; HttpOnly
+      - KEYCLOAK_IDENTITY_LEGACY=eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjMyNTAzMjksImlhdCI6MTcyMzIxNDMyOSwianRpIjoiZjViMTQ2MTYtZjE4OC00MTZmLTk3OGEtM2U5ZGQ1N2E5YTJiIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiU2VyaWFsaXplZC1JRCIsInNlc3Npb25fc3RhdGUiOiI3ZjBhYmYxMy1jZWE5LTQwNWEtYTUwZC1mZDM5NWI0NDMyMTgiLCJzaWQiOiI3ZjBhYmYxMy1jZWE5LTQwNWEtYTUwZC1mZDM5NWI0NDMyMTgiLCJzdGF0ZV9jaGVja2VyIjoiU2ZFcVBQcTBTQXNVM0VwT2tRaUpydmdBVHZGX0N2aVR5RFNtTW9FdnJTSSJ9.CVanGRl3av9oFTE8Pu_e3Wmm0fNUbtZA51J2nCB7MIA;
+        Version=1; Path=/realms/test/; HttpOnly
+      - KEYCLOAK_SESSION=test/6db2db87-de31-4e30-9f25-cefe5da8b154/7f0abf13-cea9-405a-a50d-fd395b443218;
+        Version=1; Expires=Sat, 10-Aug-2024 00:38:49 GMT; Max-Age=36000; Path=/realms/test/;
+        SameSite=None; Secure
+      - KEYCLOAK_SESSION_LEGACY=test/6db2db87-de31-4e30-9f25-cefe5da8b154/7f0abf13-cea9-405a-a50d-fd395b443218;
+        Version=1; Expires=Sat, 10-Aug-2024 00:38:49 GMT; Max-Age=36000; Path=/realms/test/
+      - KEYCLOAK_REMEMBER_ME=; Version=1; Comment=Expiring cookie; Expires=Thu, 01-Jan-1970
+        00:00:10 GMT; Max-Age=0; Path=/realms/test/; HttpOnly
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-Robots-Tag:
+      - none
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '0'
+    status:
+      code: 302
+      message: Found
+- request:
+    body: client_id=testid&client_secret=7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I&grant_type=authorization_code&code=257f97ce-9bd4-45c9-a993-cd78fb143917.7f0abf13-cea9-405a-a50d-fd395b443218.adf4ad83-4550-4619-9231-73bd8d700f45&redirect_uri=http%3A%2F%2Ftestserver%2Foidc%2Fcallback%2F
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '267'
+      Content-Type:
+      - application/x-www-form-urlencoded
+      User-Agent:
+      - python-requests/2.32.3
+    method: POST
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/token
+  response:
+    body:
+      string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjMyMTQ2MjksImlhdCI6MTcyMzIxNDMyOSwiYXV0aF90aW1lIjoxNzIzMjE0MzI5LCJqdGkiOiIzYzAyMGVkMC0yNDgyLTRmZDMtODhjYy04ZjA0OGZkYWJkYjUiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6IjdmMGFiZjEzLWNlYTktNDA1YS1hNTBkLWZkMzk1YjQ0MzIxOCIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgZ3JvdXBzIGJzbiIsInNpZCI6IjdmMGFiZjEzLWNlYTktNDA1YS1hNTBkLWZkMzk1YjQ0MzIxOCIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiUmVnaXN0cmVlcmRlcnMiLCJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSJ9.u5Zou9g6d_x33URvC3_St1Ce4ph7pXo13T7SHVmaAZWTGfE9nwBDmnO-vtdM85FBWYLeBugh0I3JaYGXSVYqNOiW8HJ18XQLQ8HV8X5pspsa6MIb4mRfMuGtnrAyjH9dFe44Al96Z7r4uqXH2n2AfgzAWQCfzirfX4lSh7mPaPkAy1y_1Zp5f8MqtF1gVdsPJ_sD6bA2VPXfUo5KsgAbFsuQUIlkBXhxkJ8SMMJfAXTP2WrF20KLcNraB8-hK1lkrG-4zRjYAEHZ6ZGkC0wWABvNh4EFqcXJtOACn0Jy7lNMjFj3_Qc4lz4o1IRBkmSUapJi_rp7LgIvK23-EOeEBw","expires_in":300,"refresh_expires_in":1800,"refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJlNzE1ZTA1MS02Y2RiLTQ4Y2MtYjRmNC1mMDcyMmM4MWY5ZDMifQ.eyJleHAiOjE3MjMyMTYxMjksImlhdCI6MTcyMzIxNDMyOSwianRpIjoiMTc4ZDMwZDItNDkxNy00YmVmLWJiNTgtMTE2ZjljMWEyNmI4IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiYXVkIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiI3ZjBhYmYxMy1jZWE5LTQwNWEtYTUwZC1mZDM5NWI0NDMyMTgiLCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIGt2ayBncm91cHMgYnNuIiwic2lkIjoiN2YwYWJmMTMtY2VhOS00MDVhLWE1MGQtZmQzOTViNDQzMjE4In0.M24aDgm8ws11Jv6kigAW56qou6WOydUEL2p4xz-Dbxw","token_type":"Bearer","id_token":"eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjMyMTQ2MjksImlhdCI6MTcyMzIxNDMyOSwiYXV0aF90aW1lIjoxNzIzMjE0MzI5LCJqdGkiOiJlMWY3Mzc5Zi00NTA2LTQ1ZTItODUwNC0wZTVlNmY3Mzg1MWMiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJ0ZXN0aWQiLCJzdWIiOiI2ZGIyZGI4Ny1kZTMxLTRlMzAtOWYyNS1jZWZlNWRhOGIxNTQiLCJ0eXAiOiJJRCIsImF6cCI6InRlc3RpZCIsIm5vbmNlIjoibm90LWEtcmFuZG9tLXN0cmluZyIsInNlc3Npb25fc3RhdGUiOiI3ZjBhYmYxMy1jZWE5LTQwNWEtYTUwZC1mZDM5NWI0NDMyMTgiLCJhdF9oYXNoIjoiNXdzOVVObWpHLTBuWjlKbXR2TWRiUSIsImFjciI6IjEiLCJzaWQiOiI3ZjBhYmYxMy1jZWE5LTQwNWEtYTUwZC1mZDM5NWI0NDMyMTgiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiZ3JvdXBzIjpbIlJlZ2lzdHJlZXJkZXJzIiwiZGVmYXVsdC1yb2xlcy10ZXN0Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20ifQ.UatjXK5ScjxNkKHrsciSmhQ3lIjPnV_QsNoulwiHXr079v48HkNhZ6Lv8y9Op8LmOLPbxxFLvK1ssikDBAVwD4k2ifPlpEdpp7NH2hkFAVsyNNUelyn2PFbdwxs84qp6TWBaY8hxO1uvsInYtDzMBLdZk2UbUESRftV_dw-F08QumXqN5OMekqGqhgAVv0m9JkImAdjns0g3D_Pg0ZQu30EAbsgNsMF00-VwJNUebCBAqLmAkfXrKHRCgQiQvKfGTMCMX71X23qOp4mzl2AEFOi4sKXV9qjwM1JbhQlM3mF164AsG7tfibhFU96B0nLg2k_0vga1E18kJjNJfSdCuA","not-before-policy":0,"session_state":"7f0abf13-cea9-405a-a50d-fd395b443218","scope":"openid
+        email profile kvk groups bsn"}'
+    headers:
+      Cache-Control:
+      - no-store
+      Content-Type:
+      - application/json
+      Pragma:
+      - no-cache
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '3698'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/certs
+  response:
+    body:
+      string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}'
+    headers:
+      Cache-Control:
+      - no-cache
+      Content-Type:
+      - application/json;charset=UTF-8
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '2909'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Authorization:
+      - Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJleHAiOjE3MjMyMTQ2MjksImlhdCI6MTcyMzIxNDMyOSwiYXV0aF90aW1lIjoxNzIzMjE0MzI5LCJqdGkiOiIzYzAyMGVkMC0yNDgyLTRmZDMtODhjYy04ZjA0OGZkYWJkYjUiLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvcmVhbG1zL3Rlc3QiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNmRiMmRiODctZGUzMS00ZTMwLTlmMjUtY2VmZTVkYThiMTU0IiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGVzdGlkIiwibm9uY2UiOiJub3QtYS1yYW5kb20tc3RyaW5nIiwic2Vzc2lvbl9zdGF0ZSI6IjdmMGFiZjEzLWNlYTktNDA1YS1hNTBkLWZkMzk1YjQ0MzIxOCIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiaHR0cDovLzEyNy4wLjAuMTo4MDAwIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3VudCIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSBrdmsgZ3JvdXBzIGJzbiIsInNpZCI6IjdmMGFiZjEzLWNlYTktNDA1YS1hNTBkLWZkMzk1YjQ0MzIxOCIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJncm91cHMiOlsiUmVnaXN0cmVlcmRlcnMiLCJkZWZhdWx0LXJvbGVzLXRlc3QiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl0sInByZWZlcnJlZF91c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSJ9.u5Zou9g6d_x33URvC3_St1Ce4ph7pXo13T7SHVmaAZWTGfE9nwBDmnO-vtdM85FBWYLeBugh0I3JaYGXSVYqNOiW8HJ18XQLQ8HV8X5pspsa6MIb4mRfMuGtnrAyjH9dFe44Al96Z7r4uqXH2n2AfgzAWQCfzirfX4lSh7mPaPkAy1y_1Zp5f8MqtF1gVdsPJ_sD6bA2VPXfUo5KsgAbFsuQUIlkBXhxkJ8SMMJfAXTP2WrF20KLcNraB8-hK1lkrG-4zRjYAEHZ6ZGkC0wWABvNh4EFqcXJtOACn0Jy7lNMjFj3_Qc4lz4o1IRBkmSUapJi_rp7LgIvK23-EOeEBw
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/userinfo
+  response:
+    body:
+      string: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0VU5RQWN2VWN2LURGVU94XzRPMWd0MTNPZEpTb3RxRUtQWnVyczJ2UVc4In0.eyJzdWIiOiI2ZGIyZGI4Ny1kZTMxLTRlMzAtOWYyNS1jZWZlNWRhOGIxNTQiLCJhdWQiOiJ0ZXN0aWQiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy90ZXN0IiwiZ3JvdXBzIjpbIlJlZ2lzdHJlZXJkZXJzIiwiZGVmYXVsdC1yb2xlcy10ZXN0Iiwib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AZXhhbXBsZS5jb20ifQ.vx4dCJ-Y-PEzjy8p7CNPB3yy0TyV_QugOHRbiV6UY3qHtZUnZqSsJD991QUostcYECuyTHefqfRtdCbvSJcPWI4ucosY65vshUMBtQeahsFOgNwWp2BvCkALJmEya4H_gh63vVlVZ2ZOSpWpah6eV2PNhiiYWD-Y9qEuLMzwngNvp5hna30BiRKAEsStB7izjE5pGECqkQm7pxCeZWHU81Lbh5fSo_2XvcGZ1Z-tf6DN95Oz4ers9YrG6dKSuh-HciY1zhv7mcee_tlJaeKjITue6r06163oKdjsYKRpiR4bLQ9256KafoxmU6O0IIlpkQhmtXrmaFSg0XyBYU8qcQ
+    headers:
+      Cache-Control:
+      - no-cache
+      Content-Type:
+      - application/jwt
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '813'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.32.3
+    method: GET
+    uri: http://localhost:8080/realms/test/protocol/openid-connect/certs
+  response:
+    body:
+      string: '{"keys":[{"kid":"4UNQAcvUcv-DFUOx_4O1gt13OdJSotqEKPZurs2vQW8","kty":"RSA","alg":"RS256","use":"sig","n":"2DOZ0qHie73SuFVR7civrl6r82YUiAghfzaMowjCg0o06AF--2lIS7vNV_PbsVVznPAAMqVrNG-8CcevEzvVZMQD9nH4DI7xlOxK0lrYu8rmMeSfOvXVbBVsWBZe0jnGNukZqjwmRE5__ttJdxPfIBT5-2L6mguQbDfhSUEEdIW7y7UfOXvqLqEcBtoIEB-ORKDTUIQwGZM5mSCy-cY3cHvvZfZVgaUUy5NvujPRXTMje4n_hG0KfEV-40G9qC2_Xvx4EooJzBZ6FSThiWhCpwhIvzcQqB6M9lHW7nU6wADhYPNCa2OKWvphwZ_zbrF4B9dmS6Zli5rBvbox9Hh45w","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMLTANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANgzmdKh4nu90rhVUe3Ir65eq/NmFIgIIX82jKMIwoNKNOgBfvtpSEu7zVfz27FVc5zwADKlazRvvAnHrxM71WTEA/Zx+AyO8ZTsStJa2LvK5jHknzr11WwVbFgWXtI5xjbpGao8JkROf/7bSXcT3yAU+fti+poLkGw34UlBBHSFu8u1Hzl76i6hHAbaCBAfjkSg01CEMBmTOZkgsvnGN3B772X2VYGlFMuTb7oz0V0zI3uJ/4RtCnxFfuNBvagtv178eBKKCcwWehUk4YloQqcISL83EKgejPZR1u51OsAA4WDzQmtjilr6YcGf826xeAfXZkumZYuawb26MfR4eOcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAsnQG/Yi2g1XTCJn74hWv9MjxVAaZb4gBAc2AWm5VgAjhFEM9h6x6m1mQkq7JM4rIdAj8jw55Ok9CBVBIqq4G4cME3eUvVytkj2lC9zcRoAivjjZF2HPg7zNPa2TTR50asmHPRokppV6gewO/C+o5as+4P2zqDXBh61aRd/9kdQfkg14LBbH5/dYccAuvUqlTYC4IEPCvVmBNC1xsMjf0vohvoSjm9vL2bfqG/RJH0ScdCjOd5d2zju4/e2oVdluWm+vzKBQplc7tVMuKpn6LcLmVHiGNAl+EBIZH+WVLlTx0D1+kbHZsfLYG53lQg2LsvurRbWyF/a5fVM/oLTn5ag=="],"x5t":"H5xfs1pRtvX0HyVTskx7eTXx88U","x5t#S256":"XurVtKAIEyc4w9HCGOhnjoRHnYu4d9HCn_5YHmkScJg"},{"kid":"TV3Tl5jIY1nrJLSb53UKEubLR5gYiq9slq1SsDDg1HU","kty":"RSA","alg":"RSA-OAEP","use":"enc","n":"pNvU3ecpVHbJT4bCOEpw6cnV1yi65tB3I0bRF2ilLVOY944QRAGnjBBECPIzNbgqavghYp1j75F2nq6_ny1CYfoaxTV2iDpRUw8_f7sliYbl8FrLLat0S25ItlZrg5TEJHObvOqlG2_nXoeH36MRWwNhms2uCqfhn5VgtenIzpQIBolnM7zzGp21NvdJ1C_ZAUzkXC-l3oQ-BXTtpEVM4h2KpYh4gfZJWCbYij5d1e1YApKD6V61_Cs3Oa2OY7CAUyq5kgAWJZFDB6CpzIr226u3bV7F9RbrQu3Ybc_Lv33EwykscLznKWZY2Mbs3Iz_rFNv3sVX_vHpH4DHWlKu7Q","e":"AQAB","x5c":["MIIClzCCAX8CBgGNeYaMlzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDAR0ZXN0MB4XDTI0MDIwNTEzNDYxN1oXDTM0MDIwNTEzNDc1N1owDzENMAsGA1UEAwwEdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKTb1N3nKVR2yU+GwjhKcOnJ1dcouubQdyNG0RdopS1TmPeOEEQBp4wQRAjyMzW4Kmr4IWKdY++Rdp6uv58tQmH6GsU1dog6UVMPP3+7JYmG5fBayy2rdEtuSLZWa4OUxCRzm7zqpRtv516Hh9+jEVsDYZrNrgqn4Z+VYLXpyM6UCAaJZzO88xqdtTb3SdQv2QFM5Fwvpd6EPgV07aRFTOIdiqWIeIH2SVgm2Io+XdXtWAKSg+letfwrNzmtjmOwgFMquZIAFiWRQwegqcyK9turt21exfUW60Lt2G3Py799xMMpLHC85ylmWNjG7NyM/6xTb97FV/7x6R+Ax1pSru0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAQGJHeTYSMvp0yndbIn7DLohO9lom5nRrx/bLyb7TiRfogyJEF6rQZ66CAkQFk5eMF878fsHTuMVjtmXVBnhojhVmK91HwjsNQu/8xR6QMXNKJQMvHR245vwUGxlWRw/36ObM1D7QjCd/q+FonpBEY4m5Y6Uz1U0HR2Cbh0E2afVlPLeV+F0LKrlyVMdIaWBGWftCGIKDAHaG/PD66zbAKtxerv2fBIDq100WHPhd57BZxX+2aGJp1IaRDgkxV0E/CjEy3+Knd8xbAgUSW0Tl6OTC75exIvlbzeluEBe0wlapAb7WvBKYsipSW8G8Ey7tjoolDT4AU82EaKUPstiMnA=="],"x5t":"AlfHDI0FOPQpt3RBAILt0dtW1yw","x5t#S256":"a7bhm8-JsnfY7bL_m8Yl72hgmp5516VZlFcVloKzk08"}]}'
+    headers:
+      Cache-Control:
+      - no-cache
+      Content-Type:
+      - application/json;charset=UTF-8
+      Referrer-Policy:
+      - no-referrer
+      Strict-Transport-Security:
+      - max-age=31536000; includeSubDomains
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - SAMEORIGIN
+      X-XSS-Protection:
+      - 1; mode=block
+      content-length:
+      - '2909'
+    status:
+      code: 200
+      message: OK
+version: 1
diff --git a/src/objects/accounts/tests/test_oidc.py b/src/objects/accounts/tests/test_oidc.py
index b677f192..9eaa0732 100644
--- a/src/objects/accounts/tests/test_oidc.py
+++ b/src/objects/accounts/tests/test_oidc.py
@@ -1,9 +1,30 @@
+from functools import partial
+from pathlib import Path
+
 from django.urls import reverse
 from django.utils.translation import gettext as _
 
+import vcr
 from django_webtest import WebTest
 from mozilla_django_oidc_db.models import OpenIDConnectConfig
 
+from objects.utils.tests.keycloak import keycloak_login, mock_oidc_db_config
+
+from ..models import User
+from .factories import StaffUserFactory
+
+TEST_FILES = (Path(__file__).parent / "keycloak_cassets").resolve()
+
+
+mock_admin_oidc_config = partial(
+    mock_oidc_db_config,
+    app_label="mozilla_django_oidc_db",
+    model="OpenIDConnectConfig",
+    id=1,  # required for the group queries because we're using in-memory objects
+    make_users_staff=True,
+    username_claim=["preferred_username"],
+)
+
 
 class OIDCLoginButtonTestCase(WebTest):
     def test_oidc_button_disabled(self):
@@ -40,3 +61,86 @@ def test_oidc_button_enabled(self):
         self.assertEqual(
             oidc_login_link.attrs["href"], reverse("oidc_authentication_init")
         )
+
+
+class OIDCFLowTests(WebTest):
+    @vcr.use_cassette(str(TEST_FILES / "duplicate_email.yaml"))
+    @mock_admin_oidc_config()
+    def test_duplicate_email_unique_constraint_violated(self):
+        # this user collides on the email address
+        staff_user = StaffUserFactory.create(
+            username="no-match", email="admin@example.com"
+        )
+        login_page = self.app.get(reverse("admin:login"))
+        start_response = login_page.click(
+            description=_("Login with organization account")
+        )
+        assert start_response.status_code == 302
+        redirect_uri = keycloak_login(
+            start_response["Location"], username="admin", password="admin"
+        )
+
+        error_page = self.app.get(redirect_uri, auto_follow=True)
+
+        with self.subTest("error page"):
+            self.assertEqual(error_page.status_code, 200)
+            self.assertEqual(error_page.request.path, reverse("admin-oidc-error"))
+            self.assertEqual(
+                error_page.context["oidc_error"],
+                'duplicate key value violates unique constraint "filled_email_unique"\n'
+                "DETAIL:  Key (email)=(admin@example.com) already exists.\n",
+            )
+            self.assertContains(
+                error_page, "duplicate key value violates unique constraint"
+            )
+
+        with self.subTest("user state unmodified"):
+            self.assertEqual(User.objects.count(), 1)
+            staff_user.refresh_from_db()
+            self.assertEqual(staff_user.username, "no-match")
+            self.assertEqual(staff_user.email, "admin@example.com")
+            self.assertTrue(staff_user.is_staff)
+
+    @vcr.use_cassette(str(TEST_FILES / "happy_flow.yaml"))
+    @mock_admin_oidc_config()
+    def test_happy_flow(self):
+        login_page = self.app.get(reverse("admin:login"))
+        start_response = login_page.click(
+            description=_("Login with organization account")
+        )
+        assert start_response.status_code == 302
+        redirect_uri = keycloak_login(
+            start_response["Location"], username="admin", password="admin"
+        )
+
+        admin_index = self.app.get(redirect_uri, auto_follow=True)
+
+        self.assertEqual(admin_index.status_code, 200)
+        self.assertEqual(admin_index.request.path, reverse("admin:index"))
+
+        self.assertEqual(User.objects.count(), 1)
+        user = User.objects.get()
+        self.assertEqual(user.username, "admin")
+
+    @vcr.use_cassette(str(TEST_FILES / "happy_flow_existing_user.yaml"))
+    @mock_admin_oidc_config(make_users_staff=False)
+    def test_happy_flow_existing_user(self):
+        staff_user = StaffUserFactory.create(username="admin", email="update-me")
+        login_page = self.app.get(reverse("admin:login"))
+        start_response = login_page.click(
+            description=_("Login with organization account")
+        )
+        assert start_response.status_code == 302
+        redirect_uri = keycloak_login(
+            start_response["Location"], username="admin", password="admin"
+        )
+
+        admin_index = self.app.get(redirect_uri, auto_follow=True)
+
+        self.assertEqual(admin_index.status_code, 200)
+        self.assertEqual(admin_index.request.path, reverse("admin:index"))
+
+        self.assertEqual(User.objects.count(), 1)
+        staff_user.refresh_from_db()
+        self.assertEqual(staff_user.username, "admin")
+        self.assertEqual(staff_user.email, "admin@example.com")
diff --git a/src/objects/api/kanalen.py b/src/objects/api/kanalen.py
index d2b29bb1..71d27719 100644
--- a/src/objects/api/kanalen.py
+++ b/src/objects/api/kanalen.py
@@ -23,9 +23,11 @@ def __init__(
     def get_kenmerken(self, obj: models.Model, data: dict = None) -> dict:
         data = data or {}
         return {
-            kenmerk: data.get("type") or obj.object.object_type.url
-            if kenmerk == "object_type"
-            else data.get(kenmerk, getattr(obj, kenmerk))
+            kenmerk: (
+                data.get("type") or obj.object.object_type.url
+                if kenmerk == "object_type"
+                else data.get(kenmerk, getattr(obj, kenmerk))
+            )
             for kenmerk in self.kenmerken
         }
 
diff --git a/src/objects/api/v1/views.py b/src/objects/api/v1/views.py
index cbc994b4..85a0f265 100644
--- a/src/objects/api/v1/views.py
+++ b/src/objects/api/v1/views.py
@@ -147,13 +147,13 @@ def finalize_response(self, request, response, *args, **kwargs):
 
         if serializer and response.status_code == 200:
             if self.action == "retrieve" and serializer.not_allowed:
-                self.headers[
-                    settings.UNAUTHORIZED_FIELDS_HEADER
-                ] = serializer.not_allowed.pretty()
+                self.headers[settings.UNAUTHORIZED_FIELDS_HEADER] = (
+                    serializer.not_allowed.pretty()
+                )
 
             elif self.action in ("list", "search") and serializer.child.not_allowed:
-                self.headers[
-                    settings.UNAUTHORIZED_FIELDS_HEADER
-                ] = serializer.child.not_allowed.pretty()
+                self.headers[settings.UNAUTHORIZED_FIELDS_HEADER] = (
+                    serializer.child.not_allowed.pretty()
+                )
 
         return super().finalize_response(request, response, *args, **kwargs)
diff --git a/src/objects/api/v2/openapi.yaml b/src/objects/api/v2/openapi.yaml
index 915ad60b..a2d5409b 100644
--- a/src/objects/api/v2/openapi.yaml
+++ b/src/objects/api/v2/openapi.yaml
@@ -934,6 +934,9 @@ components:
           $ref: '#/components/schemas/GeoWithin'
     PaginatedHistoryRecordList:
       type: object
+      required:
+      - count
+      - results
       properties:
         count:
           type: integer
@@ -954,6 +957,9 @@ components:
             $ref: '#/components/schemas/HistoryRecord'
     PaginatedObjectList:
       type: object
+      required:
+      - count
+      - results
       properties:
         count:
           type: integer
@@ -974,6 +980,9 @@ components:
             $ref: '#/components/schemas/Object'
     PaginatedPermissionList:
       type: object
+      required:
+      - count
+      - results
       properties:
         count:
           type: integer
diff --git a/src/objects/api/v2/views.py b/src/objects/api/v2/views.py
index 1cca735f..4c7aae33 100644
--- a/src/objects/api/v2/views.py
+++ b/src/objects/api/v2/views.py
@@ -157,14 +157,14 @@ def finalize_response(self, request, response, *args, **kwargs):
                 response.data.get("results"), "serializer", None
             )
             if self.action == "retrieve" and serializer.not_allowed:
-                self.headers[
-                    settings.UNAUTHORIZED_FIELDS_HEADER
-                ] = serializer.not_allowed.pretty()
+                self.headers[settings.UNAUTHORIZED_FIELDS_HEADER] = (
+                    serializer.not_allowed.pretty()
+                )
 
             elif self.action in ("list", "search") and serializer.child.not_allowed:
-                self.headers[
-                    settings.UNAUTHORIZED_FIELDS_HEADER
-                ] = serializer.child.not_allowed.pretty()
+                self.headers[settings.UNAUTHORIZED_FIELDS_HEADER] = (
+                    serializer.child.not_allowed.pretty()
+                )
 
         return super().finalize_response(request, response, *args, **kwargs)
 
diff --git a/src/objects/conf/base.py b/src/objects/conf/base.py
index 686459cc..8ab45a50 100644
--- a/src/objects/conf/base.py
+++ b/src/objects/conf/base.py
@@ -66,6 +66,16 @@
     "objects.utils.admin_index.should_display_dropdown_menu"
 )
 
+#
+# MAYKIN-2FA
+#
+# It uses django-two-factor-auth under the hood so you can configure
+# those settings too.
+#
+# we run the admin site monkeypatch instead.
+# Relying Party name for WebAuthn (hardware tokens)
+TWO_FACTOR_WEBAUTHN_RP_NAME = "objects api"
+
 
 # VNG API Common
 CUSTOM_CLIENT_FETCHER = "objects.utils.client.get_client"
diff --git a/src/objects/conf/ci.py b/src/objects/conf/ci.py
index def866cd..019c705b 100644
--- a/src/objects/conf/ci.py
+++ b/src/objects/conf/ci.py
@@ -1,6 +1,7 @@
 """
 Continuous integration settings module.
 """
+
 import logging
 import os
 
diff --git a/src/objects/conf/staging.py b/src/objects/conf/staging.py
index 23de7696..f2058007 100644
--- a/src/objects/conf/staging.py
+++ b/src/objects/conf/staging.py
@@ -2,6 +2,7 @@
 Staging environment settings module.
 This *should* be nearly identical to production.
 """
+
 import os
 
 os.environ.setdefault("ENVIRONMENT", "staging")
diff --git a/src/objects/setup.py b/src/objects/setup.py
index 36a1751c..5e410b90 100644
--- a/src/objects/setup.py
+++ b/src/objects/setup.py
@@ -9,6 +9,7 @@
     do NOT import anything Django related here, as this file needs to be loaded
     before Django is initialized.
 """
+
 import os
 
 from dotenv import load_dotenv
diff --git a/src/objects/tests/commands/test_setup_configuration.py b/src/objects/tests/commands/test_setup_configuration.py
index 5a0d06e6..5ba3add9 100644
--- a/src/objects/tests/commands/test_setup_configuration.py
+++ b/src/objects/tests/commands/test_setup_configuration.py
@@ -57,7 +57,7 @@ def test_setup_configuration(self, m):
                 f"{ObjecttypesStep()} is successfully configured",
                 f"Configuring {DemoUserStep()}...",
                 f"{DemoUserStep()} is successfully configured",
-                "Instance configuration completed.",
+                f"Instance configuration completed.",
             ]
 
             self.assertEqual(command_output, expected_output)
diff --git a/src/objects/tests/v1/test_stuf.py b/src/objects/tests/v1/test_stuf.py
index 33da0bd5..f601f4fe 100644
--- a/src/objects/tests/v1/test_stuf.py
+++ b/src/objects/tests/v1/test_stuf.py
@@ -3,6 +3,7 @@
 material and formal history defined in the StUF 03.01 (Standaard Uitwisseling Formaat)
 https://www.gemmaonline.nl/images/gemmaonline/f/fa/Stuf0301.pdf
 """
+
 from datetime import date
 
 from rest_framework import status
diff --git a/src/objects/tests/v2/test_stuf.py b/src/objects/tests/v2/test_stuf.py
index 33da0bd5..f601f4fe 100644
--- a/src/objects/tests/v2/test_stuf.py
+++ b/src/objects/tests/v2/test_stuf.py
@@ -3,6 +3,7 @@
 material and formal history defined in the StUF 03.01 (Standaard Uitwisseling Formaat)
 https://www.gemmaonline.nl/images/gemmaonline/f/fa/Stuf0301.pdf
 """
+
 from datetime import date
 
 from rest_framework import status
diff --git a/src/objects/urls.py b/src/objects/urls.py
index e54bba45..74647f37 100644
--- a/src/objects/urls.py
+++ b/src/objects/urls.py
@@ -9,6 +9,7 @@
 
 from maykin_2fa import monkeypatch_admin
 from maykin_2fa.urls import urlpatterns as maykin_2fa_urlpatterns, webauthn_urlpatterns
+from mozilla_django_oidc_db.views import AdminLoginFailure
 from rest_framework.settings import api_settings
 
 handler500 = "objects.utils.views.server_error"
@@ -29,6 +30,7 @@
         auth_views.PasswordResetDoneView.as_view(),
         name="password_reset_done",
     ),
+    path("admin/login/failure/", AdminLoginFailure.as_view(), name="admin-oidc-error"),
     path("admin/", include((maykin_2fa_urlpatterns, "maykin_2fa"))),
     path("admin/", include((webauthn_urlpatterns, "two_factor"))),
     path("admin/", admin.site.urls),
diff --git a/src/objects/utils/tests/__init__.py b/src/objects/utils/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/objects/utils/tests/keycloak.py b/src/objects/utils/tests/keycloak.py
new file mode 100644
index 00000000..73633ed6
--- /dev/null
+++ b/src/objects/utils/tests/keycloak.py
@@ -0,0 +1,89 @@
+from contextlib import contextmanager, nullcontext
+from unittest.mock import patch
+
+from django.apps import apps
+
+from pyquery import PyQuery as pq
+from requests import Session
+
+KEYCLOAK_BASE_URL = "http://localhost:8080/realms/test/protocol/openid-connect"
+
+
+def keycloak_login(
+    login_url: str,
+    username: str = "testuser",
+    password: str = "testuser",
+    host: str = "http://testserver/",
+    session: Session | None = None,
+) -> str:
+    """
+    Test helper to perform a keycloak login.
+
+    :param login_url: A login URL for keycloak with all query string parameters. E.g.
+        `client.get(reverse("login"))["Location"]`.
+    :returns: The redirect URI to consume in the django application, with the ``code``
+        ``state`` query parameters. Consume this with ``response = client.get(url)``.
+    """
+    cm = Session() if session is None else nullcontext(session)
+    with cm as session:
+        login_page = session.get(login_url)
+        assert login_page.status_code == 200
+
+        # process keycloak's login form and submit the username + password to
+        # authenticate
+        document = pq(login_page.text)
+        login_form = document("form#kc-form-login")
+        submit_url = login_form.attr("action")
+        assert isinstance(submit_url, str)
+        login_response = session.post(
+            submit_url,
+            data={
+                "username": username,
+                "password": password,
+                "credentialId": "",
+                "login": "Sign In",
+            },
+            allow_redirects=False,
+        )
+
+        assert login_response.status_code == 302
+        assert (redirect_uri := login_response.headers["Location"]).startswith(host)
+
+        return redirect_uri
+
+
+@contextmanager
+def mock_oidc_db_config(app_label: str, model: str, **overrides):
+    """
+    Bundle all the required mocks.
+
+    This context manager deliberately prevents the mocked things from being injected in
+    the test method signature.
+    """
+    defaults = {
+        "enabled": True,
+        "oidc_rp_client_id": "testid",
+        "oidc_rp_client_secret": "7DB3KUAAizYCcmZufpHRVOcD0TOkNO3I",
+        "oidc_rp_sign_algo": "RS256",
+        "oidc_rp_scopes_list": ["openid"],
+        "oidc_op_jwks_endpoint": f"{KEYCLOAK_BASE_URL}/certs",
+        "oidc_op_authorization_endpoint": f"{KEYCLOAK_BASE_URL}/auth",
+        "oidc_op_token_endpoint": f"{KEYCLOAK_BASE_URL}/token",
+        "oidc_op_user_endpoint": f"{KEYCLOAK_BASE_URL}/userinfo",
+    }
+    field_values = {**defaults, **overrides}
+    model_cls = apps.get_model(app_label, model)
+    with (
+        # bypass django-solo queries + cache hits
+        patch(
+            f"{model_cls.__module__}.{model}.get_solo",
+            return_value=model_cls(**field_values),
+        ),
+        # mock the state & nonce random value generation so we get predictable URLs to
+        # match with VCR
+        patch(
+            "mozilla_django_oidc.views.get_random_string",
+            return_value="not-a-random-string",
+        ),
+    ):
+        yield
diff --git a/src/objects/wsgi.py b/src/objects/wsgi.py
index 8fd6e705..6076faee 100644
--- a/src/objects/wsgi.py
+++ b/src/objects/wsgi.py
@@ -6,6 +6,7 @@
 For more information on this file, see
 https://docs.djangoproject.com/en/3.0/howto/deployment/wsgi/
 """
+
 from django.core.wsgi import get_wsgi_application
 
 from objects.setup import setup_env