Create Passkey Over Authorized Session
This flow applies to scenarios such as:
-
Post sign-up/onboarding completion. Passkeys are created after successful onboarding, ensuring users meet verification requirements, reinforcing security right from the start.
-
Users in a pre-authenticated session. This ensures users are authenticated or pre-approved by your server before registering, preventing unauthorized access and ensuring only legitimate users can create a passkey.
To protect the passkey creation process, ensure you have an authorized session by using API keys to request authorization tokens, which are passed to LoginID client SDKs.
This flow applies when your LoginID application is classified as a protected application, meaning that Registration Requires Authentication Token is enabled in your application settings.

When this setting is enabled, users must be authenticated or pre-authorized. This ensures that only verified users can create accounts and generate passkeys, requiring a valid authorization token during the registration process.
Overview Diagram
This high-level sequence diagram outlines the process:
- Finalized user onboarding or pre-authenticated session.
- Your backend requests an authorization token from LoginID by calling POST /fido2/v2/mgmt/grant authorized with your API key with the scope reg:write.
- The token is passed to the LoginID client SDK to execute client.createPasskey(username, token).
- The token authorizes the creation of the passkey with LoginID.

Here is an example of how it might look like:


Prerequisites
- Create an application to obtain a base URL. The SDK uses this base URL to interact with the LoginID authentication service.
- Create an API key with at least the reg:write scope. You’ll need this to request authorization tokens from your backend.
- Make sure your application's register APIs are secure.
Setup SDK
- Javascript
- Kotlin
- Swift
npm i @loginid/websdk3
Import and initialize an instance:
import { LoginIDWebSDK } from "@loginid/websdk3";
const lid = new LoginIDWebSDK({
baseUrl: process.env.LOGINID_BASE_URL,
});
To obtain the SDK:
- Go to the LoginID Dashboard and select one of your apps.
- Open the Get Started section and choose the Android icon.
- Follow the instructions to download the binary
.aarfile and include it in your project.
Initialize a singleton configuration for the LoginID service in the application's onCreate method.
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
// Initialize the singleton instance
val config = LoginIDServiceConfig("<BASE_URL>")
LoginID.configure(config).client()
}
}
To obtain the SDK:
- Go to the LoginID Dashboard and select one of your apps.
- Open the Get Started section and choose the iOS icon.
- Follow the instructions to download the binary
xcframeworkfile and include it in your project.
Configure the singleton instance of LoginIDSDK with a base URL during the app's launch in the App struct initializer.
import SwiftUI
import LoginID
@main
struct MyApp: App {
init() {
let baseUrl = "<BASE_URL>"
// Initialize the singleton instance
LoginIDSDK.shared.configure(baseUrl: baseUrl)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Create Passkey
After obtaining the authorization token from your backend, pass it to the LoginID client SDK. The user creates a passkey, and the response includes a LoginID token.
If you run into issues, be sure to check the Troubleshooting section. Since implementing passkey creation is often one of the first steps in integration, reviewing common issues early can help you resolve problems faster.
- Javascript
- Kotlin
- Swift
import { useAuth } from "../../contexts/AuthContext";
import { LoginIDWebSDK } from "@loginid/websdk3";
const lid = new LoginIDWebSDK({
baseUrl: process.env.REACT_APP_LOGINID_BASE_URL,
});
const Register: React.FC = () => {
const [username, setUsername] = useState<string>("");
const [error, setError] = useState<string>("");
const { setAuthUser } = useAuth();
const handleRegister = async (e: React.FormEvent) => {
e.preventDefault();
try {
// Get the authorization token from your backend after a successful onboarding
// or pre-authenticated session
// User creates a passkey
const { token } = await lid.createPasskey(username, authzToken);
// You can return LoginID token to your backend for verification
setAuthUser(user);
} catch (e) {
if (e instanceof Error) {
setError(e.message);
}
}
};
};
import loginid.LoginID
import services.modals.LoginIDOptions
class MainActivity : AppCompatActivity() {
private lateinit var usernameEditText: EditText
private lateinit var errorTextView: TextView
private lateinit var registerButton: Button
private fun handleRegister() {
val username = usernameEditText.text.toString()
errorTextView.text = ""
GlobalScope.launch(Dispatchers.Main) {
try {
// Get the authorization token from your backend after a successful onboarding
// or pre-authenticated session
// User creates a passkey
val options = LoginIDOptions(token = authToken)
val result = LoginID.client().registerWithPasskey(this@MainActivity, username, options)
// You can return LoginID token to your backend for verification
AuthContext.setAuthUser(user)
} catch (e: Exception) {
when (e) {
is LoginIDError -> {
errorTextView.text = e.message ?: "A LoginID error occurred"
}
else -> {
errorTextView.text = e.message ?: "An error occurred"
}
}
}
}
}
}
import SwiftUI
import LoginID
@main
struct ExampleApp: App {
@State private var errorMessage: String? = nil
@State private var username: String = "user@example.com"
init() {
// Configure the LoginID SDK
LoginIDSDK.shared.configure(
baseUrl: "<BASE_URL>",
)
}
var body: some Scene {
WindowGroup {
VStack {
Button("Register with Passkey") {
Task {
await registerUser()
}
}
.padding()
}
}
}
private func registerUser() async {
do {
// Get the authorization token from your backend after a successful onboarding
// or pre-authenticated session
let result = try await LoginIDSDK.shared.createPasskey(
username: username,
authzToken: authzToken,
options: nil
)
// You can return LoginID token to your backend for verification
AuthContext.shared.setAuthUser(result.user)
} catch let error as LoginIDError {
errorMessage = error.message
} catch {
errorMessage = error.localizedDescription
}
}
}
Once you have received the result LoginID token, you can send it to your backend, and verify it. For detailed technical instructions, refer to this section on verifying LoginID tokens.