<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>Nutfield Security</title>
      <link>https://nutfieldsecurity.com</link>
      <description>Independent cybersecurity leadership for medical device and SaMD companies: board advisory, transaction due diligence, and FDA premarket and postmarket security.</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://nutfieldsecurity.com/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Mon, 15 Apr 2024 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Comply with FDA Device Security Requirements</title>
          <pubDate>Mon, 15 Apr 2024 00:00:00 +0000</pubDate>
          <author>Jamie Orlando</author>
          <link>https://nutfieldsecurity.com/posts/comply-with-fda-device-security-requirements/</link>
          <guid>https://nutfieldsecurity.com/posts/comply-with-fda-device-security-requirements/</guid>
          <description xml:base="https://nutfieldsecurity.com/posts/comply-with-fda-device-security-requirements/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;On September 27, 2023, the Food and Drug Administration (FDA) finalized it&#x27;s cybersecurity
guidance for medical devices titled,
&lt;strong&gt;Cybersecurity in Medical Devices: Quality System Considerations and Content of Premarket Submissions&lt;&#x2F;strong&gt; (&lt;a href=&quot;https:&#x2F;&#x2F;www.fda.gov&#x2F;media&#x2F;119933&#x2F;download?attachment&quot;&gt;link&lt;&#x2F;a&gt;).
Medical devices under review for FDA clearance use the published guidance as a framework to
demonstrate that effective policies and processes will be in place to maintain security throughout
the devices product lifecycle. The following table is intended to help organizations
trace their own internal practices to the controls defined by the FDA.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;table-of-controls&quot;&gt;Table of Controls&lt;&#x2F;h2&gt;
&lt;p&gt;The following table maps all current FDA cybersecurity documents and the controls they require.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;ID&lt;&#x2F;th&gt;&lt;th&gt;Category&lt;&#x2F;th&gt;&lt;th&gt;FDA Requirement&lt;&#x2F;th&gt;&lt;th&gt;Regulatory Mapping&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Avoid the use of implicit authentication mechanisms (ie. trusted IP addresses and handshakes that do not rely on cryptographic secrets).&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Use cryptographic authentication protocols&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Use cryptographically strong authentication, where the authentication functionality resides on the device, to authenticate personnel, messages, commands updates, and as applicable, all other communication pathways. Hardware-based security solutions should be considered and employed when possible&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Authenticate external connections at a frequency commensurate with the associated risks. For example, if a device connects to an offsite server, then the device and the server should mutually authenticate each session and limit the duration of the session, even if the connection is initiated over one or more existing trusted channels.&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Use appropriate user authentication (e.g., multi-factor authentication to permit privileged device access to system administrators, service technicians, or maintenance personnel, among others, as needed)&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Require authentication, and authorization in certain instances, before permitting software or firmware updates, including those updates affecting the operating system, applications, and anti-malware functionality&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Strengthen password protections. Do not use passwords that are hardcoded, default, easily guessed, or easily compromised (e.g., passwords that are the same for each device; unchangeable; can persist as default; difficult to change; and&#x2F;or vulnerable to public disclosure)&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Implement anti-replay measures in critical communications such as potentially harmful commands. This can be accomplished with the use of several methods including the use of cryptographic nonces (an arbitrary number used only once in a cryptographic communication)&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Provide mechanisms for verifying the authenticity of information originating from the device, such as telemetry. This is especially important for data that, if spoofed or otherwise modified, could result in patient harm, such as the link between a clinician programmer or monitoring device and an implanted device like a pacemaker, defibrillator, or neurostimulator; or the link between a continuous glucose monitor system and an automated insulin pump&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Do not rely on cyclic redundancy checks (CRCs) as security controls. CRCs do not provide integrity or authentication protections in a security environment. While CRCs are an error detecting code and provide integrity protection against environmental factors (e.g., noise or EMC), they do not provide protections against an intentional or malicious actor&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;Authentication&lt;&#x2F;td&gt;&lt;td&gt;Consider how the device and&#x2F;or system should respond in event of authentication failure(s)&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;Authorization&lt;&#x2F;td&gt;&lt;td&gt;Limit authorized access to devices through the authentication of users (e.g., user ID and password, smartcard, biometric, certificates, or other appropriate authentication method)&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;Authorization&lt;&#x2F;td&gt;&lt;td&gt;Use automatic timed methods to terminate sessions within the medical device system where appropriate for the use environment&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;Authorization&lt;&#x2F;td&gt;&lt;td&gt;Employ an authorization model that incorporates the principle of least privileges by differentiating privileges based on the user role (e.g., caregiver, patient, healthcare provider, system administrator) or device functions&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;Authorization&lt;&#x2F;td&gt;&lt;td&gt;Design devices to “deny by default” (i.e., that which is not expressly permitted by a device is denied by default). For example, the device should generally reject all unauthorized connections (e.g., incoming TCP, USB, Bluetooth, serial connections). Ignoring requests is one form of denying authorization.&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;Cryptography&lt;&#x2F;td&gt;&lt;td&gt;Select industry-standard cryptographic algorithms and protocols, and select appropriate key generation, distribution, management and protection, as well as robust nonce mechanisms.&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;Cryptography&lt;&#x2F;td&gt;&lt;td&gt;Use current NIST recommended standards for cryptography (e.g., FIPS 140-3, NIST Suite B), or equivalent-strength cryptographic protection that are expected to be considered cryptographically strong throughout the service life of the device. Manufacturers should not implement cryptographic algorithms that have been deprecated or disallowed in applicable standards or best practices (e.g., NIST SP 800-131A, Transitioning the Use of Cryptographic Algorithms and Key Lengths). Implementation of algorithms with a status of “legacy use” should be discussed with FDA during a pre-submission meeting&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;Cryptography&lt;&#x2F;td&gt;&lt;td&gt;Design a system architecture and implement security controls to prevent a situation where the full compromise of any single device can result in the ability to reveal keys for other devices. For example, avoid using master-keys stored on device, or key derivation algorithms based solely on device identifiers or other readily discoverable information.&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;Cryptography&lt;&#x2F;td&gt;&lt;td&gt;Implement cryptographic protocols that permit negotiated parameters&#x2F;versions such that the most recent, secure configurations are used, unless otherwise necessary&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;Cryptography&lt;&#x2F;td&gt;&lt;td&gt;Do not allow downgrades, or version rollbacks, unless absolutely necessary for safety reasons, and log and document the event. Downgrades can allow attackers to exploit prior, less protected versions and should be avoided&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Hardware-based security solutions should be considered and employed when possible&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Authenticate firmware and software. Verify authentication tags (e.g., signatures, message authentication codes (MACs)) of software&#x2F;firmware content, version numbers, and other metadata. The version numbers intended to be installed should themselves be signed or have MACs. Devices should be electronically and visibly identifiable (e.g., Unique device identifier (UDI), model number, serial number);&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Allow installation of cryptographically authenticated firmware and software updates, and do not allow installation where such cryptographic authentication either is absent or fails&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Ensure that all software and firmware on the device is protected from unauthorized access, modification, and deletion, regardless of whether the software and firmware resides within a virtual private network (VPN) or on the cloud. Maintain all software and firmware in a secure environment and perform routine security updates. Encrypt all software updates prior to transmission.&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Ensure that all software&#x2F;firmware changes are tracked and that the appropriate personnel review and approve these changes prior to implementation. Software or firmware changes that are not approved should not be allowed to execute. A cryptographic mechanism such as digital signatures should be used to ensure software&#x2F;firmware integrity (e.g., during updates or during execution) and to confirm that the software&#x2F;firmware originates from a known source, is up-to-date, and has not been tampered with&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Provide secure coding guidance to developers (e.g., guidance from the FDA, NIST, ISO, IEEE, etc.) and encourage compliance with industry-recognized secure coding standards. Review the software design and coding process for security vulnerabilities, especially those resulting from faulty design, implementation, or integration&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Implement and maintain secure software development lifecycle practices throughout the entire lifecycle of the device (e.g., requirements definition, design, implementation, verification, maintenance, and retirement)&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Incorporate security features into the design of the device, such as data execution prevention (DEP), address space layout randomization (ASLR), and stack overflow protections. These protections are intended to mitigate the risk of common software security vulnerabilities.&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Use hardware features designed to support security in depth, such as trusted platform modules (TPMs), secure enclaves, and hardware root of trust&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;30&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Design and implement software&#x2F;firmware updates to be secure by design. Ensure that updates can be verified for integrity, that they are resistant to man-in-the-middle attacks, and that updates are obtained from an authenticated source. Consider using secure boot mechanisms and encrypted channels for secure software&#x2F;firmware updates&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;31&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Implement runtime integrity protections to detect and prevent unauthorized changes to critical files, settings, and configurations. For example, deploy integrity monitoring solutions that can detect unauthorized changes to files, registry settings, and configuration parameters, and generate alerts or take other appropriate actions (e.g., halt, notify administrator)&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Employ controls to protect against rollback of software&#x2F;firmware updates to a less secure version. For example, use cryptographic hashes or signatures to ensure that software&#x2F;firmware updates have not been tampered with and that only signed updates are accepted and applied&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;33&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Implement measures to mitigate the risk of supply chain compromises, including tamper-evident packaging, supply chain visibility, and vetting of suppliers&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;34&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Ensure that all components, including open source and third-party software, are kept up-to-date with the latest security patches and updates. Establish a process for monitoring and applying patches and updates in a timely manner&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;35&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Ensure that code, data, and execution integrity mechanisms function properly throughout the lifecycle of the device. Test these mechanisms during design verification, validation, and during routine maintenance&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;36&lt;&#x2F;td&gt;&lt;td&gt;Code, Data, and Execution Integrity&lt;&#x2F;td&gt;&lt;td&gt;Develop a response plan for addressing vulnerabilities discovered post-market and take appropriate corrective actions to mitigate risk, which may include software patches, firmware updates, or other remediation measures. Ensure that post-market vulnerability assessments and remediation efforts follow a risk-based approach&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;37&lt;&#x2F;td&gt;&lt;td&gt;Confidentiality&lt;&#x2F;td&gt;&lt;td&gt;Ensure that sensitive data is encrypted both in transit and at rest using industry-standard encryption algorithms (e.g., AES, RSA, ECC) and appropriate key management practices&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;38&lt;&#x2F;td&gt;&lt;td&gt;Confidentiality&lt;&#x2F;td&gt;&lt;td&gt;Protect the confidentiality of sensitive data (e.g., patient information, device configurations, system logs) through access controls, encryption, and other appropriate means. Limit access to sensitive data to only those users and systems that require it for legitimate purposes&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;39&lt;&#x2F;td&gt;&lt;td&gt;Confidentiality&lt;&#x2F;td&gt;&lt;td&gt;Implement logging mechanisms to record access to sensitive data, security-related events, and other relevant activities. Ensure that logs are protected from unauthorized access, tampering, and deletion. Periodically review and analyze logs for indications of security incidents, unauthorized access, or other anomalies&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;40&lt;&#x2F;td&gt;&lt;td&gt;Confidentiality&lt;&#x2F;td&gt;&lt;td&gt;Provide a mechanism to allow authorized users (e.g., system administrators, healthcare providers) to access audit logs for review and analysis. Ensure that audit logs capture key security events (e.g., logins, failed login attempts, privilege changes, configuration changes, critical system events)&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;41&lt;&#x2F;td&gt;&lt;td&gt;Confidentiality&lt;&#x2F;td&gt;&lt;td&gt;Limit the collection, storage, and transmission of personally identifiable information (PII) and other sensitive data to only what is necessary for the intended purpose of the device. Encrypt any stored or transmitted PII or sensitive data&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;42&lt;&#x2F;td&gt;&lt;td&gt;Confidentiality&lt;&#x2F;td&gt;&lt;td&gt;Implement appropriate access controls and authorization mechanisms to prevent unauthorized access to sensitive data. Enforce the principle of least privilege by granting users only the access necessary to perform their authorized functions&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;43&lt;&#x2F;td&gt;&lt;td&gt;Confidentiality&lt;&#x2F;td&gt;&lt;td&gt;Encrypt communication channels to prevent eavesdropping, tampering, and other unauthorized access. Use secure protocols (e.g., TLS) and strong cryptographic algorithms to protect data in transit&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;44&lt;&#x2F;td&gt;&lt;td&gt;Confidentiality&lt;&#x2F;td&gt;&lt;td&gt;Protect sensitive data (e.g., PHI, PII) stored in the cloud by implementing appropriate security controls (e.g., encryption, access controls, data masking)&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;45&lt;&#x2F;td&gt;&lt;td&gt;Confidentiality&lt;&#x2F;td&gt;&lt;td&gt;Ensure that cloud service providers (CSPs) comply with applicable security and privacy regulations (e.g., HIPAA, GDPR) and provide assurances of compliance through contractual agreements, certifications, and third-party audits&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;46&lt;&#x2F;td&gt;&lt;td&gt;Integrity&lt;&#x2F;td&gt;&lt;td&gt;Use digital signatures, message authentication codes (MACs), or other cryptographic mechanisms to ensure the integrity of transmitted data, including commands, configuration data, and updates&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;47&lt;&#x2F;td&gt;&lt;td&gt;Integrity&lt;&#x2F;td&gt;&lt;td&gt;Protect against unauthorized modification of critical configuration settings, parameters, and other data that could affect the safety, effectiveness, or performance of the device. This includes preventing unauthorized changes to software, firmware, and hardware configurations&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;48&lt;&#x2F;td&gt;&lt;td&gt;Integrity&lt;&#x2F;td&gt;&lt;td&gt;Validate input data to ensure that it is well-formed, valid, and within acceptable ranges. Implement input validation controls to prevent buffer overflows, SQL injection, cross-site scripting (XSS), and other common attack vectors&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;49&lt;&#x2F;td&gt;&lt;td&gt;Integrity&lt;&#x2F;td&gt;&lt;td&gt;Employ integrity checks and checksums to detect unauthorized changes to firmware, software, and critical data. Perform regular integrity checks during operation and upon startup to ensure that the device has not been tampered with or compromised&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;50&lt;&#x2F;td&gt;&lt;td&gt;Integrity&lt;&#x2F;td&gt;&lt;td&gt;Implement controls to ensure the integrity of critical processes, including those related to device operation, data handling, and system configuration. These controls should prevent unauthorized access, tampering, and other forms of interference&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;51&lt;&#x2F;td&gt;&lt;td&gt;Integrity&lt;&#x2F;td&gt;&lt;td&gt;Use secure boot mechanisms to ensure that only trusted and authenticated firmware&#x2F;software is loaded and executed on the device. Validate the integrity of firmware&#x2F;software during the boot process and refuse to boot if the integrity checks fail&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;52&lt;&#x2F;td&gt;&lt;td&gt;Integrity&lt;&#x2F;td&gt;&lt;td&gt;Use hardware features such as secure boot, secure enclave, and hardware root of trust to protect against unauthorized modifications to firmware and critical system components&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;53&lt;&#x2F;td&gt;&lt;td&gt;Integrity&lt;&#x2F;td&gt;&lt;td&gt;Employ runtime integrity protections to detect and prevent unauthorized changes to critical files, settings, and configurations. Implement integrity monitoring solutions that can detect and respond to unauthorized changes in real-time&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;54&lt;&#x2F;td&gt;&lt;td&gt;Integrity&lt;&#x2F;td&gt;&lt;td&gt;Use cryptographic mechanisms to ensure the integrity of data stored in non-volatile memory (e.g., flash memory, EEPROM). Implement protections to prevent unauthorized modifications to stored data, including encryption, digital signatures, and access controls&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;55&lt;&#x2F;td&gt;&lt;td&gt;Non-repudiation&lt;&#x2F;td&gt;&lt;td&gt;Implement mechanisms to ensure the integrity and authenticity of data generated by the device, such as timestamps, digital signatures, and cryptographic hashes. These mechanisms should be used to provide non-repudiation, ensuring that the origin and integrity of data can be verified and attributed to specific sources&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;56&lt;&#x2F;td&gt;&lt;td&gt;Non-repudiation&lt;&#x2F;td&gt;&lt;td&gt;Ensure that audit logs and other records of device activity are tamper-evident and resistant to modification. Use cryptographic techniques to protect the integrity of logs and to provide evidence of tampering or unauthorized access&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;57&lt;&#x2F;td&gt;&lt;td&gt;Non-repudiation&lt;&#x2F;td&gt;&lt;td&gt;Implement controls to prevent the deletion, alteration, or tampering of audit logs and other records of device activity. Log entries should be time-stamped, and changes to logs should be logged and reviewed&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;58&lt;&#x2F;td&gt;&lt;td&gt;Non-repudiation&lt;&#x2F;td&gt;&lt;td&gt;Ensure that audit logs capture key security events (e.g., logins, failed login attempts, privilege changes, configuration changes, critical system events). Implement mechanisms to detect and respond to suspicious or anomalous behavior&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;59&lt;&#x2F;td&gt;&lt;td&gt;Non-repudiation&lt;&#x2F;td&gt;&lt;td&gt;Provide a mechanism for authorized users (e.g., system administrators, healthcare providers) to review and analyze audit logs. Implement access controls to restrict access to audit logs to authorized personnel&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;60&lt;&#x2F;td&gt;&lt;td&gt;Non-repudiation&lt;&#x2F;td&gt;&lt;td&gt;Use cryptographic techniques to provide non-repudiation for device commands and actions. Digital signatures and other cryptographic mechanisms should be used to ensure that commands and actions can be attributed to specific users or entities&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;61&lt;&#x2F;td&gt;&lt;td&gt;Resilience&lt;&#x2F;td&gt;&lt;td&gt;Implement resilience measures to ensure continued device functionality in the event of component failures, network interruptions, or other adverse conditions. This may include redundancy, failover mechanisms, and graceful degradation of non-essential services&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;62&lt;&#x2F;td&gt;&lt;td&gt;Resilience&lt;&#x2F;td&gt;&lt;td&gt;Design devices to recover gracefully from unexpected faults, errors, and exceptions. Implement error handling and recovery mechanisms to mitigate the impact of software bugs, hardware failures, and other faults&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;63&lt;&#x2F;td&gt;&lt;td&gt;Resilience&lt;&#x2F;td&gt;&lt;td&gt;Ensure that critical device functions (e.g., therapeutic delivery, patient monitoring) continue to operate correctly in the event of software or firmware failures. Implement safety-critical software in accordance with relevant standards (e.g., IEC 62304, ISO 14971) and perform thorough testing to validate safety and reliability&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;64&lt;&#x2F;td&gt;&lt;td&gt;Resilience&lt;&#x2F;td&gt;&lt;td&gt;Implement robust error detection and correction mechanisms to prevent or mitigate data corruption, transmission errors, and other forms of data loss or degradation. Use error checking and correction (ECC) codes, checksums, and other techniques to detect and correct errors in data transmission and storage&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;65&lt;&#x2F;td&gt;&lt;td&gt;Resilience&lt;&#x2F;td&gt;&lt;td&gt;Use redundant and diverse communication pathways (e.g., wired, wireless, cellular) to ensure continued connectivity in the event of network failures or disruptions. Implement failover mechanisms to automatically switch to alternate communication channels if primary channels become unavailable&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;66&lt;&#x2F;td&gt;&lt;td&gt;Resilience&lt;&#x2F;td&gt;&lt;td&gt;Employ backup and recovery mechanisms to protect against data loss and corruption. Regularly backup critical data and configurations, and test backup and recovery procedures to ensure their effectiveness. Store backups in a secure location, separate from the primary data storage, to prevent loss due to disasters or other catastrophic events&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;67&lt;&#x2F;td&gt;&lt;td&gt;Resilience&lt;&#x2F;td&gt;&lt;td&gt;Implement mechanisms to detect and respond to abnormal system behavior, such as resource exhaustion, memory leaks, and process crashes. Use monitoring tools and diagnostic capabilities to identify and troubleshoot issues before they impact device functionality&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;68&lt;&#x2F;td&gt;&lt;td&gt;Resilience&lt;&#x2F;td&gt;&lt;td&gt;Design devices to be modular and easily upgradeable to accommodate future enhancements and changes. Implement hot-swappable components and interfaces to minimize downtime during maintenance and upgrades&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;69&lt;&#x2F;td&gt;&lt;td&gt;Resilience&lt;&#x2F;td&gt;&lt;td&gt;Conduct thorough risk assessments and hazard analyses to identify potential failure modes, their impact on device performance, and mitigation strategies. Use failure mode and effects analysis (FMEA) and other risk management techniques to prioritize risks and develop resilience measures&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;70&lt;&#x2F;td&gt;&lt;td&gt;Resilience&lt;&#x2F;td&gt;&lt;td&gt;Establish a robust incident response plan to address security breaches, device failures, and other adverse events. Define roles and responsibilities, escalation procedures, and communication protocols for responding to incidents in a timely and effective manner&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;71&lt;&#x2F;td&gt;&lt;td&gt;Transparency and Traceability&lt;&#x2F;td&gt;&lt;td&gt;Provide transparent and accurate information about device security features, capabilities, and limitations to users, healthcare providers, regulators, and other stakeholders. Include security-related information in user manuals, labeling, and other documentation provided with the device&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;72&lt;&#x2F;td&gt;&lt;td&gt;Transparency and Traceability&lt;&#x2F;td&gt;&lt;td&gt;Maintain records of security-related activities, including security testing, vulnerability assessments, and remediation efforts. Keep documentation of security controls, configurations, and security incidents for auditing and regulatory purposes&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;73&lt;&#x2F;td&gt;&lt;td&gt;Transparency and Traceability&lt;&#x2F;td&gt;&lt;td&gt;Engage in proactive communication with customers and stakeholders regarding security vulnerabilities, patches, updates, and other security-related information. Establish channels for reporting security incidents, vulnerabilities, and concerns, and respond to reports in a timely and transparent manner&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;74&lt;&#x2F;td&gt;&lt;td&gt;Transparency and Traceability&lt;&#x2F;td&gt;&lt;td&gt;Provide clear and concise security advisories and alerts to inform users and administrators about security vulnerabilities, patches, updates, and other relevant information. Make security advisories readily accessible through multiple channels (e.g., websites, email notifications, social media)&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;75&lt;&#x2F;td&gt;&lt;td&gt;Transparency and Traceability&lt;&#x2F;td&gt;&lt;td&gt;Maintain a comprehensive inventory of all software and hardware components used in the device, including third-party libraries and dependencies. Keep records of version numbers, patch levels, and other relevant information to facilitate vulnerability management and risk assessment&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;76&lt;&#x2F;td&gt;&lt;td&gt;Transparency and Traceability&lt;&#x2F;td&gt;&lt;td&gt;Collaborate with regulators, industry groups, and other stakeholders to share information and best practices for medical device security. Participate in working groups, standards development organizations, and other forums to contribute to the advancement of medical device cybersecurity&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;77&lt;&#x2F;td&gt;&lt;td&gt;Transparency and Traceability&lt;&#x2F;td&gt;&lt;td&gt;Maintain accurate and up-to-date documentation for the device, including design specifications, security architecture, threat models, risk assessments, and security testing reports. Make documentation available to authorized users, regulators, and other stakeholders upon request&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;78&lt;&#x2F;td&gt;&lt;td&gt;Transparency and Traceability&lt;&#x2F;td&gt;&lt;td&gt;Provide mechanisms for reporting security vulnerabilities and concerns to the manufacturer, regulatory authorities, and other relevant organizations. Establish clear channels for receiving and triaging reports, and respond to reports in a timely and responsible manner&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;79&lt;&#x2F;td&gt;&lt;td&gt;Transparency and Traceability&lt;&#x2F;td&gt;&lt;td&gt;Implement procedures for reviewing and assessing third-party products and services used in the development and operation of the device. Evaluate the security posture of third-party vendors and conduct due diligence to ensure that they meet security requirements and standards&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;80&lt;&#x2F;td&gt;&lt;td&gt;Transparency and Traceability&lt;&#x2F;td&gt;&lt;td&gt;Conduct regular security assessments and audits to evaluate the effectiveness of security controls, identify vulnerabilities, and validate compliance with security requirements and standards. Use the results of assessments to improve security posture and mitigate risks&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;81&lt;&#x2F;td&gt;&lt;td&gt;Usability&lt;&#x2F;td&gt;&lt;td&gt;Design devices to be intuitive and easy to use, with clear and consistent user interfaces. Incorporate human factors engineering principles to optimize usability and minimize user errors&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;82&lt;&#x2F;td&gt;&lt;td&gt;Usability&lt;&#x2F;td&gt;&lt;td&gt;Provide user training and education to ensure that users understand how to operate the device safely and securely. Develop user manuals, training materials, and other educational resources to support users in learning and using the device effectively&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;83&lt;&#x2F;td&gt;&lt;td&gt;Usability&lt;&#x2F;td&gt;&lt;td&gt;Implement access controls and authorization mechanisms that balance security requirements with usability. Ensure that users can access the functions and information they need to perform their tasks without unnecessary barriers or impediments&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;84&lt;&#x2F;td&gt;&lt;td&gt;Usability&lt;&#x2F;td&gt;&lt;td&gt;Use clear and informative error messages to communicate with users in the event of errors, warnings, or other system events. Provide guidance on how to resolve issues and take appropriate actions&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;85&lt;&#x2F;td&gt;&lt;td&gt;Usability&lt;&#x2F;td&gt;&lt;td&gt;Incorporate feedback mechanisms to gather input from users and stakeholders about device usability, performance, and security. Use feedback to identify areas for improvement and inform future iterations of the device&lt;&#x2F;td&gt;&lt;td&gt;US FDA 2023 - Premarket&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
</description>
      </item>
      <item>
          <title>Implement SSO With Keycloak</title>
          <pubDate>Thu, 15 Feb 2024 00:00:00 +0000</pubDate>
          <author>Jamie Orlando</author>
          <link>https://nutfieldsecurity.com/posts/implement-sso-with-keycloak/</link>
          <guid>https://nutfieldsecurity.com/posts/implement-sso-with-keycloak/</guid>
          <description xml:base="https://nutfieldsecurity.com/posts/implement-sso-with-keycloak/">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;Authentication is hard. The selection pressure from Cheeto finger basement
hackers, sophisticated criminal organizations, and everyone in-between has led
to the development of new ideas and standards in web security in recent years.
Among these developments are two similarly named standards, &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Initiative_for_Open_Authentication&quot;&gt;OATH&lt;&#x2F;a&gt;
and &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;OAuth&quot;&gt;OAUTH&lt;&#x2F;a&gt;. OATH is an open standard for
Authentication (AuthN), while OAUTH is a standard for Authorization (AuthZ).
AuthN is the process of proving a principal is who they say they are and AuthZ
is the process of checking if a principal is allowed to perform the operation
they are asking to perform. AuthN and AuthZ, together with Accounting (the
appropriate logging of AuthN and AuthZ actions), make up the 3 dimensions of
the &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;AAA_(computer_security)&quot;&gt;AAA&lt;&#x2F;a&gt; security
model.&lt;&#x2F;p&gt;
&lt;p&gt;The focus of this post is to demonstrate how to use the open source
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;keycloak&#x2F;keycloak&quot;&gt;Keycloak SSO&lt;&#x2F;a&gt; to implement OATH
compliant authentication (AuthN) login flows for a SaaS application using the
OpenID Connect (OIDC) protocol. This architecture simplifies identity claims
for developers by allowing them to offload AuthN to a hardened service and
focus on consuming and validating JWT bearer tokens from the trusted identity
service. Additionally, it simplifies operational burden on application users by
allowing them to use one identity and credential across many related services.
Lastly, for fun, we will configure the realm to only support login with passkeys!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;passkeys&quot;&gt;Passkeys?&lt;&#x2F;h2&gt;
&lt;p&gt;Passkeys are a modern attempt to replace passwords using an app specific
cryptographic key pair that is managed for the user by a platform authenticator.
Platform authenticators are passkey API aware password managers that help users
automatically set strong, unique credentials for every application while also
validating the web app through a process called origin verification. These
mutliple touch points allow us to consider passkeys as MFA compliant credentials
for compliance standards such as SOC 2, HISTRUST, and ISO 2700x.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;install-keycloak&quot;&gt;Install Keycloak&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;a href=&quot;https:&#x2F;&#x2F;www.keycloak.org&#x2F;documentation&quot;&gt;Keycloak Documentation&lt;&#x2F;a&gt; describes
the Keycloak installation process for many different platforms. I generally
run services in container based environments, so I follow the docker&#x2F;podman
instructions. Ultimately, the underlying platform does not matter, as the
important configurations are done within a Keycloak realm.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; style=&quot;background-color:#2b303b;color:#6c7079;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;podman&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt; run&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt; --name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt; keycloak&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt; -p&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt; 8080:8080&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt; --replace &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;\
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;    -e&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt; KEYCLOAK_ADMIN=admin&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt; -e&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt; KEYCLOAK_ADMIN_PASSWORD=change_me \
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    quay.io&#x2F;keycloak&#x2F;keycloak:24.0.1 \
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    start-dev
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;create-a-realm&quot;&gt;Create a Realm&lt;&#x2F;h2&gt;
&lt;p&gt;Realms are the main subdivision of user pools in Keycloak. Often, a realm will
be dedicated per client company in a multi-tenant hosting scenario or per
logical app in an app factory scenario. This example uses the realm name, &lt;code&gt;sso.example.com&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-03-21-21-53-07.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Most user facing apps want some flavor of the following settings applied.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-03-21-21-58-28.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You will also want to ensure that both user and admin events are being saved.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-03-21-22-00-02.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For this example, I want to configure an SMTP connection to simulate a real
workflow without passwords.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-01-51-55.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configure-authenticators-for-the-realm&quot;&gt;Configure Authenticators for the Realm&lt;&#x2F;h2&gt;
&lt;p&gt;Keycloak is designed to support a handful of different authentication types.
Tradtitional architectures are built on top of passwords and OTP MFA devices.
In this example, we will disable passwords and OTP authenticators, and only
allow login with Passkeys (WebAuthn Passwordless).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-03-23-08-41-10.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configure-passkey-flow-for-the-realm&quot;&gt;Configure passkey flow for the Realm&lt;&#x2F;h2&gt;
&lt;p&gt;Keycloak authentication flows give administrators flexibilitiy in providing
different authentication mechanisms to end users. We will copy the default
browser flow which contains the vanilla username and password form and we
replace it with a passkey login.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-00-54-48.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Name it the &lt;em&gt;passkey-browser&lt;&#x2F;em&gt; flow or something else that makes sense to you.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-00-57-56.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The order of these authenticators defines the login process workflow. We leave
the cookie authenticator, as that allows users to maintain sessions to keycloak.
We remove the Kerberos login because we don&#x27;t like Windows systems flinging
credentials around. We allow the Identity Provider Redirect to allow login from
upstream providers like Google, Okta, or another Keycloak instance. The next
row starts to define the actual form. By default, the browser form supports
login with a username, password, and MFA if configured. We delete everthing in
that section and add a new step to add a WebAuthn Passwordless Authenticator.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-01-06-33.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The eventual flow should look similar to the following.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-01-08-07.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When you are done, you need to bind the authenticator to the browser login flow.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-01-09-17.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-a-test-user&quot;&gt;Create a Test User&lt;&#x2F;h2&gt;
&lt;p&gt;Now that we have a realm configured, we should create a user to test with.
This user should be registered to an email address you control.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-01-43-41.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Navigate to the new user, go to the Credentials tab, and then click to start
a Credential Reset.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-01-54-00.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Set the reset action to &lt;em&gt;Webauthn Register Passwordless&lt;&#x2F;em&gt; and send the email.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-01-55-11.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When the email arrives, click the magic link to register the user&#x27;s passkey.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-01-56-11.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Keycloak will show a dialog instructing the user to register their passkey,&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-01-56-48.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Click to register the passkey.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-01-57-52.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Your devices platform authenticator will pop up. This example is on Fedora,
so we use the 1password browser extension for passkey support.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-00-18.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Set a name for the newly registered passkey.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-00-57.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;A window will confirm that the account was successfully updated!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-01-23.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;test-the-passkey&quot;&gt;Test the Passkey&lt;&#x2F;h2&gt;
&lt;p&gt;Test the passkey by finding the login link under the SSO clients menu and
opening it in a new browser.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-02-52.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Keycloak will present the login page with a Sign in with Passkey button.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-03-57.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Your platform authenticator should pop up offering to use the registered passkey.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-05-17.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We are then successfully authenticated into Keycloak.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-06-32.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We can reconfirm the user only has a passkey configured as a credential.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-07-19.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;create-an-oidc-client&quot;&gt;Create an OIDC client&lt;&#x2F;h2&gt;
&lt;p&gt;Now we want to integrate Keyclaok with our web app. Navigate to clients and
create a client for the example web application.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-23-55.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;set a client name and other information.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-25-01.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Disable the Direct access grant flow and ensure the client is public.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-26-56.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Set valid redirect_uris. My example webapp will run at &lt;code&gt;http:&#x2F;&#x2F;loclhost:8000&#x2F;keycloak-example-login.html&lt;&#x2F;code&gt;
so I set the valid redirect links to be relative to that.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-02-28-38.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;deploy-the-web-app&quot;&gt;Deploy the web app&lt;&#x2F;h2&gt;
&lt;p&gt;My webapp code in HTML looks like the following.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;html&quot; style=&quot;background-color:#2b303b;color:#6c7079;&quot; class=&quot;language-html &quot;&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;lt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;DOCTYPE &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;html &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;lang&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;en&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;head&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;meta &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;charset&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;UTF-8&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;meta &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;viewport&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;content&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;width=device-width, initial-scale=1.0&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;title&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;Login with Keycloak&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;title&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;  &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;head&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;  &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;body&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;h1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;Login with Keycloak&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;h1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;button &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;onclick&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;login&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;()&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;Login with Keycloak&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;button&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;div &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;emailDisplay&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;style&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;display: none;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;Email: &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;span &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;id&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;email&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;span&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;div&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;script &lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;src&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;https:&#x2F;&#x2F;cdn.jsdelivr.net&#x2F;npm&#x2F;keycloak-js@24.0.2&#x2F;dist&#x2F;keycloak.min.js&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;script&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;script&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#5cb3fa;&quot;&gt;login&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;() {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Define Keycloak configuration URL
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;keycloakConfigUrl =
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;http:&#x2F;&#x2F;localhost:8080&#x2F;realms&#x2F;sso.example.com&#x2F;.well-known&#x2F;openid-configuration&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Fetch Keycloak configuration
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;fetch&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;keycloakConfigUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;)
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;response&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;!response&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.ok) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;throw &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f0c678;&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;Network response was not ok&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            }
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;response&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;json&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;();
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          })
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Construct login URL with email scope
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;loginUrl =
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;config&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.authorization_endpoint &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;+
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;?client_id=example-web-app&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;+
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;&amp;amp;redirect_uri=http:&#x2F;&#x2F;localhost:8000&#x2F;keycloak-example-login.html&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;+
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;&amp;amp;response_type=code&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;+ &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Request authorization code
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;&amp;amp;scope=openid&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;; &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Include openid scope
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Redirect to Keycloak login page
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            window.location.href &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;= loginUrl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          })
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            console.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#5ebfcc;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;Error fetching Keycloak configuration:&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          });
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      }
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#5cb3fa;&quot;&gt;displayEmail&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;email&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        document.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;getElementById&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;email&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;).innerText &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;= email&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        document.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;getElementById&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;emailDisplay&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;).style.display &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;block&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      }
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Function to parse and display email from JWT
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#5cb3fa;&quot;&gt;parseAndDisplayEmail&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;token&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;decodedToken = &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;JSON.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#5ebfcc;&quot;&gt;parse&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;atob&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;token&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;split&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;.&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;)[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#db9d63;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;]));
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;email = decodedToken&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.email;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;displayEmail&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;email&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      }
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Function to store tokens in session storage
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;function &lt;&#x2F;span&gt;&lt;span style=&quot;color:#5cb3fa;&quot;&gt;storeTokens&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;sessionStorage&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;setItem&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;access_token&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.access_token);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;sessionStorage&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;setItem&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;id_token&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.id_token);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Optionally store refresh token if available
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.refresh_token) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;sessionStorage&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;setItem&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;refresh_token&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.refresh_token);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        }
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      }
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Check if the URL contains a code parameter
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;urlParams = new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;URLSearchParams&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(window.location.search);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;urlParams&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;has&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;code&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;)) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;code = urlParams&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;code&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Once the code is received, exchange it for tokens
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;fetch&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;http:&#x2F;&#x2F;localhost:8080&#x2F;realms&#x2F;sso.example.com&#x2F;protocol&#x2F;openid-connect&#x2F;token&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            method: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;POST&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            headers: {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;Content-Type&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;application&#x2F;x-www-form-urlencoded&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            },
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            body: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;URLSearchParams&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;({
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              grant_type: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;authorization_code&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              client_id: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;example-web-app&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              redirect_uri: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;http:&#x2F;&#x2F;localhost:8000&#x2F;keycloak-example-login.html&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              code: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;code&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            }),
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          }
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;        )
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;response&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;if &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;!response&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.ok) {
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;throw &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;new &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f0c678;&quot;&gt;Error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;Failed to exchange code for tokens&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            }
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;response&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;json&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;();
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          })
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;then&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Store tokens in session storage
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;storeTokens&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#5f697a;&quot;&gt;&#x2F;&#x2F; Once the tokens are received, extract and display the email from the ID token
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;parseAndDisplayEmail&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;tokens&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;.id_token);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          })
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          .&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;catch&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;((&lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color:#cd74e8;&quot;&gt;=&amp;gt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;            console.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#5ebfcc;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#9acc76;&quot;&gt;&amp;quot;Error exchanging code for tokens:&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#adb7c9;&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;);
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;          });
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;      }
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;    &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;script&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;  &amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;body&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#eb6772;&quot;&gt;html&lt;&#x2F;span&gt;&lt;span style=&quot;color:#abb2bf;&quot;&gt;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On first load, the page just shows the keycloak login button.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-04-01-03.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;When we click the login button, we are redirected to our Keycloak instance.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-03-31-18.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We sign in with our Passkey and are redirected back to our web app. However,
we are now able to display the users email from the id token.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-03-33-17.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Further inspection shows that we have a valid JWT from the keycloak server to
pass to our APIs.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;Implement-SSO-With-Keycloak&#x2F;2024-04-13-03-45-33.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;This example demonstrates how to quickly configure a Keycloak realm to support
passkey login and integrate with a simple front end web app. Leveraging this
pattern allows us to quickly add standard authentication workflows to web apps
that are hardened and support the strongest MFA available.&lt;&#x2F;p&gt;
&lt;p&gt;Nutfield Security has deep experience implementing and improving authentication
systems. Please &lt;a href=&quot;&#x2F;contact&quot;&gt;Contact Us&lt;&#x2F;a&gt; to see how Nutfield Security can help
you implement Keycloak and Passkeys for your web app today.&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
