diff --git a/driver/config/config.go b/driver/config/config.go index 3978c24668ac..0a8196edc849 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -189,12 +189,14 @@ const ( ViperKeyIgnoreNetworkErrors = "selfservice.methods.password.config.ignore_network_errors" ViperKeyTOTPIssuer = "selfservice.methods.totp.config.issuer" ViperKeyOIDCBaseRedirectURL = "selfservice.methods.oidc.config.base_redirect_uri" + ViperKeyWebAuthnAttachmentModality = "selfservice.methods.webauthn.config.attachment.modality" ViperKeyWebAuthnRPDisplayName = "selfservice.methods.webauthn.config.rp.display_name" ViperKeyWebAuthnRPID = "selfservice.methods.webauthn.config.rp.id" ViperKeyWebAuthnRPOrigin = "selfservice.methods.webauthn.config.rp.origin" ViperKeyWebAuthnRPOrigins = "selfservice.methods.webauthn.config.rp.origins" ViperKeyWebAuthnPasswordless = "selfservice.methods.webauthn.config.passwordless" ViperKeyPasskeyEnabled = "selfservice.methods.passkey.enabled" + ViperKeyPasskeyAttachmentModality = "selfservice.methods.passkey.config.attachment.modality" ViperKeyPasskeyRPDisplayName = "selfservice.methods.passkey.config.rp.display_name" ViperKeyPasskeyRPID = "selfservice.methods.passkey.config.rp.id" ViperKeyPasskeyRPOrigins = "selfservice.methods.passkey.config.rp.origins" @@ -1474,12 +1476,23 @@ func (p *Config) WebAuthnConfig(ctx context.Context) *webauthn.Config { id := p.GetProvider(ctx).String(ViperKeyWebAuthnRPID) origin := p.GetProvider(ctx).String(ViperKeyWebAuthnRPOrigin) origins := p.GetProvider(ctx).StringsF(ViperKeyWebAuthnRPOrigins, []string{stringsx.Coalesce(origin, scheme+"://"+id)}) + authenticatorModalityValue := p.GetProvider(ctx).String(ViperKeyWebAuthnAttachmentModality) + var authenticatorModality protocol.AuthenticatorAttachment + switch authenticatorModalityValue { + case "platform": + authenticatorModality = protocol.Platform + case "cross-platform": + authenticatorModality = protocol.CrossPlatform + default: + authenticatorModality = "" + } return &webauthn.Config{ RPDisplayName: p.GetProvider(ctx).String(ViperKeyWebAuthnRPDisplayName), RPID: id, RPOrigins: origins, AuthenticatorSelection: protocol.AuthenticatorSelection{ - UserVerification: protocol.VerificationDiscouraged, + AuthenticatorAttachment: authenticatorModality, + UserVerification: protocol.VerificationDiscouraged, }, EncodeUserIDAsString: false, } @@ -1489,12 +1502,22 @@ func (p *Config) PasskeyConfig(ctx context.Context) *webauthn.Config { scheme := p.SelfPublicURL(ctx).Scheme id := p.GetProvider(ctx).String(ViperKeyPasskeyRPID) origins := p.GetProvider(ctx).StringsF(ViperKeyPasskeyRPOrigins, []string{scheme + "://" + id}) + authenticatorModalityValue := p.GetProvider(ctx).String(ViperKeyPasskeyAttachmentModality) + var authenticatorModality protocol.AuthenticatorAttachment + switch authenticatorModalityValue { + case "": + authenticatorModality = "" + case "cross-platform": + authenticatorModality = protocol.CrossPlatform + default: + authenticatorModality = protocol.Platform + } return &webauthn.Config{ RPDisplayName: p.GetProvider(ctx).String(ViperKeyPasskeyRPDisplayName), RPID: id, RPOrigins: origins, AuthenticatorSelection: protocol.AuthenticatorSelection{ - AuthenticatorAttachment: "platform", + AuthenticatorAttachment: authenticatorModality, RequireResidentKey: pointerx.Ptr(true), UserVerification: protocol.VerificationPreferred, }, @@ -1610,7 +1633,6 @@ func (p *Config) DefaultConsistencyLevel(ctx context.Context) crdbx.ConsistencyL } func (p *Config) PasswordMigrationHook(ctx context.Context) *PasswordMigrationHook { - hook := &PasswordMigrationHook{ Enabled: p.GetProvider(ctx).BoolF(ViperKeyPasswordMigrationHook+".enabled", false), } diff --git a/embedx/config.schema.json b/embedx/config.schema.json index a2802ed0a0b7..bb68f29f643d 100644 --- a/embedx/config.schema.json +++ b/embedx/config.schema.json @@ -1744,6 +1744,20 @@ "title": "Use For Passwordless Flows", "description": "If enabled will have the effect that WebAuthn is used for passwordless flows (as a first factor) and not for multi-factor set ups. With this set to true, users will see an option to sign up with WebAuthn on the registration screen." }, + "attachment": { + "title": "Authenticator Configuration", + "properties": { + "modality": { + "type": "string", + "title": "Authenticator Modality", + "description": "Restrict types of authenticators that are allowed.", + "examples": ["platform", "cross-platform", ""], + "default": "" + } + }, + "type": "object", + "required": [] + }, "rp": { "title": "Relying Party (RP) Config", "properties": { @@ -1858,6 +1872,20 @@ "type": "object", "title": "Passkey Configuration", "properties": { + "attachment": { + "title": "Authenticator Configuration", + "properties": { + "modality": { + "type": "string", + "title": "Authenticator Modality", + "description": "Restrict types of authenticators that are allowed.", + "examples": ["platform", "cross-platform", ""], + "default": "platform" + } + }, + "type": "object", + "required": [] + }, "rp": { "title": "Relying Party (RP) Config", "properties": {