diff --git a/.github/workflows/cleanup-pr.yml b/.github/workflows/cleanup-pr.yml new file mode 100644 index 00000000..5b90c0c0 --- /dev/null +++ b/.github/workflows/cleanup-pr.yml @@ -0,0 +1,26 @@ +name: Cleanup PR Deployment + +on: + pull_request: + types: + - closed + +jobs: + cleanup: + runs-on: ubuntu-latest + + steps: + - name: Set variables + run: | + BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF##*/}}" + BRANCH_SAFE=${BRANCH//\//-} + echo "NAMESPACE=tsd-$BRANCH_SAFE" >> $GITHUB_ENV + + - name: Set up Kubeconfig + run: | + echo "${{ secrets.KUBECONFIG }}" > kubeconfig + echo "KUBECONFIG=$(pwd)/kubeconfig" >> $GITHUB_ENV + + - name: Delete Namespace + run: | + kubectl --kubeconfig="${KUBECONFIG}" delete namespace ${{ env.NAMESPACE }} --ignore-not-found \ No newline at end of file diff --git a/.github/workflows/deploy-to-k8.yml b/.github/workflows/deploy-to-k8.yml deleted file mode 100644 index 366cfd79..00000000 --- a/.github/workflows/deploy-to-k8.yml +++ /dev/null @@ -1,85 +0,0 @@ -name: Deploy to Kubernetes - -on: - push: - branches: - - main - - develop - -jobs: - build-and-push: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Log in to GHCR - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Cache Docker layers - uses: actions/cache@v3 - with: - path: /tmp/.buildx-cache - key: ${{ runner.os }}-buildx-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-buildx- - - - name: Set REPO, TAG, NAMESPACE, and VALUES_FILE environment variables - run: | - echo "REPO=${GITHUB_REPOSITORY,,}" >> $GITHUB_ENV - if [[ "${GITHUB_REF##*/}" == "main" ]]; then - echo "TAG=latest" >> $GITHUB_ENV - echo "NAMESPACE=tsd-prod" >> $GITHUB_ENV - echo "VALUES_FILE=./infrastructure/whiteboard-app/production.values.yaml" >> $GITHUB_ENV - echo "ENV=production" >> $GITHUB_ENV - elif [[ "${GITHUB_REF##*/}" == "develop" ]]; then - echo "TAG=develop" >> $GITHUB_ENV - echo "NAMESPACE=tsd-staging" >> $GITHUB_ENV - echo "VALUES_FILE=./infrastructure/whiteboard-app/staging.values.yaml" >> $GITHUB_ENV - echo "ENV=staging" >> $GITHUB_ENV - fi - - - name: Client -> Build and push Docker image - uses: docker/build-push-action@v3 - with: - context: ./client - file: ./client/Dockerfile - push: true - tags: ghcr.io/${{ env.REPO }}/client:${{ env.TAG }} - build-args: ENV=${{ env.ENV }} - platforms: linux/amd64 - - - name: Server -> Build and push Docker image - uses: docker/build-push-action@v3 - with: - context: ./server - file: ./server/Dockerfile - push: true - tags: ghcr.io/${{ env.REPO }}/server:${{ env.TAG }} - build-args: ENV=${{ env.ENV }} - platforms: linux/amd64 - - - name: Set up Kubeconfig - run: | - echo "${{ secrets.KUBECONFIG }}" > kubeconfig - echo "KUBECONFIG=$(pwd)/kubeconfig" >> $GITHUB_ENV - - - name: Install Helm - uses: azure/setup-helm@v3 - - - name: Deploy App with Helm - run: | - helm upgrade whiteboard ./infrastructure/whiteboard-app/ \ - -f ${{ env.VALUES_FILE }} \ - -n ${{ env.NAMESPACE }} \ - --install \ - --atomic \ - --kubeconfig ${{ env.KUBECONFIG }} \ No newline at end of file diff --git a/.github/workflows/deploy-to-k8s.yml b/.github/workflows/deploy-to-k8s.yml new file mode 100644 index 00000000..f077ed99 --- /dev/null +++ b/.github/workflows/deploy-to-k8s.yml @@ -0,0 +1,208 @@ +name: Deploy to Kubernetes + +on: + push: + branches: + - main + - develop + pull_request: + types: [ opened, synchronize, reopened ] + branches: + - develop + +jobs: + setup: + runs-on: ubuntu-latest + if: github.event.pull_request.draft == false + outputs: + repo: ${{ steps.set-vars.outputs.repo }} + tag: ${{ steps.set-vars.outputs.tag }} + api_url: ${{ steps.set-vars.outputs.api_url }} + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set variables + id: set-vars + run: | + BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF##*/}}" + echo "repo=${GITHUB_REPOSITORY,,}" >> $GITHUB_OUTPUT + if [[ "$BRANCH" == "main" ]]; then + echo "tag=latest" >> $GITHUB_OUTPUT + echo "api_url=https://api.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_OUTPUT + elif [[ "$BRANCH" == "develop" ]]; then + echo "tag=develop" >> $GITHUB_OUTPUT + echo "api_url=https://staging.api.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_OUTPUT + else + BRANCH_SAFE=${BRANCH//\//-} + echo "tag=$BRANCH_SAFE" >> $GITHUB_OUTPUT + echo "api_url=https://$BRANCH_SAFE.api.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_OUTPUT + fi + + build-client: + needs: setup + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Log in to GHCR + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache-client + key: ${{ runner.os }}-client-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-client- + + - name: Build and push client image + uses: docker/build-push-action@v3 + with: + context: ./client + file: ./client/Dockerfile + push: true + tags: ghcr.io/${{ needs.setup.outputs.repo }}/client:${{ needs.setup.outputs.tag }} + build-args: API_URL=${{ needs.setup.outputs.api_url }} + platforms: linux/amd64 + + build-server: + needs: setup + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Log in to GHCR + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Cache Docker layers + uses: actions/cache@v3 + with: + path: /tmp/.buildx-cache-server + key: ${{ runner.os }}-server-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-server- + + - name: Build and push server image + uses: docker/build-push-action@v3 + with: + context: ./server + file: ./server/Dockerfile + push: true + tags: ghcr.io/${{ needs.setup.outputs.repo }}/server:${{ needs.setup.outputs.tag }} + build-args: API_URL=${{ needs.setup.outputs.api_url }} + platforms: linux/amd64 + + deploy: + needs: + - build-client + - build-server + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set variables + run: | + BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF##*/}}" + if [[ "$BRANCH" == "main" ]]; then + echo "NAMESPACE=tsd-prod" >> $GITHUB_ENV + echo "IMAGE_TAG=lastest" >> $GITHUB_ENV + echo "VALUES_FILE=./infrastructure/whiteboard-app/production.values.yaml" >> $GITHUB_ENV + echo "CLIENT_URL=whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_ENV + echo "SERVER_URL=api.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_ENV + echo "AUTH_URL=auth.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_ENV + elif [[ "$BRANCH" == "develop" ]]; then + echo "NAMESPACE=tsd-staging" >> $GITHUB_ENV + echo "IMAGE_TAG=develop" >> $GITHUB_ENV + echo "VALUES_FILE=./infrastructure/whiteboard-app/staging.values.yaml" >> $GITHUB_ENV + echo "CLIENT_URL=staging.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_ENV + echo "SERVER_URL=staging.api.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_ENV + echo "AUTH_URL=staging.auth.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_ENV + else + BRANCH_SAFE=${BRANCH//\//-} + echo "NAMESPACE=tsd-$BRANCH_SAFE" >> $GITHUB_ENV + echo "IMAGE_TAG=$BRANCH_SAFE" >> $GITHUB_ENV + echo "VALUES_FILE=./infrastructure/whiteboard-app/pullrequest.values.yaml" >> $GITHUB_ENV + echo "CLIENT_URL=$BRANCH_SAFE.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_ENV + echo "SERVER_URL=$BRANCH_SAFE.api.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_ENV + echo "AUTH_URL=$BRANCH_SAFE.auth.whiteboard.student.k8s.aet.cit.tum.de" >> $GITHUB_ENV + fi + + - name: Set up Kubeconfig + run: | + echo "${{ secrets.KUBECONFIG }}" > kubeconfig + echo "KUBECONFIG=$(pwd)/kubeconfig" >> $GITHUB_ENV + + - name: Install Helm + uses: azure/setup-helm@v3 + + - name: Deploy App with Helm + run: | + helm upgrade whiteboard ./infrastructure/whiteboard-app/ \ + -f ${{ env.VALUES_FILE }} \ + -n ${{ env.NAMESPACE }} \ + --create-namespace \ + --install \ + --atomic \ + --kubeconfig ${{ env.KUBECONFIG }} \ + --set namespace="${{ env.NAMESPACE }}" \ + --set server.image.tag="${{ env.IMAGE_TAG }}" \ + --set client.image.tag="${{ env.IMAGE_TAG }}" \ + --set client.url="${{ env.CLIENT_URL }}" \ + --set server.url="${{ env.SERVER_URL }}" \ + --set auth.url="${{ env.AUTH_URL }}" + + comment-pr: + needs: deploy + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + steps: + - name: Comment on Pull Request with URLs + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const prNumber = context.payload.pull_request.number; + const clientUrl = `https://${process.env.CLIENT_URL}`; + const serverUrl = `https://${process.env.SERVER_URL}`; + const authUrl = `https://${process.env.AUTH_URL}`; + + // Check existing comments to avoid duplicates + const { data: comments } = await github.rest.issues.listComments({ + ...context.repo, + issue_number: prNumber, + }); + + const commentExists = comments.some(comment => + comment.body.includes('### Deployment URL') + ); + + if (!commentExists) { + const body = ` + ### Deployment URL + - [${clientUrl}](${clientUrl}) + - [${serverUrl}](${serverUrl}) + - [${authUrl}](${authUrl}) + `; + + await github.rest.issues.createComment({ + ...context.repo, + issue_number: prNumber, + body, + }); + } \ No newline at end of file diff --git a/client/Dockerfile b/client/Dockerfile index 09df1d26..b4d9d4cf 100644 --- a/client/Dockerfile +++ b/client/Dockerfile @@ -6,12 +6,8 @@ RUN npm ci COPY . . -ARG ENV=production -RUN if [ "$ENV" = "staging" ]; then \ - cp .env.staging .env; \ - elif [ "$ENV" = "production" ]; then \ - cp .env.prod .env; \ - fi +ARG API_URL +ENV NEXT_PUBLIC_API_URL=${API_URL} RUN npm run build diff --git a/infrastructure/whiteboard-app/files/keycloak/realm-export-staging.json b/infrastructure/whiteboard-app/files/keycloak/realm-export-staging.json deleted file mode 100644 index 5956f03c..00000000 --- a/infrastructure/whiteboard-app/files/keycloak/realm-export-staging.json +++ /dev/null @@ -1,2229 +0,0 @@ -{ - "id": "b36292b9-c4ed-4b3b-84b6-e9274821b709", - "realm": "staging", - "displayName": "", - "displayNameHtml": "", - "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": true, - "registrationEmailAsUsername": false, - "rememberMe": true, - "verifyEmail": false, - "loginWithEmailAllowed": true, - "duplicateEmailsAllowed": false, - "resetPasswordAllowed": true, - "editUsernameAllowed": false, - "bruteForceProtected": false, - "permanentLockout": false, - "maxTemporaryLockouts": 0, - "maxFailureWaitSeconds": 900, - "minimumQuickLoginWaitSeconds": 60, - "waitIncrementSeconds": 60, - "quickLoginCheckMilliSeconds": 1000, - "maxDeltaTimeSeconds": 43200, - "failureFactor": 30, - "roles": { - "realm": [ - { - "id": "500d1053-80ba-47b9-8206-986de9ae2289", - "name": "default-roles-staging", - "description": "${role_default-roles}", - "composite": true, - "composites": { - "realm": [ - "offline_access", - "uma_authorization" - ], - "client": { - "account": [ - "view-profile", - "manage-account" - ] - } - }, - "clientRole": false, - "containerId": "b36292b9-c4ed-4b3b-84b6-e9274821b709", - "attributes": {} - }, - { - "id": "5fb22171-e348-4a48-b9fa-5b76bb8630fe", - "name": "offline_access", - "description": "${role_offline-access}", - "composite": false, - "clientRole": false, - "containerId": "b36292b9-c4ed-4b3b-84b6-e9274821b709", - "attributes": {} - }, - { - "id": "a26758de-1edf-42b1-b4cb-f047892df01b", - "name": "uma_authorization", - "description": "${role_uma_authorization}", - "composite": false, - "clientRole": false, - "containerId": "b36292b9-c4ed-4b3b-84b6-e9274821b709", - "attributes": {} - } - ], - "client": { - "realm-management": [ - { - "id": "2b522345-da51-466c-a806-1674e9301f56", - "name": "manage-realm", - "description": "${role_manage-realm}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "605492c9-b8bd-4e04-aecf-fbe8530cc7e0", - "name": "view-events", - "description": "${role_view-events}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "81a6a76e-a98b-4abf-b2b1-c63b08584ed0", - "name": "view-clients", - "description": "${role_view-clients}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-clients" - ] - } - }, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "7ff04bad-a542-416d-868f-dd4900157d67", - "name": "realm-admin", - "description": "${role_realm-admin}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "manage-realm", - "view-events", - "view-clients", - "view-identity-providers", - "view-users", - "create-client", - "manage-authorization", - "view-realm", - "query-users", - "manage-users", - "query-realms", - "manage-clients", - "manage-identity-providers", - "query-clients", - "impersonation", - "view-authorization", - "manage-events", - "query-groups" - ] - } - }, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "0616ad64-c775-4d12-9d41-47307cf35146", - "name": "view-identity-providers", - "description": "${role_view-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "59b677f4-4a97-4582-b329-d0912df25aa0", - "name": "view-users", - "description": "${role_view-users}", - "composite": true, - "composites": { - "client": { - "realm-management": [ - "query-users", - "query-groups" - ] - } - }, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "568b7218-5deb-4d6b-8120-41363b074a53", - "name": "create-client", - "description": "${role_create-client}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "5b08223e-7fe8-412b-ab50-146f39d1d551", - "name": "manage-authorization", - "description": "${role_manage-authorization}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "a7f8535f-4a8b-4ae1-84ea-e1d0ac3d4863", - "name": "view-realm", - "description": "${role_view-realm}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "ac41f160-f85a-4a62-948d-8320d6718d8d", - "name": "query-users", - "description": "${role_query-users}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "b20d4d27-464f-40d1-b301-891d142ed6a1", - "name": "manage-users", - "description": "${role_manage-users}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "b8410aa6-a4e4-4b47-8c0c-eae9a804bd70", - "name": "query-realms", - "description": "${role_query-realms}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "be951022-3b18-4736-ba10-5c2f811d30db", - "name": "manage-clients", - "description": "${role_manage-clients}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "5864bf1e-d0a0-4fb4-a0cc-46d4fdee532c", - "name": "manage-identity-providers", - "description": "${role_manage-identity-providers}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "41da20d4-a791-41af-835d-345836333126", - "name": "query-clients", - "description": "${role_query-clients}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "58dbca2a-df9a-482c-a1ab-38ec319886c7", - "name": "impersonation", - "description": "${role_impersonation}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "bc662f5c-df51-44bb-8c0f-d8b9ed97e06b", - "name": "view-authorization", - "description": "${role_view-authorization}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "ef24224a-d3f0-44a7-b08b-122d3985a7b6", - "name": "manage-events", - "description": "${role_manage-events}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - }, - { - "id": "62de30b4-b660-4ac3-af5b-64b791a2338f", - "name": "query-groups", - "description": "${role_query-groups}", - "composite": false, - "clientRole": true, - "containerId": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "attributes": {} - } - ], - "webclient": [], - "security-admin-console": [], - "admin-cli": [], - "account-console": [], - "broker": [ - { - "id": "458e2422-0101-4b2a-9667-dfca9e9b738a", - "name": "read-token", - "description": "${role_read-token}", - "composite": false, - "clientRole": true, - "containerId": "ac218318-0c76-4e01-93fa-4c4e1c8dc300", - "attributes": {} - } - ], - "account": [ - { - "id": "37af2be4-a416-4c22-b459-4afdb2a48060", - "name": "manage-consent", - "description": "${role_manage-consent}", - "composite": true, - "composites": { - "client": { - "account": [ - "view-consent" - ] - } - }, - "clientRole": true, - "containerId": "02c640d1-327d-4227-a6e9-0435f9b1760e", - "attributes": {} - }, - { - "id": "b8b2f48f-e41a-46f9-8307-374c65bb1df2", - "name": "manage-account-links", - "description": "${role_manage-account-links}", - "composite": false, - "clientRole": true, - "containerId": "02c640d1-327d-4227-a6e9-0435f9b1760e", - "attributes": {} - }, - { - "id": "d3ef0fb9-8e0c-4324-b487-128621b8e7ce", - "name": "view-groups", - "description": "${role_view-groups}", - "composite": false, - "clientRole": true, - "containerId": "02c640d1-327d-4227-a6e9-0435f9b1760e", - "attributes": {} - }, - { - "id": "3ba1fc71-79b7-48a5-85dc-0dea8a1f5bd0", - "name": "delete-account", - "description": "${role_delete-account}", - "composite": false, - "clientRole": true, - "containerId": "02c640d1-327d-4227-a6e9-0435f9b1760e", - "attributes": {} - }, - { - "id": "98aee1c3-6c94-498f-8477-4e89a7fc03fc", - "name": "view-profile", - "description": "${role_view-profile}", - "composite": false, - "clientRole": true, - "containerId": "02c640d1-327d-4227-a6e9-0435f9b1760e", - "attributes": {} - }, - { - "id": "e9dba9be-7fc6-4845-a93c-9acc3ea2e37b", - "name": "view-consent", - "description": "${role_view-consent}", - "composite": false, - "clientRole": true, - "containerId": "02c640d1-327d-4227-a6e9-0435f9b1760e", - "attributes": {} - }, - { - "id": "c38032c3-73de-4d37-9c4b-24480b3f98b6", - "name": "manage-account", - "description": "${role_manage-account}", - "composite": true, - "composites": { - "client": { - "account": [ - "manage-account-links" - ] - } - }, - "clientRole": true, - "containerId": "02c640d1-327d-4227-a6e9-0435f9b1760e", - "attributes": {} - }, - { - "id": "d43a2e81-cb7b-4932-b3bf-26c05f484305", - "name": "view-applications", - "description": "${role_view-applications}", - "composite": false, - "clientRole": true, - "containerId": "02c640d1-327d-4227-a6e9-0435f9b1760e", - "attributes": {} - } - ] - } - }, - "groups": [], - "defaultRole": { - "id": "500d1053-80ba-47b9-8206-986de9ae2289", - "name": "default-roles-staging", - "description": "${role_default-roles}", - "composite": true, - "clientRole": false, - "containerId": "b36292b9-c4ed-4b3b-84b6-e9274821b709" - }, - "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": [], - "scopeMappings": [ - { - "clientScope": "offline_access", - "roles": [ - "offline_access" - ] - } - ], - "clientScopeMappings": { - "account": [ - { - "client": "account-console", - "roles": [ - "manage-account", - "view-groups" - ] - } - ] - }, - "clients": [ - { - "id": "02c640d1-327d-4227-a6e9-0435f9b1760e", - "clientId": "account", - "name": "${client_account}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/staging/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "/realms/staging/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": "7762b786-1fa6-4dea-b51c-0af0e38c8348", - "clientId": "account-console", - "name": "${client_account-console}", - "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/staging/account/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "/realms/staging/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": "bba76bcf-bc89-4728-9356-41ca420a0326", - "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": "ecc207f7-abfc-49a6-8fa6-e1c6e89d84c6", - "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": "ac218318-0c76-4e01-93fa-4c4e1c8dc300", - "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": "eddc021b-a650-4cdc-ba12-37691a81fbbb", - "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": "d55ad226-81d8-49c4-b8be-2c62ece0fe2d", - "clientId": "security-admin-console", - "name": "${client_security-admin-console}", - "rootUrl": "${authAdminUrl}", - "baseUrl": "/admin/staging/console/", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": false, - "clientAuthenticatorType": "client-secret", - "redirectUris": [ - "/admin/staging/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": "70c74099-3ccd-4b9d-ad29-2dbe9bf5a0f8", - "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": "8036d461-3b22-4e7a-b2f3-a80ab6ffccea", - "clientId": "webclient", - "name": "Web Client", - "description": "", - "rootUrl": "", - "adminUrl": "", - "baseUrl": "", - "surrogateAuthRequired": false, - "enabled": true, - "alwaysDisplayInConsole": true, - "clientAuthenticatorType": "client-secret", - "secret": "SXiMvr1GG10bk2J63ODZC9SOaoAZ4dbe", - "redirectUris": [ - "https://staging.whiteboard.student.k8s.aet.cit.tum.de/api/auth/callback/keycloak", - "https://staging.api.whiteboard.student.k8s.aet.cit.tum.de/*" - ], - "webOrigins": [ - "https://staging.api.whiteboard.student.k8s.aet.cit.tum.de", - "https://staging.whiteboard.student.k8s.aet.cit.tum.de" - ], - "notBefore": 0, - "bearerOnly": false, - "consentRequired": false, - "standardFlowEnabled": true, - "implicitFlowEnabled": true, - "directAccessGrantsEnabled": true, - "serviceAccountsEnabled": false, - "publicClient": false, - "frontchannelLogout": true, - "protocol": "openid-connect", - "attributes": { - "oidc.ciba.grant.enabled": "false", - "client.secret.creation.time": "1708880081", - "backchannel.logout.session.required": "true", - "post.logout.redirect.uris": "https://staging.whiteboard.student.k8s.aet.cit.tum.de##https://staging.api.whiteboard.student.k8s.aet.cit.tum.de", - "display.on.consent.screen": "false", - "oauth2.device.authorization.grant.enabled": "true", - "backchannel.logout.revoke.offline.tokens": "false" - }, - "authenticationFlowBindingOverrides": {}, - "fullScopeAllowed": true, - "nodeReRegistrationTimeout": -1, - "defaultClientScopes": [ - "web-origins", - "acr", - "roles", - "profile", - "email" - ], - "optionalClientScopes": [ - "address", - "phone", - "offline_access", - "microprofile-jwt" - ] - } - ], - "clientScopes": [ - { - "id": "5247110f-f0e2-4a01-a64e-22aa4e1f0551", - "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": "261edfee-8d55-4616-8c7a-17ca0509989e", - "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": "eb01d2e6-e1c6-40ca-9da4-f3f1e42dca49", - "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": "e1bae987-e8de-4096-a2bb-dfff8f069022", - "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": "aacb899e-0fbd-406f-b537-8bd1cf4e6715", - "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": "beb25224-a81a-40c6-9862-ea01d19ddad7", - "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": "ab24de96-09e8-4d92-b61c-917ff2ef6763", - "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": "1a6f0ed1-6ecb-40d9-af82-3906ddffa7e5", - "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": "4ac49eaf-d476-4dc5-a226-77324e5e56b4", - "name": "audience resolve", - "protocol": "openid-connect", - "protocolMapper": "oidc-audience-resolve-mapper", - "consentRequired": false, - "config": { - "access.token.claim": "true", - "introspection.token.claim": "true" - } - } - ] - }, - { - "id": "c490baca-b14a-4832-916c-ace1df532810", - "name": "offline_access", - "description": "OpenID Connect built-in scope: offline_access", - "protocol": "openid-connect", - "attributes": { - "consent.screen.text": "${offlineAccessScopeConsentText}", - "display.on.consent.screen": "true" - } - }, - { - "id": "0961b697-1074-4924-8082-b83c541258fe", - "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": "6edd981a-d225-47c7-8fc5-2f713b971242", - "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": "7fc0fc5c-d450-48e3-b285-ed4bb3a29a72", - "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": "3486255b-1770-4a9f-bd24-4e2dd80f28e6", - "name": "role_list", - "description": "SAML role list", - "protocol": "saml", - "attributes": { - "consent.screen.text": "${samlRoleListScopeConsentText}", - "display.on.consent.screen": "true" - }, - "protocolMappers": [ - { - "id": "e87d4e86-d35f-41c6-b13b-dfefd277bcde", - "name": "role list", - "protocol": "saml", - "protocolMapper": "saml-role-list-mapper", - "consentRequired": false, - "config": { - "single": "false", - "attribute.nameformat": "Basic", - "attribute.name": "Role" - } - } - ] - }, - { - "id": "7822b2f4-bb70-4108-ab13-88773ac3f397", - "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": "5c0b08fd-041d-4f21-a24d-5d20f116ede6", - "name": "acr loa level", - "protocol": "openid-connect", - "protocolMapper": "oidc-acr-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "introspection.token.claim": "true", - "userinfo.token.claim": "true" - } - } - ] - }, - { - "id": "f1640b2e-98eb-4175-8c19-7f0b642f8d62", - "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": "a60c53b6-1b6e-4465-9457-27bb099e6921", - "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": "dc526c04-1053-47e4-8f92-d45318c6f600", - "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": "4601b69d-ea83-4d66-bfb7-d6095a8b8b51", - "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": "002884fc-7bc8-4583-bffb-e5772413cf14", - "name": "allowed web origins", - "protocol": "openid-connect", - "protocolMapper": "oidc-allowed-origins-mapper", - "consentRequired": false, - "config": { - "access.token.claim": "true", - "introspection.token.claim": "true" - } - } - ] - }, - { - "id": "309d4a2c-208f-4549-a2a5-40f2f0867765", - "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": "d6153d95-a33a-4c0e-8fa3-a5ea9df103e6", - "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": "bae8e15c-3a27-4b05-8895-ab073dff8683", - "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": "913c01af-7409-4e17-b94f-60521ab49a9f", - "name": "full name", - "protocol": "openid-connect", - "protocolMapper": "oidc-full-name-mapper", - "consentRequired": false, - "config": { - "id.token.claim": "true", - "access.token.claim": "true", - "introspection.token.claim": "true", - "userinfo.token.claim": "true" - } - }, - { - "id": "6d6aa12f-1e6b-4d27-9b6d-3e8955881593", - "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": "b527e182-898a-441a-afdf-cc2319aaacc0", - "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": "c8e7eb48-7055-411c-86a2-36d116454b8b", - "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": "e014fa8b-a03e-40c4-a174-b2a7a956aa57", - "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": "64e5a635-85a9-42ad-86f2-2d43a72524b2", - "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": "824d1c93-0d1c-48bc-901a-17d00b74364b", - "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": "36876d97-38a5-4994-9f13-b92ef4cd7ea9", - "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": "d998e5f2-7c65-4b68-a8ee-34386fdf404b", - "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": "ebc5d2cd-3442-4cef-8d5b-5146cb5e2824", - "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": "e6e76b52-b790-44aa-beda-e20e2626cd45", - "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": "59d693cc-d6e9-452d-96cd-cacf4ead1dc8", - "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" - } - } - ] - } - ], - "defaultDefaultClientScopes": [ - "profile", - "role_list", - "web-origins", - "acr", - "roles", - "email" - ], - "defaultOptionalClientScopes": [ - "microprofile-jwt", - "phone", - "offline_access", - "address" - ], - "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": "3526f51d-762e-45dd-b034-7cccbfa7e6c0", - "name": "Consent Required", - "providerId": "consent-required", - "subType": "anonymous", - "subComponents": {}, - "config": {} - }, - { - "id": "52ce25a4-1a2d-463f-8f88-a46ab1e08995", - "name": "Trusted Hosts", - "providerId": "trusted-hosts", - "subType": "anonymous", - "subComponents": {}, - "config": { - "host-sending-registration-request-must-match": [ - "true" - ], - "client-uris-must-match": [ - "true" - ] - } - }, - { - "id": "78230ed7-c91d-4bf4-993c-d1463105063d", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-usermodel-attribute-mapper", - "oidc-address-mapper", - "oidc-full-name-mapper", - "oidc-usermodel-property-mapper", - "saml-user-attribute-mapper", - "saml-user-property-mapper", - "saml-role-list-mapper", - "oidc-sha256-pairwise-sub-mapper" - ] - } - }, - { - "id": "08f58cfd-4847-4246-bc79-2268dc51305d", - "name": "Max Clients Limit", - "providerId": "max-clients", - "subType": "anonymous", - "subComponents": {}, - "config": { - "max-clients": [ - "200" - ] - } - }, - { - "id": "fb5f3eb5-406f-465c-b3d1-19fd1fb1ffc1", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "authenticated", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "5ffb837f-8001-42fb-bfa6-c98ae7530b37", - "name": "Allowed Client Scopes", - "providerId": "allowed-client-templates", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allow-default-scopes": [ - "true" - ] - } - }, - { - "id": "6da6ac13-31e5-4f15-8606-e16d1e834006", - "name": "Allowed Protocol Mapper Types", - "providerId": "allowed-protocol-mappers", - "subType": "anonymous", - "subComponents": {}, - "config": { - "allowed-protocol-mapper-types": [ - "oidc-usermodel-attribute-mapper", - "saml-user-property-mapper", - "oidc-usermodel-property-mapper", - "saml-user-attribute-mapper", - "oidc-address-mapper", - "saml-role-list-mapper", - "oidc-sha256-pairwise-sub-mapper", - "oidc-full-name-mapper" - ] - } - }, - { - "id": "35358f5e-137f-4689-b87f-873f372f2396", - "name": "Full Scope Disabled", - "providerId": "scope", - "subType": "anonymous", - "subComponents": {}, - "config": {} - } - ], - "org.keycloak.userprofile.UserProfileProvider": [ - { - "id": "74e1ebbf-606a-4293-86a2-f9cc0d8e91fb", - "providerId": "declarative-user-profile", - "subComponents": {}, - "config": { - "kc.user.profile.config": [ - "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}],\"unmanagedAttributePolicy\":\"ENABLED\"}" - ] - } - } - ], - "org.keycloak.keys.KeyProvider": [ - { - "id": "86b3f7c5-64c9-48ad-9355-fe913ac203c1", - "name": "aes-generated", - "providerId": "aes-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "1d6fd7c8-76d1-4a9d-9877-60eca8a30336", - "name": "rsa-generated", - "providerId": "rsa-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "1c57ab36-e4f7-4118-b225-6fdabc10321e", - "name": "rsa-enc-generated", - "providerId": "rsa-enc-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "RSA-OAEP" - ] - } - }, - { - "id": "59724de6-ec76-43de-b8f8-6218085971c9", - "name": "hmac-generated", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS256" - ] - } - }, - { - "id": "08057a00-49e2-47b3-89c1-ec25f5fdcc2f", - "name": "hmac-generated-hs512", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS512" - ] - } - } - ] - }, - "internationalizationEnabled": false, - "supportedLocales": [], - "authenticationFlows": [ - { - "id": "b3499093-847b-494f-b0eb-2dcd82c5d9cb", - "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": "dffa8a81-4fde-4b55-ae4f-e002525a2185", - "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": "dd9679f7-401d-4468-9098-d649fb3f1464", - "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": "112394b4-c201-4faa-8538-c80eeb94746a", - "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": "bc5bbc57-1be2-4c9f-9a68-3fe0afda1070", - "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": "682f2aac-0139-4ca0-8d2d-004d658ef2b2", - "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": "c9b04df1-d208-4a80-8363-cd6023154468", - "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": "313bf938-0fa7-4f8e-a7f9-95ef5f136614", - "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": "a9f14a30-1eb2-46de-b4f0-72a378e82fc5", - "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": "b0dae209-2a32-44a1-8e44-33fa25b1d7dc", - "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": "b935570a-e80c-433c-a19f-918f9714395e", - "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": "aa6af759-eca7-435f-ba9f-b73f3f607b47", - "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": "b5572683-b1a9-4c85-935d-dccd1f8aa595", - "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": "6cc4262d-78c1-4eda-8851-e277c3ac53b4", - "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": "a7c8ab1c-8f6b-4772-b892-242e8cbbe84c", - "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": "a3a22ca3-dc16-4c4d-9bd7-725790fe874c", - "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": "0ddae3de-4d23-4325-af3e-ef6058c954e6", - "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": "d4648fe7-5538-4f23-91cf-6c76e59b641f", - "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": "e5b43b21-14cb-44d1-9752-f74729d1a3af", - "alias": "create unique user config", - "config": { - "require.password.update.after.registration": "false" - } - }, - { - "id": "f0a855aa-67e8-4e5d-a65a-d1d5e207ddaa", - "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", - "firstBrokerLoginFlow": "first broker login", - "attributes": { - "cibaBackchannelTokenDeliveryMode": "poll", - "cibaAuthRequestedUserHint": "login_hint", - "clientOfflineSessionMaxLifespan": "0", - "oauth2DevicePollingInterval": "5", - "clientSessionIdleTimeout": "0", - "clientOfflineSessionIdleTimeout": "0", - "cibaInterval": "5", - "realmReusableOtpCode": "false", - "cibaExpiresIn": "120", - "oauth2DeviceCodeLifespan": "600", - "parRequestUriLifespan": "60", - "clientSessionMaxLifespan": "0", - "frontendUrl": "", - "acr.loa.map": "{}" - }, - "keycloakVersion": "24.0.2", - "userManagedAccessAllowed": true, - "clientProfiles": { - "profiles": [] - }, - "clientPolicies": { - "policies": [] - }, - "users": [] -} \ No newline at end of file diff --git a/infrastructure/whiteboard-app/files/keycloak/realm-export-production.json b/infrastructure/whiteboard-app/files/keycloak/realm-export.json similarity index 98% rename from infrastructure/whiteboard-app/files/keycloak/realm-export-production.json rename to infrastructure/whiteboard-app/files/keycloak/realm-export.json index 9671d8a1..48c945cc 100644 --- a/infrastructure/whiteboard-app/files/keycloak/realm-export-production.json +++ b/infrastructure/whiteboard-app/files/keycloak/realm-export.json @@ -1,6 +1,6 @@ { "id": "b36292b9-c4ed-4b3b-84b6-e9274821b709", - "realm": "production", + "realm": "{{ .Values.namespace }}", "displayName": "", "displayNameHtml": "", "notBefore": 0, @@ -50,7 +50,7 @@ "realm": [ { "id": "500d1053-80ba-47b9-8206-986de9ae2289", - "name": "default-roles-production", + "name": "default-roles-{{ .Values.namespace }}", "description": "${role_default-roles}", "composite": true, "composites": { @@ -409,7 +409,7 @@ "groups": [], "defaultRole": { "id": "500d1053-80ba-47b9-8206-986de9ae2289", - "name": "default-roles-production", + "name": "default-roles-{{ .Values.namespace }}", "description": "${role_default-roles}", "composite": true, "clientRole": false, @@ -482,13 +482,13 @@ "clientId": "account", "name": "${client_account}", "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/production/account/", + "baseUrl": "/realms/{{ .Values.namespace }}/account/", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", "redirectUris": [ - "/realms/production/account/*" + "/realms/{{ .Values.namespace }}/account/*" ], "webOrigins": [], "notBefore": 0, @@ -526,13 +526,13 @@ "clientId": "account-console", "name": "${client_account-console}", "rootUrl": "${authBaseUrl}", - "baseUrl": "/realms/production/account/", + "baseUrl": "/realms/{{ .Values.namespace }}/account/", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", "redirectUris": [ - "/realms/production/account/*" + "/realms/{{ .Values.namespace }}/account/*" ], "webOrigins": [], "notBefore": 0, @@ -701,13 +701,13 @@ "clientId": "security-admin-console", "name": "${client_security-admin-console}", "rootUrl": "${authAdminUrl}", - "baseUrl": "/admin/production/console/", + "baseUrl": "/admin/{{ .Values.namespace }}/console/", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", "redirectUris": [ - "/admin/production/console/*" + "/admin/{{ .Values.namespace }}/console/*" ], "webOrigins": [ "+" @@ -775,12 +775,12 @@ "clientAuthenticatorType": "client-secret", "secret": "SXiMvr1GG10bk2J63ODZC9SOaoAZ4dbe", "redirectUris": [ - "https://whiteboard.student.k8s.aet.cit.tum.de/api/auth/callback/keycloak", - "https://api.whiteboard.student.k8s.aet.cit.tum.de/*" + "https://{{ .Values.client.url }}/api/auth/callback/keycloak", + "https://{{ .Values.server.url }}/*" ], "webOrigins": [ - "https://api.whiteboard.student.k8s.aet.cit.tum.de", - "https://whiteboard.student.k8s.aet.cit.tum.de" + "https://{{ .Values.client.url }}/*", + "https://{{ .Values.server.url }}/*" ], "notBefore": 0, "bearerOnly": false, @@ -796,7 +796,7 @@ "oidc.ciba.grant.enabled": "false", "client.secret.creation.time": "1708880081", "backchannel.logout.session.required": "true", - "post.logout.redirect.uris": "https://whiteboard.student.k8s.aet.cit.tum.de##https://api.whiteboard.student.k8s.aet.cit.tum.de", + "post.logout.redirect.uris": "https://{{ .Values.client.url }}##https://{{ .Values.server.url }}", "display.on.consent.screen": "false", "oauth2.device.authorization.grant.enabled": "true", "backchannel.logout.revoke.offline.tokens": "false" diff --git a/infrastructure/whiteboard-app/production.values.yaml b/infrastructure/whiteboard-app/production.values.yaml index 532a6ff6..1033db3d 100644 --- a/infrastructure/whiteboard-app/production.values.yaml +++ b/infrastructure/whiteboard-app/production.values.yaml @@ -1,6 +1,3 @@ -namespace: "tsd-prod" -environment: production - client: image: repository: ghcr.io/aet-devops25/team-server-down/client diff --git a/infrastructure/whiteboard-app/pullrequest.values.yaml b/infrastructure/whiteboard-app/pullrequest.values.yaml new file mode 100644 index 00000000..629fce5c --- /dev/null +++ b/infrastructure/whiteboard-app/pullrequest.values.yaml @@ -0,0 +1,138 @@ +client: + image: + repository: ghcr.io/aet-devops25/team-server-down/client + tag: "" + pullPolicy: Always + service: + type: ClusterIP + port: 3000 + targetPort: 3000 + replicaCount: 1 + env: + - name: KEYCLOAK_CLIENT_SECRET + value: SXiMvr1GG10bk2J63ODZC9SOaoAZ4dbe + - name: NEXTAUTH_URL + value: 'https://{{ .Values.client.url }}/api/auth/' + - name: NEXTAUTH_SECRET + value: feZJWB3mcQ93VBmqHKQI5er5NEIxcDPb3wtT/KaLB9s= + - name: KEYCLOAK_CLIENT_ID + value: webclient + - name: KEYCLOAK_ISSUER + value: 'https://{{ .Values.auth.url }}/realms/{{ .Values.namespace }}' + - name: KEYCLOAK_END_SESSION_ENDPOINT + value: 'https://{{ .Values.auth.url }}/realms/{{ .Values.namespace }}/protocol/openid-connect/logout' + +server: + image: + repository: ghcr.io/aet-devops25/team-server-down/server + tag: "" + pullPolicy: Always + service: + type: ClusterIP + port: 9091 + targetPort: 9091 + env: + - name: DB_HOST + value: '{{ printf "%s-postgresql" .Release.Name }}' + - name: DB_PORT + value: "5432" + - name: DB_NAME + value: main + - name: DB_USER + value: postgres + - name: DB_PASSWORD + value: password + - name: ALLOWED_ORIGIN + value: 'https://{{ .Values.client.url }}' + - name: IDP_INTERNAL_URI + value: 'https://{{ .Values.auth.url }}/realms/{{ .Values.namespace }}' + - name: IDP_EXTERNAL_URI + value: 'https://{{ .Values.auth.url }}/realms/{{ .Values.namespace }}' + replicaCount: 1 + +postgresql: + primary: + extraEnvVars: + - name: POSTGRES_USER + value: postgres + - name: POSTGRES_PASSWORD + value: password + - name: POSTGRES_MULTIPLE_DATABASES + value: "main,keycloak" + extraVolumes: + - name: db-init + configMap: + name: postgresql-configmap + extraVolumeMounts: + - name: db-init + mountPath: /docker-entrypoint-initdb.d + +keycloak: + ingress: + enabled: true + hostname: '{{ .Values.auth.url }}' + auth: + adminUser: admin + adminPassword: password + postgresql: + enabled: false + externalDatabase: + host: '{{ printf "%s-postgresql" .Release.Name }}' + user: postgres + password: password + database: keycloak + port: 5432 + extraEnvVars: + - name: KEYCLOAK_EXTRA_ARGS + value: "--import-realm" + - name: KC_PROXY + value: edge + - name: KC_PROXY_HEADERS + value: xforwarded + extraVolumes: + - name: realm-export + configMap: + name: keycloak-configmap + extraVolumeMounts: + - name: realm-export + mountPath: /opt/bitnami/keycloak/data/import + +ingress: + enabled: true + className: "nginx" + annotations: + cert-manager.io/cluster-issuer: "letsencrypt-prod" + nginx.ingress.kubernetes.io/rewrite-target: / + nginx.ingress.kubernetes.io/use-forwarded-headers: "true" + nginx.ingress.kubernetes.io/proxy-buffer-size: "8k" + tls: + hosts: + - '{{ .Values.client.url }}' + - '{{ .Values.server.url }}' + - '{{ .Values.auth.url }}' + secretName: '{{ .Values.namespace }}-whiteboard-devops25-tls' + rules: + - host: '{{ .Values.client.url }}' + paths: + - path: / + pathType: Prefix + service: + name: client-service + port: + number: 3000 + - host: '{{ .Values.server.url }}' + paths: + - path: / + pathType: Prefix + service: + name: server-service + port: + number: 9091 + - host: '{{ .Values.auth.url }}' + paths: + - path: / + pathType: Prefix + service: + name: '{{ printf "%s-keycloak" .Release.Name }}' + port: + number: 80 \ No newline at end of file diff --git a/infrastructure/whiteboard-app/staging.values.yaml b/infrastructure/whiteboard-app/staging.values.yaml index 44212b9e..1a293de7 100644 --- a/infrastructure/whiteboard-app/staging.values.yaml +++ b/infrastructure/whiteboard-app/staging.values.yaml @@ -1,6 +1,3 @@ -namespace: "tsd-staging" -environment: staging - client: image: repository: ghcr.io/aet-devops25/team-server-down/client @@ -47,9 +44,7 @@ server: value: password - name: ALLOWED_ORIGIN value: "https://staging.whiteboard.student.k8s.aet.cit.tum.de" - - name: IDP_INTERNAL_URI - value: "https://staging.auth.whiteboard.student.k8s.aet.cit.tum.de/realms/staging" - - name: IDP_EXTERNAL_URI + - name: IDP_URI value: "https://staging.auth.whiteboard.student.k8s.aet.cit.tum.de/realms/staging" replicaCount: 1 @@ -120,9 +115,9 @@ ingress: - path: / pathType: Prefix service: - name: client-service - port: - number: 3000 + name: client-service + port: + number: 3000 - host: "staging.api.whiteboard.student.k8s.aet.cit.tum.de" paths: - path: / diff --git a/infrastructure/whiteboard-app/templates/client-deployment.yaml b/infrastructure/whiteboard-app/templates/client-deployment.yaml index b3e06387..edee1fd8 100644 --- a/infrastructure/whiteboard-app/templates/client-deployment.yaml +++ b/infrastructure/whiteboard-app/templates/client-deployment.yaml @@ -2,7 +2,6 @@ apiVersion: apps/v1 kind: Deployment metadata: name: whiteboard-client - namespace: {{ .Values.namespace }} spec: replicas: {{ .Values.client.replicaCount }} selector: diff --git a/infrastructure/whiteboard-app/templates/client-service.yaml b/infrastructure/whiteboard-app/templates/client-service.yaml index 68a06882..47030ff8 100644 --- a/infrastructure/whiteboard-app/templates/client-service.yaml +++ b/infrastructure/whiteboard-app/templates/client-service.yaml @@ -2,7 +2,6 @@ apiVersion: v1 kind: Service metadata: name: client-service - namespace: {{ .Values.namespace }} spec: type: {{ .Values.client.service.type }} selector: diff --git a/infrastructure/whiteboard-app/templates/configmap.yaml b/infrastructure/whiteboard-app/templates/configmap.yaml deleted file mode 100644 index 75cddfa8..00000000 --- a/infrastructure/whiteboard-app/templates/configmap.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: app-config - namespace: {{ .Values.namespace }} -data: - api_url: "api.whiteboard.student.k8s.aet.cit.tum.de" \ No newline at end of file diff --git a/infrastructure/whiteboard-app/templates/ingress.yaml b/infrastructure/whiteboard-app/templates/ingress.yaml index 329cc26b..b722793c 100644 --- a/infrastructure/whiteboard-app/templates/ingress.yaml +++ b/infrastructure/whiteboard-app/templates/ingress.yaml @@ -3,7 +3,6 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: "whiteboard-ingress" - namespace: {{ .Values.namespace }} {{- $annotations := .Values.ingress.annotations | default dict }} {{- if $annotations }} annotations: @@ -12,17 +11,17 @@ metadata: spec: tls: - hosts: - {{- range .Values.ingress.tls.hosts }} - - {{ . }} - {{- end }} - secretName: {{ .Values.ingress.tls.secretName }} + {{- range .Values.ingress.tls.hosts }} + - {{ tpl . $ }} + {{- end }} + secretName: {{ tpl .Values.ingress.tls.secretName $ }} ingressClassName: nginx rules: {{- range .Values.ingress.rules }} - - host: {{ .host }} + - host: {{ tpl .host $ }} http: paths: - {{- range .paths }} + {{- range .paths }} - path: {{ .path }} pathType: {{ .pathType }} backend: @@ -30,6 +29,6 @@ spec: name: {{ tpl .service.name $ | quote }} port: number: {{ .service.port.number }} - {{- end}} + {{- end}} {{- end }} {{- end }} \ No newline at end of file diff --git a/infrastructure/whiteboard-app/templates/keycloak-configmap.yaml b/infrastructure/whiteboard-app/templates/keycloak-configmap.yaml index a55522b1..99f73e44 100644 --- a/infrastructure/whiteboard-app/templates/keycloak-configmap.yaml +++ b/infrastructure/whiteboard-app/templates/keycloak-configmap.yaml @@ -4,6 +4,5 @@ metadata: name: keycloak-configmap data: realm-export.json: |- -{{- $env := .Values.environment }} -{{- $filename := printf "files/keycloak/realm-export-%s.json" $env }} -{{ .Files.Get $filename | indent 4 }} \ No newline at end of file +{{- $realmJson := .Files.Get "files/keycloak/realm-export.json" }} +{{ tpl $realmJson . | indent 4 }} \ No newline at end of file diff --git a/infrastructure/whiteboard-app/templates/server-deployment.yaml b/infrastructure/whiteboard-app/templates/server-deployment.yaml index 3c4a8e30..0cc31d77 100644 --- a/infrastructure/whiteboard-app/templates/server-deployment.yaml +++ b/infrastructure/whiteboard-app/templates/server-deployment.yaml @@ -2,7 +2,6 @@ apiVersion: apps/v1 kind: Deployment metadata: name: whiteboard-server - namespace: {{ .Values.namespace }} spec: replicas: {{ .Values.server.replicaCount }} selector: diff --git a/infrastructure/whiteboard-app/templates/server-service.yaml b/infrastructure/whiteboard-app/templates/server-service.yaml index 24767991..ce6ec167 100644 --- a/infrastructure/whiteboard-app/templates/server-service.yaml +++ b/infrastructure/whiteboard-app/templates/server-service.yaml @@ -2,7 +2,6 @@ apiVersion: v1 kind: Service metadata: name: server-service - namespace: {{ .Values.namespace }} spec: selector: app: whiteboard-server-selector