Repository navigation
Conversation
This commit introduces a production-ready Redis storage provider for Keycloak sessions, enabling cloud-native deployments with managed Redis services (AWS ElastiCache, Azure Cache, etc.). Key Features: Session Management, High Availability, Security, Performance (>1000 TPS validated, 80%+ code coverage, 33 ATDD scenarios) Implementation: Pure SPI implementation with Lettuce client, JSON serialization, optimistic locking via Lua scripts Components: Connection provider, Session providers, Single-use object provider, Login failure provider, Cluster provider Testing: 130 files with 38,266 lines of code including unit tests, integration tests, and Cucumber ATDD scenarios Co-Authored-By: Claude Code
…iderFactory This commit integrates the Redis provider with Keycloak's feature flag system, marking it as EXPERIMENTAL and requiring explicit enablement via the redis-storage feature flag. Changes: - Added REDIS_STORAGE feature to Profile.java (Type: EXPERIMENTAL, Policy: SHUTDOWN) - Implemented EnvironmentDependentProviderFactory interface across all Redis provider factories - Added Profile.isFeatureEnabled() checks in isSupported() methods - Fixed NullPointerException in RedisUserSessionProviderFactoryTest by initializing Profile singleton - Updated README.md with comprehensive feature enablement documentation - Added feature flag configuration to test resources - Added order() method implementation for provider precedence (order=10) Provider Factories Updated: - AbstractRedisProviderFactory: Base implementation with feature flag check - DefaultRedisConnectionProviderFactory: Feature flag + order method - RedisClusterProviderFactory: Feature flag + order method - RedisUserSessionProviderFactory: Feature flag check (replaces hardcoded true) - RedisSingleUseObjectProviderFactory: Updated spacing/formatting Test Improvements: - Added @BeforeAll/@afterall hooks to initialize Profile with REDIS_STORAGE enabled - Resolves NullPointerException when calling Profile.getInstance() in unit tests Documentation: - Added 'Enabling the Feature' section to README with multiple enablement methods - Added experimental warnings to architecture documentation - Documented verification steps and important notes This ensures the Redis provider integrates properly with Keycloak's feature management system and requires explicit opt-in, aligning with Keycloak's experimental feature policies. Co-Authored-By: Claude Code
…dentProviderFactory" This reverts commit ecf9938.
Updated find command in find_and_export_jar function to exclude -sources.jar and -tests.jar files when locating the Redis provider JAR. Co-Authored-By: Claude Code
Fix JAR file detection to exclude sources and test JARs
|
Hi @Anoopgopi. This is an amazing submission. ❤️ 🥳 @rtufisi and I did a talk at Keycloak DevDay last week about this subject and our implementation of the same thing. I think it's interesting that we ended up with many of the same design choices (e.g. a Lua function for CAS, We'll do a a more thorough review of your PR in the coming days, but I wanted to add a few comments and recommendations based on our experience after reading your architecture summaries:
|
|
Thank you @Anoopgopi for this PR. This is a rather big change, and we would like to see some community engagement in this topic first: Both if this is being actively maintained, and if it actively used by the community. For that, I suggest to start with an extension first that lives in its own repository. This allows you to iterate over it with other contributors, and release it independently of the main Keycloak releases. Once it gets traction, there is a chance that it will be part of Keycloak core eventually. I see that this has Apache License 2.0, which would be a prerequisite for that. Something that we would want to avoid is having a feature in Keycloak core that only a few users activate, but the Keycloak core team would need to provide support for it. While this is an extension, we can discuss if the SPIs that Keycloak offers need to evolve to better enable this and possibly other future providers. Given your comment above stating "This implementation provides a pure SPI-based integration requiring no Keycloak core modifications", there might be no need for that? If you agree to that, I suggest to close this PR and continue the discussion in the extension's repository. |
|
Hi @ahus1, I’d like to share a slightly different perspective on this. Redis cache support has seen sustained and growing community interest since 2022, with multiple issues and discussions reflecting strong and ongoing community demand. Redis support ranks within the top 10 most-requested/liked features. If our goal is to encourage broader community and enterprise sustainable upstream contributions, along with a more open governance model, I believe it is important for Keycloak to actively support and enable such upstream efforts. In my view, we should consolidate effort rather than fragment it, focus on upstream collaboration and contribution. In my view, rather than developing competing extensions we should enable collaboration. Keycloak already supports multiple database providers and vendors; similarly, it would be beneficial to offer flexibility in caching options for Keycloak users. This is particularly relevant for users leveraging managed container services from cloud providers, where external caching solutions can help reduce operational complexity and issues. I fully understand the concern about the maintenance burden for the Keycloak core/IBM/RedHat team. To address this CapitalOne is committed to long-term, sustainable upstream contribution and maintenance.There have also been prior discussions on this topic, including @xgp's and @rtufisi's Keycloak DevDay presentation, and conversations within the SIG on externalising the Infinispan cache dependency. This indicates both technical interest and growing momentum within the community.I am currently collaborating with Anoop on this PR, and he will be joining the SIG meetings starting next week. Anoop is also keen to collaborate with @xgp and others and incorporate their feedback. We are happy to formalise a maintenance commitment if that would be helpful. There is also an established precedent of including features for a subset of Keycloak users, including most of the features contributed by SIG. Would you be open to considering this as an experimental feature? This approach could enable broader community adoption and feedback while keeping expectations appropriately scoped. From an end-user perspective, many enterprises see limited value in maintaining their own forks or extensions and would be more inclined to contribute upstream in a way that benefits the wider ecosystem. |
|
@Anoopgopi @VinodAnandan thank you for your work, it is impressive. I agree with @ahus1 here. This is quite a big change to be included in a minor Keycloak release. In my opinion, I would postpone until the next major release, Keycloak 27, and open a PR to promote the provider in https://www.keycloak.org/extensions. It will require a lot of man-hours to go through the code, but I have some comments:
|
|
@pruivo Thank you for your kind words and feedback. I would just like to clarify that I was not directly involved in the implementation work. The full credit truly belongs to Anoop and his team at Capital One. My involvement was limited to participating in several discussions and meeting with Anoop. My primary focus has been on exploring how Capital One’s work can be leveraged for the broader Keycloak community, particularly for those who are using, or considering using, managed container services such as AWS Fargate to help mitigate potential production issues and challenges related to Infinispan. I would be more than happy to help arrange or coordinate meetings with you, @ahus1 , and others as needed. Please let us know your availability over the coming weeks, and I will do my best to accommodate. |
|
I want to add a perspective from Phase Two here. We (@rtufisi and I) recently shared our implementation at Keycloak DevDay, and I had a good, albeit brief conversation with @ahus1 about how we could start directing such a contribution into Keycloak core. We see Redis-backed distributed cache as a long-standing requirement from a meaningful part of the Keycloak user base. This is not just about an alternative implementation detail; for many teams, it is about whether Keycloak can fit naturally into the operational model they already have. In some cases, it is also a requirement that has pushed potential users away from Keycloak altogether. That is why we think this work matters, and why we think it belongs in the project itself. To help move this forward, we are planning to open-source our own Redis cache/session implementation under ASL 2.0. We want to do that specifically in a way that facilitates collaboration and lowers the barrier to bringing this capability into Keycloak core. Our intention is not to create a parallel answer outside the project, but to contribute in a form that can be reviewed, improved, and maintained in the open with the rest of the community. We believe core is the right home for this. If this functionality lives only as an external extension, it will always have a smaller audience, weaker visibility, and less confidence from users who need to bet on it. Putting it in Keycloak core, even initially behind an experimental feature flag, would show that the project is serious about meeting this requirement and about evolving with the needs of cloud and enterprise deployments. It would also make collaboration much easier, because the implementation could be developed alongside the APIs, expectations, documentation, and release process that define the user experience. More broadly, this feels like an opportunity for Keycloak to clarify how major features like this can be contributed. A contribution of this size naturally raises questions that are not only technical, but also about ownership, review, and long-term maintenance. That is especially true when the contributors are organizations that have made significant investments in Keycloak because they need the project to satisfy requirements beyond what the current core team has had the bandwidth to deliver. Even if the answer is not a new formal process, it would be very valuable for the project to express and document its expectations for how work like this should enter the project and how stewardship should be shared. On that point, we are committed to collaborating with Capital One and others who have expressed interest here, potentially including Backbase and anyone else willing to help shepherd this through. We are prepared to contribute not only implementation work, but also the supporting work that makes a feature sustainable: documentation, examples, tests, operational guidance, review support, and maintenance. We are also open to different ways of formalizing that commitment, whether that means designated maintainers, a working group around the feature, or some other model that gives the core maintainers confidence that this will not become an unowned burden. I also agree with the suggestion that this should begin as an experimental feature and should land only in a major release, such as 27. That seems like the right balance between momentum and caution. It gives enough time to do the work properly: align on architecture, document tradeoffs, harden the implementation, define support expectations, and make clear how the feature will be maintained if it enters core. From the discussion so far, it sounds like the biggest concern is maintenance, and I think that is the right concern to focus on. But I do not think maintenance has to mean additional unsustainable burden on the existing core maintainers. With a committed set of external maintainers, visible ownership, and ongoing feedback from the community, this can be introduced in a way that is sustainable. The project should absolutely expect high standards here, but there is a real opportunity to meet those standards with shared stewardship instead of assuming the core team has to carry everything alone. To make that concrete, it may be useful to explicitly list what needs to be true for this addition to be considered maintainable. For example:
My suggestion would be to use this PR and discussion not only to evaluate the implementation itself, but also to define that checklist. That would help everyone: maintainers would have a clearer basis for review, contributors would know what is expected, and users would have more confidence in the eventual result. From our side, we would be glad to help with that work and to collaborate on turning this from a promising PR into something the project can realistically accept and sustain. This is a real, long-standing user need; multiple serious adopters are now willing to invest to solve it in the open; the right place to do that is Keycloak core; and the way to make that sustainable is to pair an experimental release with an explicit maintenance/governance model. |
I don't see how creating it as an extension first stands in the way of that. On the contrary, I think collaboration will be simpler in a separate repository. We can help boost the visibility for example by hosting a blog post in the Keycloak blog.
This would make this a very long running and big PR, which adds to the first point, having its own repository for this. Also that there is soon to be a second implementation which would then need to be eventually compared and merged. I haven't heard from @Anoopgopi yet, let's wait for them. |
|
Thanks, @ahus1 — that makes sense, and I agree that a separate repository may be the better place for the next phase of collaboration. Our concern is less about where the work starts, and more about whether there is a credible path for work like this to eventually become part of Keycloak itself if it proves successful. For a capability that addresses a long-standing user requirement, starting as an extension seems reasonable; treating it as extension-only forever is the part we would be more hesitant about. Furthermore, a core question that I think a lot of "outsiders" are wrestling with is the pathway for how to get a big feature like this heard, evaluated and eventually integrated. That's one of the reasons I suggested using this as a test case — so that process could be defined in public, and ultimately form a template for other contributions in the future. So I think there is a productive compromise here: use a separate repository to keep iteration fast, reduce PR overhead, and allow multiple contributors to converge on the right design, while also being explicit that the goal is to evaluate whether this can mature into an experimental core feature in a future major release. That gives us a way to avoid a huge and long-running PR now without losing the strategic value of doing this work in the open with Keycloak in mind. However, as you say, this is @Anoopgopi's PR, and I'm eager to hear his perspective. My understanding is that he's at a conference, so we might not hear from him until next week. On the other utility function I introduced:
I'd really like to hear some feedback here. I think we can get the feature across the line, but understanding more explicitly what has to happen in order to meet the "maintainable" bar that was mentioned many times in the DevDay "Meet the Maintainers" session would be golden. It's something I've never understood, can't find concrete guidance for, and know that others would benefit from documentation in this regard. |
|
Playing a bit of devil's advocate here, I am not sure Redis support should ever be part of the core. We don't use it and from my perspective, I would like to have Keycloak the least amount of source code possible. So I don't really see why Redis support should not live as an extension in a separate repository for people that actually need it. Maybe it's time for another survey to find out how big the demand to have it in the core really is and then decide if it outweighs the cost of doing that. In any case, with two competing existing implementations, we should definitely start with a separate repository and then see if one good implementation emerges and it is maintained well. |
@sschu I totally agree with you here here, but that has been the opposite of the way Keycloak has bloated over the last few years. Having extensions be more of a "first class citizen" solves this problem. If anything can start a serious dialogue about how to make that happen, I think there's a way forward. Until then, having things in core is one of the few ways to get visibility and utilization.
I do note in the recently released Distribution Survey Results that "Many respondents want to remove ISPN/JGroups to make Keycloak truly stateless - allow replacement with managed services like Redis" |
|
My vision for the future is a proper extension registry, with a better way to browse extensions, more information about the extensions, and a better and simpler mechanism for installing extensions, including required dependencies. This will be a place where extensions can gain visibility and maturity. I'd also like to look at ways to elevate extensions from purely community extensions, to more "officially" approved extensions of some sort, perhaps even graduating some extensions to the Keycloak organization on GitHub, as well as having a route for the extensions to become part of the core distribution when that makes sense. I'd also like to incorporate testing of some extensions as part of the Keycloak release process. Perhaps testing nightlies, but also considering a release freeze for major and minor releases where extension developers can test and update their extensions to have them ready together with the Keycloak release. Alongside this of course we need to work on making it more viable to build extensions; better and stable APIs, make it easy to test extensions, and have integrations for testing. For the Redis extension the more folks can collaborate on one single great Redis extension the better. Maybe one day Redis could be part of Keycloak core, but then again maybe it doesn't have to be and can get the visibility and traction (as well as easy of use/installation) without it being part of core. |
There was a problem hiding this comment.
I'm not in favour of adding Redis support to Keycloak at this point in time. As mentioned by others I believe it would be much better to provide this as an extension at least for now; and we can work together on providing more visibility to the Redis extension (and other extensions of course)
|
Thank you all for the thoughtful reviews and constructive feedback. I apologize for the delay in responding - I was at a conference for the past two days. I'm grateful for the time invested by @xgp, @stianst @rtufisi, @ahus1, @pruivo, @VinodAnandan, and @sschu in evaluating this contribution. @xgp: Your technical recommendations (Redis Hashes, Lua-based indexes, transaction caching) are well noted. We're eager to collaborate and consolidate learnings from both implementations. @ahus1, @pruivo, @stianst : We understand the maintenance concerns and appreciate the specific technical feedback. @VinodAnandan, @sschu: Thank you for the broader perspective on community needs and project goals. Our Perspective on Core vs ExtensionWe appreciate the extension-first suggestion and understand the reasoning. However, we'd like to respectfully share why we believe there needs to be a clear path to have it in core: Operational Reality: As Garth pointed out in the recent Distribution Survey, many users want to "remove ISPN/JGroups to make Keycloak truly stateless - allow replacement with managed services like Redis." We've also experienced significant production challenges with Infinispan/JGroups that require institutional knowledge and create barriers for enterprise-scale adoption. Strategic Direction: If the vision is moving to persistent stores (managed PostgreSQL with multi-region support), Redis as an extension makes sense. But if Infinispan remains the default, we believe Keycloak should offer alternatives (Redis/Valkey) in core. This gives users choice based on operational requirements. Core Competency Focus: Keycloak's strength lies in its IAM capabilities - authentication, authorization, and identity management. Organizations should be able to focus on leveraging these features rather than managing caching infrastructure complexity. While Infinispan is a solid solution, the lack of managed Infinispan services creates operational overhead that the Infinispan community needs to solve for. Supporting managed caching alternatives (Redis/Valkey) aligns with cloud-native deployment patterns and reduces barriers to Keycloak adoption. Consolidation vs Fragmentation: Echoing @VinodAnandan's point about community needs, our primary goal is to encourage collaboration and avoid a landscape of fragmented, competing extensions. With multiple implementations emerging (ours, Phase Two's, potentially others), core inclusion enables collaborative improvement under unified governance. Relegating this to separate extensions risks duplication of effort, user confusion, and reduced confidence in long-term support. Path Forward: Options and QuestionsWe're flexible on approach but want to ensure a credible path to core inclusion if this proves successful. We'd appreciate guidance from @stianst , @ahus1 and @pruivo: Option A: Extension-First with Roadmap to Core
Option B: Experimental Feature in KC 27 from Start
Questions: Long-term Strategic Alignment: Could @stianst @ahus1 and @pruivo share Keycloak's long-term vision for caching architecture? Understanding whether the project is moving toward persistent stores (managed PostgreSQL) and potentially sunsetting Infinispan/JGroups would help us align our investment with the project's strategic direction. If Keycloak is moving toward a target architecture utilizing persistent stores, that context would inform which option makes most sense including eliminating Option B entirely. Also will help with @sschu point on ensuring Keycloak having least amount of source code possible for supporting core capability Which approach do you prefer? Request for Contribution Guidance: It would also help future contributions if @stianst, @ahus1 and @pruivo could clarify:
Installation & Distribution of Keycloak approved extension We're wiling to invest in making this a model extension @stianst you are suggesting that demonstrates the viability of building an extension ecosystem. Would you be open to the Redis extension serving as a pilot for some of these extension ecosystem improvements? We'd be happy to participate in working groups or discussions to help shape this framework. Next Steps and Addressing Technical FeedbackCollaboration Commitment:
Addressing @pruivo's Technical Feedback:
Our goal is to address a real user need sustainably through community collaboration. Whether as extension or experimental core feature, we commit to meet Keycloak's standards for code, testing, and documentation, work openly with maintainers, and community to adapt to whatever process serves the project best Thank you for your expertise and guidance. Looking forward to your feedback on the preferred path forward. cc: @xgp @rtufisi @ahus1 @stianst @pruivo @VinodAnandan @sschu @amarbat @rsquared226 @cgurtshaw |
|
We have a maintainers meeting coming up on the 9th of April we will be discussing this then. |
Hi @stianst, could you share any outcomes or decisions from the April 9th maintainers meeting regarding this PR? We're very interested in the direction the team has decided to take — whether it's the extension-first approach, experimental inclusion in core, or another path forward. Any update would be greatly appreciated. Thanks! |
|
This was discussed on the maintainers meeting last week. I'm currently preparing the meeting minutes. Once they are approved, I'll post a comment here. |
Thanks @ahus1 . Looking forward to hearing more about the maintainers' perspectives. In the meantime, we (Phase Two) have released our version of a Redis/Valkey replacement for Keycloak's Infinispan distributed caches that we presented in our talk at Keycloak DevDay 2026:
This implementation has the advantages of:
At this point, it should be considered alpha software, and we are actively looking for help with testing, validation and improvement. |
|
@ahus1 do we have any ETA on when the meeting minutes will be published. Hoping for a positive response on community supported extension path. Thanks @xgp for making the Phase Two implementation publicly available, based on the direction from the maintainers' perspectives we can decide on the next steps, we are happy to collaborate to have a solution which takes in the best from both implementation. |
|
After discussions in the maintainers group have decided to not adding support for Redis directly to Keycloak. For more details see #48577 |
Description
This PR adds support for Redis storage provider for Keycloak sessions, enabling organizations to leverage managed Redis services (example AWS ElastiCache) as an additional deployment option alongside Keycloak's existing Infinispan caching.
This implementation provides a pure SPI-based integration requiring no Keycloak core modifications, giving organizations flexibility in choosing their cache infrastructure based on operational requirements.
Discussion: #37137
Motivation
While Keycloak's Infinispan caching serves many deployment scenarios effectively, organizations increasingly adopt managed cloud services to reduce operational overhead. This provider adds support for managed Redis services as an alternative cache backend, offering organizations additional deployment flexibility.
Use Cases
Key Benefits
Changes
New Module:
model/redisAdds 6 Keycloak SPI provider implementations for Redis-based storage:
Redis Connection Provider - Foundation layer for Redis operations
User Session Provider - Online and offline user session management
Authentication Session Provider - Login flow state tracking
Single-Use Object Provider - Authorization codes and action tokens
Login Failure Provider - Brute force protection
Cluster Provider - Multi-node coordination
Configuration
Basic Configuration
$KC_HOME/bin/kc.sh start \ --spi-user-sessions-provider=redis \ --spi-authentication-sessions-provider=redis \ --spi-single-use-object-provider=redis \ --spi-user-login-failure-provider=redis \ --spi-cluster-provider=redis \ --spi-redis-connection-default-host=redis.example.com \ --spi-redis-connection-default-port=6379 \ --spi-redis-connection-default-ssl=trueFull configuration reference:
model/redis/README.mdTesting
Comprehensive Test Coverage
Unit Tests:
Integration/ATDD Tests:
atdd-env.shscriptChaos Engineering:
Performance Validation:
Documentation
Comprehensive documentation included in the
/model/redis/package:Main Documentation
Architecture Documentation
Provider Implementation Guides
Testing Documentation
Backwards Compatibility
Fully backwards compatible - Infinispan remains the default
AI Disclosure
This implementation was developed with assistance from Claude Code and Windsurf AI tools.
As the contributors, we:
Community Feedback Requested
We formally request the community's input and review on the following aspects:
Architecture and Design
Feature and Functional Completeness
Performance and Scalability Analysis
Operational and Deployment Aspects
Integration Pathway to Keycloak Core
Checklist
/model/redis/)Additional Notes
License Compliance:
Thank you for considering this contribution! This provider expands Keycloak's deployment options while maintaining full compatibility with existing Infinispan-based deployments. We are committed to addressing feedback and ensuring this implementation meets Keycloak's high standards for quality and maintainability.
cc : @amarbat @rsquared226 @cgurtshaw