Keycloak in an AI platform: where it fits, what it solves and the two standards MCP requires and it does not implement
Contents
This post opens the identity block of the operations track. The previous one covered the gateway side: the JWT that does not validate audience, the user who never reaches the trace. This one covers the piece on the other side. Verified against Keycloak 26.7.3, revision 2026-07-28 of the MCP specification and the text of Royal Decree 311/2022 in the BOE.
TL;DR
Keycloak 26.7.3 was released on 31 August 2026 and is still incubating at the CNCF, which it entered in April 2023. The cadence is four minor releases a year and support in practice covers a single branch: the twenty security bugs fixed in 26.7.3 were not backported to the 26.4, 26.5 or 26.6 branches at the time of release.
The Quarkus-based distribution separates build and runtime configuration. What is set in the build phase is frozen into the image, and changing it at startup forces a rebuild. In containers, the pattern is to build into the image and start with the optimised flag.
Storage is relational and only relational. The alternative engine that was in development was withdrawn in version 25.0. Since 26.0 sessions are persisted to the database by default, which changes the load profile: the dominant cost in the official benchmarks is database CPU.
Organisations solves multi-tenancy inside a realm, fully supported since 26.0. It groups members, associates email domains and links identity providers per organisation. It is the alternative to replicating realms per customer.
The measured bottleneck is password hashing. Since 25.0 the default algorithm outside FIPS environments is Argon2, with around 7 MB of memory per operation. The official sizing guide gives one vCPU for every 15 password logins per second, against 120 per second for client credentials and for refreshes.
Keycloak does not implement two standards the MCP specification marks as mandatory. Protected resource metadata belongs to the MCP server, not the authorisation server, so there is nothing to hold against it there. Resource indicators do belong to it and are not supported. Keycloak’s own documentation declares partial conformance with the last three MCP revisions for that reason. The practical substitute is scopes plus an audience mapper.
There is a recent critical bug worth looking at today. CVE-2026-18963, scored 9.1, allowed resetting any user’s password without authenticating, administrators included. Fixed in 26.7.2, released on 19 August 2026.
You are here: the cross-cutting layer
Identity is not a stage of the pipeline, it is a layer that crosses all of them. It shows up in stack hardening as one of the seven layers of defence, in the model’s chain of trust as workload identity, in the gateway as token validation, and in the post about authenticating MCP servers as authorisation server.
What was missing was the post about the piece itself, and above all the decision of where to put it and what to expect from it.
The analogy: the civil registry and building permits
A small town hall has a population register, which says who lives there, and it has permits, which say who can do what. They are two different things and it is worth not confusing them, because the register is good for the whole town while a permit is good for one specific job on one specific street.
Keycloak is the register. It knows who each person is, identifies them reliably, knows which groups they belong to and issues a credential document that expires. What it does not do is decide whether this person can modify this particular file: that is the permit, and it lives in each service.
Confusing the two produces the most expensive design mistake in platforms of this kind, which consists of putting into the token everything that will need to be decided later. The register document grows, gets handed out everywhere, and when a permission changes you have to wait for everyone’s document to expire.
There is a third element the analogy captures well. A credential document issued for presenting at the tax office should not be good for entering the municipal depot. That is the token’s audience, and it is the central subject of the second half of this post.
Part 1. What Keycloak is today
Project status
| Item | Value |
|---|---|
| Latest stable version | 26.7.3, released on 31 August 2026 |
| Previous ones | 26.7.2 (19 August), 26.7.0 (9 July), 26.6.0 (8 April) |
| Cadence | four minor releases a year |
| CNCF | incubating since 10 April 2023, not graduated |
| Support | the current branch; earlier ones do not receive fixes reliably |
That last point deserves underlining because it conditions the upgrade policy. The analysis of 26.7.3 shows that its twenty security fixes were not backported to earlier branches at release time. Operating Keycloak means keeping up to date with the current branch, not staying on a “stable” version for a year.
Since 26.0 there is a backward compatibility guarantee across minor versions for features marked as fully supported, and breaking changes are opt-in.
The internal architecture in five pieces
Two startup modes. The development one enables HTTP, does not resolve the hostname strictly and disables the theme cache. The production one requires a hostname and TLS, or it will not start. Confusing them in production is the first antipattern on the final list.
The build phase. The build command materialises the optimisations into the image. Build options, such as the database engine, the enabled features or metrics, are frozen. Runtime ones, such as the database password or the hostname, are applied at startup. Changing a build option at startup forces a rebuild with the corresponding latency cost. The correct pattern in containers is to build into the image and start with the optimised flag.
Extensions via SPI. Authenticators, protocol mappers, user storage, event listeners, hashing algorithms and secret vaults. They are packaged as JARs and resolved in the build phase.
Infinispan cache. Embedded by default, with database-based discovery as the recommended mechanism. The discovery alternatives via Kubernetes DNS, TCP and UDP are deprecated. There are local caches, with default capacities of 10,000 entries in several of them, and replicated caches for sessions, client sessions, offline sessions, authentication sessions, login failures and action tokens. Remote mode, with an external Infinispan, is needed for first-generation multi-site deployment.
Relational storage. JPA over a database. The alternative engine was removed in version 25.0. The databases supported today include PostgreSQL from 14 to 18, MariaDB and MySQL in their extended support versions, SQL Server 2019 and 2022, Oracle 19c and 23.x, and the managed variants Aurora PostgreSQL and Azure SQL.
The minimum conceptual model
Before touching anything you need to be clear on eight concepts, and the order in which they relate:
- Realm: the isolation boundary. Its own users, its own signing keys, its own policies. Two realms share nothing.
- Client: an application that asks for tokens. Public if it cannot keep a secret, such as a browser application; confidential if it can, such as a service; and bearer-only if it merely validates tokens without requesting them.
- Client scope: a reusable bundle of scopes and mappers, assigned to clients as default or as optional. It is the unit with which you bound what a token carries.
- Protocol mapper: what projects an attribute, a role or an audience into the token. The audience mapper is the one that solves the central problem of this post.
- Role, realm or client, and composite role, which aggregates others.
- Group, hierarchical, with inherited roles and attributes.
- Identity provider: federation towards another external OIDC or SAML. User federation: LDAP, Active Directory and Kerberos, with synchronisation and attribute mapping.
- Authentication flow: a sequence of executions with required, alternative, conditional or disabled requirements, and subflows. It is where you build a second factor or a check of your own.
And one feature that changes architectures: organisations, fully supported since 26.0. It solves multi-tenancy inside a single realm, grouping members, associating email domains and linking identity providers per organisation, so that provider discovery is done by the user’s email domain. The classic alternative, one realm per customer, multiplies administration and shares no configuration.
Part 2. Who can authenticate against it
This is the table you need before drawing anything. The right-hand column is usually the one that decides.
| Piece | Protocol | Cost |
|---|---|---|
| Kubernetes API | native OIDC, or the structured authentication configuration file | Free |
| LiteLLM | OIDC and JWT, plus UI SSO | JWT and SSO above five users: Enterprise |
| vLLM | static key only | No OIDC |
| Langfuse | generic OIDC and Keycloak provider | SSO free; per-project access control: Enterprise |
| Grafana | generic OAuth yes in the open edition | Team synchronisation: Enterprise |
| Backstage | generic OIDC and community-maintained Keycloak provider | Free |
| Open WebUI | OIDC, with role management by claim | Free |
| LibreChat | generic OIDC, with Keycloak documented | Free |
| Argo CD | native OIDC or Dex, with groups into its RBAC file | Free |
| MinIO | OIDC with role assumption via web identity | See the note below |
Two clarifications that change decisions.
Kubernetes. The modern mechanism is structured authentication configuration, which allows several JWT issuers plus validations and mappings with CEL expressions. The corresponding proposal, KEP-3331, went alpha in 1.29, beta in 1.30 and is stable since 1.34. It is the route to use today, and it replaces the loose API server flags.
vLLM has no identity. All there is is a static key via environment variable. This is not a defect to fix, it is an architectural fact: the engine sits behind the gateway and its access control is network-based, not identity-based. Any design that exposes vLLM directly to users is giving up per-person traceability.
About MinIO a note of honesty is in order: the public documentation now redirects to the commercial edition, so the detail of how it maps policies from a claim is verified there and not in the open edition. Anyone depending on that mechanism should confirm it against their own version before designing on top of it.
Part 3. Humans and machines
They are two different problems and it is worth solving them separately.
People
Authorization code with PKCE, with the S256 method. The MCP specification requires it when the client is technically capable, and it goes further: it mandates rejecting the flow if the authorisation server metadata does not publish the supported challenge methods.
Workloads with no person behind them
Here the obvious option is client credentials with a Keycloak service account, authenticated with a secret or, better, with a JWT signed by private key.
But there is a less known and better option for workloads inside the cluster: federated client authentication, introduced in January 2026 under the banner of doing away with secrets. It lets a client authenticate with a token issued by an external provider, and one of those providers is Kubernetes. The announcement placed full support for the Kubernetes service account variant and for OIDC in version 26.6; the SPIFFE variant, by contrast, expressly says it will stay in preview until the SPIFFE client authentication standard is finalised at the IETF.
That means a pod can authenticate against Keycloak with the token the kubelet already projects into it, with no additional secret to rotate. It is worth confirming the exact status and the flag name against the release notes of whichever version you have deployed, because the feature is recent and has changed status between 26.5 and 26.6. It is preferable to token exchange, whose standard version is supported but is internal-to-internal only, while the old one, which covered external-to-internal and impersonation, is deprecated and in preview.
Keycloak against SPIFFE
The question always comes up and the answer is that they solve different things with a small overlap.
SPIRE attests the node and the process, and issues short-lived identity documents with no prior secret. Keycloak does not attest workloads: it trusts a credential someone had to place there, except in the federated authentication case just mentioned, where the one attesting is Kubernetes. In exchange, Keycloak federates people, issues tokens with business data and governs consent, things SPIFFE does not do.
The practical rule: SPIFFE for service-to-service identity inside the perimeter, Keycloak for anything that has a person behind it or crosses the perimeter. The SPIFFE detail is in the close of the chain of trust series.
Part 4. MCP, and the two missing standards
This part has the most consequences and is the worst documented outside the primary sources.
What the specification requires
From revision 2026-07-28, with the normative words as they appear:
- The MCP server must implement RFC 9728 protected resource metadata, and the client must use it to discover the authorisation server.
- The client must implement RFC 8707 resource indicators, including the
resourceparameter in both the authorisation request and the token request, and must send it regardless of whether the authorisation server supports it. - The MCP server must validate that the access token was issued specifically for it as the audience, and must not accept or relay any other token.
- Authorisation servers and clients should support client identifier metadata documents. RFC 7591 dynamic registration becomes optional and is declared deprecated, retained for compatibility.
The revision also adds the issuer in the authorisation response, from RFC 9207, and a stateless model with state handlers where it is expressly stated that holding a state handler is not equivalent to being authenticated.
What Keycloak supports
From its own MCP integration guide:
| Standard | Keycloak |
|---|---|
| OAuth 2.1 and authorisation server metadata | Supported |
| RFC 9207, issuer in the response | Supported |
| RFC 7591, dynamic registration | Supported |
| Client identifier metadata document | Supported, experimental, after enabling the feature |
| RFC 8707, resource indicators | Not supported |
| RFC 9728, protected resource metadata | Out of scope, it belongs to the MCP server |
The conformance declared by the project itself is “partially supported, without resource indicators” for the last three MCP revisions.
Two practical conclusions:
- The protected resource metadata document is published by the MCP server or a proxy in front of it, never by Keycloak. That is correct and there is nothing to fix, but you have to remember to implement it, because the client needs it to discover where to go.
- Without resource indicators, the audience is bounded with scopes. The official route is to use the
scopeparameter instead ofresource, and to hang from that client scope an audience mapper with the MCP server URL as the included custom audience.
It is a workaround, it works, and it has to be documented in the design because anyone coming after will look for the standard parameter and will not find it.
Part 5. The confused deputy
With the above on the table, the classic mistake becomes obvious on its own. A token with a generic audience turns any compromised service into a master key: whoever obtains the token a user presented to the dashboard can present it to the gateway, and from there to the MCP server.
The MCP specification is explicit in three sentences worth quoting verbatim in any architecture document:
- MCP servers must not accept tokens that were not explicitly issued for them.
- If the MCP server calls upstream APIs, it must not forward the token it received from the client.
- MCP proxies that use static client identifiers must obtain user consent for each dynamically registered client before forwarding to third-party authorisation servers.
Translated into the specific figure this track has been dealing with: the gateway must not forward the user’s JWT to third-party MCP servers. It has to obtain a different token with the right audience, or act as an OAuth client in its own right. By default, as already documented in the MCP gateway post, the behaviour is to use the server’s own credential, which is the correct one; there are two modes that forward the caller’s token and both have a name in the specification.
Part 6. Two hours of task against five minutes of token
The specification pushes towards short-lived tokens and mandatory refresh token rotation in public clients. A two-hour agentic task comfortably exceeds the life of an access token and may also exceed session idle time if nobody refreshes.
Three real options, with their cost:
Offline tokens. They survive session expiry, and expire through their own idle timeout or through a maximum if that limit is enabled. The risk is obvious: a near-permanent credential, hard to inventory. And the MCP specification adds that MCP servers should not include that scope either in the authentication header or in the supported scopes of their metadata.
Automatic refresh in the client. It is the right answer when there is a client that can implement it, with refresh token rotation and secure storage. For an agent with no person behind it, it is better to renew via client credentials.
Long-lived virtual keys in the gateway. It works, and it is what most people end up doing. The price has to be written down in the risk analysis: identity ends up decoupled from the provider, so deactivating someone in Keycloak does not invalidate their key, and traceability back to the real person depends on the discipline with which the keys were created. The levers that compensate are expiry, automatic rotation and a mandatory alias, covered in the virtual keys post.
A note of honesty about the default values. The numbers going around (five minutes of access token, thirty of session idle time, ten hours of maximum) do not appear published in the administration guide and I did not locate them in the code. Treat them as a console observation and confirm them in your own realm before quoting them in a document.
Part 7. Sizing and operating
On Kubernetes
The operator exposes three custom resources: the server, the realm import and the OIDC client. Probes and metrics live on management port 9000, with the health and readiness paths, and metrics in Prometheus format provided the corresponding option was enabled in the build phase. That port is not exposed publicly.
For high availability there are three shapes. A single cluster spread across zones, with no additional infrastructure. First-generation multi-cluster, with an external load balancer and an external Infinispan at each site. And second-generation multi-cluster, introduced in 26.7.0 and still in preview, which connects clusters without external Infinispan, using the synchronously replicated database as the source of truth, with less cache and more database load.
The official sizing figures
From the CPU and memory sizing concepts guide, which is still published:
- 1 vCPU for every 15 password logins per second, tested up to 300 per second.
- 1 vCPU for every 120 client credential grants per second, tested up to 2,000.
- 1 vCPU for every 120 token refresh requests per second, tested up to 435.
- Leave a 150 % CPU headroom for spikes, startup and failover.
- 1,250 MB of memory per pod with realm data and 10,000 cached sessions. Keycloak allocates 70 % of the limit to the heap and around 300 MB outside it, so the limit comes from subtracting those 300 MB from the expected usage and dividing by 0.7.
The stated assumptions behind those figures include Argon2 with five iterations, sessions in the database and the default cache of 10,000 entries.
The difference between 15 and 120 is the whole story of Keycloak’s performance: the cost is in password hashing. Since 25.0, the default algorithm outside FIPS environments is Argon2, with around 7 MB of memory per operation. Before it was PBKDF2, whose iterations were multiplied by ten in version 24. In FIPS mode PBKDF2 is still used.
From that comes an architectural consequence for an AI platform: machine workloads, which go through client credentials, cost eight times less than a human login. Sizing by number of services is cheap; sizing by morning login peaks is the expensive part.
The benchmark
From the 26.4 performance report, published on 1 October 2025: up to 2,000 logins per second and 10,000 refreshes per second with three pods, 74 vCPU in total and 8 GB per pod, over an Aurora PostgreSQL database, with almost linear vertical scaling.
Two useful findings from that report. With 20 ms of round-trip time between sites, the 99th percentile rises from 51 to 130 ms, and the project advises against deploying across different regions. And raising the cache from 10,000 to 200,000 entries brought the database CPU peak down from 77.77 % to 63.77 %, in exchange for somewhat longer garbage collection pauses.
Security
The urgent matter, if the deployment is below 26.7.2:
CVE-2026-18963, score 9.1, critical. A bypass of the email action token in the credential reset flow allowed resetting any user’s password with no prior authentication, administrators included. Fixed in 26.7.2, released on 19 August 2026. The temporary mitigation, if you cannot upgrade, is to disable password recovery in all realms. No known exploitation was recorded as of the end of August.
In 26.7.3 there are another nineteen, among them the missing hostname verification in the TLS certificate towards LDAP with a score of 8.8, two tenant restriction bypasses in token exchange with Microsoft and Google brokers, and two access control bypasses in organisations.
Official hardening comes down to four decisions:
- Strict hostname, which is the default value since the second generation of that configuration. The server does not infer the URL from headers, which prevents poisoning email links and redirects.
- Administration console on a different hostname, and network-restricted.
- Proxy headers declared explicitly, trusting only a controlled reverse proxy.
- Separate management port, not exposed.
Part 8. The mapping to the ENS
The codes and titles below are verified against the official text of Royal Decree 311/2022 published in the BOE, Annex II.
| Code | Literal title | What a central IdP contributes |
|---|---|---|
| op.acc.1 | Identificación | A unique identifier per entity, user or process that gains access |
| op.acc.2 | Requisitos de acceso | Permissions are granted by role and group, not by loose credential |
| op.acc.3 | Segregación de funciones y tareas | It supports it with roles, but the control is organisational |
| op.acc.4 | Proceso de gestión de derechos de acceso | Least privilege and a specific remote access policy |
| op.acc.5 | Mecanismo de autenticación (usuarios externos) | Flows and factors configurable per flow |
| op.acc.6 | Mecanismo de autenticación (usuarios de la organización) | Reinforcements required already at the low level |
| op.exp.8 | Registro de la actividad | It contributes part of the events, not all of them |
| op.exp.10 | Protección de claves criptográficas | Management and rotation of the realm signing keys |
Two nuances an auditor is going to look for.
The first, about op.acc.1: the text requires every entity that accesses the system, whether user or process, to have a unique identifier. That includes agents. A virtual key shared between several agents does not comply, and that is exactly what usually happens when JWT authentication falls outside the budget.
The second, about op.exp.8: the control requires recording the identifier of the user or entity associated with the event, the date and time, what information it is performed on, the type and the result. Keycloak contributes the authentication events. The usage events are contributed by the gateway and the MCP servers, and there the two already documented gaps reappear: adding and removing MCP servers generates no audit log and the trace user is set by the client.
The correspondence between control and product in this table is my own interpretation and must be validated by the certification body. The codes and titles are not: those are literal from the BOE.
Part 9. The configuration to leave written down
Three concrete pieces, so as not to stay at the level of concepts.
Hardened startup, as container arguments:
kc.sh start --optimized \
--hostname=https://sso.ejemplo.es \
--hostname-admin=https://sso-admin.interna.ejemplo.es \
--proxy-headers=xforwarded \
--health-enabled=true \
--metrics-enabled=true \
--http-management-port=9000 \
--cache=ispn --cache-stack=jdbc-ping \
--db=postgres
The metrics, health, cache and database options are build options: they go into the image, and passing them here forces a rebuild if they do not match.
The client scope with audience, which is the workaround forced by the lack of resource indicators. Created with the administration tool:
# one scope per protected resource
kcadm.sh create client-scopes -r plataforma \
-s name=mcp-inventario -s protocol=openid-connect \
-s 'attributes."include.in.token.scope"=true'
# the mapper that sets the token audience
kcadm.sh create "client-scopes/<id>/protocol-mappers/models" -r plataforma \
-s name=aud-mcp-inventario \
-s protocol=openid-connect \
-s protocolMapper=oidc-audience-mapper \
-s 'config."included.custom.audience"=https://mcp.ejemplo.es/inventario' \
-s 'config."access.token.claim"=true'
The client asks for that scope and receives a token whose audience is only that MCP server. The MCP server validates the audience and rejects any other token, as the specification requires.
Realm import via GitOps, with the operator’s custom resource, so that the configuration does not live only in the console:
apiVersion: k8s.keycloak.org/v2beta1
kind: KeycloakRealmImport
metadata:
name: plataforma
namespace: identidad
spec:
keycloakCRName: sso
realm:
realm: plataforma
enabled: true
# without this, the recovery email is attack surface
resetPasswordAllowed: false
bruteForceProtected: true
sslRequired: all
Part 10. What Keycloak does not solve
Fine-grained authorisation over resources. The question “can this person see this particular trace” is a relation between objects, not a role. That problem is solved by Zanzibar-style engines, with OpenFGA and its object, relation and user tuples, or a policy language such as Cedar. Keycloak gives roles and scopes, and with those you do not model a graph of relations.
Machine secrets. Storage credentials, provider keys, database passwords. That is a secrets manager, covered in stack hardening.
Cryptographic workload identity with attestation. That is SPIFFE and SPIRE. In Keycloak it exists as an identity provider in preview, which is a different thing.
Authorisation inside the model. Which MCP tool an agent may invoke, and with what arguments. The specification offers scopes, the insufficient scope error and step-up elevation, but the per-tool and per-argument decision is taken by the MCP server or a policy engine, not by the identity provider.
Antipatterns
- Forwarding the user’s token from the gateway to third-party MCP servers. Explicitly forbidden by the specification.
- Static client identifier with dynamic registration and no per-client consent, which is the exact recipe for the confused deputy.
- General scopes, of the full-access kind, and publishing the entire catalogue of supported scopes in the metadata.
- Treating a state handler as authentication, which the new revision expressly forbids.
- Following OAuth discovery towards any URL, which opens the door to requests towards internal addresses. It also applies to the authorisation server when it downloads a client metadata document.
- Trust headers badly exposed in chat front ends. The Open WebUI documentation warns that an incorrect configuration allows authenticating as any user.
- Starting in development mode in production, with the hostname not resolved strictly.
- A single shared static key as the only control between the gateway and the engine.
Startup checklist
- Check the version. Below 26.7.2 there is a critical password reset bug.
- Build the image with the build phase done and start with the optimised flag.
- Strict hostname, administration console on another hostname, separate management port and not exposed.
- Decide between organisations and one realm per tenant before creating the second tenant.
- One client scope per resource, with an audience mapper, because resource indicators are not supported.
- In the gateway, define the two audience and issuer variables. Without them none of that is validated.
- For workloads inside the cluster, look at the Kubernetes identity provider before handing out client secrets.
- Size by login peaks, not by number of services: the difference is eightfold.
- Export the Keycloak events to the same place the gateway’s go, because the activity logging control needs them together.
- Write into the design what the system does with a two-hour task, before someone solves the problem with an offline token.
Closing
Keycloak is a mature piece that solves one bounded problem well: knowing who the caller is, and saying so verifiably in a document that expires. In a sovereign inference platform that is worth a lot, because the alternative is an inventory of static keys spread across ten services that no audit can walk through.
What is not advisable is asking more of it. Fine-grained authorisation lives in each service, workload identity with attestation lives in SPIFFE, and the decision of which tool an agent may call lives in the MCP server.
And there is one concrete gap worth noting down, because it does not close on its own: the MCP specification marks two standards as mandatory, and of the two that would fall to an authorisation server, resource indicators are not implemented. The workaround with scopes and an audience mapper works, but it is a workaround, and whoever comes after will look for the standard parameter. Leaving it written in the design saves an afternoon.
See also
- The gateway does not live alone: how the gateway validates the tokens this piece issues, and the two variables you have to define.
- When MCP grows up: giving it authentication with Keycloak: the concrete setup for MCP servers.
- LiteLLM’s MCP gateway: the second front door, its permissions and its lack of audit logging.
- The model’s chain of trust (4 of 4): SPIFFE, SPIRE and workload identity with attestation.
- Hardening and secrets of the sovereign LLM stack: where identity fits among the seven layers.
- Virtual keys, budgets and limits: the alternative when JWT falls outside the budget.
- Technical controls: ENS, ISO 42001 and the EU AI Act.
- Completing Keycloak for MCP: the follow-up: the protected resource side you have to build, token exchange and the enterprise authorisation extension.
Sources
- Keycloak 26.7.3, 31 de agosto de 2026, y descargas.
- Configuración del servidor, caché, bases de datos y nombre de host.
- Integración con Model Context Protocol, intercambio de tokens y autenticación federada de clientes, 27 de enero de 2026.
- Dimensionado de CPU y memoria e introducción a alta disponibilidad.
- Bancos de pruebas de rendimiento de Keycloak 26.4, 1 de octubre de 2025.
- Especificación de MCP, revisión 2026-07-28, autorización y buenas prácticas de seguridad.
- KEP-3331, configuración estructurada de autenticación.
- Real Decreto 311/2022, Anexo II.
- Registro de
CVE-2026-18963en la base de datos de Red Hat y notas de la versión 26.7.3 en GitHub. - CNCF, proyecto Keycloak.