Upgrading from rc.11 to rc.12¶
This page lists what you must change, and what behaves differently, when you move a HelixIAM install from
v1.0.0-rc.11 to v1.0.0-rc.12. The source is the rc.12 release notes and the security review (findings H4 and H5).
What rc.12 is
rc.12 adds bring-your-own realm signing keys and certificates, with ES256 alongside RS256. It also closes two admin privilege findings (H4 and H5) and protects everything administrators sign in through. Most of the changes below tighten who may do what. One adds a start-up report for you to review.
Before you upgrade: checklist¶
| # | Do this | Applies if |
|---|---|---|
| 1 | Optionally run the pre-upgrade query to see which administrators sign in through an external identity provider | you use identity providers |
| 2 | After the upgrade, review the start-up report, confirm the AMBIGUOUS links that are right and revoke trust in any link you do not recognise |
the report lists anyone |
| 3 | Tell administrators that new links are made from the account console | administrators sign in through an identity provider |
| 4 | Give realm-admin to the people who do the actions listed there |
you delegate administration with narrower permissions |
| 5 | Review realm keys and signing before you activate an ES256 key | you plan to bring your own key or use ES256 |
| 6 | Nothing to do for Flyway V86: it is applied automatically on start-up | always (informational) |
1. Administrators who sign in through an identity provider¶
What changed. Each federated link now records how it was made. An administrator signs in through a link only when the link is trusted:
| Provenance | Meaning | Signs in an administrator |
|---|---|---|
LEGACY |
existed before the upgrade | yes |
JIT |
the sign-in created the account | yes |
SELF |
linked by the user from the account console | yes |
WALLET |
an EU Digital Identity Wallet linked from the account console | yes |
ADMIN_CONFIRMED |
confirmed by a realm admin | yes |
AUTO |
matched by a verified e-mail address, or trust revoked | no |
Links belong to a realm. A link now signs its user in only in the realm it belongs to. V86 places each existing
link in the realm whose identity provider has that alias. If the alias is used in several realms, or the provider comes
from the realm config folder (which the migration cannot see), it holds the link as UNRESOLVED and logs how many
there are. At the first start, after the realm config folder is loaded, each such link is resolved:
- The alias now belongs to exactly one realm: the link moves there and keeps working (
LEGACY). This is audited asLEGACY_LINK_RESOLVED. - No stored provider has the alias, and exactly one static
helix.federation.*provider does (it serves every realm): the link stays in the user's home realm and keeps working (LEGACY), audited the same way. - Anything else (the alias is stored in several realms, a stored and a static provider share it, or the
definitions differ): the link goes to the user's home realm and becomes
AUTO. It still works for ordinary users, but it signs no administrator in until a realm admin confirms it. It is reported asAMBIGUOUS(see the next section). A link the migration cannot place at all signs no one in and is logged at start-up; the user links the provider again.
No lockout. Every link that exists at the upgrade becomes LEGACY and keeps working as it did in rc.11. Wallet
links become WALLET. The attack these links were open to, a lower admin pointing the identity provider at their own
issuer, now needs the linked administrators' own permissions.
To check in advance (optional). Run this on the rc.11 database. It lists every user who holds the admin role, or
a role with admin permissions, and has a federated link:
SELECT DISTINCT r.tenant_id AS realm, u.username, f.idp_alias
FROM federated_link f
JOIN user_credentials u ON u.user_id = f.user_id
JOIN user_in_role ur ON ur.user_id = f.user_id
JOIN user_roles r ON r.role_id = ur.role_id
WHERE r.name = 'admin'
OR EXISTS (SELECT 1 FROM admin_role_permission p WHERE p.role_id = r.role_id)
ORDER BY realm, u.username, f.idp_alias;
Admin permissions that come through a group (user_group_member and user_group_role) are not in this query. The
start-up report below includes them.
2. The start-up report: PRIVILEGED_LEGACY_LINK¶
What changed. At every start, the server reports each user who is an administrator in any realm (or in master) and has one of these links:
- a
LEGACYlink (it still signs them in): a WARN and aPRIVILEGED_LEGACY_LINKaudit event; - an
AMBIGUOUSlink (it signs them in only after a realm admin confirms it): a WARN and aPRIVILEGED_AMBIGUOUS_LINKaudit event.
Each entry names the realm of the link, the username, the identity provider and the realms where the user is an administrator. The report never blocks anything.
What you must do. Review the report. In the console: Events, filter on type PRIVILEGED_LEGACY_LINK. Over the
API: GET /admin/realms/{realm}/events?type=PRIVILEGED_LEGACY_LINK. For each entry, confirm that the account at the
identity provider belongs to that administrator. Confirm an AMBIGUOUS link that is theirs (see the next section).
If you are unsure about a LEGACY link, revoke trust in it:
- Console: Users → (user) → Linked identities → Revoke trust.
- API:
POST /admin/realms/{realm}/users/{userId}/federated-identities/{alias}/revoke-trustwith body{"externalSubject": "…"}. A user can have several links to one provider, so each request names one link.
Revoking trust needs realm-admin, and the user's admin permissions in every other realm they belong to (so only a
master admin can act on a master admin's link). It is audited as FEDERATED_LINK_TRUST_REVOKED. The link then counts as AUTO:
it still signs in an ordinary user, but never an administrator. The administrator can link the provider again
themselves (see the next section). GET /admin/realms/{realm}/users/{userId}/federated-identities lists a user's links
with their provenance.
3. New links for administrators¶
What changed. A link made after the upgrade by matching a verified e-mail address never signs in an administrator.
Each refusal is audited as PRIVILEGED_LINK_REFUSED. An administrator gets a trusted link in one of two ways:
- Themselves, from the account console. Connected accounts → Link next to the provider. If they have not
signed in within the step-up window (
helix.account.step-up-max-age-seconds, 300 s by default), they sign in again first. Then they sign in at the provider, and the link is stored asSELF. The flow is bound to their session; an identity already linked to someone else is refused. It is audited asACCOUNT_IDENTITY_LINK. - By a realm admin. For an administrator who cannot use the account console:
Users → (user) → Linked identities → Confirm link, or
POST /admin/realms/{realm}/users/{userId}/federated-identities/{alias}/confirmwith body{"externalSubject": "…"}(one link). This needsrealm-adminand is audited asFEDERATED_LINK_CONFIRMED. Like revoking trust, it also needs the user's admin permissions in every other realm they belong to.
Ordinary users are not affected: e-mail linking and just-in-time accounts work as before.
4. Actions that now need realm-admin¶
What changed. These used to be open to narrower permissions. See Admin roles (RBAC).
- Signing keys and settings: every realm key write and
PUT /admin/realms/{realm}/settings/signing. Reads keepmanage-realm. - Admin grants: changing a role's admin permissions. Assigning a role, through any path, also needs the role's admin permissions to be your own (H5).
- Acting on someone more privileged: acting on a user or client that holds admin permissions you do not hold needs those permissions, for example a password reset, impersonation or a client secret.
- Sign-in surfaces: creating
helix-consoleorhelix-cli, and changing their Application, mappers or allowed resources. Also the realm'sbrowserflow and the flows bound to the sign-in clients. - Identity providers that administrators are linked to: changing or deleting one needs the linked administrators' permissions. Changing a trusted list their wallet providers use needs the same.
- Messaging and sign-in policy: messaging providers and templates, the MFA policy, magic links, the subject claim, and realm settings other than the display name, the legacy branding and self-registration.
- Groups and roles: deleting a role or group, or moving a group, needs the admin permissions it grants.
- Push devices: registering one for a user needs that user's admin permissions.
- Unknown routes: any
/adminroute the permission catalogue does not name.
Also: manage-users, manage-clients, manage-identity-providers and manage-events now include their view-
counterparts. A percent-encoded realm id or route name in an /admin path is refused with 400 (H4).
helix-cli is now created in every realm. On every start, a helix-cli that allows more than the built-in client is
corrected: a redirect URI that is not a loopback address is dropped, as are grant types outside the built-in set, a
secret, or a confidential setting. Each correction is logged and audited as SIGN_IN_CLIENT_RECONCILED. Narrower
choices are kept, such as dropping device_code or a custom loopback port or path.
5. Realm signing keys, ES256 and the staging time¶
What changed. See Realm keys.
- You can import a key and its certificate chain, or have the server generate a key and a CSR.
- New keys start
PENDING: published, but not signing. You activate them afterhelix.keys.min-staging(5 minutes by default), or earlier with?force=true. - An ES256 key can be active alongside the RS256 key. Every realm keeps an active RS256 key, and retiring it is refused.
- ID tokens use each client's
id_token_signed_response_alg. Other tokens use the realm'ssigning.defaultAlg(RS256 by default).
What you must do. If a client asks for an ID-token algorithm that has no active key, for example RS384, change it before its next save. During a rolling upgrade you can import and stage keys, but activate an ES256 key only once every replica runs rc.12. Realm exports still contain no keys, certificates or signing settings.
6. Flyway V86¶
What changed. V86 (and schema.sql) changes the following:
realm_key: adds the certificate columns and a unique index on the public key, and rewrites the algorithm fromRSAtoRS256. Existing keys keep their kid and keep signing. Duplicate rows that an rc.11 race could leave are removed. If the same key is stored in two realms, the migration stops and names them.- New table: adds
realm_signing_settings. federated_link: addsrealm_idandcreated_via, backfills both as described in section 1, and keys links by realm, provider and subject.
What you must do. Nothing; it runs on start-up.