2024 App ServicesSystem ServicesPrivacy & Security
WWDC24 · 14 min · App Services / System Services / Privacy & Security
Streamline sign-in with passkey upgrades and credential managers
Learn how to automatically upgrade existing, password-based accounts to use passkeys. We’ll share why and how to improve account security and ease of sign-in, information about new features available for credential manager apps, and how to make your app information shine in the new Passwords app.
Watch at developer.apple.com ↗Chapters
- 0:00 — Introduction
- 0:38 — Automatic passkey upgrades
- 2:37 — The passkey journey
- 4:18 — Automatic passkey upgrade sequence
- 7:46 — Shipping and deploying passkey support
- 9:17 — Improvements for credential managers
- 10:14 — The new Passwords app!
- 11:30 — Updating appearance in the Passwords app
- 12:31 — One-tap verification code setup
Code shown on screen · 5 snippets
Offering a passkey upsell
// Offering a passkey upsell
func signIn() async throws {
let userInfo = try await signInWithPassword()
guard !userInfo.hasPasskey else { return }
let provider = ASAuthorizationPlatformPublicKeyCredentialProvider(
relyingPartyIdentifier: "example.com")
guard try offerPasskeyUpsell() else { return }
let request = provider.createCredentialRegistrationRequest(
challenge: try await fetchChallenge(),
name: userInfo.user,
userID: userInfo.accountID)
do {
let passkey = try await authorizationController.performRequest(request)
// Save new passkey to the backend
} catch { … }
} Automatic passkey upgrade
// Automatic passkey upgrade
func signIn() async throws {
let userInfo = try await signInWithPassword()
guard !userInfo.hasPasskey else { return }
let provider = ASAuthorizationPlatformPublicKeyCredentialProvider(
relyingPartyIdentifier: "example.com")
let request = provider.createCredentialRegistrationRequest(
challenge: try await fetchChallenge(),
name: userInfo.user,
userID: userInfo.accountID,
requestStyle: .conditional)
do {
let passkey = try await authorizationController.performRequest(request)
// Save new passkey to the backend
} catch { … }
} Modal passkey creation (web)
// Modal passkey creation
const options = {
"publicKey": {
"rp": { … },
"user": {
"name": userInfo.user,
…
},
"challenge": …,
"pubKeyCredParams": [ … ]
},
};
await navigator.credentials.create(options); Automatic passkey creation (web)
// Automatic passkey creation
let capabilities = await PublicKeyCredential.getClientCapabilities();
if (!capabilities.conditionalCreate) { return; }
const options = {
"publicKey": {
"rp": { … },
"user": {
"name": userInfo.user,
…
},
"challenge": …,
"pubKeyCredParams": [ … ]
},
"mediation": "conditional"
};
await navigator.credentials.create(options); New Credential provider Info.plist keys
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>ASCredentialProviderExtensionCapabilities</key>
<dict>
<key>ProvidesPasswords</key>
<true/>
<key>ProvidesPasskeys</key>
<true/>
<key>SupportsConditionalPasskeyRegistration</key>
<true/>
<key>ProvidesOneTimeCodes</key>
<true/>
<key>ProvidesTextToInsert</key>
<true/>
</dict>
</dict>
</dict> Resources
Related sessions
-
33 min -
16 min -
15 min