The frontend is using the keycloak-js client integrated with React to operate the authentication flows.
The main page is implemented in the index.tsx and the authentication flow is implemented in the UserService.ts.
The init
method verifies authenticated users following the common implementation described in the documentation of Keycloak JS Adapter. The code also includes an update
method to refresh the token when it is expired (the Access Token Lifespan
realm property sets that duration). This method is invoke from time to time (by the setInterval()
) to update and refresh the token. However, that method is not really needed to invoke as the Keycloak JS client has the onTokenExpired
method that it is invoked when the token expired. We recommend to comment the setInterval()
method invocation and delegate the refresh procedure to the onTokenExpired
method, already implemented in the same file.
The frontend application works as expected when the user has one single tab, it means, the initialization and refresh mechanisms work successfully. We found the issue when the user has multiple tabs, where the same process are executed. At some point between the Keycloak JS client execution and React, the page is rendered again (the effect looks like a page reload, but the page is rendered again). After some debugging, and researching we found some issues in the Keycloak community about similar behaviors:
- Refresh token rotation and multi-tabs : is KeyCloak's behavior the best one (for ex compared to Auth0)?
- Refresh token rotation with multiple tabs
- Refresh token rotation used with an app opened in multiple web browser tabs causes revocation of everything
- Silent Refresh with multiple tabs
This is a known behavior (or bug
) between revoking refresh token mechanism and multiple tabs. There is no a clear workaround and an estimated time to be resolved by the Keycloak community, so we can have two approaches:
- Disabling the revoking refresh token mechanism allows the users to have multiple tabs without issues. The main implication is the longer access to resources. If a refresh token is compromised or stolen, an attacker could potentially have long-term access to the resources protected. Token storing must more critical with a securely stored on the user's device.
- Increasing the
Access Token Lifespan
to a higher value (instead of the 5 minutes by default) allows to reduce the reloading effect from time to time. The new time should be enough to allow users operate with the frontend reducing the reloading effects but no longer that the session lifespan. The users from time to time can suffer the reloading effect, but the tokens have a limited lifetime so an attacker is limited to access.
Both approaches have pros and cons and it should have a team discussion about which one gives more benefits to the overall platform and user experience.
Keycloak configurations can be complex, and security is an ongoing process. Regularly review, audit, and update your configurations to adapt to changing security threats and organizational needs. It's also a good practice to stay informed about Keycloak updates and security advisories.
However, here are some key aspects to consider when reviewing Keycloak configuration:
- Authentication Configuration:
- Password Policies: Review the password policies to enforce strong passwords. Ensure that password policies align with your organization's security requirements.
passwordPolicy
: Specifies the password policy for the realm. It can be set to "hashIterations", "regexPattern", "length", etc., depending on your requirements.
- Multi-Factor Authentication (MFA): Evaluate whether MFA is enabled for relevant clients and users, especially for
applications handling sensitive data.
otpPolicyType
: The type of one-time password (OTP) policy (e.g., "totp").otpPolicyAlgorithm
: The OTP algorithm.otpPolicyDigits
: The number of digits in OTPs.otpPolicyPeriod
: The OTP validity period in seconds.otpPolicyLookAheadWindow
: The OTP look-ahead window.
- Password Policies: Review the password policies to enforce strong passwords. Ensure that password policies align with your organization's security requirements.
- Security Defenses:
- Brute Force Detection: Enable and configure brute force detection to protect against password guessing attacks.
bruteForceProtected
: Enable brute force protection for authentication.permanentLockout
: Whether to permanently lock users out after too many failed login attempts.minimumQuickLoginWaitSeconds
: The minimum time to wait between quick logins.
- Security Headers: Ensure that Keycloak is configured to add necessary security headers to HTTP responses.
browserSecurityHeaders
: A set of security headers to be applied to HTTP responses. Includes headers like contentSecurityPolicy, xFrameOptions, xXSSProtection, etc.strictTransportSecurity
: Specifies the Strict Transport Security (HSTS) header settings.xContentTypeOptions
: Sets the X-Content-Type-Options header.xRobotsTag
: Configures the X-Robots-Tag header.contentSecurityPolicy
: Defines the Content Security Policy (CSP) header.
- Brute Force Detection: Enable and configure brute force detection to protect against password guessing attacks.
- AccessToken and RefreshToken Configuration:
accessTokenLifespan
: The lifespan of access tokens. Adjust this based on your desired token expiration policy.accessTokenLifespanForImplicitFlow
: The lifespan of access tokens for the Implicit Flow. Adjust as needed.revokeRefreshToken
: Whether to revoke refresh tokens after use. Consider your security requirements when setting this.
- Session Configuration:
ssoSessionIdleTimeout
: The maximum time a single sign-on (SSO) session can be idle before timing out.ssoSessionMaxLifespan
: The maximum lifespan of an SSO session.
Again, there are no-recommended values (only default ones). The final values will require an analysis and measure about the behavior of the platform and a review from time to time to adapt them.
This topic is described in this file.
There is a clear issue if we clone the Keycloak database to have a second instance. The Keycloak database includes a lot of custom information based on the environment (mostly urls) that they can impact into a second instance of Keycloak. The migration process from one version to another must be done on top of the current database schema used by the productive instance of Keycloak. Blue/Green deployments can be used just only for the keycloak instance, never for the database. The upgrading and migrating procedures do not include references about cloning/exporting database. So, the recommendation about upgrading to Keycloak 22 must be done on top of the current database schema and data. Upgrading the database server is a completely differently story and it must not be included in the same process.
Keycloak 22 invested a lot of time and efforts to have an implementation to upgrade and migrate the database schema in the right way from previous versions.
The overall process of migration should be similar to:
- Scale down current Keycloak services
- Backup current database schema and data - allow a rollback process
- Deploy new Keycloak instance (it can be as a different instance (e.g:
-green
,-kc22
, ...) - allowing a rollback process - Starts new Keycloak instance
The #3 means to use a new definition of the Keycloak instance to be deployed, basically a new Helm release of the application.
on 🎩 ❯ helm list
NAME REVISION UPDATED STATUS CHART APP VERSION
kc-central-kc16 2 2023-10-06 09:09:25.069156223 +0200 CEST deployed portal-iam-1.2.0 16.0.1
kc-central-kc22 1 2023-10-06 09:09:31.28131872 +0200 CEST deployed portal-iam-2.0.0-alpha 22.0.3
Kubernetes does not include any specific tool to clone or replicate PVC, or data, between other PVCs, namespaces, or clusters. The solution should be done using some of the tools available in the community space. For example, the following ones are the most common used:
pv-migrate
- a CLI tool/kubectl plugin to easily migrate the contents of one Kubernetes PersistentVolumeClaim to another.- VolSync - a Kubernetes operator that performs asynchronous replication of persistent volumes within, or across, clusters.
This is an example of migration of data from a source PVC (blue
) to target PVC (green
):
on 🎩 ❯ pv-migrate migrate postgresql-pvc-central-blue postgresql-pvc-central-green \
--strategies mnt2 \
--source-mount-read-only \
--ignore-mounted
🚀 Starting migration
💭 Will attempt 1 strategies: mnt2
🚁 Attempting strategy: mnt2
🧹 Cleaning up
📂 Copying data... 100% |██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████|
✨ Cleanup done
✅ Migration succeeded
- GitHub Keycloak monorepo
- Keycloak Site
- Keycloak Documentation
- Keycloak Guides
- Keycloak Admin REST API
- Keycloak Quickstarts
- Red Hat Single Sign-On Component Details
- Red Hat Single Sign-On Supported Configurations
- Red Hat Single Sign-On Release History
- Red Hat Build of Keycloak - Issues Tracker
This work is licensed under the Apache-2.0.
- SPDX-License-Identifier: Apache-2.0
- SPDX-FileCopyrightText: 2023 Contributors to the Eclipse Foundation
- Source URL: https://github.com/eclipse-tractusx/portal-iam