> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `/plugin marketplace add scalekit-inc/claude-code-authstack` then `/plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agentkit`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Add passkeys login method

Enable passkey authentication for your users
Passkeys replace passwords with biometric authentication (fingerprint, face recognition) or device PINs. Built on FIDO® standards (WebAuthn and CTAP), passkeys offer superior security by eliminating phishing and credential stuffing vulnerabilities, while also providing a seamless one-tap login experience. Unlike traditional authentication methods, passkeys sync across devices, removing the need for multiple enrollments and providing better recovery options when devices are lost.

Your [existing Scalekit integration](/authenticate/fsa/quickstart) already supports passkeys. To implement, enable passkeys in the Scalekit dashboard and leverage Scalekit's built-in user passkey registration functionality.

1. ## Enable passkeys in the Scalekit dashboard

    Go to Scalekit Dashboard > Authentication > Auth methods > Passkeys and click "Enable"

    > Image: Enable passkeys button in Scalekit settings

2. ## Manage passkey registration

    Let users manage passkeys just by redirecting them to Scalekit from your app (usually through a button in your app that says "Manage passkeys"), or building your own UI.

    #### Using Scalekit UI

    To enable users to register and manage their passkeys, redirect them to the Scalekit passkey registration page.

    > Image: Passkey registration page in Scalekit UI

    Construct the URL by appending `/ui/profile/passkeys` to your Scalekit environment URL

    ```js title="Passkey Registration URL" showLineNumbers=false
    /ui/profile/passkeys
    ```

    This opens a page where users can:
    - Register new passkeys
    - Remove existing passkeys
    - View their registered passkeys

    > Scalekit registers & authenticates user's passkeys through the browser's native passkey API. This API prompts users to authenticate with device-supported passkeys — such as fingerprint, PIN, or password managers.

    #### In your own UI

    If you prefer to create a custom user interface for passkey management, Scalekit offers comprehensive APIs that enable you to build a personalized experience. These APIs allow you to list registered passkeys, rename them, and remove them entirely. However registration of passkeys is only supported through the Scalekit UI.

    
    ### Node.js

```js title="List user's passkeys" showLineNumbers=false
// : fetch from Access Token or ID Token after identity verification
const res = await fetch(
  '/api/v1/webauthn/credentials?user_id=',
  { headers: { Authorization: 'Bearer ' } }
);
const data = await res.json();
console.log(data);
```

```js title="Rename a passkey" showLineNumbers=false
// : obtained from list response (id of each passkey)
await fetch('/api/v1/webauthn/credentials/', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'Bearer '
  },
  body: JSON.stringify({ display_name: '' })
});
```

```js title="Remove a passkey" showLineNumbers=false
// : obtained from list response (id of each passkey)
await fetch('/api/v1/webauthn/credentials/', {
  method: 'DELETE',
  headers: { Authorization: 'Bearer ' }
});
```

    ### Python

```python title="List user's passkeys" showLineNumbers=false
import requests
# : fetch from access token or ID token after identity verification
r = requests.get(
  '/api/v1/webauthn/credentials',
  params={'user_id': ''},
  headers={'Authorization': 'Bearer '}
)
print(r.json())
```

```python title="Rename a passkey" showLineNumbers=false
import requests
# : obtained from list response (id of each passkey)
requests.patch(
    '/api/v1/webauthn/credentials/',
    json={'display_name': ''},
    headers={'Authorization': 'Bearer '}
)
```

```python title="Remove a passkey" showLineNumbers=false
import requests
# : obtained from list response (id of each passkey)
requests.delete(
  '/api/v1/webauthn/credentials/',
  headers={'Authorization': 'Bearer '}
)
```

    ### Java

```java title="List user's passkeys" showLineNumbers=false
var client = java.net.http.HttpClient.newHttpClient();
// : fetch from Access Token or ID Token after identity verification
var req = java.net.http.HttpRequest.newBuilder(
  java.net.URI.create("/api/v1/webauthn/credentials?user_id=")
)
.header("Authorization", "Bearer ")
.GET().build();
var res = client.send(req, java.net.http.HttpResponse.BodyHandlers.ofString());
System.out.println(res.body());
```

```java title="Rename a passkey" showLineNumbers=false
var client = java.net.http.HttpClient.newHttpClient();
var body = "{\"display_name\":\"\"}";
// : obtained from list response (id of each passkey)
var req = java.net.http.HttpRequest.newBuilder(
  java.net.URI.create("/api/v1/webauthn/credentials/")
)
.header("Authorization", "Bearer ")
.header("Content-Type","application/json")
.method("PATCH", java.net.http.HttpRequest.BodyPublishers.ofString(body))
.build();
client.send(req, java.net.http.HttpResponse.BodyHandlers.discarding());
```

```java title="Remove a passkey" showLineNumbers=false
var client = java.net.http.HttpClient.newHttpClient();
// : obtained from list response (id of each passkey)
var req = java.net.http.HttpRequest.newBuilder(
  java.net.URI.create("/api/v1/webauthn/credentials/")
)
.header("Authorization", "Bearer ")
.DELETE().build();
client.send(req, java.net.http.HttpResponse.BodyHandlers.discarding());
```

    ### Go

```go title="List user's passkeys" showLineNumbers=false
// imports: net/http, io, fmt
// : fetch from access token or ID token after identity verification
req, _ := http.NewRequest("GET", "/api/v1/webauthn/credentials?user_id=", nil)
req.Header.Set("Authorization", "Bearer ")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
b, _ := io.ReadAll(resp.Body)
fmt.Println(string(b))
```

```go title="Rename a passkey" showLineNumbers=false
// imports: net/http, bytes
payload := bytes.NewBufferString(`{"display_name":""}`)
// : obtained from list response (id of each passkey)
req, _ := http.NewRequest("PATCH", "/api/v1/webauthn/credentials/", payload)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer ")
http.DefaultClient.Do(req)
```

```go title="Remove a passkey" showLineNumbers=false
// imports: net/http
// : obtained from list response (id of each passkey)
req, _ := http.NewRequest("DELETE", "/api/v1/webauthn/credentials/", nil)
req.Header.Set("Authorization", "Bearer ")
http.DefaultClient.Do(req)
```

    

    > note
>
> All API requests require an access token obtained via the OAuth 2.0 client credentials flow. Follow [Authenticate with the Scalekit API](/guides/authenticate-scalekit-api), then replace `` in the examples below.
3. ## Users can log in with passkeys

    Users who have registered passkeys can log in with them.

    This time when login page shows, users can select "Passkey" as the authentication method.

    > Image: Login with passkey option on sign-in page

    During sign-up, you'll continue to use established authentication methods like [verification codes, magic links](/authenticate/auth-methods/passwordless/) or [social logins](/authenticate/auth-methods/social-logins/). Once a user is registered, they can then add passkeys as an additional, convenient login option.


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
