diff --git a/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties b/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties index e38b89c0934..9505cd06cac 100644 --- a/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties +++ b/js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties @@ -3602,10 +3602,38 @@ request_uri_not_supported=Request uri not supported registration_not_supported=Registration not supported oid4vciAttributes=OID4VCI attributes oid4vciNonceLifetime=OID4VCI Nonce Lifetime -oid4vciNonceLifetimeHelp=The lifetime of the OID4VCI nonce in seconds. +oid4vciNonceLifetimeHelp=The lifetime of the OID4VCI nonce. preAuthorizedCodeLifespan=Pre-Authorized Code Lifespan -preAuthorizedCodeLifespanHelp=The lifespan of the pre-authorized code in seconds. +preAuthorizedCodeLifespanHelp=The lifespan of the pre-authorized code. oid4vciFormValidationError=Please ensure the OID4VCI attribute fields are filled with values 30 seconds or greater. +signedIssuerMetadata=Signed Issuer Metadata +signedIssuerMetadataHelp=Enable signing of the issuer metadata. When enabled, the issuer metadata will be signed using the configured signing algorithm. +signedMetadataLifespan=Signed Metadata Lifespan +signedMetadataLifespanHelp=The lifetime of the signed metadata. After this time, the signed metadata will expire. +signedMetadataSigningAlgorithm=Signed Metadata Signing Algorithm +signedMetadataSigningAlgorithmHelp=The algorithm used to sign the issuer metadata. This ensures the integrity and authenticity of the metadata. +requireEncryption=Require Encryption +requireEncryptionHelp=If enabled, encryption is required for credential requests. Clients must encrypt their requests using the supported encryption algorithms. +enableDeflateCompression=Enable DEF compression +enableDeflateCompressionHelp=If enabled, the DEF compression algorithm is supported for credential requests. This allows clients to compress their requests to reduce payload size. +batchIssuanceSize=Batch Issuance Size +batchIssuanceSizeHelp=The maximum number of credentials that can be issued in a single batch request. This helps manage server load and response times. +timeClaimCorrelationMitigation=Time-claim correlation mitigation +timeClaimsStrategy=Strategy to apply to time claims +timeClaimsStrategyHelp=Strategy to apply to time claims. Supported values: off, randomize, round. +randomizeWindow=Randomize Window +randomizeWindowHelp=When strategy is randomize, subtract a random number of seconds between 0 and the value of this attribute from the original timestamp to mitigate correlation attacks. +roundUnit=Round Unit +roundUnitHelp=When strategy is round, truncate timestamps to the selected unit boundary (UTC). Supported values: SECOND, MINUTE, HOUR, DAY. +randomize=Randomize +round=Round +second=Second +day=Day +attestationTrust=Attestation Trust +trustedKeyIds=Trusted Key IDs +trustedKeyIdsHelp=Comma-separated list of Key IDs (kid) from the realm keystore. These keys are trusted for validating wallet attestations. +trustedKeys=Trusted Keys (JSON) +trustedKeysHelp=A JSON array of JWK objects. These keys are trusted for validating wallet attestations in addition to realm keys. # OID4VCI Credential Configuration credentialConfigurationId=Credential Configuration ID credentialConfigurationIdHelp=The unique identifier for this credential configuration. This ID is used in the credential issuer metadata and credential requests. diff --git a/js/apps/admin-ui/src/realm-settings/TokensTab.tsx b/js/apps/admin-ui/src/realm-settings/TokensTab.tsx index 45d833643f4..ec58222bb97 100644 --- a/js/apps/admin-ui/src/realm-settings/TokensTab.tsx +++ b/js/apps/admin-ui/src/realm-settings/TokensTab.tsx @@ -5,6 +5,8 @@ import { SelectVariant, ScrollForm, useAlerts, + SelectControl, + NumberControl, } from "@keycloak/keycloak-ui-shared"; import { AlertVariant, @@ -17,6 +19,7 @@ import { Switch, Text, TextInput, + TextArea, TextVariants, } from "@patternfly/react-core"; import { useState } from "react"; @@ -24,6 +27,7 @@ import { Controller, useFormContext, useWatch } from "react-hook-form"; import { useTranslation } from "react-i18next"; import { FormAccess } from "../components/form/FormAccess"; import { FixedButtonsGroup } from "../components/form/FixedButtonGroup"; +import { DefaultSwitchControl } from "../components/SwitchControl"; import { convertAttributeNameToForm } from "../util"; import { TimeSelector, @@ -37,7 +41,7 @@ import useIsFeatureEnabled, { Feature } from "../utils/useIsFeatureEnabled"; import "./realm-settings-section.css"; -type RealmSettingsSessionsTabProps = { +type RealmSettingsTokensTabProps = { realm: RealmRepresentation; save: (realm: RealmRepresentation) => void; }; @@ -45,7 +49,7 @@ type RealmSettingsSessionsTabProps = { export const RealmSettingsTokensTab = ({ realm, save, -}: RealmSettingsSessionsTabProps) => { +}: RealmSettingsTokensTabProps) => { const { t } = useTranslation(); const { addAlert } = useAlerts(); const serverInfo = useServerInfo(); @@ -59,6 +63,9 @@ export const RealmSettingsTokensTab = ({ serverInfo.providers!["signature"].providers, ); + const asymmetricSigAlgOptions = + serverInfo.cryptoInfo?.clientSignatureAsymmetricAlgorithms ?? []; + const { control, register, reset, formState, handleSubmit } = useFormContext(); @@ -85,6 +92,26 @@ export const RealmSettingsTokensTab = ({ defaultValue: false, }); + const signedMetadataEnabled = useWatch({ + control, + name: convertAttributeNameToForm( + "attributes.oid4vci.signed_metadata.enabled", + ), + defaultValue: realm.attributes?.["oid4vci.signed_metadata.enabled"], + }); + + const encryptionRequired = useWatch({ + control, + name: convertAttributeNameToForm("attributes.oid4vci.encryption.required"), + defaultValue: realm.attributes?.["oid4vci.encryption.required"], + }); + + const strategy = useWatch({ + control, + name: convertAttributeNameToForm("attributes.oid4vci.time.claims.strategy"), + defaultValue: realm.attributes?.["oid4vci.time.claims.strategy"] ?? "off", + }); + const sections = [ { title: t("general"), @@ -674,6 +701,193 @@ export const RealmSettingsTokensTab = ({ min={30} units={["second", "minute", "hour"]} /> + + {signedMetadataEnabled === "true" && ( + <> + + ({ + key: p, + value: p, + }))} + data-testid="signed-metadata-signing-algorithm" + /> + + )} + + {encryptionRequired === "true" && ( + + )} + + + + {t("attestationTrust")} + + + } + > + + + + } + > + ( +