<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	
	xmlns:georss="http://www.georss.org/georss"
	xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
	>

<channel>
	<title>Keycloak - Inero Software - Software Consulting</title>
	<atom:link href="https://inero-software.com/category/keycloak/feed/" rel="self" type="application/rss+xml" />
	<link>https://inero-software.com/category/keycloak/</link>
	<description>We unleash innovations using cutting-edge technologies, modern design and AI</description>
	<lastBuildDate>Tue, 10 Feb 2026 11:48:41 +0000</lastBuildDate>
	<language>en-GB</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.1</generator>

<image>
	<url>https://inero-software.com/wp-content/uploads/2018/11/inero-logo-favicon.png</url>
	<title>Keycloak - Inero Software - Software Consulting</title>
	<link>https://inero-software.com/category/keycloak/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">153509928</site>	<item>
		<title>Keycloak and SIEM Integration at Enterprise Scale</title>
		<link>https://inero-software.com/keycloak-and-siem-integration-at-enterprise-scale/</link>
		
		<dc:creator><![CDATA[Andrzej Chybicki]]></dc:creator>
		<pubDate>Tue, 10 Feb 2026 09:20:41 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Enterprise IAM]]></category>
		<category><![CDATA[Enterprise Security]]></category>
		<category><![CDATA[Identity and Access Management]]></category>
		<category><![CDATA[keycloak]]></category>
		<category><![CDATA[Keycloak Deployment]]></category>
		<category><![CDATA[Keycloak Integration]]></category>
		<category><![CDATA[Security Architecture]]></category>
		<category><![CDATA[Security Monitoring]]></category>
		<category><![CDATA[SIEM]]></category>
		<category><![CDATA[uthentication & Authorization]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=8507</guid>

					<description><![CDATA[<p>KeyCloak is one of the most widely adopted enterprise identity and access management (IAM) platforms today. At Inero Software, we work with Keycloak on a daily basis — delivering Keycloak deployment, integration, and consulting services for organizations that rely on it as a core security component. In one of our&#8230;</p>
<p>Artykuł <a href="https://inero-software.com/keycloak-and-siem-integration-at-enterprise-scale/">Keycloak and SIEM Integration at Enterprise Scale</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="8507" class="elementor elementor-8507" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-e305c10 e-flex e-con-boxed e-con e-parent" data-id="e305c10" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-5a02e35 e-con-full e-flex e-con e-child" data-id="5a02e35" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-2e568f5 e-con-full e-flex e-con e-child" data-id="2e568f5" data-element_type="container">
				<div class="elementor-element elementor-element-16f7e65 elementor-widget elementor-widget-text-editor" data-id="16f7e65" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p data-start="582" data-end="919"><a href="https://keycloak.org">KeyCloak</a> is one of the most widely adopted <strong data-start="654" data-end="705">enterprise identity and access management (IAM)</strong> platforms today. At Inero Software, we work with Keycloak on a daily basis — delivering <strong data-start="794" data-end="855">Keycloak deployment, integration, and consulting services</strong> for organizations that rely on it as a core security component.</p><p data-start="921" data-end="1211">In one of our recent production projects, Keycloak was integrated with a SIEM platform to provide full visibility into authentication and authorization events. Below, we share what this integration looks like in practice — and what really matters when Keycloak operates at enterprise scale.</p>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-158fdb8 e-con-full e-flex e-con e-child" data-id="158fdb8" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-d28b7fe e-flex e-con-boxed e-con e-parent" data-id="d28b7fe" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-ecca0c5 e-con-full e-flex e-con e-child" data-id="ecca0c5" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-1cfaba3 e-con-full e-flex e-con e-child" data-id="1cfaba3" data-element_type="container">
				<div class="elementor-element elementor-element-9330b53 elementor-widget elementor-widget-text-editor" data-id="9330b53" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h3 data-start="1218" data-end="1267">SIEM as a natural extension of enterprise IAM</h3><p data-start="1269" data-end="1593">In large organizations, IAM is never an isolated system. Authentication and authorization are just one step in a much broader chain of business and security processes. That’s why enterprises rely on SIEM platforms such as <a href="https://www.splunk.com/"><span class="hover:entity-accent entity-underline inline cursor-pointer align-baseline"><span class="whitespace-normal">Splunk</span></span> </a>to centralize and correlate events coming from multiple systems.</p><p data-start="1595" data-end="1998">From our experience with <strong data-start="1620" data-end="1656">Keycloak-based SSO architectures</strong>, IAM events are among the most valuable data points in SIEM pipelines. We previously described the foundations of such setups in our post on<br data-start="1797" data-end="1800" /><strong data-start="1800" data-end="1932"><a class="decorated-link" href="https://inero-software.com/hands-on-keycloak-sso-from-setup-to-integration/?utm_source=chatgpt.com" target="_new" rel="noopener" data-start="1802" data-end="1930">hands-on Keycloak SSO – from setup to integration</a></strong>, where identity becomes a shared service across the organization.</p>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-12245b7 e-con-full e-flex e-con e-child" data-id="12245b7" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-80c19e3 e-flex e-con-boxed e-con e-parent" data-id="80c19e3" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-b79e81a e-con-full e-flex e-con e-child" data-id="b79e81a" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-4104080 e-con-full e-flex e-con e-child" data-id="4104080" data-element_type="container">
				<div class="elementor-element elementor-element-153a14e elementor-widget elementor-widget-text-editor" data-id="153a14e" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h3 data-start="2005" data-end="2064">Starting point: no ready-made Keycloak–SIEM integration</h3><p data-start="2066" data-end="2326">Although Keycloak offers extensive APIs and extension points, enterprise deployments often expose gaps that are invisible in smaller setups. In this case, the SIEM platform did not provide a maintained, production-ready connector for ingesting Keycloak events.</p><p data-start="2328" data-end="2732">This is a pattern we frequently encounter during <strong data-start="2377" data-end="2413">Keycloak enterprise integrations</strong>:<br data-start="2414" data-end="2417" />out-of-the-box features cover the IAM core well, but integration with security tooling often requires custom work. Similar limitations — and ways to address them — are discussed in our overview of <strong data-start="2614" data-end="2731"><a class="decorated-link" href="https://inero-software.com/best-keycloak-practices/?utm_source=chatgpt.com" target="_new" rel="noopener" data-start="2616" data-end="2729">Keycloak best practices for secure enterprise environments</a></strong>.</p>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-6b59a08 e-con-full e-flex e-con e-child" data-id="6b59a08" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-236dd85 e-flex e-con-boxed e-con e-parent" data-id="236dd85" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-1f616e1 e-con-full e-flex e-con e-child" data-id="1f616e1" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-f128069 e-con-full e-flex e-con e-child" data-id="f128069" data-element_type="container">
				<div class="elementor-element elementor-element-55cd74f elementor-widget elementor-widget-text-editor" data-id="55cd74f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h3 data-start="3413" data-end="3466">Keycloak clustering and consistent event delivery</h3><p data-start="3468" data-end="3737">As is typical for enterprise environments, Keycloak was deployed in a <strong data-start="3538" data-end="3565">clustered configuration</strong> with multiple nodes handling authentication traffic. While events are generated across many instances, the SIEM system must receive a single, consistent security timeline.</p><p data-start="3739" data-end="3802">Using Keycloak’s cluster-aware APIs, we implemented logic that:</p><ul><li style="list-style-type: none;"><ul data-start="3803" data-end="3956"><li data-start="3803" data-end="3845"><p data-start="3805" data-end="3845">coordinates event delivery across nodes,</p></li><li data-start="3846" data-end="3918"><p data-start="3848" data-end="3918">ensures that scheduler tasks execute on the appropriate instance only,</p></li><li data-start="3919" data-end="3956"><p data-start="3921" data-end="3956">avoids duplication or missing data.</p></li></ul></li></ul><p data-start="3958" data-end="4192">This kind of orchestration is rarely mentioned in basic tutorials, but it becomes essential once Keycloak is part of a broader security ecosystem — something we often highlight when discussing <strong data-start="4151" data-end="4191">enterprise-grade Keycloak operations</strong>.</p>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-8ca813d e-con-full e-flex e-con e-child" data-id="8ca813d" data-element_type="container">
				<div class="elementor-element elementor-element-8dafe29 elementor-widget elementor-widget-image" data-id="8dafe29" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img fetchpriority="high" decoding="async" data-attachment-id="8513" data-permalink="https://inero-software.com/keycloak-and-siem-integration-at-enterprise-scale/keycloak_splunk_integration/" data-orig-file="https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration.png" data-orig-size="1536,1024" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="KeyCloak_Splunk_Integration" data-image-description="" data-image-caption="&lt;p&gt;KeyCloak Splunk Integration&lt;/p&gt;
" data-medium-file="https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration-300x200.png" data-large-file="https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration-1030x687.png" tabindex="0" role="button" width="768" height="512" src="https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration-768x512.png" class="attachment-medium_large size-medium_large wp-image-8513" alt="" srcset="https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration-768x512.png 768w, https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration-300x200.png 300w, https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration-1030x687.png 1030w, https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration-450x300.png 450w, https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration.png 1536w" sizes="(max-width: 768px) 100vw, 768px" data-attachment-id="8513" data-permalink="https://inero-software.com/keycloak-and-siem-integration-at-enterprise-scale/keycloak_splunk_integration/" data-orig-file="https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration.png" data-orig-size="1536,1024" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="KeyCloak_Splunk_Integration" data-image-description="" data-image-caption="&lt;p&gt;KeyCloak Splunk Integration&lt;/p&gt;
" data-medium-file="https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration-300x200.png" data-large-file="https://inero-software.com/wp-content/uploads/2026/02/KeyCloak_Splunk_Integration-1030x687.png" role="button" />													</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-e5ec0a2 e-flex e-con-boxed e-con e-parent" data-id="e5ec0a2" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-c134319 e-con-full e-flex e-con e-child" data-id="c134319" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-a5d0d39 e-con-full e-flex e-con e-child" data-id="a5d0d39" data-element_type="container">
				<div class="elementor-element elementor-element-7658a07 elementor-widget elementor-widget-text-editor" data-id="7658a07" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h3 data-start="425" data-end="494">Architectural alternatives for delivering Keycloak events to SIEM</h3><p data-start="496" data-end="710">While the core challenge remains the same — <strong data-start="540" data-end="617">high event volume and the need for buffering and batching before delivery</strong> — there are two primary architectural approaches to integrating Keycloak with a SIEM system.</p><h4 data-start="712" data-end="762">Application-level integration inside Keycloak</h4><p data-start="764" data-end="1079">The first approach is to handle event collection, buffering, and delivery <strong data-start="838" data-end="866">at the application level</strong>, directly within the Keycloak runtime. This can be implemented either as custom code or by leveraging existing Java libraries that provide built-in mechanisms for buffering, batching, and reliable event delivery.</p><p data-start="1081" data-end="1226">Because Keycloak itself is Java-based, this model allows the integration to stay close to the IAM layer and offers <strong data-start="1196" data-end="1220">fine-grained control</strong> over:</p><ul><li style="list-style-type: none;"><ul data-start="1227" data-end="1349"><li data-start="1227" data-end="1256"><p data-start="1229" data-end="1256">which events are collected,</p></li><li data-start="1257" data-end="1293"><p data-start="1259" data-end="1293">how they are enriched or filtered,</p></li><li data-start="1294" data-end="1349"><p data-start="1296" data-end="1349">when and in what form they are delivered to the SIEM.</p></li></ul></li></ul><p data-start="1351" data-end="1519">The trade-off is ownership: this approach requires custom implementation, testing, and long-term maintenance, but in return provides maximum flexibility and visibility.</p><h4 data-start="1521" data-end="1576">Platform-level integration using Kubernetes agents</h4><p data-start="1578" data-end="1884">The second approach moves the responsibility for event collection and delivery <strong data-start="1657" data-end="1687">outside of the application</strong>, to the platform layer. In Kubernetes-based deployments, SIEM vendors such as Splunk provide dedicated agents that can collect and forward logs and events from applications running in the cluster.</p><p data-start="1886" data-end="1900">In this model:</p><ul><li style="list-style-type: none;"><ul data-start="1901" data-end="2106"><li data-start="1901" data-end="1964"><p data-start="1903" data-end="1964">the application’s implementation language becomes irrelevant,</p></li><li data-start="1965" data-end="2034"><p data-start="1967" data-end="2034">buffering, formatting, and delivery logic are handled by the agent,</p></li><li data-start="2035" data-end="2106"><p data-start="2037" data-end="2106">operational effort is reduced by relying on vendor-supported tooling.</p></li></ul></li></ul><p data-start="2108" data-end="2270">This comes at the cost of reduced control over event semantics and processing, but can significantly simplify integration in standardized Kubernetes environments.</p><p data-start="2272" data-end="2630">In practice, the decision between these approaches comes down to a balance between <strong data-start="2355" data-end="2392">control and implementation effort</strong>. Application-level integration offers maximum precision and flexibility, while platform-level integration prioritizes speed of delivery and operational simplicity — both valid choices depending on enterprise requirements and constraints.</p>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-9e7cac9 e-con-full e-flex e-con e-child" data-id="9e7cac9" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-c04da62 e-flex e-con-boxed e-con e-parent" data-id="c04da62" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-8e67aa2 e-con-full e-flex e-con e-child" data-id="8e67aa2" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-493156d e-con-full e-flex e-con e-child" data-id="493156d" data-element_type="container">
				<div class="elementor-element elementor-element-a534a80 elementor-widget elementor-widget-text-editor" data-id="a534a80" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h3 data-start="4199" data-end="4241">What we take away from this deployment</h3><p data-start="4243" data-end="4437">Our key takeaway is simple: <strong data-start="4271" data-end="4436">Keycloak scales extremely well in enterprise environments, but its real value emerges when it is thoughtfully integrated with surrounding security infrastructure</strong>.</p><p data-start="4439" data-end="4670">SIEM integration is not an optional add-on — it is a natural extension of a mature IAM architecture. For organizations operating at scale, this is where <strong data-start="4592" data-end="4641">Keycloak integration and deployment expertise</strong> makes a tangible difference.</p><p data-start="4672" data-end="4898">At Inero, solutions like this are not experiments or proofs of concept — they are part of how we deliver production-ready IAM platforms for enterprise clients, building on real-world experience rather than documentation alone.</p>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-479023a e-con-full e-flex e-con e-child" data-id="479023a" data-element_type="container">
				</div>
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/keycloak-and-siem-integration-at-enterprise-scale/">Keycloak and SIEM Integration at Enterprise Scale</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8507</post-id>	</item>
		<item>
		<title>Keycloak Deployment Auditing – General Scope and Guidelines</title>
		<link>https://inero-software.com/keycloak-deployment-auditing-general-scope-and-guidelines/</link>
		
		<dc:creator><![CDATA[Andrzej Chybicki]]></dc:creator>
		<pubDate>Mon, 29 Dec 2025 10:08:56 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[authorization server audit]]></category>
		<category><![CDATA[client-side OAuth security]]></category>
		<category><![CDATA[dentity and access management audit]]></category>
		<category><![CDATA[enterprise Keycloak deployment]]></category>
		<category><![CDATA[Keycloak audit best practices]]></category>
		<category><![CDATA[Keycloak client configuration]]></category>
		<category><![CDATA[Keycloak deployment auditing]]></category>
		<category><![CDATA[Keycloak IAM audit]]></category>
		<category><![CDATA[Keycloak security audit]]></category>
		<category><![CDATA[token validation best practices]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=8306</guid>

					<description><![CDATA[<p>Keycloak Deployment Auditing – General Scope and Guidelines Practical lessons from auditing multi-realm, multi-client Keycloak environments in medium and large organizations  1. Introduction In medium and large enterprises, Keycloak deployments rarely follow a simple “one realm – one application” pattern. In reality, such environments typically consist of multiple realms reflecting&#8230;</p>
<p>Artykuł <a href="https://inero-software.com/keycloak-deployment-auditing-general-scope-and-guidelines/">Keycloak Deployment Auditing – General Scope and Guidelines</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="8306" class="elementor elementor-8306" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-2f79978 e-flex e-con-boxed e-con e-parent" data-id="2f79978" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-d183de2 e-con-full e-flex e-con e-child" data-id="d183de2" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-b58a909 e-con-full e-flex e-con e-child" data-id="b58a909" data-element_type="container">
				<div class="elementor-element elementor-element-1e33c8a elementor-widget elementor-widget-text-editor" data-id="1e33c8a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1>Keycloak Deployment Auditing – General Scope and Guidelines</h1><blockquote><h5 style="text-align: center;">Practical lessons from auditing multi-realm, multi-client Keycloak environments in medium and large organizations</h5></blockquote>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-c9cf0b5 e-con-full e-flex e-con e-child" data-id="c9cf0b5" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-5ee1ead e-flex e-con-boxed e-con e-parent" data-id="5ee1ead" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-99d9ce5 elementor-widget elementor-widget-spacer" data-id="99d9ce5" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-0de96d9 e-flex e-con-boxed e-con e-parent" data-id="0de96d9" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-ecdd67e e-con-full e-flex e-con e-child" data-id="ecdd67e" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-1fed69f e-con-full e-flex e-con e-child" data-id="1fed69f" data-element_type="container">
				<div class="elementor-element elementor-element-c07326c elementor-widget elementor-widget-text-editor" data-id="c07326c" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h2> 1. Introduction</h2><p class="MsoNormal"><span lang="EN-US">In medium and large enterprises, Keycloak deployments rarely follow a simple “one realm – one application” pattern. In reality, such environments typically consist of multiple realms reflecting organizational structures, environments, or business domains, alongside dozens or even hundreds of client applications.</span></p><p class="MsoNormal"><span lang="EN-US"> </span></p><p class="MsoNormal"><span lang="EN-US">These clients often include web frontends, backend services, machine-to-machine integrations, and legacy systems, all maintained by different teams with varying levels of IAM expertise. As a result, Identity and Access Management quickly becomes a shared responsibility rather than a centrally controlled component.</span></p><blockquote><p>“A Keycloak audit is not about verifying settings in the admin console — it is about understanding how identity, applications, and security decisions interact at scale.”</p></blockquote><p class="MsoNormal"><span lang="EN-US">The primary goal of a Keycloak deployment audit is therefore not to “find flaws in Keycloak itself”, but to assess whether the entire authentication and authorization ecosystem is secure, coherent, and aligned with modern OAuth 2.1 and OpenID Connect best practices.</span></p><p class="MsoNormal"><span lang="EN-US"><a href="https://inero-software.com/keycloak-migration-made-easy-tips-and-best-practices/">From our experience auditing complex enterprise IAM landscapes</a>, a comprehensive Keycloak security audit focuses on three complementary objectives:</span></p><ul><li style="list-style-type: none;"><ul><li class="MsoNormal"><span lang="EN-US">evaluating the configuration of the Keycloak Authorization Server,</span></li><li class="MsoNormal"><span lang="EN-US">reviewing how client applications integrate with Keycloak,</span></li><li class="MsoNormal"><span lang="EN-US">identifying security risks emerging from the interaction between both sides.</span></li></ul></li></ul><p class="MsoNormal"><span lang="EN-US"> </span></p><p class="MsoNormal"><span lang="EN-US">This holistic approach is essential, as many real-world security issues do not stem from a single misconfiguration, but from subtle inconsistencies across multiple realms, clients, and applications.</span></p><p class="MsoNormal"><span lang="EN-US"> </span></p><div align="center"> </div>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-311be98 e-con-full e-flex e-con e-child" data-id="311be98" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-79ba960 e-flex e-con-boxed e-con e-parent" data-id="79ba960" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-e28818b e-con-full e-flex e-con e-child" data-id="e28818b" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-ad54fa6 e-con-full e-flex e-con e-child" data-id="ad54fa6" data-element_type="container">
				<div class="elementor-element elementor-element-ff385ae elementor-widget elementor-widget-text-editor" data-id="ff385ae" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p style="text-align: center;"><strong>OVERALL RISK SEVERITY (ORS) MODEL</strong></p><div align="center"><table class="MsoNormalTable" style="width: 423.1pt;" border="1" width="564" cellspacing="0" cellpadding="0"><tbody><tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; height: 12.6pt;"><td style="width: 423.1pt; background: #98afc7; padding: 5.75pt 5.4pt; height: 12.6pt; border: 1.5pt solid #cdcdcd;" colspan="5" width="564"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><b><span lang="EN-US" style="font-family: 'Calibri',sans-serif; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 'Times New Roman'; mso-hansi-theme-font: major-latin; mso-bidi-theme-font: major-latin; color: black;">ORS</span></b></p></td></tr><tr style="mso-yfti-irow: 1; height: 1.0pt;"><td style="width: 85.85pt; border-right: 1.5pt solid #cdcdcd; border-bottom: 1.5pt solid #cdcdcd; border-left: 1.5pt solid #cdcdcd; border-top-width: initial; border-top-style: none; padding: 5.75pt 5.4pt; height: 1pt;" rowspan="4" width="114"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><b><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; color: black;">Impact</span></b></p></td><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: #98afc7; padding: 5.75pt 5.4pt; height: 1pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; color: black;">HIGH</span></p></td><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: orange; padding: 5.75pt 5.4pt; height: 1pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="font-family: 'Calibri',sans-serif; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 'Times New Roman'; mso-hansi-theme-font: major-latin; mso-bidi-theme-font: major-latin; color: black;">Medium</span></p></td><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: red; padding: 5.75pt 5.4pt; height: 1pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="font-family: 'Calibri',sans-serif; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 'Times New Roman'; mso-hansi-theme-font: major-latin; mso-bidi-theme-font: major-latin; color: black;">High</span></p></td><td style="width: 79.55pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: pink; padding: 5.75pt 5.4pt; height: 1pt; border-width: initial 1.5pt 1.5pt initial;" width="106"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; color: black;">Critical</span></p></td></tr><tr style="mso-yfti-irow: 2; height: 9.3pt;"><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: #98afc7; padding: 5.75pt 5.4pt; height: 9.3pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; color: black;">MEDIUM</span></p></td><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: yellow; padding: 5.75pt 5.4pt; height: 9.3pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="font-family: 'Calibri',sans-serif; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 'Times New Roman'; mso-hansi-theme-font: major-latin; mso-bidi-theme-font: major-latin; color: black;">Low</span></p></td><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: orange; padding: 5.75pt 5.4pt; height: 9.3pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="font-family: 'Calibri',sans-serif; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 'Times New Roman'; mso-hansi-theme-font: major-latin; mso-bidi-theme-font: major-latin; color: black;">Medium</span></p></td><td style="width: 79.55pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: red; padding: 5.75pt 5.4pt; height: 9.3pt; border-width: initial 1.5pt 1.5pt initial;" width="106"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; color: black;">High</span></p></td></tr><tr style="mso-yfti-irow: 3; height: 2.1pt;"><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: #98afc7; padding: 5.75pt 5.4pt; height: 2.1pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; color: black;">LOW</span></p></td><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: lightgreen; padding: 5.75pt 5.4pt; height: 2.1pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="font-family: 'Calibri',sans-serif; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 'Times New Roman'; mso-hansi-theme-font: major-latin; mso-bidi-theme-font: major-latin; color: black;">Note</span></p></td><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: yellow; padding: 5.75pt 5.4pt; height: 2.1pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="font-family: 'Calibri',sans-serif; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 'Times New Roman'; mso-hansi-theme-font: major-latin; mso-bidi-theme-font: major-latin; color: black;">Low</span></p></td><td style="width: 79.55pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: orange; padding: 5.75pt 5.4pt; height: 2.1pt; border-width: initial 1.5pt 1.5pt initial;" width="106"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; color: black;">Medium</span></p></td></tr><tr style="mso-yfti-irow: 4; height: 1.0pt;"><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: #98afc7; padding: 5.75pt 5.4pt; height: 1pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; color: black;"> </span></p></td><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: #98afc7; padding: 5.75pt 5.4pt; height: 1pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="font-family: 'Calibri',sans-serif; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 'Times New Roman'; mso-hansi-theme-font: major-latin; mso-bidi-theme-font: major-latin; color: black;">LOW</span></p></td><td style="width: 85.9pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: #98afc7; padding: 5.75pt 5.4pt; height: 1pt; border-width: initial 1.5pt 1.5pt initial;" width="115"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="font-family: 'Calibri',sans-serif; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 'Times New Roman'; mso-hansi-theme-font: major-latin; mso-bidi-theme-font: major-latin; color: black;">MEDIUM</span></p></td><td style="width: 79.55pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; background: #98afc7; padding: 5.75pt 5.4pt; height: 1pt; border-width: initial 1.5pt 1.5pt initial;" width="106"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; color: black;">HIGH</span></p></td></tr><tr style="mso-yfti-irow: 5; mso-yfti-lastrow: yes; height: .9pt;"><td style="width: 85.85pt; border-style: none solid none none; border-right-color: #cdcdcd; padding: 5.75pt 5.4pt; height: 0.9pt; border-width: initial 1.5pt initial initial;" width="114"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; color: black;"> </span></p></td><td style="width: 337.25pt; border-style: none solid solid none; border-bottom-color: #cdcdcd; border-right-color: #cdcdcd; padding: 5.75pt 5.4pt; height: 0.9pt; border-width: initial 1.5pt 1.5pt initial;" colspan="4" width="450"><p class="MsoNormal" style="margin-bottom: 0cm; text-align: center; line-height: normal;" align="center"><b><span lang="EN-US" style="font-family: 'Calibri',sans-serif; mso-ascii-theme-font: major-latin; mso-fareast-font-family: 'Times New Roman'; mso-hansi-theme-font: major-latin; mso-bidi-theme-font: major-latin; color: black;">Likelihood</span></b></p></td></tr></tbody></table><p class="MsoNormal"> </p></div>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-4ca23e0 e-con-full e-flex e-con e-child" data-id="4ca23e0" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-f5cdcc2 e-flex e-con-boxed e-con e-parent" data-id="f5cdcc2" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-25853b2 e-con-full e-flex e-con e-child" data-id="25853b2" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-cc333e3 e-con-full e-flex e-con e-child" data-id="cc333e3" data-element_type="container">
				<div class="elementor-element elementor-element-205a0d1 elementor-widget elementor-widget-text-editor" data-id="205a0d1" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p class="MsoNormal"><span lang="EN-US"> To prioritize findings in a meaningful and actionable way, audit results are typically classified using a risk-based approach inspired by OWASP methodologies. Each finding is evaluated as a combination of:</span></p><ul><li style="list-style-type: none;"><ul><li class="MsoNormal"> likelihood of exploitation, </li><li class="MsoNormal">potential impact on confidentiality, integrity, and availability.</li></ul></li></ul><p class="MsoNormal"><span lang="EN-US"> </span></p><p class="MsoNormal"><span lang="EN-US">This allows organizations to distinguish between:</span></p><ul><li style="list-style-type: none;"><ul><li class="MsoNormal"> critical risks with immediate business impact, </li><li class="MsoNormal">medium and low risks related to configuration hardening and attack surface reduction,</li><li class="MsoNormal"> best-practice recommendations aimed at long-term security maturity.</li></ul></li></ul>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-75921b3 e-con-full e-flex e-con e-child" data-id="75921b3" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-946a336 e-flex e-con-boxed e-con e-parent" data-id="946a336" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-e26da36 elementor-widget elementor-widget-spacer" data-id="e26da36" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-fde5878 e-flex e-con-boxed e-con e-parent" data-id="fde5878" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-90ba2d6 e-con-full e-flex e-con e-child" data-id="90ba2d6" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-b22a03b e-con-full e-flex e-con e-child" data-id="b22a03b" data-element_type="container">
				<div class="elementor-element elementor-element-69899c9 elementor-widget elementor-widget-text-editor" data-id="69899c9" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h3><span lang="EN-US">Keycloak-side</span><b><span lang="EN-US"> audit – known patterns, real-world consequences</span></b></h3><p><b><span lang="EN-US"> </span></b></p><p class="MsoNormal"><span lang="EN-US"><a href="https://inero-software.com/best-keycloak-practices/">Configuration aspects of Keycloak itself are well documented and widely discussed in official  documentation and community guidelines</a>. Nevertheless, real-world audits of large-scale deployments consistently reveal recurring issues such as:</span></p><ul><li style="list-style-type: none;"><ul><li class="MsoNormal"><span lang="EN-US">lack of regular realm key rotation,</span></li><li class="MsoNormal"><span lang="EN-US">missing client secret rotation,</span></li><li class="MsoNormal"><span lang="EN-US">overly permissive redirect URIs and web origins,</span></li><li class="MsoNormal"><span lang="EN-US">unused but enabled service accounts,</span></li><li class="MsoNormal"><span lang="EN-US">globally enabled “full scope allowed” settings,</span></li><li class="MsoNormal"><span lang="EN-US">deprecated direct access grants left active,</span></li><li class="MsoNormal"><span lang="EN-US">missing or inconsistent enforcement of PKCE.</span></li></ul></li></ul><p class="MsoNormal"><span lang="EN-US"> </span></p><blockquote><p class="MsoNormal"><span lang="EN-US">While these topics are well known, they are worth revisiting from an operational perspective. In large, multi-realm Keycloak deployments, even seemingly minor configuration oversights can accumulate and significantly increase the overall attack surface.</span></p></blockquote>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-9503a76 e-con-full e-flex e-con e-child" data-id="9503a76" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-1e30445 e-flex e-con-boxed e-con e-parent" data-id="1e30445" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-149bd34 elementor-widget elementor-widget-spacer" data-id="149bd34" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-c9c066d e-flex e-con-boxed e-con e-parent" data-id="c9c066d" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-e1250b7 elementor-widget elementor-widget-spacer" data-id="e1250b7" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-dc00e5e e-flex e-con-boxed e-con e-parent" data-id="dc00e5e" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-db7a09c e-con-full e-flex e-con e-child" data-id="db7a09c" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-6f60a0d e-con-full e-flex e-con e-child" data-id="6f60a0d" data-element_type="container">
				<div class="elementor-element elementor-element-06970d8 elementor-widget elementor-widget-text-editor" data-id="06970d8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h2 class="MsoNormal"><span lang="EN-US">2. Client-side audit – where the highest risks emerge</span></h2><p>From a security standpoint, the most sensitive and often underestimated part of a Keycloak deployment is the client application layer. Even a well-configured Authorization Server cannot compensate for insecure client-side implementations.</p><blockquote><p>“In real-world Keycloak deployments, the most critical security risks rarely originate in the IAM platform itself — they emerge at the client application layer.”</p></blockquote><p>In practice, the most severe findings during Keycloak audits are almost always related to how applications consume tokens, validate authentication state, and handle sensitive data after a successful login.</p><h5> </h5><h5>Missing token validation in client applications</h5><p>One of the most critical issues observed in enterprise environments is incomplete or missing access token validation on the application side. This includes scenarios where:</p><ul><li style="list-style-type: none;"><ul><li>endpoints do not verify authentication at all,</li><li>token signatures or claims are not fully validated,</li><li>authorization checks are inconsistently applied across APIs.</li></ul></li></ul><p>Such vulnerabilities effectively bypass Keycloak entirely, allowing attackers to interact directly with application endpoints without compromising the IAM platform itself.</p><h5> </h5><h5>Insecure token storage and handling</h5><p>Another high-impact issue involves improper handling of access tokens within client applications. Common anti-patterns include:</p><ul><li style="list-style-type: none;"><ul><li>storing tokens in cookies without Secure or HttpOnly flags,</li><li>persisting tokens in local or session storage,</li><li>sharing tokens across application components in a durable form.</li></ul></li></ul><p>In browser-based applications, these practices dramatically increase exposure to XSS attacks and session hijacking. From an architectural perspective, this is an application design flaw rather than a Keycloak configuration issue.</p><h5> </h5><h5>Token transmission via URLs</h5><p>Despite being widely discouraged, access tokens are still occasionally transmitted through URL query parameters or redirects, especially in legacy systems. This practice poses a severe security risk, as tokens may be exposed through:</p><ul><li style="list-style-type: none;"><ul><li>browser history,</li><li>server and proxy logs,</li><li>monitoring and analytics tools,</li><li>third-party integrations.</li></ul></li></ul><p>In multi-application IAM environments, such leakage can have cascading effects across multiple systems.</p><h5> </h5><h5>Incomplete PKCE or nonce support</h5><p>Some client applications technically use the Authorization Code Flow, but fail to:</p><ul><li style="list-style-type: none;"><ul><li>properly implement PKCE,</li><li>validate nonce values,</li><li>or explicitly enforce secure defaults in client libraries.</li></ul></li></ul><p>In complex deployments with numerous redirect paths and client types, this significantly increases the risk of authorization code injection attacks, even when Keycloak itself is correctly configured.</p><p>Missing security headers and improper cookie configuration</p><p>Finally, many audited applications lack basic web security hardening measures such as:</p><ul><li style="list-style-type: none;"><ul><li>Content-Security-Policy (CSP),</li><li>HTTP Strict Transport Security (HSTS),</li><li>properly configured SameSite cookie attributes.</li></ul></li></ul><p> </p><p><strong>These controls are not managed by Keycloak, yet they play a crucial role in protecting authentication flows and user sessions at the application level.</strong></p>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-3af0d31 e-con-full e-flex e-con e-child" data-id="3af0d31" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-aab7bdc e-flex e-con-boxed e-con e-parent" data-id="aab7bdc" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-d4b4986 elementor-widget elementor-widget-spacer" data-id="d4b4986" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-4273c47 e-flex e-con-boxed e-con e-parent" data-id="4273c47" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-449f2ba e-con-full e-flex e-con e-child" data-id="449f2ba" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-978d452 e-con-full e-flex e-con e-child" data-id="978d452" data-element_type="container">
				<div class="elementor-element elementor-element-604823d elementor-widget elementor-widget-text-editor" data-id="604823d" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h2>Summary</h2><p>Auditing a Keycloak deployment in an enterprise environment requires looking far beyond realm and client configuration screens. While proper Keycloak hardening is essential, the highest security risks typically arise from insecure client-side implementations and architectural decisions.</p><p> </p><blockquote><p>“Keycloak can be hardened perfectly, yet the overall security posture will always be defined by the weakest client application integrated with it.”</p></blockquote><p> </p><p>Based on practical audit experience in large, multi-realm Keycloak environments:</p><ul><li style="list-style-type: none;"><ul><li>the most critical vulnerabilities emerge at the intersection of Keycloak and client applications,</li><li>correct IAM configuration does not mitigate insecure application behavior,</li><li>many high-impact issues can be resolved without changes to Keycloak itself, by improving application architecture and integration patterns.</li></ul></li></ul><p> </p><p>A well-executed Keycloak security audit helps organizations reduce attack surface, standardize IAM integrations, and safely scale their identity infrastructure across teams, environments, and business units.</p><p> </p><p>In large organizations, Keycloak effectively becomes the backbone of digital identity — and its real security strength is determined by the weakest link in the surrounding application ecosystem.</p>						</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-ed20b07 e-con-full e-flex e-con e-child" data-id="ed20b07" data-element_type="container">
				</div>
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/keycloak-deployment-auditing-general-scope-and-guidelines/">Keycloak Deployment Auditing – General Scope and Guidelines</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8306</post-id>	</item>
		<item>
		<title>Secure Email Delivery in Keycloak 26.2 Using XOAUTH2</title>
		<link>https://inero-software.com/secure-email-delivery-in-keycloak-26-2-using-xoauth2/</link>
		
		<dc:creator><![CDATA[Andrzej Chybicki]]></dc:creator>
		<pubDate>Mon, 15 Sep 2025 10:48:22 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[keycloak]]></category>
		<category><![CDATA[Multi-Factor Authentication]]></category>
		<category><![CDATA[SMTP]]></category>
		<category><![CDATA[XOAUTH2]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=8141</guid>

					<description><![CDATA[<p>Secure Email Delivery in Keycloak 26.2 Using XOAUTH2 Email has been one of the oldest and most fundamental services on the internet, used for notifications, password resets, verifications, and more. Over time we’ve seen major improvements — encryption via TLS, then STARTTLS, and now many providers are moving away from&#8230;</p>
<p>Artykuł <a href="https://inero-software.com/secure-email-delivery-in-keycloak-26-2-using-xoauth2/">Secure Email Delivery in Keycloak 26.2 Using XOAUTH2</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="8141" class="elementor elementor-8141" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-bb57bd9 e-flex e-con-boxed e-con e-parent" data-id="bb57bd9" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-437b6d1 elementor-widget elementor-widget-spacer" data-id="437b6d1" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-db34a4b e-flex e-con-boxed e-con e-parent" data-id="db34a4b" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-641bb6a elementor-widget elementor-widget-spacer" data-id="641bb6a" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-50bb99f e-flex e-con-boxed e-con e-parent" data-id="50bb99f" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-4a41088 elementor-widget elementor-widget-text-editor" data-id="4a41088" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1>Secure Email Delivery in Keycloak 26.2 Using XOAUTH2</h1><p>Email has been one of the oldest and most fundamental services on the internet, used for notifications, password resets, verifications, and more. Over time we’ve seen major improvements — encryption via TLS, then STARTTLS, and now many providers are moving away from basic password authentication in favor of modern token-based schemes like XOAUTH2. With Keycloak 26.2, this evolution has arrived: Keycloak now supports XOAUTH2 for outgoing SMTP mail, adding greater security and compatibility with providers who have deprecated legacy authentication</p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-8c716d3 e-flex e-con-boxed e-con e-parent" data-id="8c716d3" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-45fb36f elementor-widget elementor-widget-spacer" data-id="45fb36f" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-b657726 e-flex e-con-boxed e-con e-parent" data-id="b657726" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-a743437 elementor-widget elementor-widget-text-editor" data-id="a743437" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h2>1. What is XOAUTH2, and Why It Matters</h2><p>XOAUTH2 is a means of authenticating to an SMTP (or other email-sending) server using an OAuth2 access token rather than a username + password. Some of the key benefits include:</p><ul><li style="list-style-type: none;"><ul><li>Improved Security: Tokens can be more tightly controlled, with limited scope and lifetime.</li><li>Compliance with Modern Providers: Many providers are disabling basic auth.</li><li>Centralised and Auditable Auth: Easier management and rotation. Each client&#8217;s access can be revoked independently of other clients&#8217; operations.</li><li>Reduced Risk of Credential Leakage: No raw passwords stored or transmitted.</li></ul></li></ul>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-49d6f0b e-flex e-con-boxed e-con e-parent" data-id="49d6f0b" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-761d03b elementor-widget elementor-widget-spacer" data-id="761d03b" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-cac6421 e-flex e-con-boxed e-con e-parent" data-id="cac6421" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-dc1c0d3 elementor-widget elementor-widget-text-editor" data-id="dc1c0d3" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h2>2. How XOAUTH2 is Implemented in Keycloak 26.2</h2><p>With version 26.2, Keycloak adds native support for XOAUTH2 when sending emails via SMTP. This means administrators can move away from static username and password credentials and instead configure Keycloak to obtain an OAuth2 access token at runtime.</p><p>In the Admin Console under Realm → Realm Settings → Email, you can now switch the Authentication Type from Password to Token (XOAUTH2). Once enabled, additional fields appear where you provide:</p><p>&#8211; Client ID and Client Secret from your identity provider (e.g., Azure AD).<br />&#8211; The OAuth2 Token Endpoint used to request an access token.<br />&#8211; Optional Scopes, depending on your provider (for Microsoft 365: https://outlook.office365.com/.default).<br />&#8211; A From address / SMTP username, which may still be required by the mail server.</p><p>Keycloak then handles the process of requesting and refreshing tokens using the Client Credentials Grant flow. You can use the “Test connection” button to verify that the configuration is correct and that emails can be sent successfully.</p><p>This approach aligns Keycloak with modern security standards and prepares deployments for providers that are phasing out legacy authentication.</p><p><img decoding="async" data-attachment-id="8207" data-permalink="https://inero-software.com/image-12/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/09/image-12.png" data-orig-size="1235,1095" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="image (12)" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/09/image-12-300x266.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/09/image-12-1030x913.png" tabindex="0" role="button" class="aligncenter wp-image-8207 size-large" src="https://inero-software.com/wp-content/uploads/2025/09/image-12-1030x913.png" alt="" width="1030" height="913" srcset="https://inero-software.com/wp-content/uploads/2025/09/image-12-1030x913.png 1030w, https://inero-software.com/wp-content/uploads/2025/09/image-12-300x266.png 300w, https://inero-software.com/wp-content/uploads/2025/09/image-12-768x681.png 768w, https://inero-software.com/wp-content/uploads/2025/09/image-12-338x300.png 338w, https://inero-software.com/wp-content/uploads/2025/09/image-12.png 1235w" sizes="(max-width: 1030px) 100vw, 1030px" /></p><p><strong data-start="0" data-end="9" data-is-only-node="">Note:</strong> The <strong data-start="14" data-end="35">Enable Debug SMTP</strong> option (visible at the bottom of the form) activates extended logging for outgoing email. When enabled, Keycloak produces detailed debug output of the SMTP communication, which can be very useful for diagnosing integration issues such as authentication failures, token retrieval problems, or TLS misconfigurations. It is recommended to use this setting only in testing or troubleshooting scenarios, as it may expose sensitive information in the logs.</p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-2e4203c e-flex e-con-boxed e-con e-parent" data-id="2e4203c" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-44a4294 elementor-widget elementor-widget-spacer" data-id="44a4294" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-94072c9 e-flex e-con-boxed e-con e-parent" data-id="94072c9" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-802a36b elementor-widget__width-inherit elementor-invisible elementor-widget elementor-widget-text-editor" data-id="802a36b" data-element_type="widget" data-settings="{&quot;_animation&quot;:&quot;fadeIn&quot;}" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h4 style="text-align: center;"><span style="color: #431773;">Retirement of Basic Authentication for SMTP AUTH (Client Submission) in Exchange Online</span></h4>						</div>
				</div>
				<div class="elementor-element elementor-element-5f3b86e elementor-widget elementor-widget-spacer" data-id="5f3b86e" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-86a8aa1 e-flex e-con-boxed e-con e-parent" data-id="86a8aa1" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-2b76e0f elementor-widget elementor-widget-spacer" data-id="2b76e0f" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-04082db e-flex e-con-boxed e-con e-parent" data-id="04082db" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-7185a3d elementor-countdown--label-inline elementor-widget elementor-widget-countdown" data-id="7185a3d" data-element_type="widget" data-settings="{&quot;motion_fx_motion_fx_scrolling&quot;:&quot;yes&quot;,&quot;motion_fx_devices&quot;:[&quot;desktop&quot;,&quot;tablet&quot;,&quot;mobile&quot;]}" data-widget_type="countdown.default">
				<div class="elementor-widget-container">
					<div class="elementor-countdown-wrapper" data-date="1772319600">
			<div class="elementor-countdown-item"><span class="elementor-countdown-digits elementor-countdown-days"></span> <span class="elementor-countdown-label">Days</span></div><div class="elementor-countdown-item"><span class="elementor-countdown-digits elementor-countdown-hours"></span> <span class="elementor-countdown-label">Hours</span></div>		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-846c707 e-flex e-con-boxed e-con e-parent" data-id="846c707" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-bfa7caf elementor-widget elementor-widget-spacer" data-id="bfa7caf" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-0aa70e1 e-flex e-con-boxed e-con e-parent" data-id="0aa70e1" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-1d91819 elementor-widget elementor-widget-text-editor" data-id="1d91819" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h2>3. Why This Matters for Microsoft Azure / Office 365 Users</h2><blockquote><p>Microsoft has announced the retirement of Basic Authentication for SMTP AUTH (Client Submission) in Exchange Online. Starting March 1, 2026, Microsoft will begin phasing out Basic Auth, and by April 30, 2026, it will be completely disabled. This change directly impacts Keycloak deployments where outgoing emails are sent via Office 365 / Exchange Online SMTP.</p></blockquote><p>If your Keycloak instance is still configured with a username and password for SMTP, it will stop working once Basic Auth is retired. The solution is to migrate to XOAUTH2 configuration in Keycloak 26.2.</p><p>By adopting XOAUTH2, you ensure:</p><ul><li style="list-style-type: none;"><ul><li>Continued compatibility with Microsoft email services</li><li>Stronger security and compliance</li><li>Reduced risk compared to static credentials</li></ul></li></ul>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-8ef377e e-flex e-con-boxed e-con e-parent" data-id="8ef377e" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-126b40c elementor-widget elementor-widget-spacer" data-id="126b40c" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-0cdb0ae e-flex e-con-boxed e-con e-parent" data-id="0cdb0ae" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-8707cdb elementor-widget elementor-widget-text-editor" data-id="8707cdb" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h2><b data-stringify-type="bold">4. Beyond XOAUTH2?</b></h2><p>There’s even more going on in modern email delivery. Many email delivery platforms steer away from traditional SMTP protocol towards API-based approach (e.g. MailJet, SendGrid or MailGun). This gives more flexibility to integrators and allows platform providers to offer additional features. API-based email sending is not jet supported by Keycloak out-of-the-box, but this support can be added via custom extensions. Contact us if you are interested in integrating Keycloak with API-based email delivery platforms.</p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-cc7f0e5 e-flex e-con-boxed e-con e-parent" data-id="cc7f0e5" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-cbe5851 elementor-widget elementor-widget-spacer" data-id="cbe5851" data-element_type="widget" data-widget_type="spacer.default">
				<div class="elementor-widget-container">
					<div class="elementor-spacer">
			<div class="elementor-spacer-inner"></div>
		</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-edbac9e e-flex e-con-boxed e-con e-parent" data-id="edbac9e" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-121b9ff elementor-widget elementor-widget-text-editor" data-id="121b9ff" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h2>Conclusion</h2><p>The addition of XOAUTH2 support in Keycloak 26.2 is more than just a feature upgrade — it’s an essential step for organizations that rely on Office 365, Gmail, or other providers who are deprecating legacy authentication. By adopting XOAUTH2 today, you can future-proof your Keycloak deployment, comply with provider requirements, and improve overall email security.</p>						</div>
				</div>
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/secure-email-delivery-in-keycloak-26-2-using-xoauth2/">Secure Email Delivery in Keycloak 26.2 Using XOAUTH2</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8141</post-id>	</item>
		<item>
		<title>Keycloak or SaaS IdP? A Tech Leader’s Guide to Making the Right IAM Choice</title>
		<link>https://inero-software.com/keycloak-or-saas-idp-a-tech-leaders-guide-to-making-the-right-iam-choice/</link>
		
		<dc:creator><![CDATA[Andrzej Chybicki]]></dc:creator>
		<pubDate>Thu, 24 Jul 2025 07:45:53 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[Technology]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=8063</guid>

					<description><![CDATA[<p>Introduction Shipping single sign‑on quickly is tempting. Stakeholders push for a smooth login experience, developers want to move on to core features, and security teams are eager to tick the “MFA enabled” box. The trouble is that identity and access management (IAM) decisions outlive launch days. Once you choose a&#8230;</p>
<p>Artykuł <a href="https://inero-software.com/keycloak-or-saas-idp-a-tech-leaders-guide-to-making-the-right-iam-choice/">Keycloak or SaaS IdP? A Tech Leader’s Guide to Making the Right IAM Choice</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="8063" class="elementor elementor-8063" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-dd2241f e-flex e-con-boxed e-con e-parent" data-id="dd2241f" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-7a92edd e-con-full e-flex e-con e-child" data-id="7a92edd" data-element_type="container">
				<div class="elementor-element elementor-element-92153e6 elementor-widget elementor-widget-text-editor" data-id="92153e6" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1><span lang="EN-US">Introduction</span></h1><p class="MsoNormal"><span lang="EN-US">Shipping single sign‑on quickly is tempting. Stakeholders push for a smooth login experience, developers want to move on to core features, and security teams are eager to tick the “MFA enabled” box. The trouble is that identity and access management (IAM) decisions outlive launch days. Once you choose a platform, you inherit its operational model, cost structure and compliance implications for years.</span></p><p class="MsoNormal"><span lang="EN-US">In this blogpost we provide technical leads some few crucial issues when evaluating Keycloak—an open‑source IAM platform that has become a go‑to choice in many Java and cloud‑native environments. Rather than a hands‑on tutorial, you’ll get a decision framework that starts with business realities. We’ll walk through seven questions that determine whether Keycloak fits your context. For each, you’ll see why it matters, how to assess it, the red flags to watch for, and a concrete deliverable to capture the outcome.</span></p><p class="MsoNormal"><span lang="EN-US">By the end, you’ll fill in a short scorecard and see if your organization toward Keycloak, a commercial SaaS IdP (Auth0, Okta, Azure AD B2C, etc.), or a hybrid path. If you want a sanity check, we offer a free 45‑minute Keycloak readiness consultation—no slides, just practical advice.</span></p><p class="MsoNormal"><span lang="EN-US"> </span></p>						</div>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-1c3872c e-flex e-con-boxed e-con e-parent" data-id="1c3872c" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-ac23027 e-flex e-con-boxed e-con e-child" data-id="ac23027" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-f2b969a elementor-widget elementor-widget-text-editor" data-id="f2b969a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1><span lang="EN-US">Where Keycloak Lives in Your Stack</span></h1><p class="MsoNormal"><span lang="EN-US">Keycloak usually sits between your user‑facing applications and the identity sources they rely on. Applications delegate authentication and authorization to Keycloak. Keycloak can manage users internally or federate with LDAP/Active Directory. It also exposes logs and metrics that feed your SIEM and monitoring stack. Even if this picture seems obvious to engineers, spelling it out helps align legal, compliance and product stakeholders on who owns what.</span></p>						</div>
				</div>
					</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-926763e e-flex e-con-boxed e-con e-parent" data-id="926763e" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-c0f0f10 elementor-widget elementor-widget-image" data-id="c0f0f10" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img decoding="async" data-attachment-id="8093" data-permalink="https://inero-software.com/keycloak-or-saas-idp-a-tech-leaders-guide-to-making-the-right-iam-choice/keycloak_diagram/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-scaled.png" data-orig-size="2560,1777" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="KeyCloak_Diagram" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-300x208.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-1030x715.png" tabindex="0" role="button" width="768" height="533" src="https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-768x533.png" class="attachment-medium_large size-medium_large wp-image-8093" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-768x533.png 768w, https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-300x208.png 300w, https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-1030x715.png 1030w, https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-1536x1066.png 1536w, https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-2048x1422.png 2048w, https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-432x300.png 432w" sizes="(max-width: 768px) 100vw, 768px" data-attachment-id="8093" data-permalink="https://inero-software.com/keycloak-or-saas-idp-a-tech-leaders-guide-to-making-the-right-iam-choice/keycloak_diagram/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-scaled.png" data-orig-size="2560,1777" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="KeyCloak_Diagram" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-300x208.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/07/KeyCloak_Diagram-1030x715.png" role="button" />													</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-02b5497 e-flex e-con-boxed e-con e-parent" data-id="02b5497" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-1b72159 elementor-widget elementor-widget-text-editor" data-id="1b72159" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1><span lang="EN-US">Keycloak in a Nutshell (and Two Misconceptions)</span></h1><p class="MsoNormal"><span lang="EN-US">Keycloak is an open‑source IAM server supporting OIDC, SAML, MFA, theming and an extension model (SPIs). Originally developed by Red Hat, it now thrives under a large community.</span></p><p class="MsoNormal"><span lang="EN-US">Misconception #1: “Open source = free to run”. The software is free, but production IAM also needs infrastructure, monitoring, upgrades and people. Misconception #2: “It’s just for developers”. In reality, without governance and processes, any IAM platform becomes a liability.</span></p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-934ad5e e-flex e-con-boxed e-con e-parent" data-id="934ad5e" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-26d21cd elementor-widget elementor-widget-text-editor" data-id="26d21cd" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1 style="font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal;"><span lang="EN-US">Seven Questions to Frame the Decision</span></h1><div style="font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; font-size: 14px; font-family: Roboto, sans-serif;"><span lang="EN-US"> </span></div><p style="font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; font-size: 14px; font-family: Roboto, sans-serif;"><span lang="EN-US">Treat these questions as a workshop agenda, not a checklist. Bring security, operations, product and finance to the same table. The goal is to leave each session with an artifact that informs budgeting, architecture and planning.</span></p><p style="font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; font-size: 14px; font-family: Roboto, sans-serif;"><span lang="EN-US"> </span></p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-6beb500 e-flex e-con-boxed e-con e-parent" data-id="6beb500" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-a4797f7 elementor-widget elementor-widget-text-editor" data-id="a4797f7" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h2>1. Compliance &amp; Risk: Do You Need Full Control Over IAM?</h2>
<p class="MsoNormal"><span lang="EN-US">Regulatory frameworks such as NIS2 or&nbsp;GDPR—and sector standards like PCI DSS or HIPAA—often demand demonstrable&nbsp;control over identities, audit trails and incident response. If auditors expect&nbsp;you to produce detailed logs or prove exactly who changed what, a black‑box&nbsp;SaaS can create friction&nbsp;</span></p>
<p class="MsoNormal"><span lang="EN-US">List the controls and evidence you must&nbsp;provide. Do you need to host IAM in a specific region?&nbsp;</span></p>
<p class="MsoNormal"><span lang="EN-US">How quickly must you&nbsp;produce logs? Are you required to approve every policy change?&nbsp;</span></p>
<p class="MsoNormal"><span lang="EN-US">If many answers&nbsp;point to tight control, Keycloak’s self‑hosted nature becomes an advantage.</span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoNormal"><span lang="EN-US">The biggest red flag is deferring&nbsp;compliance: “we’ll pass audits later”. Another is that nobody owns IAM data&nbsp;retention or log policies.</span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;</span></p>
<p class="MsoNormal"><span lang="EN-US"><b>Deliverable</b>: a compliance checklist mapped&nbsp;to IAM features and governance processes.</span></p>
<h2><span lang="EN-US">2. Integration Map: How Many Apps and Protocols Today—and in<br>Two Years?</span></h2>
<p><span lang="EN-US">Integration effort—not software&nbsp;choice—usually drives project cost and timeline. Keycloak handles&nbsp;OIDC/SAML/LDAP well, but legacy systems and partner constraints can complicate<br>the picture.&nbsp;</span>Inventory every application that authenticates users. Classify by protocol, business criticality and migration difficulty. Project changes over the next 24 months: new products,</p>
<p><span lang="EN-US">acquisitions, vendor switches.&nbsp;</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><b>Red flags</b>: no authoritative app inventory; underestimating testing for each integration.</p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Deliverable</b>: a prioritized integration&nbsp;backlog with rough sizing.</span></p>
<h2><span lang="EN-US">3. Team &amp; Operations Capacity: Can You Secure and Run It<br>24/7 (or Outsource)?</span></h2>
<p><span lang="EN-US">IAM outages stop business. Someone must&nbsp;patch, monitor, respond to incidents and plan upgrades. Decide whether your&nbsp;DevOps/SecOps team can own this or you’ll offload parts to a partner.</span></p>
<p><span lang="EN-US">Assess on‑call capacity, automation&nbsp;maturity, security expertise. Define SLAs, RTO/RPO. Consider managed services&nbsp;for routine ops while retaining architectural control&nbsp;</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Red flags</b>: a single overworked DevOps, lack&nbsp;of monitoring/alerting, no upgrade plan.</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Deliverable</b>: a RACI matrix for IAM&nbsp;operations and an initial ops budget.</span></p>
<h2><span lang="EN-US">4. Customization Needs: Themes, Extensions and Advanced<br>Authorization</span></h2>
<p><span lang="EN-US">Keycloak’s extensibility is a major&nbsp;advantage: custom authenticators, advanced policies (ABAC), branded login flows, phishing‑resistant UX. If differentiation or strict UX/security is a<br>requirement, flexibility matters.</span></p>
<p><span lang="EN-US">Gauge UX/theming demands, multilingual support, accessibility, device trust, passkeys, fine‑grained authorization.Each adds value to an extensible platform.</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Red flags</b>: assuming the default theme is&nbsp;enough; ignoring SPI development complexity.</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Deliverable</b>: a customization backlog with&nbsp;effort estimates and ownership.</span></p>
<h2><span lang="EN-US">5. Scalability &amp; High Availability: What Are Your Peak<br>Loads and DR Needs?</span></h2>
<p><span lang="EN-US">If login fails, revenue stops. HA/DR design&nbsp;impacts infrastructure cost and complexity. You need clarity on peaks,&nbsp;acceptable downtime and recovery objectives.</span></p>
<p><span lang="EN-US">Estimate peak concurrent logins (launch&nbsp;days, campaigns). Define RTO/RPO. Choose between VM clusters or Kubernetes with&nbsp;an operator. Decide on multi‑region strategies.</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Red flags</b>: “we’ll scale later”, skipping DR tests entirely.</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Deliverable</b>: an HA/DR architecture option&nbsp;matrix with pros, cons and cost</span></p>
<p><span lang="EN-US">.</span></p>
<h2><span lang="EN-US">6. Budget &amp; TCO: What Does Three Years Really Cost vs<br>SaaS?</span></h2>
<p><span lang="EN-US">Keycloak costs = infra + people +&nbsp;consulting. SaaS costs = subscriptions + add‑ons + overage fees.</span></p>
<p><span lang="EN-US">Only a 3‑year&nbsp;TCO model reveals the truth.</span></p>
<p><span lang="EN-US">Build a spreadsheet covering infra,&nbsp;backups, monitoring, labor, upgrades. Do the same for SaaS: MAU fees, advanced features, support tiers. Stress‑test both with growth scenarios.</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Red flags</b>: ignoring people costs, assuming&nbsp;maintenance is free, overlooking SaaS overage triggers.</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Deliverable</b>: a TCO calculator you can keep&nbsp;updating as data changes.</span></p>
<h2><span lang="EN-US">7. Vendor Lock‑In &amp; Roadmap Control: How Much Flexibility<br>Do You Need?</span></h2>
<p><span lang="EN-US">Open source gives you architectural&nbsp;freedom. SaaS gives you speed but ties you to someone else’s roadmap and&nbsp;pricing. Sometimes that’s fine; sometimes it’s a risk.</span></p>
<p><span lang="EN-US">Map likely IAM needs for 2–3 years. How&nbsp;critical is it to add custom flows quickly or hold back an upgrade? Could&nbsp;pricing shifts hurt you?</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Red flag</b>: &#8216;we’ll never need to extend&#8217;.<br>Organizations evolve and regulations shift.</span></p>
<p><span lang="EN-US">&nbsp;</span></p>
<p><span lang="EN-US"><b>Deliverable</b>: a risk&nbsp;matrix—flexibility/control vs speed/convenience—plotting Keycloak, SaaS and&nbsp;Hybrid for your case.</span></p>
<p><span lang="EN-US">&nbsp;</span></p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-3ff8df0 e-flex e-con-boxed e-con e-parent" data-id="3ff8df0" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-160dc54 elementor-widget elementor-widget-text-editor" data-id="160dc54" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1><span lang="EN-US">A Visual Decision Flow</span></h1><p> </p><p class="MsoNormal"><span lang="EN-US">If your team prefers a diagram to spark discussion, start with the simplified flow below. It nudges you toward Keycloak, SaaS or Hybrid based on the dominant answers. Use it as an icebreaker, not as a final verdict.</span></p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-f7741db e-flex e-con-boxed e-con e-parent" data-id="f7741db" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-19caa3f elementor-widget elementor-widget-image" data-id="19caa3f" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="8083" data-permalink="https://inero-software.com/keycloak-or-saas-idp-a-tech-leaders-guide-to-making-the-right-iam-choice/decisionflowdiagram/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-scaled.png" data-orig-size="2560,1972" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="DecisionFlowDiagram" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-300x231.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-1030x794.png" tabindex="0" role="button" width="768" height="592" src="https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-768x592.png" class="attachment-medium_large size-medium_large wp-image-8083" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-768x592.png 768w, https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-300x231.png 300w, https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-1030x794.png 1030w, https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-1536x1183.png 1536w, https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-2048x1578.png 2048w, https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-389x300.png 389w" sizes="(max-width: 768px) 100vw, 768px" data-attachment-id="8083" data-permalink="https://inero-software.com/keycloak-or-saas-idp-a-tech-leaders-guide-to-making-the-right-iam-choice/decisionflowdiagram/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-scaled.png" data-orig-size="2560,1972" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="DecisionFlowDiagram" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-300x231.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/07/DecisionFlowDiagram-1030x794.png" role="button" />													</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-eafdc58 e-flex e-con-boxed e-con e-parent" data-id="eafdc58" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-99e0a6e elementor-widget elementor-widget-text-editor" data-id="99e0a6e" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1><span lang="EN-US">Quantify It: The Scorecard</span></h1><p class="MsoNormal"><span lang="EN-US">To make debates objective, translate the seven questions into numbers. Give each one a score from 1 to 5 (5 means a strong push toward Keycloak). Totals near the high end suggest Keycloak or Hybrid; lower totals suggest SaaS. More important than the number is the conversation it forces: why did we give compliance a 5 but ops capacity a 2?</span></p><table class="MsoNormalTable" style="border-width: initial; border-style: none;" border="1" cellspacing="0" cellpadding="0"><tbody><tr><td style="width: 108pt; padding: 0cm 5.4pt; border: 1pt solid windowtext;" valign="top" width="144"><h5><span lang="EN-US"><b>Question</b></span></h5></td><td style="width: 108pt; border-top: 1pt solid windowtext; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left-width: initial; border-left-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><h5><span lang="EN-US"><b>Score (1–5)</b></span></h5></td><td style="width: 108pt; border-top: 1pt solid windowtext; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left-width: initial; border-left-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><h5><span lang="EN-US"><b>Notes</b></span></h5></td><td style="width: 108pt; border-top: 1pt solid windowtext; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left-width: initial; border-left-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><h5><span lang="EN-US"><b>Leaning</b></span></h5></td></tr><tr><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left: 1pt solid windowtext; border-top-width: initial; border-top-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><pre><span lang="EN-US">Compliance &amp; Risk: Do You Need Full Control Over IAM?</span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left: 1pt solid windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td></tr><tr><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left: 1pt solid windowtext; border-top-width: initial; border-top-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><pre><span lang="EN-US">Integration Map: How Many Apps and Protocols Today—and in Two Years?</span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td></tr><tr><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left: 1pt solid windowtext; border-top-width: initial; border-top-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><pre><span lang="EN-US">Team &amp; Operations Capacity: Can You Secure and Run It 24/7 (or Outsource)?</span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td></tr><tr><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left: 1pt solid windowtext; border-top-width: initial; border-top-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><pre><span lang="EN-US">Customization Needs: Themes, Extensions and Advanced Authorization</span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td></tr><tr><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left: 1pt solid windowtext; border-top-width: initial; border-top-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><pre><span lang="EN-US">Scalability &amp; High Availability: What Are Your Peak Loads and DR Needs?</span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td></tr><tr><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left: 1pt solid windowtext; border-top-width: initial; border-top-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><pre><span lang="EN-US">Budget &amp; TCO: What Does Three Years Really Cost vs SaaS?</span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td></tr><tr><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left: 1pt solid windowtext; border-top-width: initial; border-top-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><pre><span lang="EN-US">Vendor Lock‑In &amp; Roadmap Control: How Much Flexibility Do You Need?</span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"> </span></pre></td></tr><tr><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-left: 1pt solid windowtext; border-top-width: initial; border-top-style: none; padding: 0cm 5.4pt;" valign="top" width="144"><pre><span lang="EN-US"><b>Total / Recommendation</b></span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"><b> </b></span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"><b> </b></span></pre></td><td style="width: 108pt; border-right: 1pt solid windowtext; border-bottom: 1pt solid windowtext; border-bottom-color: windowtext; border-right-color: windowtext; padding: 0cm 5.4pt; border-width: initial 1pt 1pt initial;" valign="top" width="144"><pre><span lang="EN-US"><b>Keycloak / SaaS / Hybrid</b></span></pre></td></tr></tbody></table>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-044e606 e-flex e-con-boxed e-con e-parent" data-id="044e606" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-a55fec5 elementor-widget elementor-widget-text-editor" data-id="a55fec5" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1> </h1><h1 style="font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal;">From Decision to Deployment: A Pragmatic Pipeline</h1><p style="font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 300; font-size: 14px; font-family: Roboto, sans-serif;">Assuming Keycloak is the direction, you still need a process to avoid chaos. We recommend a pipeline that mirrors proven delivery patterns: Discovery → Assessment → Architecture → PoC → Pilot → Production → Operate. Each phase ends with a clear artifact and go/no‑go gate.</p><h1><img loading="lazy" decoding="async" data-attachment-id="8094" data-permalink="https://inero-software.com/keycloak-or-saas-idp-a-tech-leaders-guide-to-making-the-right-iam-choice/oragmatic-pipeline/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/07/Oragmatic-Pipeline.png" data-orig-size="1200,246" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Oragmatic Pipeline" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/07/Oragmatic-Pipeline-300x62.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/07/Oragmatic-Pipeline-1030x211.png" tabindex="0" role="button" class="aligncenter wp-image-8094 size-large" src="https://inero-software.com/wp-content/uploads/2025/07/Oragmatic-Pipeline-1030x211.png" alt="" width="1030" height="211" srcset="https://inero-software.com/wp-content/uploads/2025/07/Oragmatic-Pipeline-1030x211.png 1030w, https://inero-software.com/wp-content/uploads/2025/07/Oragmatic-Pipeline-300x62.png 300w, https://inero-software.com/wp-content/uploads/2025/07/Oragmatic-Pipeline-768x157.png 768w, https://inero-software.com/wp-content/uploads/2025/07/Oragmatic-Pipeline.png 1200w" sizes="(max-width: 1030px) 100vw, 1030px" /></h1><p>Discovery clarifies drivers, constraints and stakeholders. Without this, technical work drifts. Assessment inventories integrations and compliance needs, and identifies risks and skill gaps.Architecture produces the reference design, HA/DR plan and governance model. PoC attacks the riskiest assumptions first—often a tricky integration or compliance requirement. Pilot rolls out to a subset of apps/users to validate processes, comms and support.</p><p>Production rollout happens in phases with rollback strategies (blue/green, canary).</p><p>Operate means continuous monitoring, patching, upgrades and cost optimization—often where a partner can help your team breathe.</p><p> </p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-17d764e e-flex e-con-boxed e-con e-parent" data-id="17d764e" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-9b32f71 elementor-widget elementor-widget-text-editor" data-id="9b32f71" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1>Next Steps</h1><p>If your scorecard favors Keycloak, schedule a Discovery &amp; Governance workshop to align stakeholders, draft a high‑level architecture and turn assumptions into a roadmap. If you’re unsure, run a PoC targeting the top two risks. And if SaaS seems better today, design an exit strategy anyway—lock‑in is fine when it’s deliberate, not accidental.</p><p> </p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-fb6022e e-flex e-con-boxed e-con e-parent" data-id="fb6022e" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-e06c810 elementor-widget elementor-widget-text-editor" data-id="e06c810" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1>&nbsp;Ready to Validate Your Choice?</h1>
<p><span lang="EN-US"><a href="https://calendar.app.google/saTsdh7e5G3YqMQD7" target="_blank">Book a free 45‑minute Keycloak Readiness Consultation</a>. We’ll go through the seven questions together, fill out the scorecard and outline concrete next steps—whether that’s an internal PoC, a hybrid approach or a full advisory engagement.</span></p>
<p><span lang="EN-US">&nbsp;</span></p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-15aa28d e-flex e-con-boxed e-con e-parent" data-id="15aa28d" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-bea0396 elementor-widget elementor-widget-text-editor" data-id="bea0396" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h1>FAQ</h1><p><strong>Is Keycloak free to use in production?</strong></p><p>Yes. The software is open source, but production‑grade IAM still requires infrastructure, operations and security work. Some organizations use managed Keycloak or a consulting partner to offload that burden.</p><p><strong>How long does a typical Keycloak deployment take?</strong></p><p>A focused PoC can be done in weeks. Larger rollouts with dozens of integrations and strict compliance tend to span several months from assessment to stable production.</p><p><strong>Can Keycloak meet NIS2/GDPR requirements?</strong></p><p>Technically yes—Keycloak offers detailed logging, fine‑grained policies and MFA, and can be hosted where you need it. Compliance still depends on governance and evidence, not just tool capabilities.</p>						</div>
				</div>
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/keycloak-or-saas-idp-a-tech-leaders-guide-to-making-the-right-iam-choice/">Keycloak or SaaS IdP? A Tech Leader’s Guide to Making the Right IAM Choice</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">8063</post-id>	</item>
		<item>
		<title>Configuring Password Policies in Keycloak</title>
		<link>https://inero-software.com/configuring-password-policies-in-keycloak/</link>
		
		<dc:creator><![CDATA[Marceli Formela]]></dc:creator>
		<pubDate>Thu, 20 Mar 2025 12:10:07 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[IAM]]></category>
		<category><![CDATA[keycloak]]></category>
		<category><![CDATA[Password]]></category>
		<category><![CDATA[password management]]></category>
		<category><![CDATA[password policies]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=7635</guid>

					<description><![CDATA[<p>In this blog, we will first take a look at the built-in Keycloak mechanisms for password policy management. Then, we will explore the possibilities for customizing these mechanisms to better fit specific requirements.</p>
<p>Artykuł <a href="https://inero-software.com/configuring-password-policies-in-keycloak/">Configuring Password Policies in Keycloak</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="7635" class="elementor elementor-7635" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-949c242 e-flex e-con-boxed e-con e-parent" data-id="949c242" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-a9078db elementor-widget elementor-widget-html" data-id="a9078db" data-element_type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
			 
		</div>
				</div>
				<div class="elementor-element elementor-element-cc34f5b elementor-widget elementor-widget-text-editor" data-id="cc34f5b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h4><strong>Effective password management is an important aspect of securing user accounts, and Keycloak provides tools to enforce strong authentication policies. By configuring password rules, administrators can ensure that credentials meet security standards, reducing the risk of unauthorized access. The framework offers flexible options, allowing you to set requirements for password length, complexity, expiration, and reuse prevention. </strong></h4>						</div>
				</div>
				<div class="elementor-element elementor-element-0df981b elementor-widget elementor-widget-text-editor" data-id="0df981b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">In this blog, we will first take a look at the built-in Keycloak mechanisms for password policy management. Then, we will explore the possibilities for customizing these mechanisms to better fit specific requirements.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-ad5f7b2 elementor-widget elementor-widget-image" data-id="ad5f7b2" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7638" data-permalink="https://inero-software.com/configuring-password-policies-in-keycloak/attachment/115856/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/115856.png" data-orig-size="775,411" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="115856" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/115856-300x159.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/115856.png" tabindex="0" role="button" width="775" height="411" src="https://inero-software.com/wp-content/uploads/2025/03/115856.png" class="attachment-large size-large wp-image-7638" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/115856.png 775w, https://inero-software.com/wp-content/uploads/2025/03/115856-300x159.png 300w, https://inero-software.com/wp-content/uploads/2025/03/115856-768x407.png 768w, https://inero-software.com/wp-content/uploads/2025/03/115856-566x300.png 566w" sizes="(max-width: 775px) 100vw, 775px" data-attachment-id="7638" data-permalink="https://inero-software.com/configuring-password-policies-in-keycloak/attachment/115856/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/115856.png" data-orig-size="775,411" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="115856" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/115856-300x159.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/115856.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-b583771 elementor-widget elementor-widget-heading" data-id="b583771" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Built-in policies</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-b2a2079 elementor-widget elementor-widget-text-editor" data-id="b2a2079" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">These built-in password policies in Keycloak allow administrators to enforce security rules to strengthen user authentication. Here’s a brief description of each policy:</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-1dcf64f elementor-widget elementor-widget-text-editor" data-id="1dcf64f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ol><li aria-level="1"><strong>Expire Password</strong> <span style="font-weight: 400;">– Forces users to change their password after a specified period.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Hashing Iterations</strong> – Determines the number of iterations for password hashing to enhance security.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Not Recently Used</strong> – Prevents users from reusing their recent passwords.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Password Blacklist</strong> – Blocks specific passwords from being used, typically to prevent weak or common passwords.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Regular Expression</strong> – Allows enforcing a custom regex pattern for password validation.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Minimum Length</strong> – Sets the minimum number of characters required in a password.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Not Username</strong> – Prevents users from setting their username as a password.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Not Email</strong> – Prevents users from using their email address as a password.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Not Recently Used</strong> (In Days) – Prevents password reuse within a specified number of days.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Not Contains Username</strong> – Ensures the password does not include the username as part of it.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Special Character</strong>s – Requires passwords to contain at least one special character.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Uppercase Characters</strong> – Enforces at least one uppercase letter in the password.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Lowercase Characters</strong> – Requires at least one lowercase letter in the password.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Digits</strong> – Ensures the password includes at least one numeric digit.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Maximum Authentication Age</strong> – Sets a limit on how long authentication remains valid before requiring reauthentication.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Hashing Algorithm</strong> – Specifies the hashing algorithm used for password encryption.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;"><strong>Maximum Length</strong> – Defines the maximum allowable length for passwords.</span></li></ol>						</div>
				</div>
				<div class="elementor-element elementor-element-95da107 elementor-widget elementor-widget-heading" data-id="95da107" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h2 class="elementor-heading-title elementor-size-default">Implementing custom policy using SPI</h2>		</div>
				</div>
				<div class="elementor-element elementor-element-86f9385 elementor-widget elementor-widget-text-editor" data-id="86f9385" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">To implement a custom password policy in Keycloak, we should use the Service Provider Interface (SPI).</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-efcfbc7 elementor-widget elementor-widget-text-editor" data-id="efcfbc7" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">In this case, we define a custom password policy provider by implementing the PasswordPolicyProviderFactory interface:</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-a47d185 elementor-widget elementor-widget-code-highlight" data-id="a47d185" data-element_type="widget" data-widget_type="code-highlight.default">
				<div class="elementor-widget-container">
					<div class="prismjs-default copy-to-clipboard ">
			<pre data-line="" class="highlight-height language-javascript line-numbers">
				<code readonly="true" class="language-javascript">
					<xmp>public class PasswordCustomPolicyProviderFactory implements PasswordPolicyProviderFactory {

	public static final Integer DEFAULT_VALUE = 1;
	public static final String MIN_PASSWORD_LIFETIME_ID = "minimumPasswordLifetime";

	@Override
	public String getId() {
    	return MIN_PASSWORD_LIFETIME_ID;
	}

	@Override
	public PasswordPolicyProvider create(KeycloakSession session) {
    	return new PasswordCustomPolicyProvider(session);
	}
[...]
}

</xmp>
				</code>
			</pre>
		</div>
				</div>
				</div>
				<div class="elementor-element elementor-element-75140a5 elementor-widget elementor-widget-text-editor" data-id="75140a5" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Factory instantiates and returns a new instance of <strong>PasswordCustomPolicyProvider</strong>, which contains the actual validation logic for enforcing the minimum password lifetime. The <strong>MIN_PASSWORD_LIFETIME_ID</strong> constant serves as the unique identifier for this custom policy </span><span style="font-weight: 400;">and <strong>DEFAULT_VALUE</strong> constant represents the default minimum password lifetime (in days) if no custom value is configured via admin console.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-3c1cd5b elementor-widget elementor-widget-code-highlight" data-id="3c1cd5b" data-element_type="widget" data-widget_type="code-highlight.default">
				<div class="elementor-widget-container">
					<div class="prismjs-default copy-to-clipboard ">
			<pre data-line="" class="highlight-height language-javascript line-numbers">
				<code readonly="true" class="language-javascript">
					<xmp>public class PasswordCustomPolicyProvider implements PasswordPolicyProvider {
np.
   private static final String POLICY_VIOLATION_MESSAGE = "passwordLifetimeViolation";


   private final KeycloakSession keycloakSession;

   public PasswordCustomPolicyProvider(KeycloakSession keycloakSession) {
   	this.keycloakSession = keycloakSession;
   }


   @Override
   public PolicyError validate(RealmModel realm, UserModel user, String password) {
   	PasswordCredentialProvider credentialProvider = new PasswordCredentialProvider(keycloakSession);
   	PasswordCredentialModel credentialModel = credentialProvider.getPassword(realm, user);

   	if (credentialModel == null) {
       	return null;
   	}

   	long passwordCreationTime = credentialModel.getCreatedDate();
   	long currentTime = Time.currentTimeMillis();
   	long elapsedTime = currentTime - passwordCreationTime;

   	PasswordPolicy passwordPolicy = realm.getPasswordPolicy();
   	int minPasswordLifetimeDays = passwordPolicy.getPolicyConfig(PasswordCustomPolicyProviderFactory.MIN_PASSWORD_LIFETIME_ID);
   	long minPasswordLifetimeMillis = TimeUnit.DAYS.toMillis(minPasswordLifetimeDays);
   	return elapsedTime >= minPasswordLifetimeMillis ? null : new PolicyError(POLICY_VIOLATION_MESSAGE, minPasswordLifetimeDays);
   }
[...]
}
</xmp>
				</code>
			</pre>
		</div>
				</div>
				</div>
				<div class="elementor-element elementor-element-7cd9848 elementor-widget elementor-widget-text-editor" data-id="7cd9848" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">The <strong>PasswordCredentialProvider</strong> can access the stored password creation timestamp via the <strong>PasswordCredentialModel</strong> instance. It then computes <strong>elapsedTime</strong> as the difference between this timestamp and the current system time, representing how long the password has been in use.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-c8ec00f elementor-widget elementor-widget-text-editor" data-id="c8ec00f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Next, the PasswordPolicy object retrieves the password policy for the realm, extracts the minimum required password lifetime in days (minPasswordLifetimeDays), and converts it to milliseconds (minPasswordLifetimeMillis). The policy ensures that the password has been in use for at least the required duration. If this requirement is not met, a PolicyError is returned. The error message key is stored in <strong>POLICY_VIOLATION_MESSAGE</strong>, and its content can be customized within our theme. This allows us to define a user-friendly message that informs the user why the password change is restricted and how much time remains before a new password can be set.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-5c8b84b elementor-widget elementor-widget-image" data-id="5c8b84b" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7639" data-permalink="https://inero-software.com/configuring-password-policies-in-keycloak/attachment/122254/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/122254.png" data-orig-size="711,443" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="122254" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/122254-300x187.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/122254.png" tabindex="0" role="button" width="711" height="443" src="https://inero-software.com/wp-content/uploads/2025/03/122254.png" class="attachment-large size-large wp-image-7639" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/122254.png 711w, https://inero-software.com/wp-content/uploads/2025/03/122254-300x187.png 300w, https://inero-software.com/wp-content/uploads/2025/03/122254-481x300.png 481w" sizes="(max-width: 711px) 100vw, 711px" data-attachment-id="7639" data-permalink="https://inero-software.com/configuring-password-policies-in-keycloak/attachment/122254/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/122254.png" data-orig-size="711,443" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="122254" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/122254-300x187.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/122254.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-a18d447 elementor-widget elementor-widget-text-editor" data-id="a18d447" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">In this way, we can define custom password policies in Keycloak when the default set of policies is insufficient for specific requirements. This flexibility allows for more granular control over user authentication and password management when we need it.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-ed723ca elementor-widget elementor-widget-heading" data-id="ed723ca" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Customizing UI to improve user experience</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-0d876c8 elementor-widget elementor-widget-text-editor" data-id="0d876c8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">By default, Keycloak displays unsatisfied password policies</span><b> individually </b><span style="font-weight: 400;">on the login page. This can be problematic for many users, especially when there are multiple policies that are not met. It can lead to a cluttered interface and make it harder for users to understand all the password requirements at once. To address this, you can customize the login screen to display a collective list of all unsatisfied password policies together, providing a clearer and more user-friendly experience.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-129921c elementor-widget elementor-widget-code-highlight" data-id="129921c" data-element_type="widget" data-widget_type="code-highlight.default">
				<div class="elementor-widget-container">
					<div class="prismjs-default copy-to-clipboard ">
			<pre data-line="" class="highlight-height language-javascript line-numbers">
				<code readonly="true" class="language-javascript">
					<xmp>public class CustomFreeMarkerLoginFormsProvider extends FreeMarkerLoginFormsProvider {
/**
* Mapping between password policy provider IDs and custom messages
* Note: contains only standard policies that must be displayed in the UI
*/
private final Map<String, String> policyPropertyMessages = Map.of(
LengthPasswordPolicyProviderFactory.ID, MINIMUM_LENGTH_MESSAGE,
MaximumLengthPasswordPolicyProviderFactory.ID, MAXIMUM_LENGTH_MESSAGE,
DigitsPasswordPolicyProviderFactory.ID, MINIMUM_DIGIT_MESSAGE,
SpecialCharsPasswordPolicyProviderFactory.ID, MINIMUM_SPECIAL_CHAR_MESSAGE,
UpperCasePasswordPolicyProviderFactory.ID, MINIMUM_UPPERCASE_MESSAGE,
LowerCasePasswordPolicyProviderFactory.ID, MINIMUM_LOWERCASE_MESSAGE,
NotUsernamePasswordPolicyProviderFactory.ID, NOT_USERNAME_MESSAGE,
NotContainsUsernamePasswordPolicyProviderFactory.ID, NOT_CONTAINS_USERNAME_MESSAGE,
NotEmailPasswordPolicyProviderFactory.ID, NOT_EMAIL_MESSAGE
);

[...]

@Override
protected void createCommonAttributes(Theme theme, Locale locale, Properties messagesBundle,
UriBuilder baseUriBuilder, LoginFormsPages page) {
super.createCommonAttributes(theme, locale, messagesBundle, baseUriBuilder, page);
if (realm != null && realm.getPasswordPolicy() != null) {
attributes.put("passwordPolicies", getPasswordPolicyMessages(realm.getPasswordPolicy(), messagesBundle));
}}

[...]

private Map<String, String> getPasswordPolicyMessages(PasswordPolicy passwordPolicy, Properties messagesBundle) {
Map<String, String> policyMessages = new HashMap<>();
PasswordPolicy.Builder builder = passwordPolicy.toBuilder();
for (String policyName : passwordPolicy.getPolicies()) {
var value = builder.get(policyName);
String message = extractPolicyMessage(policyName, value, messagesBundle);
if (message != null) {
policyMessages.put(policyName, message);
}
}
return policyMessages;
}

[...]

/**
* Extracts a message for a given password policy from the messages bundle
* Note: Policy message is constructed by replacing the {0} placeholder with the policy value
*/
private String extractPolicyMessage(String policy, String value, Properties messagesBundle) {
String property = policyPropertyMessages.get(policy);
if (property == null) {
return null;
}
String policyMessage = messagesBundle.getProperty(property);
return policyMessage != null ? policyMessage.replace("{0}", value) : null;
}
</xmp>
				</code>
			</pre>
		</div>
				</div>
				</div>
				<div class="elementor-element elementor-element-e47c0c6 elementor-widget elementor-widget-text-editor" data-id="e47c0c6" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">The getPasswordPolicyMessages() function already collects the password policies from the PasswordPolicy and maps them to the appropriate messages from the message bundle. You can extend this function to display all unsatisfied policies in one collective message.</span></p><p> </p><p><span style="font-weight: 400;">Password policies such as minimum length, required digits, special characters, etc., are mapped to messages via the extractPolicyMessage() method. Our service implementation will iterate through each policy and check if it&#8217;s satisfied. If not, the corresponding message will be displayed.</span></p><p> </p><p><span style="font-weight: 400;">In your update-password.ftl page, you can display these unsatisfied policies as a list using FreeMarker.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-e70d98c elementor-widget elementor-widget-code-highlight" data-id="e70d98c" data-element_type="widget" data-widget_type="code-highlight.default">
				<div class="elementor-widget-container">
					<div class="prismjs-default copy-to-clipboard ">
			<pre data-line="" class="highlight-height language-javascript line-numbers">
				<code readonly="true" class="language-javascript">
					<xmp>
    	<#if passwordPolicies?has_content>
        	<div class="${properties.kcAlertClass}">
            	<div class="${properties.kcAlertIconWrapperClass}">
                	<span class="${properties.kcAlertIconClass}"></span>
            	</div>
            	<span class="${properties.kcAlertTitleClass}">
            	${msg("passwordInstruction")} <br>
            	<#list passwordPolicies?keys as key>
                	<span class="${properties.kcAlertTitleClass}">&#x2022; ${passwordPolicies[key]}</span><br/>
            	</#list>
            	</span>
        	</div>
    	</#if>

</xmp>
				</code>
			</pre>
		</div>
				</div>
				</div>
				<div class="elementor-element elementor-element-358fd5c elementor-widget elementor-widget-image" data-id="358fd5c" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7640" data-permalink="https://inero-software.com/configuring-password-policies-in-keycloak/attachment/123206/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/123206.png" data-orig-size="648,510" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="123206" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/123206-300x236.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/123206.png" tabindex="0" role="button" width="648" height="510" src="https://inero-software.com/wp-content/uploads/2025/03/123206.png" class="attachment-large size-large wp-image-7640" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/123206.png 648w, https://inero-software.com/wp-content/uploads/2025/03/123206-300x236.png 300w, https://inero-software.com/wp-content/uploads/2025/03/123206-381x300.png 381w, https://inero-software.com/wp-content/uploads/2025/03/123206-380x300.png 380w" sizes="(max-width: 648px) 100vw, 648px" data-attachment-id="7640" data-permalink="https://inero-software.com/configuring-password-policies-in-keycloak/attachment/123206/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/123206.png" data-orig-size="648,510" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="123206" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/123206-300x236.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/123206.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-6d7a6c0 elementor-widget elementor-widget-heading" data-id="6d7a6c0" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Real world policy examples
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-776740f elementor-widget elementor-widget-text-editor" data-id="776740f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Let&#8217;s see how password policies look in large companies.</span></p><p><span style="font-weight: 400;"> </span></p><p><b>Apple</b><span style="font-weight: 400;"> requires passwords to be at least eight characters long and must include both letters and numbers. Additionally, passwords cannot contain three or more consecutive identical characters and cannot be commonly used passwords.</span></p><p><span style="font-weight: 400;"> </span></p><p><b>Facebook</b><span style="font-weight: 400;"> enforces a minimum password length of more than six characters, although longer passwords are recommended. While Meta does not require the use of special characters or digits, it encourages creating complex passwords.</span></p><p><span style="font-weight: 400;"> </span></p><p><b>Microsoft</b><span style="font-weight: 400;"> passwords must be at least 8 characters long and contain at least two of the following types of characters: uppercase letters, lowercase letters, digits, and symbols. Additionally, it may block the ability to set a password that is too similar to the previous one.</span></p><p><span style="font-weight: 400;">Although these companies use different tools for authentication, it&#8217;s important to consider the security standards implemented in big real-world systems.</span></p><p><span style="font-weight: 400;"> </span></p><p><span style="font-weight: 400;">And despite the fact that these password policies are not extremely restrictive, users should still avoid using sensitive personal information, such as names, birthdates, or phone numbers, in their passwords. Additionally, it&#8217;s essential to avoid reusing passwords across different services, as this can lead to vulnerabilities in case one account is compromised. Employing two-factor authentication (2FA) and periodically reviewing password security are further steps users can take to enhance their protection.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-d64b6d9 elementor-widget elementor-widget-heading" data-id="d64b6d9" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Summary</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-911c3a6 elementor-widget elementor-widget-text-editor" data-id="911c3a6" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">As you can see now, Keycloak provides a set of default password policies that cover standard security rules, such as minimum length, complexity requirements, and password history. These built-in policies are sufficient in many cases, but if needed, there is the option to customize them to meet specific organizational requirements. Keycloak also allows the creation of custom password policies, providing greater control over security.</span></p><p><span style="font-weight: 400;">In addition to customizing policies, Keycloak enables modification of the user interface, which is especially useful when the default display of password policy violations, such as showing unmet requirements individually, does not meet our needs. In such cases, we can change how errors are presented or enrich the messages with additional details to make them more user-friendly.</span></p><p> </p><p><span style="font-weight: 400;">With these options, Keycloak demonstrates a high level of flexibility, allowing full control over security policies and the user interface, making it a versatile solution for identity and access management. The ability to define custom rules and adjust components ensures that Keycloak is a scalable tool that can be easily tailored to the specific needs of an organization.</span></p>						</div>
				</div>
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/configuring-password-policies-in-keycloak/">Configuring Password Policies in Keycloak</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7635</post-id>	</item>
		<item>
		<title>Setting Up Passwordless Login with Passkey on a Mobile Device</title>
		<link>https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/</link>
		
		<dc:creator><![CDATA[Marceli Formela]]></dc:creator>
		<pubDate>Wed, 12 Mar 2025 07:47:03 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[cybersecurity]]></category>
		<category><![CDATA[IAM]]></category>
		<category><![CDATA[keycloak]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[MFA]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[Mobile Device]]></category>
		<category><![CDATA[Multi-Factor Authentication]]></category>
		<category><![CDATA[Passkey]]></category>
		<category><![CDATA[Passwordless]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=7534</guid>

					<description><![CDATA[<p>This blog focuses on configuring Passkeys specifically for mobile devices, ensuring a seamless and secure passwordless experience.</p>
<p>Artykuł <a href="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/">Setting Up Passwordless Login with Passkey on a Mobile Device</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="7534" class="elementor elementor-7534" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-a40bff4 e-flex e-con-boxed e-con e-parent" data-id="a40bff4" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-8062b20 elementor-widget elementor-widget-html" data-id="8062b20" data-element_type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
			 		</div>
				</div>
				<div class="elementor-element elementor-element-5dc3085 elementor-widget elementor-widget-text-editor" data-id="5dc3085" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h4><strong>In our previous post, we demonstrated how to configure Passkeys in Keycloak, replacing traditional passwords with WebAuthn-based authentication. We covered the setup process, key advantages, and potential limitations, including the challenge of user adoption. This blog focuses on configuring Passkeys specifically for mobile devices, ensuring a seamless and secure passwordless experience.</strong></h4>						</div>
				</div>
				<div class="elementor-element elementor-element-8e87fa0 elementor-widget elementor-widget-text-editor" data-id="8e87fa0" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Our first publication about Passkeys in Keycloak, you can find here: <a href="https://inero-software.com/an-introduction-to-passkey-with-keycloak/">An introduction to Passkey with Keycloak</a></span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-618f1e8 elementor-widget elementor-widget-text-editor" data-id="618f1e8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">In this post, we’ll dive deeper into optimizing Passkey authentication in Keycloak, looking into a different approach, this time using more than one device.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-9754353 elementor-widget elementor-widget-heading" data-id="9754353" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Using a Passkey stored on a phone</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-f889420 elementor-widget elementor-widget-text-editor" data-id="f889420" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">When logging in on a different device, such as a laptop or desktop, users can authenticate using a Passkey stored on their phone. The process works as follows:</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-823577d elementor-widget elementor-widget-text-editor" data-id="823577d" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ol><li><strong>Selecting Passkey Login</strong> <br />Instead of entering a password, users choose the Passkey authentication option. The laptop&#8217;s browser generates a request for authentication. Now we have to establish a secure connection between your phone (e.g., iPhone) and your laptop.</li><li><strong>Scanning a QR Code</strong><br />The login interface generates a QR code, which users scan using their phone’s camera. Then the laptop sends a cryptographic challenge to the phone, asking it to sign a request using the stored passkey. The phone communicates securely with the laptop over Bluetooth or other close-range communication protocols (like NFC).</li><li><strong>Confirming Identity</strong> <br />Once the phone receives the challenge, it asks the user for biometric authentication (e.g., Face ID or Touch ID). This verifies that the person attempting the login is the authorized user.</li><li><strong>Secure Authentication</strong> <br />The laptop checks the response from the phone, verifying the cryptographic signature against the public key registered with the service. If the verification is successful, the user is logged in without having to enter a password.</li></ol>						</div>
				</div>
				<div class="elementor-element elementor-element-5edfe44 elementor-widget elementor-widget-heading" data-id="5edfe44" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Step by step: Configuring Passkey with a smartphone</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-b53966d elementor-widget elementor-widget-text-editor" data-id="b53966d" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Before we dive into our custom authentication flow, it&#8217;s important to check if the </span><b>Webauthn Register Passwordless</b><span style="font-weight: 400;"> required action is enabled in the realm (</span><b>Authentication</b><span style="font-weight: 400;"> -&gt; </span><b>Required actions</b><span style="font-weight: 400;"> tab).</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-6d213d0 elementor-widget elementor-widget-image" data-id="6d213d0" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7536" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/12025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/12025-03-11.png" data-orig-size="773,180" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="12025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/12025-03-11-300x70.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/12025-03-11.png" tabindex="0" role="button" width="773" height="180" src="https://inero-software.com/wp-content/uploads/2025/03/12025-03-11.png" class="attachment-large size-large wp-image-7536" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/12025-03-11.png 773w, https://inero-software.com/wp-content/uploads/2025/03/12025-03-11-300x70.png 300w, https://inero-software.com/wp-content/uploads/2025/03/12025-03-11-768x179.png 768w" sizes="(max-width: 773px) 100vw, 773px" data-attachment-id="7536" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/12025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/12025-03-11.png" data-orig-size="773,180" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="12025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/12025-03-11-300x70.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/12025-03-11.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-271f72a elementor-widget elementor-widget-text-editor" data-id="271f72a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">This gives us, for example, the ability to enforce passkey configuration from users after their next successful login. However, it’s important to remember that this is just one of many ways to configure multiple authentication methods.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-456b3a4 elementor-widget elementor-widget-image" data-id="456b3a4" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7537" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/22025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/22025-03-11.png" data-orig-size="616,227" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="22025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/22025-03-11-300x111.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/22025-03-11.png" tabindex="0" role="button" width="616" height="227" src="https://inero-software.com/wp-content/uploads/2025/03/22025-03-11.png" class="attachment-large size-large wp-image-7537" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/22025-03-11.png 616w, https://inero-software.com/wp-content/uploads/2025/03/22025-03-11-300x111.png 300w" sizes="(max-width: 616px) 100vw, 616px" data-attachment-id="7537" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/22025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/22025-03-11.png" data-orig-size="616,227" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="22025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/22025-03-11-300x111.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/22025-03-11.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-a3f5cac elementor-widget elementor-widget-text-editor" data-id="a3f5cac" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Once we confirm that this option is active, we can proceed with configuring the authentication flow.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-0950898 elementor-widget elementor-widget-image" data-id="0950898" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7538" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/32025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/32025-03-11.png" data-orig-size="770,452" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="32025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/32025-03-11-300x176.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/32025-03-11.png" tabindex="0" role="button" width="770" height="452" src="https://inero-software.com/wp-content/uploads/2025/03/32025-03-11.png" class="attachment-large size-large wp-image-7538" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/32025-03-11.png 770w, https://inero-software.com/wp-content/uploads/2025/03/32025-03-11-300x176.png 300w, https://inero-software.com/wp-content/uploads/2025/03/32025-03-11-768x451.png 768w, https://inero-software.com/wp-content/uploads/2025/03/32025-03-11-511x300.png 511w, https://inero-software.com/wp-content/uploads/2025/03/32025-03-11-512x300.png 512w" sizes="(max-width: 770px) 100vw, 770px" data-attachment-id="7538" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/32025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/32025-03-11.png" data-orig-size="770,452" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="32025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/32025-03-11-300x176.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/32025-03-11.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-87518d4 elementor-widget elementor-widget-text-editor" data-id="87518d4" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">This custom authentication flow for Keycloak is designed to demonstrate how users can choose between password-based authentication and passkey authentication (WebAuthn) during login. Here’s how it works:</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-d372519 elementor-widget elementor-widget-text-editor" data-id="d372519" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li style="list-style-type: none;"><ul><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Users are required to provide their username to proceed with authentication.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">This step enforces authentication, but users can choose between password-based login or passkey-based login.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">If the user opts for password authentication, they enter their credentials here.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">If the user prefers passwordless authentication using passkeys, they can authenticate using this method instead.</span></li></ul></li></ul>						</div>
				</div>
				<div class="elementor-element elementor-element-5a1acc1 elementor-widget elementor-widget-image" data-id="5a1acc1" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7539" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/42025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/42025-03-11.png" data-orig-size="643,279" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="42025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/42025-03-11-300x130.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/42025-03-11.png" tabindex="0" role="button" width="643" height="279" src="https://inero-software.com/wp-content/uploads/2025/03/42025-03-11.png" class="attachment-large size-large wp-image-7539" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/42025-03-11.png 643w, https://inero-software.com/wp-content/uploads/2025/03/42025-03-11-300x130.png 300w" sizes="(max-width: 643px) 100vw, 643px" data-attachment-id="7539" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/42025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/42025-03-11.png" data-orig-size="643,279" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="42025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/42025-03-11-300x130.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/42025-03-11.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-d065fdf elementor-widget elementor-widget-text-editor" data-id="d065fdf" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">In this step, users can enter their username or email to proceed with authentication. This is a required step, ensuring that the system identifies the user before offering authentication options.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-4b5d087 elementor-widget elementor-widget-image" data-id="4b5d087" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7540" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/52025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/52025-03-11.png" data-orig-size="644,292" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="52025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/52025-03-11-300x136.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/52025-03-11.png" tabindex="0" role="button" width="644" height="292" src="https://inero-software.com/wp-content/uploads/2025/03/52025-03-11.png" class="attachment-large size-large wp-image-7540" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/52025-03-11.png 644w, https://inero-software.com/wp-content/uploads/2025/03/52025-03-11-300x136.png 300w" sizes="(max-width: 644px) 100vw, 644px" data-attachment-id="7540" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/52025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/52025-03-11.png" data-orig-size="644,292" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="52025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/52025-03-11-300x136.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/52025-03-11.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-a1bfcfe elementor-widget elementor-widget-text-editor" data-id="a1bfcfe" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">At this stage, we can only use password authentication because we haven&#8217;t configured our Passkey (WebAuthn) yet. Once Passkey is set up, users will have the option to choose between password-based and passwordless authentication.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-c2348be elementor-widget elementor-widget-image" data-id="c2348be" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7541" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/62025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/62025-03-11.png" data-orig-size="655,236" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="62025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/62025-03-11-300x108.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/62025-03-11.png" tabindex="0" role="button" width="655" height="236" src="https://inero-software.com/wp-content/uploads/2025/03/62025-03-11.png" class="attachment-large size-large wp-image-7541" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/62025-03-11.png 655w, https://inero-software.com/wp-content/uploads/2025/03/62025-03-11-300x108.png 300w" sizes="(max-width: 655px) 100vw, 655px" data-attachment-id="7541" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/62025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/62025-03-11.png" data-orig-size="655,236" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="62025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/62025-03-11-300x108.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/62025-03-11.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-4a740ef elementor-widget elementor-widget-text-editor" data-id="4a740ef" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Instead of registering a device PIN as mentioned earlier, we will use authentication via a phone, specifically an iPhone, in this example</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-8e0e308 elementor-widget elementor-widget-image" data-id="8e0e308" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7542" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/72025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/72025-03-11.png" data-orig-size="558,686" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="72025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/72025-03-11-244x300.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/72025-03-11.png" tabindex="0" role="button" width="558" height="686" src="https://inero-software.com/wp-content/uploads/2025/03/72025-03-11.png" class="attachment-large size-large wp-image-7542" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/72025-03-11.png 558w, https://inero-software.com/wp-content/uploads/2025/03/72025-03-11-244x300.png 244w" sizes="(max-width: 558px) 100vw, 558px" data-attachment-id="7542" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/72025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/72025-03-11.png" data-orig-size="558,686" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="72025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/72025-03-11-244x300.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/72025-03-11.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-512ac1c elementor-widget elementor-widget-image" data-id="512ac1c" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7543" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/82025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/82025-03-11.png" data-orig-size="554,704" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="82025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/82025-03-11-236x300.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/82025-03-11.png" tabindex="0" role="button" width="554" height="704" src="https://inero-software.com/wp-content/uploads/2025/03/82025-03-11.png" class="attachment-large size-large wp-image-7543" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/82025-03-11.png 554w, https://inero-software.com/wp-content/uploads/2025/03/82025-03-11-236x300.png 236w" sizes="(max-width: 554px) 100vw, 554px" data-attachment-id="7543" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/82025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/82025-03-11.png" data-orig-size="554,704" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="82025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/82025-03-11-236x300.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/82025-03-11.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-579c8d6 elementor-widget elementor-widget-text-editor" data-id="579c8d6" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Now, a QR code should appear, allowing us to register a Passkey on our account. Let&#8217;s scan it using our phone&#8217;s camera and verify the operation, for example, using Face ID.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-e3e3a98 elementor-widget elementor-widget-image" data-id="e3e3a98" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7544" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/92025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/92025-03-11.png" data-orig-size="547,241" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="92025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/92025-03-11-300x132.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/92025-03-11.png" tabindex="0" role="button" width="547" height="241" src="https://inero-software.com/wp-content/uploads/2025/03/92025-03-11.png" class="attachment-large size-large wp-image-7544" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/92025-03-11.png 547w, https://inero-software.com/wp-content/uploads/2025/03/92025-03-11-300x132.png 300w" sizes="(max-width: 547px) 100vw, 547px" data-attachment-id="7544" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/92025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/92025-03-11.png" data-orig-size="547,241" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="92025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/92025-03-11-300x132.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/92025-03-11.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-48105ee elementor-widget elementor-widget-text-editor" data-id="48105ee" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Now, our Passkey should be visible in the Credentials section.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-1d1bbc7 elementor-widget elementor-widget-image" data-id="1d1bbc7" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7545" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/102025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/102025-03-11.png" data-orig-size="776,486" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="102025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/102025-03-11-300x188.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/102025-03-11.png" tabindex="0" role="button" width="776" height="486" src="https://inero-software.com/wp-content/uploads/2025/03/102025-03-11.png" class="attachment-large size-large wp-image-7545" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/03/102025-03-11.png 776w, https://inero-software.com/wp-content/uploads/2025/03/102025-03-11-300x188.png 300w, https://inero-software.com/wp-content/uploads/2025/03/102025-03-11-768x481.png 768w, https://inero-software.com/wp-content/uploads/2025/03/102025-03-11-479x300.png 479w" sizes="(max-width: 776px) 100vw, 776px" data-attachment-id="7545" data-permalink="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/102025-03-11/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/03/102025-03-11.png" data-orig-size="776,486" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="102025-03-11" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/03/102025-03-11-300x188.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/03/102025-03-11.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-7b13102 elementor-widget elementor-widget-text-editor" data-id="7b13102" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">During the next login, we should see the option to choose between password authentication and Passkey authentication.</span></p><p> </p><p><span style="font-weight: 400;">This setup enhances user convenience by allowing them to pick their preferred authentication method. Passkeys provide a more secure and phishing-resistant login experience, while passwords remain available for users who prefer traditional authentication. With this flexibility, we can ensure both security and ease of access for different user preferences.</span></p><p> </p><p><span style="font-weight: 400;">It is worth remembering that traditional passwords are a weak link in digital security, often compromised through reuse, phishing, or data breaches. Passkeys offer a modern, passwordless authentication method that enhances security and usability by leveraging cryptographic key pairs managed by platform authenticators. They provide phishing resistance, seamless multi-device access, and compliance with multi-factor authentication (MFA) standards.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-4a97718 elementor-cta--skin-cover elementor-animated-content elementor-bg-transform elementor-bg-transform-zoom-in elementor-widget elementor-widget-call-to-action" data-id="4a97718" data-element_type="widget" data-widget_type="call-to-action.default">
				<div class="elementor-widget-container">
					<a class="elementor-cta" href="https://inero-software.com/best-keycloak-practices/">
					<div class="elementor-cta__bg-wrapper">
				<div class="elementor-cta__bg elementor-bg" style="background-image: url(https://inero-software.com/wp-content/uploads/2025/01/cta-wm-1-1030x579.png);" role="img" aria-label="cta wm (1)"></div>
				<div class="elementor-cta__bg-overlay"></div>
			</div>
							<div class="elementor-cta__content">
				
									<h2 class="elementor-cta__title elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
						Best Practices in Keycloak: Secure Your System in 5 Steps					</h2>
				
				
									<div class="elementor-cta__button-wrapper elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
					<span class="elementor-cta__button elementor-button elementor-size-">
						Read more 					</span>
					</div>
							</div>
						</a>
				</div>
				</div>
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/setting-up-passwordless-login-with-passkey-on-a-mobile-device/">Setting Up Passwordless Login with Passkey on a Mobile Device</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7534</post-id>	</item>
		<item>
		<title>Trusted devices in Keycloak</title>
		<link>https://inero-software.com/trusted-devices-in-keycloak/</link>
		
		<dc:creator><![CDATA[Marta Kuprasz]]></dc:creator>
		<pubDate>Thu, 06 Mar 2025 10:47:08 +0000</pubDate>
				<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[2FA]]></category>
		<category><![CDATA[corporate]]></category>
		<category><![CDATA[cybersecurity]]></category>
		<category><![CDATA[IAM]]></category>
		<category><![CDATA[keycloak]]></category>
		<category><![CDATA[login]]></category>
		<category><![CDATA[MFA]]></category>
		<category><![CDATA[trusted devices]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=7522</guid>

					<description><![CDATA[<p>The trusted devices mechanism in Keycloak is a way to enhance login convenience without significantly compromising cybersecurity.</p>
<p>Artykuł <a href="https://inero-software.com/trusted-devices-in-keycloak/">Trusted devices in Keycloak</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="7522" class="elementor elementor-7522" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-61f5765 e-flex e-con-boxed e-con e-parent" data-id="61f5765" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-bd55449 elementor-widget elementor-widget-html" data-id="bd55449" data-element_type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
			 		</div>
				</div>
				<div class="elementor-element elementor-element-a676703 elementor-widget elementor-widget-text-editor" data-id="a676703" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h4>User authentication in IT systems requires finding a balance between convenience and security. On one hand, users expect the login process to involve the fewest steps possible; on the other, it is essential to protect system access from unauthorized use. One way to manage security levels flexibly is through the trusted devices mechanism, which allows users to reduce the number of required login steps for recognized and secure devices.</h4>						</div>
				</div>
				<div class="elementor-element elementor-element-56ff357 elementor-widget elementor-widget-text-editor" data-id="56ff357" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>The stricter the security policy, the more inconvenient it becomes for users—this is the eternal dilemma for system administrators. Long and complex passwords, frequent password changes, and additional authentication factors enhance security but also lead users to find ways to bypass procedures—such as writing passwords down in notebooks or saving them in browsers.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-2bce090 elementor-widget elementor-widget-heading" data-id="2bce090" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Trusted Devices – How Does It Work?</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-50fe905 elementor-widget elementor-widget-text-editor" data-id="50fe905" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>By default, Keycloak does not recognize or remember devices, meaning each session is treated independently. However, with extensions, support for trusted devices can be added, allowing users to skip certain steps during subsequent logins.</p><p><span data-ccp-props="{}"> </span></p><p>CTO of Inero Software, Waldemar Korłub, emphasizes:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-696e202 elementor-blockquote--skin-border elementor-blockquote--button-color-official elementor-widget elementor-widget-blockquote" data-id="696e202" data-element_type="widget" data-widget_type="blockquote.default">
				<div class="elementor-widget-container">
					<blockquote class="elementor-blockquote">
			<p class="elementor-blockquote__content">
				"Hence the concept of trusted devices – the first time, we need to go through all the steps, but afterward, the application can, for example, skip asking for the two-factor authentication code."			</p>
					</blockquote>
				</div>
				</div>
				<div class="elementor-element elementor-element-f14d2c6 elementor-widget elementor-widget-text-editor" data-id="f14d2c6" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Once a device is marked as &#8220;trusted,&#8221; the system can retain its status for a specified period, allowing for a simplified login process. However, the user may still be periodically asked to reauthenticate to ensure security.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-b8b437d elementor-widget elementor-widget-heading" data-id="b8b437d" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Is remembering devices secure?</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-785c726 elementor-widget elementor-widget-text-editor" data-id="785c726" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>While the trusted devices mechanism improves user convenience, it also introduces additional risks. The biggest threat is the theft or loss of a device that has been previously marked as trusted.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-a64bc8c elementor-widget elementor-widget-text-editor" data-id="a64bc8c" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>As Waldemar Korłub points out:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d11c9c8 elementor-blockquote--skin-border elementor-blockquote--button-color-official elementor-widget elementor-widget-blockquote" data-id="d11c9c8" data-element_type="widget" data-widget_type="blockquote.default">
				<div class="elementor-widget-container">
					<blockquote class="elementor-blockquote">
			<p class="elementor-blockquote__content">
				"If the system does not require an additional authentication factor, an attacker could gain access to all stored applications. That’s why it is crucial for users to have control over their trusted devices—ideally through a panel where they can remove them at any time."			</p>
					</blockquote>
				</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-1059003 e-flex e-con-boxed e-con e-parent" data-id="1059003" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-aa6f62d elementor-widget elementor-widget-text-editor" data-id="aa6f62d" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Introducing a device management panel and the option to revoke a device&#8217;s trusted status in case of loss are essential elements for ensuring security.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-0483644 elementor-widget elementor-widget-heading" data-id="0483644" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">How can administrators control access in Keycloak?</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-84cbf21 elementor-widget elementor-widget-text-editor" data-id="84cbf21" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Administrators can restrict the device remembering mechanism, for example, to specific networks or corporate devices.</p><p>Waldemar Korłub explains:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-4323398 elementor-blockquote--skin-border elementor-blockquote--button-color-official elementor-widget elementor-widget-blockquote" data-id="4323398" data-element_type="widget" data-widget_type="blockquote.default">
				<div class="elementor-widget-container">
					<blockquote class="elementor-blockquote">
			<p class="elementor-blockquote__content">
				"We can limit this mechanism, for example, to computers within the local network—if users connect via the corporate VPN, we can recognize company-owned devices and enable the trusted devices option for them."			</p>
					</blockquote>
				</div>
				</div>
				<div class="elementor-element elementor-element-4265831 elementor-widget elementor-widget-text-editor" data-id="4265831" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Thanks to such solutions, organizations can prevent users from assigning trusted status to personal devices that are beyond their control.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-32fce0a elementor-widget elementor-widget-heading" data-id="32fce0a" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Trusted Devices in Keycloak – Key Takeaways</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-d135dd4 elementor-widget elementor-widget-text-editor" data-id="d135dd4" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li style="list-style-type: none;"><ul><li data-leveltext="" data-font="Symbol" data-listid="13" data-list-defn-props="{&quot;335552541&quot;:1,&quot;335559683&quot;:0,&quot;335559684&quot;:-2,&quot;335559685&quot;:717,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}" aria-setsize="-1" data-aria-posinset="1" data-aria-level="1"><p><strong>Trusted Devices Help Simplify Login but Require Proper Security Measures</strong></p><p>The trusted devices mechanism in Keycloak allows users to skip certain authentication steps, such as entering a 2FA code. While this is a convenient solution that streamlines daily operations, it also requires the implementation of appropriate security measures. It is essential to define the validity period of a trusted device and monitor changes in login behavior to prevent misuse.</p></li></ul></li></ul>						</div>
				</div>
				<div class="elementor-element elementor-element-e312c00 elementor-widget elementor-widget-text-editor" data-id="e312c00" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li style="list-style-type: none;"><ul><li data-leveltext="" data-font="Symbol" data-listid="14" data-list-defn-props="{&quot;335552541&quot;:1,&quot;335559683&quot;:0,&quot;335559684&quot;:-2,&quot;335559685&quot;:717,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}" aria-setsize="-1" data-aria-posinset="1" data-aria-level="1"><p><strong>Administrators Can Control the Trusted Device Access Policy</strong></p><p>Not every device should be marked as trusted, which is why administrators can restrict this feature to corporate computers or require a VPN connection. This helps prevent situations where a user assigns trusted status to a personal computer that the organization cannot control.</p></li></ul></li></ul>						</div>
				</div>
				<div class="elementor-element elementor-element-715f0c8 elementor-widget elementor-widget-text-editor" data-id="715f0c8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li style="list-style-type: none;"><ul><li><p><strong>Device Management Panel Enhances Security</strong></p><p>To give users greater control over their sessions, it is beneficial to implement a panel that allows them to review and remove trusted devices. This way, in case of device loss or suspected unauthorized access, users can quickly revoke granted permissions.</p></li></ul></li></ul>						</div>
				</div>
				<div class="elementor-element elementor-element-1e4653d elementor-widget elementor-widget-text-editor" data-id="1e4653d" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li style="list-style-type: none;"><ul><li data-leveltext="" data-font="Symbol" data-listid="16" data-list-defn-props="{&quot;335552541&quot;:1,&quot;335559683&quot;:0,&quot;335559684&quot;:-2,&quot;335559685&quot;:717,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}" aria-setsize="-1" data-aria-posinset="1" data-aria-level="1"><p><strong>The Ability to Remove a Device Protects Against Account Takeover</strong></p><p>If a device is lost or stolen and the system does not require additional authentication, an attacker could gain access to the user&#8217;s account. That’s why it is crucial to allow the removal of trusted devices at any time and enforce reauthentication. This approach provides greater flexibility while reducing the risk of unauthorized account access.</p></li></ul></li></ul>						</div>
				</div>
				<div class="elementor-element elementor-element-74208e6 elementor-widget elementor-widget-heading" data-id="74208e6" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">When Should You Use the Trusted Devices Feature in Keycloak?</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-c9a0c94 elementor-widget elementor-widget-text-editor" data-id="c9a0c94" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>The trusted devices feature in Keycloak enhances login convenience while maintaining a high level of security. This functionality is particularly useful in corporate environments and BYOD (Bring Your Own Device) models, where users regularly log in from the same devices.</p><p>Marking a device as trusted reduces the number of two-factor authentication (2FA) prompts, extends session duration, and allows for dynamic security policy adjustments, such as requiring reauthentication for suspicious logins. This approach helps mitigate the risk of account takeover—even if an attacker obtains a password and 2FA code—since logging in from a new device may trigger additional verification.</p><p>Implementing trusted devices in Keycloak enables organizations to strike a balance between security and user convenience.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-eeb8eea elementor-widget elementor-widget-text-editor" data-id="eeb8eea" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>The trusted devices mechanism in Keycloak enhances login convenience without significantly compromising cybersecurity. Proper implementation of the device remembering policy in Keycloak helps balance system security and user experience.</p><p>However, administrators should ensure that mechanisms are in place for managing the list of trusted devices and enforcing periodic verification of their status to mitigate potential security risks.</p>						</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-9973b2a e-flex e-con-boxed e-con e-parent" data-id="9973b2a" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-58da433 elementor-cta--skin-cover elementor-animated-content elementor-bg-transform elementor-bg-transform-zoom-in elementor-widget elementor-widget-call-to-action" data-id="58da433" data-element_type="widget" data-widget_type="call-to-action.default">
				<div class="elementor-widget-container">
					<a class="elementor-cta" href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ3e3C_1YeBkt1uCr_qfOnG_N298UgLFwORcSTXigrPfOk0ls3ok-Uw_dSeGCoLdtYsN13GMm-n-">
					<div class="elementor-cta__bg-wrapper">
				<div class="elementor-cta__bg elementor-bg" style="background-image: url(https://inero-software.com/wp-content/uploads/2025/02/cta-2702-1030x579.png);" role="img" aria-label="cta 2702"></div>
				<div class="elementor-cta__bg-overlay"></div>
			</div>
							<div class="elementor-cta__content">
				
									<h2 class="elementor-cta__title elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
						We will help you implement Keycloak					</h2>
				
									<div class="elementor-cta__description elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
						Want to implement Keycloak or add new functionalities? Schedule a meeting to explore the possibilities.					</div>
				
									<div class="elementor-cta__button-wrapper elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
					<span class="elementor-cta__button elementor-button elementor-size-">
						Schedule a meeting					</span>
					</div>
							</div>
						</a>
				</div>
				</div>
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/trusted-devices-in-keycloak/">Trusted devices in Keycloak</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7522</post-id>	</item>
		<item>
		<title>An introduction to Passkey with Keycloak</title>
		<link>https://inero-software.com/an-introduction-to-passkey-with-keycloak/</link>
		
		<dc:creator><![CDATA[Marceli Formela]]></dc:creator>
		<pubDate>Wed, 26 Feb 2025 08:11:28 +0000</pubDate>
				<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[authentication]]></category>
		<category><![CDATA[cybersecurity]]></category>
		<category><![CDATA[digital security]]></category>
		<category><![CDATA[Face ID]]></category>
		<category><![CDATA[IAM]]></category>
		<category><![CDATA[keycloak]]></category>
		<category><![CDATA[Passkey]]></category>
		<category><![CDATA[Touch ID]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=7417</guid>

					<description><![CDATA[<p>In this blog post, we’ll show you how to set up Passkeys based on the Keycloak. </p>
<p>Artykuł <a href="https://inero-software.com/an-introduction-to-passkey-with-keycloak/">An introduction to Passkey with Keycloak</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="7417" class="elementor elementor-7417" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-55d1eac e-flex e-con-boxed e-con e-parent" data-id="55d1eac" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-6093d86 elementor-widget elementor-widget-html" data-id="6093d86" data-element_type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
			 		</div>
				</div>
				<div class="elementor-element elementor-element-05e6799 elementor-widget elementor-widget-text-editor" data-id="05e6799" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h4><strong>Traditional passwords have long been a weak factor in digital security. They are often reused, easy to compromise, and vulnerable to phishing attacks. Passkeys offer a modern solution by replacing passwords with app-specific cryptographic key pairs managed by platform authenticators. Because passkeys involve multiple authentication touchpoints, they meet multi-factor authentication (MFA) requirements and align with multiple standards.</strong></h4>						</div>
				</div>
				<div class="elementor-element elementor-element-7416163 elementor-widget elementor-widget-text-editor" data-id="7416163" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">In this blog post, we’ll show you how to set up Passkeys based on the Keycloak configuration we&#8217;ve covered in previous posts (check<a href="https://inero-software.com/securing-java-spring-endpoints-with-keycloak/"> Securing Java Spring Endpoints with Keycloak</a></span><span style="font-weight: 400;"> or <a href="https://inero-software.com/hands-on-keycloak-sso-from-setup-to-integration/">Hands-On Keycloak SSO: From Setup to Integration</a></span><span style="font-weight: 400;">). While passkeys promise a seamless and secure authentication experience, integrating them into an existing system can come with its own challenges. We’ll guide you through the basic setup process. If you&#8217;re looking to modernize your authentication strategy, this is the perfect place to start.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-c1afbd0 elementor-widget elementor-widget-heading" data-id="c1afbd0" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">How it works
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-848333b elementor-widget elementor-widget-text-editor" data-id="848333b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Passkeys are a passwordless authentication method designed to replace traditional passwords with a more secure and convenient alternative. Unlike passwords, which can be phished, stolen, or forgotten, passkeys eliminate these risks by using cryptographic key pairs stored in a trusted authenticator, such as a smartphone, another device, or a password manager. Instead of manually creating and remembering a password, users enable an authenticator to generate and manage a passkey for them. In general, a passkey consists of two parts:</span></p><ul><li style="list-style-type: none;"><ul><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">A public key, which is stored by the application</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">A private key, which remains securely stored in the user&#8217;s authenticator</span></li></ul></li></ul>						</div>
				</div>
				<div class="elementor-element elementor-element-40bb800 elementor-widget elementor-widget-text-editor" data-id="40bb800" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">The private key never leaves the device, ensuring that even if the public key is compromised, accounts remain secure.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-349583e elementor-widget elementor-widget-text-editor" data-id="349583e" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ol><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">When logging in, the app sends a challenge to the authenticator.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">The user verifies their identity using biometrics (Face ID, Touch ID), a PIN, or a password.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">The authenticator signs the challenge with the private key and sends it back for verification.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">If the signature is valid, access is granted &#8211; without ever needing a password.</span></li></ol>						</div>
				</div>
				<div class="elementor-element elementor-element-1621f94 elementor-widget elementor-widget-image" data-id="1621f94" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7419" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/passkeys-in-keycloak-schema/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema.png" data-orig-size="1920,792" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="passkeys in keycloak schema" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema-300x124.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema-1030x425.png" tabindex="0" role="button" width="1030" height="425" src="https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema-1030x425.png" class="attachment-large size-large wp-image-7419" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema-1030x425.png 1030w, https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema-300x124.png 300w, https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema-768x317.png 768w, https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema-1536x634.png 1536w, https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema-727x300.png 727w, https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema.png 1920w" sizes="(max-width: 1030px) 100vw, 1030px" data-attachment-id="7419" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/passkeys-in-keycloak-schema/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema.png" data-orig-size="1920,792" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="passkeys in keycloak schema" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema-300x124.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/passkeys-in-keycloak-schema-1030x425.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-3000e74 elementor-widget elementor-widget-heading" data-id="3000e74" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Advantages of Passkeys
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-b64357e elementor-widget elementor-widget-text-editor" data-id="b64357e" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li style="list-style-type: none;"><ul><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Unlike passwords, passkeys can’t be stolen through phishing attacks. They are bound to a specific website or app, meaning they won’t work on fake login pages. Even if a user visits a phishing site, their passkey won’t be prompted and won’t sign them in, preventing credential theft.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Users don’t have to manage multiple passwords across accounts. Logging in is as simple as using Face ID, Touch ID, or a device PIN.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Passwords can be guessed, reused, or leaked—passkeys can’t. Even some 2FA methods (like SMS codes) are vulnerable to phishing and SIM-swapping, while passkeys are not. Since passkeys use public-key cryptography, they can’t be stolen or intercepted in a data breach.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Passkeys are stored in platform authenticators (e.g., Google Password Manager, Windows Hello). They can be automatically synced across devices, ensuring access without manual transfers.</span></li></ul></li></ul>						</div>
				</div>
				<div class="elementor-element elementor-element-965d082 elementor-widget elementor-widget-heading" data-id="965d082" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Limitations of Passkeys<br>
</h3>		</div>
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-dcd18fa e-flex e-con-boxed e-con e-parent" data-id="dcd18fa" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-fba9537 elementor-widget elementor-widget-text-editor" data-id="fba9537" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li style="list-style-type: none;"><ul><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Not all websites and applications support passkeys yet, meaning users may still need to rely on passwords for some services.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Losing access to a primary device or cloud account could lock users out, requiring recovery options like backup devices.</span></li><li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Many users are still unfamiliar with passkeys, and the transition away from passwords requires education. Since passkeys don’t require manual entry, users may feel a lack of control over their credentials compared to traditional password management.</span></li></ul></li></ul>						</div>
				</div>
				<div class="elementor-element elementor-element-939f8d6 elementor-widget elementor-widget-heading" data-id="939f8d6" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Configuring Passkey for the Realm
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-5d03766 elementor-widget elementor-widget-text-editor" data-id="5d03766" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Keycloak provides flexible authentication options, traditionally relying on passwords and OTP-based multi-factor authentication (MFA). However, with the rise of passwordless security, Keycloak also supports WebAuthn Passwordless (Passkeys). In this setup, we will disable both passwords and OTP authenticators, ensuring that users can only log in using Passkeys. </span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-eefe7a4 elementor-widget elementor-widget-image" data-id="eefe7a4" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7420" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-241/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-241.png" data-orig-size="692,310" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-241" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-241-300x134.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-241.png" tabindex="0" role="button" width="692" height="310" src="https://inero-software.com/wp-content/uploads/2025/02/2025-02-241.png" class="attachment-large size-large wp-image-7420" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/2025-02-241.png 692w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-241-300x134.png 300w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-241-670x300.png 670w" sizes="(max-width: 692px) 100vw, 692px" data-attachment-id="7420" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-241/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-241.png" data-orig-size="692,310" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-241" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-241-300x134.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-241.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-7750103 elementor-widget elementor-widget-text-editor" data-id="7750103" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">The order of authenticators determines the login workflow in Keycloak. We keep the cookie authenticator to allow users to maintain active sessions. To support external authentication, we enable the Identity Provider Redirect, allowing users to log in via upstream providers like Google, or another Keycloak instance. Next, we configure the actual login form. By default, Keycloak&#8217;s browser flow includes username, password, and MFA authentication. We can disable everything in this section and replace it with a single step: adding a WebAuthn Passwordless Authenticator, ensuring that users can only log in using Passkeys. The final flow should look something like this:</span></p><p> </p>						</div>
				</div>
				<div class="elementor-element elementor-element-e24f589 elementor-widget elementor-widget-image" data-id="e24f589" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7421" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-242/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-242.png" data-orig-size="777,655" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-242" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-242-300x253.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-242.png" tabindex="0" role="button" width="777" height="655" src="https://inero-software.com/wp-content/uploads/2025/02/2025-02-242.png" class="attachment-large size-large wp-image-7421" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/2025-02-242.png 777w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-242-300x253.png 300w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-242-768x647.png 768w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-242-356x300.png 356w" sizes="(max-width: 777px) 100vw, 777px" data-attachment-id="7421" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-242/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-242.png" data-orig-size="777,655" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-242" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-242-300x253.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-242.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-805cc08 elementor-widget elementor-widget-text-editor" data-id="805cc08" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Once the WebAuthn Passwordless Authenticator is set up, the next step is to bind the authenticator to the browser login flow.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-b6799ff elementor-widget elementor-widget-image" data-id="b6799ff" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7422" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-243/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-243.png" data-orig-size="691,219" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-243" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-243-300x95.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-243.png" tabindex="0" role="button" width="691" height="219" src="https://inero-software.com/wp-content/uploads/2025/02/2025-02-243.png" class="attachment-large size-large wp-image-7422" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/2025-02-243.png 691w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-243-300x95.png 300w" sizes="(max-width: 691px) 100vw, 691px" data-attachment-id="7422" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-243/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-243.png" data-orig-size="691,219" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-243" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-243-300x95.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-243.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-3dae270 elementor-widget elementor-widget-text-editor" data-id="3dae270" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Now, all that’s left is to force a password reset for our sample user by setting the required action to </span><b>WebAuthn Register Passwordless</b><span style="font-weight: 400;">.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-f474406 elementor-widget elementor-widget-image" data-id="f474406" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7423" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-4/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-4.png" data-orig-size="721,298" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 4" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-4-300x124.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-4.png" tabindex="0" role="button" width="721" height="298" src="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-4.png" class="attachment-large size-large wp-image-7423" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-4.png 721w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-4-300x124.png 300w" sizes="(max-width: 721px) 100vw, 721px" data-attachment-id="7423" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-4/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-4.png" data-orig-size="721,298" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 4" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-4-300x124.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-4.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-64055b7 elementor-widget elementor-widget-text-editor" data-id="64055b7" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">After clicking the link in the received email, Keycloak will display a dialog instructing the user to </span><b>register their passkey</b><span style="font-weight: 400;">.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-c19dcb2 elementor-widget elementor-widget-image" data-id="c19dcb2" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7424" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-5/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-5.png" data-orig-size="677,329" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 5" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-5-300x146.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-5.png" tabindex="0" role="button" width="677" height="329" src="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-5.png" class="attachment-large size-large wp-image-7424" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-5.png 677w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-5-300x146.png 300w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-5-617x300.png 617w" sizes="(max-width: 677px) 100vw, 677px" data-attachment-id="7424" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-5/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-5.png" data-orig-size="677,329" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 5" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-5-300x146.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-5.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-dd5a7c2 elementor-widget elementor-widget-text-editor" data-id="dd5a7c2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Just click to register the passkey.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-9ea11f9 elementor-widget elementor-widget-image" data-id="9ea11f9" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7425" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-6/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-6.png" data-orig-size="574,231" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 6" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-6-300x121.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-6.png" tabindex="0" role="button" width="574" height="231" src="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-6.png" class="attachment-large size-large wp-image-7425" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-6.png 574w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-6-300x121.png 300w" sizes="(max-width: 574px) 100vw, 574px" data-attachment-id="7425" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-6/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-6.png" data-orig-size="574,231" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 6" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-6-300x121.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-6.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-c0e48a0 elementor-widget elementor-widget-text-editor" data-id="c0e48a0" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Your device&#8217;s platform authenticator will appear showing available options for confirming the user&#8217;s identity. Let&#8217;s assume we want to use Windows Hello and confirm identity with a PIN code &#8211; the same that is used when logging into the Windows account.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-2239416 elementor-widget elementor-widget-image" data-id="2239416" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7426" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-7/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-7.png" data-orig-size="532,670" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 7" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-7-238x300.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-7.png" tabindex="0" role="button" width="532" height="670" src="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-7.png" class="attachment-large size-large wp-image-7426" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-7.png 532w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-7-238x300.png 238w" sizes="(max-width: 532px) 100vw, 532px" data-attachment-id="7426" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-7/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-7.png" data-orig-size="532,670" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 7" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-7-238x300.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-7.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-4a3627a elementor-widget elementor-widget-image" data-id="4a3627a" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7427" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-8/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-8.png" data-orig-size="555,359" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 8" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-8-300x194.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-8.png" tabindex="0" role="button" width="555" height="359" src="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-8.png" class="attachment-large size-large wp-image-7427" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-8.png 555w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-8-300x194.png 300w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-8-464x300.png 464w" sizes="(max-width: 555px) 100vw, 555px" data-attachment-id="7427" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-8/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-8.png" data-orig-size="555,359" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 8" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-8-300x194.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-8.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-af69320 elementor-widget elementor-widget-text-editor" data-id="af69320" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">The passkey should now be visible in the credentials section of the specified user.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-7a17718 elementor-widget elementor-widget-image" data-id="7a17718" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7428" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24.png" data-orig-size="781,480" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-300x184.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24.png" tabindex="0" role="button" width="781" height="480" src="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24.png" class="attachment-large size-large wp-image-7428" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24.png 781w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-300x184.png 300w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-768x472.png 768w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-488x300.png 488w" sizes="(max-width: 781px) 100vw, 781px" data-attachment-id="7428" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24.png" data-orig-size="781,480" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-300x184.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-a0801c8 elementor-widget elementor-widget-text-editor" data-id="a0801c8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span id="docs-internal-guid-cd93915a-7fff-644a-0cbb-415915617b42"><span style="font-size: 12pt; font-family: Arial, sans-serif; color: #000000; background-color: transparent; font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-variant-position: normal; font-variant-emoji: normal; vertical-align: baseline; white-space-collapse: preserve;">Now we can go to the realm&#8217;s login page and try using our passkey instead of the standard username and password.</span></span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-5b7fcf8 elementor-widget elementor-widget-image" data-id="5b7fcf8" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7429" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-9/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-9.png" data-orig-size="586,201" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 9" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-9-300x103.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-9.png" tabindex="0" role="button" width="586" height="201" src="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-9.png" class="attachment-large size-large wp-image-7429" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-9.png 586w, https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-9-300x103.png 300w" sizes="(max-width: 586px) 100vw, 586px" data-attachment-id="7429" data-permalink="https://inero-software.com/an-introduction-to-passkey-with-keycloak/2025-02-24-9/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-9.png" data-orig-size="586,201" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2025-02-24 9" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-9-300x103.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/2025-02-24-9.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-077cb4b elementor-widget elementor-widget-text-editor" data-id="077cb4b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Your platform authenticator should appear again, offering to use the registered passkey.</span></p><p> </p><p><span style="font-weight: 400;">Passkeys aren’t perfect, but their benefits outweigh their drawbacks for most users. As adoption increases, many of these limitations will be addressed. However, in the short term, users and organizations need to be aware of potential challenges when integrating passkeys into their authentication workflows. Organizations seeking to integrate passkeys into their authentication systems can leverage tools like Keycloak. By integrating passkeys into Keycloak, organizations can provide users with secure, passwordless access to applications while still benefiting from Keycloak’s major features like Single Sign-On (SSO), multi-factor authentication (MFA), and fine-grained access control.</span></p>						</div>
				</div>
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/an-introduction-to-passkey-with-keycloak/">An introduction to Passkey with Keycloak</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7417</post-id>	</item>
		<item>
		<title>Cybersecurity: More Than Just Antivirus Software</title>
		<link>https://inero-software.com/cybersecurity-more-than-just-antivirus-software/</link>
		
		<dc:creator><![CDATA[Marta Kuprasz]]></dc:creator>
		<pubDate>Tue, 18 Feb 2025 12:54:19 +0000</pubDate>
				<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[BusinessProcessesOptimization]]></category>
		<category><![CDATA[cybersecurity]]></category>
		<category><![CDATA[keycloak]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=7231</guid>

					<description><![CDATA[<p>Cybersecurity experts point out that these techniques continue to evolve and adapt to better target potential victims. In 2025, it is worth paying attention to three key areas.</p>
<p>Artykuł <a href="https://inero-software.com/cybersecurity-more-than-just-antivirus-software/">Cybersecurity: More Than Just Antivirus Software</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="7231" class="elementor elementor-7231" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-12e4585 e-flex e-con-boxed e-con e-parent" data-id="12e4585" data-element_type="container">
					<div class="e-con-inner">
				<div class="elementor-element elementor-element-bc76512 elementor-widget elementor-widget-html" data-id="bc76512" data-element_type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
			 		</div>
				</div>
				<div class="elementor-element elementor-element-3fd29b7 elementor-widget elementor-widget-text-editor" data-id="3fd29b7" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h4>For many people, the first thing that comes to mind when talking about cybersecurity is antivirus software. However, modern cyber threats go far beyond traditional computer viruses. While antivirus software remains an important element of protection, an effective strategy for preventing attacks and minimizing the risk of data or financial loss must encompass a much broader range of tools and processes.</h4>						</div>
				</div>
				<div class="elementor-element elementor-element-2c09ad5 elementor-widget elementor-widget-text-editor" data-id="2c09ad5" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Cybercriminals have a vast arsenal of attack techniques and methods. In public discourse, terms such as phishing, ransomware, DDoS (Distributed Denial of Service) attacks, and social engineering are frequently mentioned.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-cebf6fb elementor-widget elementor-widget-heading" data-id="cebf6fb" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">On which threats should we focus in 2025?</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-242a0b8 elementor-widget elementor-widget-text-editor" data-id="242a0b8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Cybersecurity experts point out that these techniques continue to evolve and adapt to better target potential victims. In 2025, it is worth paying attention to three key areas:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-5f32fe9 elementor-widget__width-initial elementor-widget elementor-widget-facebook-embed" data-id="5f32fe9" data-element_type="widget" data-widget_type="facebook-embed.default">
				<div class="elementor-widget-container">
			<div style="min-height: 1px" class="elementor-facebook-widget fb-post" data-href="https://www.facebook.com/IneroSoftware/posts/pfbid0JL2d2Y1vxburNVFv8RYVzBFJKfsMtxtqnjDwnrSYP9njo4TmuG7TKUEYbGA1AWddl" data-show-text="false"></div>		</div>
				</div>
				<div class="elementor-element elementor-element-5d73e56 elementor-widget elementor-widget-heading" data-id="5d73e56" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h4 class="elementor-heading-title elementor-size-default">Passkeys are replacing passwords</h4>		</div>
				</div>
				<div class="elementor-element elementor-element-26ddf4b elementor-widget elementor-widget-text-editor" data-id="26ddf4b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Passwords remain a weak link. With the rise of phishing and authentication attacks, companies are shifting to passkeys—biometric or cryptographic authentication methods that enhance security and user convenience. Tech giants like Google and Apple are leading this transition.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-850c83f elementor-widget elementor-widget-heading" data-id="850c83f" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h4 class="elementor-heading-title elementor-size-default">Phishing is becoming hyper-personalized</h4>		</div>
				</div>
				<div class="elementor-element elementor-element-e3969c5 elementor-widget elementor-widget-text-editor" data-id="e3969c5" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Generic phishing emails are a thing of the past. Attackers now use in-depth research and social media data to create highly targeted campaigns that appear legitimate. AI-generated messages mimic real conversations, making social engineering more effective. Organizations must invest in advanced detection and employee awareness to stay protected.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-f2cb24e elementor-widget elementor-widget-heading" data-id="f2cb24e" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h4 class="elementor-heading-title elementor-size-default">Deepfakes are a growing threat</h4>		</div>
				</div>
				<div class="elementor-element elementor-element-48cf76b elementor-widget elementor-widget-text-editor" data-id="48cf76b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>AI-powered deepfake technology is becoming an increasing cybersecurity threat. Criminals use AI-generated profiles impersonating managers or other trusted individuals to bypass security measures and manipulate employees into revealing confidential information. One well-known method involves using filters during video calls to impersonate someone in real time. Companies must strengthen verification protocols and educate employees on detecting deepfakes.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-090c57a elementor-widget elementor-widget-heading" data-id="090c57a" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">When antivirus software is not enough</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-634421f elementor-widget elementor-widget-text-editor" data-id="634421f" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>Antivirus software is designed to detect, block, and remove malicious programs such as viruses, trojans, and spyware. Its functionality relies on databases of known threats. However, cybercriminal techniques are evolving beyond the capabilities of traditional antivirus solutions. Attacks like phishing, ransomware, social engineering, and deepfakes are not directly linked to classic malware and often require more advanced protection methods.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-7fb7ea2 elementor-widget elementor-widget-heading" data-id="7fb7ea2" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">How to stay secure?</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-ad58dd6 elementor-widget elementor-widget-text-editor" data-id="ad58dd6" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>First and foremost, by implementing modern authentication methods, identity management, and incident detection systems that can indicate potential attacks. This includes using multi-factor authentication (MFA), integrating with identity management systems like Keycloak, and monitoring activity through SIEM (Security Information and Event Management) tools. Such an approach enables real-time identification and response to unusual behavior that may signal a system compromise.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-dc608e7 elementor-widget elementor-widget-text-editor" data-id="dc608e7" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h5><a href="https://inero-software.com/security-information-and-event-management-systems-why-is-it-worth-adding-keycloak/">We wrote about why integrating Keycloak with a Security Information and Event Management (SIEM) system is worth considering here.</a></h5>						</div>
				</div>
				<div class="elementor-element elementor-element-1f7db8f elementor-widget elementor-widget-heading" data-id="1f7db8f" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Start by structuring the process</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-b0838c2 elementor-widget elementor-widget-text-editor" data-id="b0838c2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>A well-structured cybersecurity process begins with a thorough risk assessment and threat identification. At this stage, an organization inventories all IT assets, including devices, systems, applications, and data. It is crucial to determine which of these assets are the most sensitive and require special protection. Next, a risk analysis should be conducted to evaluate potential threats, their impact on business operations, and the likelihood of occurrence. This helps identify the key areas that require the most protection.</p><p> </p><p>The next step is to develop a comprehensive security policy. This includes a set of rules and procedures governing all aspects of technology use within the organization—from password and access management to guidelines for mobile device usage and remote work. At this stage, it is essential to consider applicable legal regulations, such as GDPR, and industry standards.</p><p> </p><p>Once policies are established, the next step is implementing the necessary security technologies and tools, such as the previously mentioned Keycloak. This stage involves integrating security measures like multi-factor authentication (MFA), data encryption, and IT infrastructure monitoring systems like SIEM (Security Information and Event Management). Simultaneously, mechanisms for regular software updates and data backups should be introduced to enable quick system recovery in the event of an incident.</p><p> </p><p>When designing a cybersecurity process, it is important to recognize that humans are often the weakest link in security. Increasing employee awareness through training programs is critical. These programs educate staff on different attack techniques and real-world examples, helping them identify potential threats.</p><p> </p><p>The final, but equally important, component is monitoring and incident response. Organizations should have clearly defined procedures for responding to security breaches, ensuring rapid detection, analysis, and mitigation of cyberattacks.</p>						</div>
				</div>
				<div class="elementor-element elementor-element-d699b05 elementor-cta--skin-cover elementor-hidden-mobile elementor-animated-content elementor-bg-transform elementor-bg-transform-zoom-in elementor-widget elementor-widget-call-to-action" data-id="d699b05" data-element_type="widget" data-widget_type="call-to-action.default">
				<div class="elementor-widget-container">
					<div class="elementor-cta">
					<div class="elementor-cta__bg-wrapper">
				<div class="elementor-cta__bg elementor-bg" style="background-image: url(https://inero-software.com/wp-content/uploads/2024/12/1-1030x1030.png);" role="img" aria-label="1"></div>
				<div class="elementor-cta__bg-overlay"></div>
			</div>
							<div class="elementor-cta__content">
				
									<h2 class="elementor-cta__title elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
						We will help you implement Keycloak					</h2>
				
									<div class="elementor-cta__description elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
						Schedule a meeting to learn how we can help you implement and fully manage Keycloak in your organization.					</div>
				
									<div class="elementor-cta__button-wrapper elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
					<a class="elementor-cta__button elementor-button elementor-size-" href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ3e3C_1YeBkt1uCr_qfOnG_N298UgLFwORcSTXigrPfOk0ls3ok-Uw_dSeGCoLdtYsN13GMm-n-">
						Schedule a meeting					</a>
					</div>
							</div>
						</div>
				</div>
				</div>
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/cybersecurity-more-than-just-antivirus-software/">Cybersecurity: More Than Just Antivirus Software</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7231</post-id>	</item>
		<item>
		<title>Behind the Scenes #2: Implementing email-based MFA in Keycloak</title>
		<link>https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/</link>
		
		<dc:creator><![CDATA[Marceli Formela]]></dc:creator>
		<pubDate>Thu, 13 Feb 2025 09:50:32 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Company]]></category>
		<category><![CDATA[Keycloak]]></category>
		<category><![CDATA[2FA]]></category>
		<category><![CDATA[emial]]></category>
		<category><![CDATA[IAM]]></category>
		<category><![CDATA[keycloak]]></category>
		<category><![CDATA[MFA]]></category>
		<category><![CDATA[Multi-Factor Authentication]]></category>
		<category><![CDATA[OTP]]></category>
		<guid isPermaLink="false">https://inero-software.com/?p=7042</guid>

					<description><![CDATA[<p>In this post, we’ll explore a custom MFA implementation that sends a one-time authentication code to the user’s email.</p>
<p>Artykuł <a href="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/">Behind the Scenes #2: Implementing email-based MFA in Keycloak</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></description>
										<content:encoded><![CDATA[		<div data-elementor-type="wp-post" data-elementor-id="7042" class="elementor elementor-7042" data-elementor-post-type="post">
				<div class="elementor-element elementor-element-091b893 e-flex e-con-boxed e-con e-parent" data-id="091b893" data-element_type="container">
					<div class="e-con-inner">
		<div class="elementor-element elementor-element-628ea76 e-con-full e-flex e-con e-child" data-id="628ea76" data-element_type="container">
				</div>
		<div class="elementor-element elementor-element-9ca8a9e e-con-full e-flex e-con e-child" data-id="9ca8a9e" data-element_type="container">
				<div class="elementor-element elementor-element-edd1fd0 elementor-widget elementor-widget-html" data-id="edd1fd0" data-element_type="widget" data-widget_type="html.default">
				<div class="elementor-widget-container">
			 		</div>
				</div>
				<div class="elementor-element elementor-element-3e56066 elementor-widget elementor-widget-text-editor" data-id="3e56066" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<h5><strong>Keycloak natively supports many secure login solutions and comes with built-in one-time password (OTP) mechanisms, such as authentication via mobile apps like Google Authenticator or our solution <a href="https://inero-software.com/introducing-authm8-a-free-cross-platform-2fa-solution-tailored-to-your-brand-for-secure-authentication/">AuthM8</a>. However, if we want to use other advanced authentication methods and for example send OTP codes via email, then similar to SMS multi factor authentication (more details <a href="https://inero-software.com/custom-sms-authenticator-with-keycloak/">HERE</a>), we need to implement this functionality ourselves. In this post, we’ll explore a custom MFA implementation that sends a one-time authentication code to the user’s email. </strong></h5>						</div>
				</div>
				<div class="elementor-element elementor-element-0994f82 elementor-widget elementor-widget-heading" data-id="0994f82" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">How does email-based MFA work?
</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-8e8909e elementor-widget elementor-widget-text-editor" data-id="8e8909e" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p>The authentication process consists of two main stages:</p>						</div>
				</div>
				<div class="elementor-element elementor-element-8435873 elementor-widget elementor-widget-text-editor" data-id="8435873" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li style="list-style-type: none;"><ul><li><b style="color: var( --e-global-color-text ); text-align: var(--text-align);">Generating and sending the MFA code</b></li></ul></li></ul><p><span style="font-weight: 400;">If the user already has an active cookie confirming a previous MFA verification, they should be immediately authenticated. Otherwise, Keycloak creates a new credential for the user and generates a one-time code based on configurable parameters like length or time-to-live.  The code is stored in the user’s credentials and then is emailed using the email provider.</span></p><p> </p><ul><li style="list-style-type: none;"><ul><li aria-level="1"><b>Verifying the entered code</b></li></ul></li></ul><p><span style="font-weight: 400;">When a user submits the code, KC retrieves the stored credential and compares the entered value. If the code is correct and still valid (not expired), authentication is successful, and a cookie is set to remember the verification. If the code is incorrect, the user is prompted to re-enter it and if the code has expired, an error message is shown and the process must be restarted.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-d65460b elementor-widget elementor-widget-image" data-id="d65460b" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7044" data-permalink="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/email-based-two-factor-authentication-flowchart/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART.png" data-orig-size="1920,1080" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="EMAIL-BASED TWO-FACTOR AUTHENTICATION FLOWCHART" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART-300x169.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART-1030x579.png" tabindex="0" role="button" width="1030" height="579" src="https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART-1030x579.png" class="attachment-large size-large wp-image-7044" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART-1030x579.png 1030w, https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART-300x169.png 300w, https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART-768x432.png 768w, https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART-1536x864.png 1536w, https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART-533x300.png 533w, https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART.png 1920w" sizes="(max-width: 1030px) 100vw, 1030px" data-attachment-id="7044" data-permalink="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/email-based-two-factor-authentication-flowchart/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART.png" data-orig-size="1920,1080" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="EMAIL-BASED TWO-FACTOR AUTHENTICATION FLOWCHART" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART-300x169.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/EMAIL-BASED-TWO-FACTOR-AUTHENTICATION-FLOWCHART-1030x579.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-5925a75 elementor-widget elementor-widget-heading" data-id="5925a75" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default"><strong data-start="157" data-end="185">Email MFA: Pros and Cons</strong> </h3>		</div>
				</div>
				<div class="elementor-element elementor-element-3c6c4e2 elementor-widget elementor-widget-text-editor" data-id="3c6c4e2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Email-based MFA offers additional security when the primary factor, such as a password, has been compromised. This is particularly helpful in cases where passwords are brute-forced or easily guessed, such as with common combinations like 123456. Similarly, this solution offers protection against credential stuffing, where attackers use leaked passwords from other breaches to attempt logging into account.</span></p><p><span style="font-weight: 400;">There are several other benefits to using email as a MFA:</span></p><ul><li style="list-style-type: none;"><ul><li aria-level="1"><span style="font-weight: 400;">Email MFA does not require users to provide additional sensitive information, such as a phone number, reducing concerns about privacy.</span></li></ul></li></ul><ul><li style="list-style-type: none;"><ul><li aria-level="1"><span style="font-weight: 400;">It does not require users to install a separate app or complete a complicated setup, which simplifies the process.</span></li></ul></li></ul><ul><li style="list-style-type: none;"><ul><li aria-level="1"><span style="font-weight: 400;"> </span><span style="font-weight: 400;">Users are accustomed to providing their email for various purposes, such as receiving important account updates or resetting passwords. This familiarity makes it more accessible.</span></li></ul></li></ul><p><span style="font-weight: 400;">However, email as a delivery channel does have some drawbacks. If an attacker compromises your email (gains access to an email account through stolen credentials or by exploiting an active session.), they could potentially reset other accounts’ passwords as well. For users in vulnerable situations, such as those with access to shared devices, email-based MFA can still leave them exposed. As with any security measure, it’s essential to weigh the benefits against the potential risks and mix email MFA with other safeguards, such as strong passwords policy and secure email practices.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-4fd89fe elementor-widget elementor-widget-heading" data-id="4fd89fe" data-element_type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
			<h3 class="elementor-heading-title elementor-size-default">Implementing Email MFA</h3>		</div>
				</div>
				<div class="elementor-element elementor-element-cfc16d2 elementor-widget elementor-widget-image" data-id="cfc16d2" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7045" data-permalink="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/zrzut-ekranu-2025-02-13-102335/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102335.png" data-orig-size="755,508" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Zrzut ekranu 2025-02-13 102335" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102335-300x202.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102335.png" tabindex="0" role="button" width="755" height="508" src="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102335.png" class="attachment-large size-large wp-image-7045" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102335.png 755w, https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102335-300x202.png 300w, https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102335-446x300.png 446w" sizes="(max-width: 755px) 100vw, 755px" data-attachment-id="7045" data-permalink="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/zrzut-ekranu-2025-02-13-102335/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102335.png" data-orig-size="755,508" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Zrzut ekranu 2025-02-13 102335" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102335-300x202.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102335.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-295f2c1 elementor-widget elementor-widget-text-editor" data-id="295f2c1" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">In this modified Browser Authentication Flow, we integrate our custom MFA as an additional authentication method. There are two new steps:</span></p><ul><li style="list-style-type: none;"><ul><li style="font-weight: 400;" aria-level="1"><b>MFA Email setup</b><span style="font-weight: 400;"> – this step ensures that email is set up and verified for the user before proceeding. If the user does not have a custom MFA Credential (which stores OTP codes as secrets), it will be set as well.</span></li></ul></li></ul>						</div>
				</div>
				<div class="elementor-element elementor-element-1cb9fd2 elementor-widget elementor-widget-text-editor" data-id="1cb9fd2" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">public class MfaEmailSetupAuthenticator implements Authenticator, CredentialValidator&lt;MfaEmailCredentialProvider&gt; {</span><br /><span style="font-weight: 400;">@Override</span><br /><span style="font-weight: 400;">public void authenticate(AuthenticationFlowContext context) {</span><br /><span style="font-weight: 400;">[…]</span><br /><span style="font-weight: 400;">// Require email verification</span><br /><span style="font-weight: 400;">if (!userModel.isEmailVerified()) {</span><br /><span style="font-weight: 400;">userModel.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);</span><br /><span style="font-weight: 400;">}</span><br /><span style="font-weight: 400;">// Add MFA email credential if not present</span><br /><span style="font-weight: 400;">if (!getCredentialProvider(context.getSession()).isConfiguredFor(realmModel, userModel, MfaEmailCredentialModel.TYPE)) {</span><br /><span style="font-weight: 400;">userModel.credentialManager().createStoredCredential(new MfaEmailCredentialModel(new MfaEmailCredentialData()));</span><br /><span style="font-weight: 400;">}</span><br /><span style="font-weight: 400;">[…]</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-6908dab elementor-widget__width-initial elementor-widget elementor-widget-image" data-id="6908dab" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7046" data-permalink="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/zrzut-ekranu-2025-02-13-102520/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102520.png" data-orig-size="635,398" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Zrzut ekranu 2025-02-13 102520" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102520-300x188.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102520.png" tabindex="0" role="button" width="635" height="398" src="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102520.png" class="attachment-large size-large wp-image-7046" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102520.png 635w, https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102520-300x188.png 300w, https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102520-479x300.png 479w" sizes="(max-width: 635px) 100vw, 635px" data-attachment-id="7046" data-permalink="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/zrzut-ekranu-2025-02-13-102520/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102520.png" data-orig-size="635,398" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Zrzut ekranu 2025-02-13 102520" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102520-300x188.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102520.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-eafd6c8 elementor-widget elementor-widget-text-editor" data-id="eafd6c8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li style="list-style-type: none;"><ul><li style="font-weight: 400;" aria-level="1"><b>MFA Email Authentication</b><span style="font-weight: 400;"> – this is the actual authentication step where a one-time code is sent via email. Marked as Alternative, meaning it can be used instead of other MFA methods like mobile app OTP.</span></li></ul></li></ul><p><span style="font-weight: 400;">Here, you can see how the configuration of this authenticator could look like in the Keycloak authentication flow.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-bdcf27f elementor-widget__width-initial elementor-widget elementor-widget-image" data-id="bdcf27f" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7047" data-permalink="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/zrzut-ekranu-2025-02-13-102652/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102652.png" data-orig-size="473,622" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Zrzut ekranu 2025-02-13 102652" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102652-228x300.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102652.png" tabindex="0" role="button" width="473" height="622" src="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102652.png" class="attachment-large size-large wp-image-7047" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102652.png 473w, https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102652-228x300.png 228w" sizes="(max-width: 473px) 100vw, 473px" data-attachment-id="7047" data-permalink="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/zrzut-ekranu-2025-02-13-102652/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102652.png" data-orig-size="473,622" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Zrzut ekranu 2025-02-13 102652" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102652-228x300.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-102652.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-10b800d elementor-widget elementor-widget-text-editor" data-id="10b800d" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<ul><li style="list-style-type: none;"><ul><li style="font-weight: 400;" aria-level="1"><b>Max Cookie Age</b><span style="font-weight: 400;"> this setting determines how long the MFA session (cookie) is valid. If the cookie is still valid, the user won&#8217;t be prompted for MFA. </span></li><li style="font-weight: 400;" aria-level="1"><b>Time-to-live</b><span style="font-weight: 400;"> indicates the lifetime of the MFA code.</span></li></ul></li></ul><p> </p><p><span style="font-weight: 400;">Now let’s take a look at the code. </span></p><p> </p><p><span style="font-weight: 400;">The method below handles the MFA process itself. If a valid cookie exists (indicating that the user has already completed MFA), the method immediately returns success, meaning the authentication flow is complete without requiring additional actions.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-89fa524 elementor-widget elementor-widget-text-editor" data-id="89fa524" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">@Override</span><br /><span style="font-weight: 400;">public void authenticate(AuthenticationFlowContext context) {</span><br /><span style="font-weight: 400;">if (hasValidCookie(context)) {</span><br /><span style="font-weight: 400;">context.success();</span><br /><span style="font-weight: 400;">return;</span><br /><span style="font-weight: 400;">}</span><br /><span style="font-weight: 400;">[…]</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-55ff859 elementor-widget elementor-widget-text-editor" data-id="55ff859" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">If there is no cookie, we should try to retrieve the user’s existing MFA credential from the credential provider. If the user doesn’t have one, a new instance is created using the MfaEmailCredentialModel which just extends the built-in CredentialModel:</span><span style="font-weight: 400;"><br /></span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-0af0624 elementor-widget elementor-widget-text-editor" data-id="0af0624" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">[…]</span><br /><span style="font-weight: 400;">// get existing credential or create a new one</span><br /><span style="font-weight: 400;">CredentialModel credentialModel = getCredentialProvider(session)</span><br /><span style="font-weight: 400;">.getDefaultCredential(session, context.getRealm(), user);</span><br /><span style="font-weight: 400;">if (credentialModel == null) {</span><br /><span style="font-weight: 400;">credentialModel = user.credentialManager().createStoredCredential(new MfaEmailCredentialModel(new MfaEmailCredentialData()));</span><br /><span style="font-weight: 400;">}</span><br /><span style="font-weight: 400;">[…]</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-c7af14a elementor-widget elementor-widget-text-editor" data-id="c7af14a" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Then the authenticate method reads configuration properties like code length and TTL (time-to-live). The code itself can be generated using some utils method and will be stored as the secretData in the credential model.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-6551375 elementor-widget elementor-widget-text-editor" data-id="6551375" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">// generate and store code</span><br /><span style="font-weight: 400;">int length = Integer.parseInt(configMap.get(CONFIG_CODE_LENGTH));</span><br /><span style="font-weight: 400;">int ttl = Integer.parseInt(configMap.get(CONFIG_CODE_TTL));</span><br /><span style="font-weight: 400;">String code = MfaEmailCodesUtils.generateCode(length);</span><br /><span style="font-weight: 400;">credentialModel.setSecretData(code);</span><br /><span style="font-weight: 400;">user.credentialManager().updateStoredCredential(credentialModel);</span><br /><span style="font-weight: 400;">AuthenticationSessionModel authSession = context.getAuthenticationSession();</span><br /><span style="font-weight: 400;">authSession.setAuthNote("ttl", Long.toString(System.currentTimeMillis() + (ttl * 1000L)));</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-b7f4d62 elementor-widget elementor-widget-text-editor" data-id="b7f4d62" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">In the end the sendCode method is called to send the generated code to the user’s email. If the email is sent successfully, the method presents the form where the user can enter the MFA code.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-dc63501 elementor-widget elementor-widget-text-editor" data-id="dc63501" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">// send email and show input form</span><br /><span style="font-weight: 400;">try {</span><br /><span style="font-weight: 400;">MfaEmailCodesUtils.sendCode(session, user, ttl, code, configMap);</span><br /><span style="font-weight: 400;">context.challenge(context.form().setAttribute("realm", context.getRealm()).createForm(TPL_CODE));</span><br /><span style="font-weight: 400;">} catch (Exception e) {</span><br /><span style="font-weight: 400;">context.failureChallenge(AuthenticationFlowError.INTERNAL_ERROR,</span><br /><span style="font-weight: 400;">context.form().setError("mfaEmailNotSent", e.getMessage())  .createErrorPage(Response.Status.INTERNAL_SERVER_ERROR));</span><br /><span style="font-weight: 400;">}</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-b41ad7b elementor-widget elementor-widget-text-editor" data-id="b41ad7b" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">The second major part of our Authenticator is the action method which handles the validation of the code entered by the user. It is invoked when the user submits the input form after receiving the email.  </span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-9551f9f elementor-widget__width-initial elementor-widget elementor-widget-image" data-id="9551f9f" data-element_type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
													<img loading="lazy" decoding="async" data-attachment-id="7048" data-permalink="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/zrzut-ekranu-2025-02-13-103114/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-103114.png" data-orig-size="663,391" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Zrzut ekranu 2025-02-13 103114" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-103114-300x177.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-103114.png" tabindex="0" role="button" width="663" height="391" src="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-103114.png" class="attachment-large size-large wp-image-7048" alt="" srcset="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-103114.png 663w, https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-103114-300x177.png 300w, https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-103114-509x300.png 509w" sizes="(max-width: 663px) 100vw, 663px" data-attachment-id="7048" data-permalink="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/zrzut-ekranu-2025-02-13-103114/" data-orig-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-103114.png" data-orig-size="663,391" data-comments-opened="0" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Zrzut ekranu 2025-02-13 103114" data-image-description="" data-image-caption="" data-medium-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-103114-300x177.png" data-large-file="https://inero-software.com/wp-content/uploads/2025/02/Zrzut-ekranu-2025-02-13-103114.png" role="button" />													</div>
				</div>
				<div class="elementor-element elementor-element-460cfb7 elementor-widget elementor-widget-text-editor" data-id="460cfb7" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">The method retrieves the user’s credential from the provider and then the code is validated by checking it against the stored credential using the custom isValid method.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-ff19a7e elementor-widget elementor-widget-text-editor" data-id="ff19a7e" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">[…]</span><br /><span style="font-weight: 400;">final MfaEmailCredentialModel credentialModel = getCredentialProvider(session)</span><br /><span style="font-weight: 400;">        .getDefaultCredential(session, context.getRealm(), user);</span><br /><span style="font-weight: 400;">boolean isValid = getCredentialProvider(session).isValid(context.getRealm(), user,</span><br /><span style="font-weight: 400;">    </span> <span style="font-weight: 400;">new UserCredentialModel(credentialModel.getId(), getCredentialProvider(context.getSession()).getType(), enteredCode));</span><br /><span style="font-weight: 400;">[…]</span></pre>						</div>
				</div>
				<div class="elementor-element elementor-element-7b502f8 elementor-widget elementor-widget-text-editor" data-id="7b502f8" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">If the code is valid, the next step is to check if it is expired. We can also set a cookie that stores the MFA session to prevent the user from </span><b>being prompted for MFA again</b><span style="font-weight: 400;"> during the cookie’s validity period.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-3db7437 elementor-widget elementor-widget-text-editor" data-id="3db7437" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<pre><span style="font-weight: 400;">[…]</span><br /><span style="font-weight: 400;">// valid</span><br /><span style="font-weight: 400;">HttpResponse response = context.getSession().getContext().getHttpResponse();</span><br /><span style="font-weight: 400;">response.setCookieIfAbsent(createCookie(context));</span><br /><span style="font-weight: 400;">context.success();</span><br /><span style="font-weight: 400;">[…]</span></pre><p><span style="font-weight: 400;"> </span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-83cf638 elementor-widget elementor-widget-text-editor" data-id="83cf638" data-element_type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
							<p><span style="font-weight: 400;">Of course, in this post, we will not cover the entire topic, omitting implementation details such as sending the code, generating the code, validation, and creating our custom cookie.</span></p><p><span style="font-weight: 400;"><br></span></p>
<p><span style="font-weight: 400;">However, we have walked through the major steps of implementing 2FA using email-based codes. On the one hand, this approach offers a simple and accessible solution. Although it has its drawbacks, using it in solutions like Keycloak helps mitigate many of these vulnerabilities. Keycloak also provides the flexibility to combine email-based MFA with other security measures, creating a more layered and resilient authentication process that can help protect against evolving cybersecurity threats.</span></p>						</div>
				</div>
				<div class="elementor-element elementor-element-a27180c elementor-cta--skin-cover elementor-animated-content elementor-bg-transform elementor-bg-transform-zoom-in elementor-widget elementor-widget-call-to-action" data-id="a27180c" data-element_type="widget" data-widget_type="call-to-action.default">
				<div class="elementor-widget-container">
					<div class="elementor-cta">
					<div class="elementor-cta__bg-wrapper">
				<div class="elementor-cta__bg elementor-bg" style="background-image: url(https://inero-software.com/wp-content/uploads/2024/11/tlo-popup-keycloak-1030x731.png);" role="img" aria-label="tło popup keycloak"></div>
				<div class="elementor-cta__bg-overlay"></div>
			</div>
							<div class="elementor-cta__content">
				
									<h3 class="elementor-cta__title elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
						Do you need help configuring multi-factor authentication?					</h3>
				
									<div class="elementor-cta__description elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
						Schedule a meeting to find out how we can help you.					</div>
				
									<div class="elementor-cta__button-wrapper elementor-cta__content-item elementor-content-item elementor-animated-item--grow">
					<a class="elementor-cta__button elementor-button elementor-size-" href="https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ3e3C_1YeBkt1uCr_qfOnG_N298UgLFwORcSTXigrPfOk0ls3ok-Uw_dSeGCoLdtYsN13GMm-n-">
						Schedule a meeting					</a>
					</div>
							</div>
						</div>
				</div>
				</div>
				</div>
		<div class="elementor-element elementor-element-6bc7752 e-con-full e-flex e-con e-child" data-id="6bc7752" data-element_type="container">
				</div>
					</div>
				</div>
		<div class="elementor-element elementor-element-091ddaf e-flex e-con-boxed e-con e-parent" data-id="091ddaf" data-element_type="container">
					<div class="e-con-inner">
					</div>
				</div>
				</div>
		<p>Artykuł <a href="https://inero-software.com/behind-the-scenes-2-implementing-email-based-mfa-in-keycloak/">Behind the Scenes #2: Implementing email-based MFA in Keycloak</a> pochodzi z serwisu <a href="https://inero-software.com">Inero Software - Software Consulting</a>.</p>
]]></content:encoded>
					
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">7042</post-id>	</item>
	</channel>
</rss>
