From 71c422792a29a9fefac59499925d2d39b6b7348a Mon Sep 17 00:00:00 2001 From: Edmund Wu <22758444+eadwu@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:52:46 -0400 Subject: [PATCH 1/9] fix: allow cross-platform devices for passkeys --- driver/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver/config/config.go b/driver/config/config.go index 3978c24668ac..d4e2497ae4b1 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -1494,7 +1494,7 @@ func (p *Config) PasskeyConfig(ctx context.Context) *webauthn.Config { RPID: id, RPOrigins: origins, AuthenticatorSelection: protocol.AuthenticatorSelection{ - AuthenticatorAttachment: "platform", + AuthenticatorAttachment: "cross-platform", RequireResidentKey: pointerx.Ptr(true), UserVerification: protocol.VerificationPreferred, }, From e1b6f5e3461401291c03bc9d0532b579156ba3ae Mon Sep 17 00:00:00 2001 From: Edmund Wu <22758444+eadwu@users.noreply.github.com> Date: Wed, 21 Aug 2024 01:17:51 -0400 Subject: [PATCH 2/9] let user choose instead --- driver/config/config.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/driver/config/config.go b/driver/config/config.go index d4e2497ae4b1..58a4993367d6 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -195,6 +195,7 @@ const ( ViperKeyWebAuthnRPOrigins = "selfservice.methods.webauthn.config.rp.origins" ViperKeyWebAuthnPasswordless = "selfservice.methods.webauthn.config.passwordless" ViperKeyPasskeyEnabled = "selfservice.methods.passkey.enabled" + ViperKeyPasskeyAttachmentModality = "selfservice.methods.passkey.attachment.modality" ViperKeyPasskeyRPDisplayName = "selfservice.methods.passkey.config.rp.display_name" ViperKeyPasskeyRPID = "selfservice.methods.passkey.config.rp.id" ViperKeyPasskeyRPOrigins = "selfservice.methods.passkey.config.rp.origins" @@ -1489,12 +1490,20 @@ 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) + authenticatorModality := switch authenticatorModalityValue { + case "platform", "cross-platform": + return authenticatorModality + default: + return "platform" + } return &webauthn.Config{ RPDisplayName: p.GetProvider(ctx).String(ViperKeyPasskeyRPDisplayName), RPID: id, RPOrigins: origins, AuthenticatorSelection: protocol.AuthenticatorSelection{ - AuthenticatorAttachment: "cross-platform", + AuthenticatorAttachment: authenticatorModality, + ResidentKey: "required", RequireResidentKey: pointerx.Ptr(true), UserVerification: protocol.VerificationPreferred, }, From 470c8895f5d3954637ebe4c24843f42f186c98ee Mon Sep 17 00:00:00 2001 From: Edmund Wu <22758444+eadwu@users.noreply.github.com> Date: Wed, 21 Aug 2024 01:20:44 -0400 Subject: [PATCH 3/9] go stuff --- driver/config/config.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/driver/config/config.go b/driver/config/config.go index 58a4993367d6..b64e3f243096 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -1491,11 +1491,12 @@ func (p *Config) PasskeyConfig(ctx context.Context) *webauthn.Config { id := p.GetProvider(ctx).String(ViperKeyPasskeyRPID) origins := p.GetProvider(ctx).StringsF(ViperKeyPasskeyRPOrigins, []string{scheme + "://" + id}) authenticatorModalityValue := p.GetProvider(ctx).String(ViperKeyPasskeyAttachmentModality) - authenticatorModality := switch authenticatorModalityValue { + var authenticatorModality string + switch authenticatorModalityValue { case "platform", "cross-platform": - return authenticatorModality + authenticatorModality = authenticatorModalityValue default: - return "platform" + authenticatorModality = "platform" } return &webauthn.Config{ RPDisplayName: p.GetProvider(ctx).String(ViperKeyPasskeyRPDisplayName), From 4a83aef75341b346c6360dad56c3c767d444d18b Mon Sep 17 00:00:00 2001 From: Edmund Wu <22758444+eadwu@users.noreply.github.com> Date: Wed, 21 Aug 2024 01:55:00 -0400 Subject: [PATCH 4/9] remove junk --- driver/config/config.go | 1 - 1 file changed, 1 deletion(-) diff --git a/driver/config/config.go b/driver/config/config.go index b64e3f243096..938a640e4576 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -1504,7 +1504,6 @@ func (p *Config) PasskeyConfig(ctx context.Context) *webauthn.Config { RPOrigins: origins, AuthenticatorSelection: protocol.AuthenticatorSelection{ AuthenticatorAttachment: authenticatorModality, - ResidentKey: "required", RequireResidentKey: pointerx.Ptr(true), UserVerification: protocol.VerificationPreferred, }, From 13eda5f4c234200f9abdc239afb8ba6e6bf61e90 Mon Sep 17 00:00:00 2001 From: Edmund Wu <22758444+eadwu@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:41:44 -0400 Subject: [PATCH 5/9] fixed --- driver/config/config.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/driver/config/config.go b/driver/config/config.go index 938a640e4576..e0a4e8a85e1d 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -1491,12 +1491,12 @@ func (p *Config) PasskeyConfig(ctx context.Context) *webauthn.Config { id := p.GetProvider(ctx).String(ViperKeyPasskeyRPID) origins := p.GetProvider(ctx).StringsF(ViperKeyPasskeyRPOrigins, []string{scheme + "://" + id}) authenticatorModalityValue := p.GetProvider(ctx).String(ViperKeyPasskeyAttachmentModality) - var authenticatorModality string + var authenticatorModality protocol.AuthenticatorAttachment switch authenticatorModalityValue { - case "platform", "cross-platform": - authenticatorModality = authenticatorModalityValue + case "cross-platform": + authenticatorModality = protocol.CrossPlatform default: - authenticatorModality = "platform" + authenticatorModality = protocol.Platform } return &webauthn.Config{ RPDisplayName: p.GetProvider(ctx).String(ViperKeyPasskeyRPDisplayName), From 2dc7760c479a98abf0d97cfbd8803197252a5644 Mon Sep 17 00:00:00 2001 From: Edmund Wu <22758444+eadwu@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:42:25 -0400 Subject: [PATCH 6/9] might as well for webauthn as well opposite to preserve behavior though --- driver/config/config.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/driver/config/config.go b/driver/config/config.go index e0a4e8a85e1d..76d2762d8ea7 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -189,6 +189,7 @@ 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.attachment.modality" ViperKeyWebAuthnRPDisplayName = "selfservice.methods.webauthn.config.rp.display_name" ViperKeyWebAuthnRPID = "selfservice.methods.webauthn.config.rp.id" ViperKeyWebAuthnRPOrigin = "selfservice.methods.webauthn.config.rp.origin" @@ -1475,11 +1476,20 @@ 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 + default: + authenticatorModality = protocol.CrossPlatform + } return &webauthn.Config{ RPDisplayName: p.GetProvider(ctx).String(ViperKeyWebAuthnRPDisplayName), RPID: id, RPOrigins: origins, AuthenticatorSelection: protocol.AuthenticatorSelection{ + AuthenticatorAttachment: authenticatorModality, UserVerification: protocol.VerificationDiscouraged, }, EncodeUserIDAsString: false, From 3c33c4a665b9ae4ec475e92a4d304308b8e70eb1 Mon Sep 17 00:00:00 2001 From: Edmund Wu <22758444+eadwu@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:58:21 -0400 Subject: [PATCH 7/9] can be configured now --- driver/config/config.go | 4 ++-- embedx/config.schema.json | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/driver/config/config.go b/driver/config/config.go index 76d2762d8ea7..e1c53d0665af 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -189,14 +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.attachment.modality" + 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.attachment.modality" + 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" diff --git a/embedx/config.schema.json b/embedx/config.schema.json index a2802ed0a0b7..3c12839a1572 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": "cross-platform" + } + }, + "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": { From 560bfca3cd4f201d36b21d87bb29374a715f3609 Mon Sep 17 00:00:00 2001 From: Edmund Wu <22758444+eadwu@users.noreply.github.com> Date: Wed, 21 Aug 2024 12:26:14 -0400 Subject: [PATCH 8/9] gofmt --- driver/config/config.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/driver/config/config.go b/driver/config/config.go index e1c53d0665af..23ac20f8adb7 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -1490,7 +1490,7 @@ func (p *Config) WebAuthnConfig(ctx context.Context) *webauthn.Config { RPOrigins: origins, AuthenticatorSelection: protocol.AuthenticatorSelection{ AuthenticatorAttachment: authenticatorModality, - UserVerification: protocol.VerificationDiscouraged, + UserVerification: protocol.VerificationDiscouraged, }, EncodeUserIDAsString: false, } @@ -1629,7 +1629,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), } From 699fcf775c4dc31f13853a761d5375e5cab07cd4 Mon Sep 17 00:00:00 2001 From: Edmund Wu <22758444+eadwu@users.noreply.github.com> Date: Thu, 22 Aug 2024 18:19:37 -0400 Subject: [PATCH 9/9] there are three values ... --- driver/config/config.go | 6 +++++- embedx/config.schema.json | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/driver/config/config.go b/driver/config/config.go index 23ac20f8adb7..0a8196edc849 100644 --- a/driver/config/config.go +++ b/driver/config/config.go @@ -1481,8 +1481,10 @@ func (p *Config) WebAuthnConfig(ctx context.Context) *webauthn.Config { switch authenticatorModalityValue { case "platform": authenticatorModality = protocol.Platform - default: + case "cross-platform": authenticatorModality = protocol.CrossPlatform + default: + authenticatorModality = "" } return &webauthn.Config{ RPDisplayName: p.GetProvider(ctx).String(ViperKeyWebAuthnRPDisplayName), @@ -1503,6 +1505,8 @@ func (p *Config) PasskeyConfig(ctx context.Context) *webauthn.Config { authenticatorModalityValue := p.GetProvider(ctx).String(ViperKeyPasskeyAttachmentModality) var authenticatorModality protocol.AuthenticatorAttachment switch authenticatorModalityValue { + case "": + authenticatorModality = "" case "cross-platform": authenticatorModality = protocol.CrossPlatform default: diff --git a/embedx/config.schema.json b/embedx/config.schema.json index 3c12839a1572..bb68f29f643d 100644 --- a/embedx/config.schema.json +++ b/embedx/config.schema.json @@ -1751,8 +1751,8 @@ "type": "string", "title": "Authenticator Modality", "description": "Restrict types of authenticators that are allowed.", - "examples": ["platform", "cross-platform"], - "default": "cross-platform" + "examples": ["platform", "cross-platform", ""], + "default": "" } }, "type": "object", @@ -1879,7 +1879,7 @@ "type": "string", "title": "Authenticator Modality", "description": "Restrict types of authenticators that are allowed.", - "examples": ["platform", "cross-platform"], + "examples": ["platform", "cross-platform", ""], "default": "platform" } },