# Passwordless auth method (API)

{% hint style="warning" %}
The passwordless and username-less auth method is provides by the custom auth plugin [vault\_plugin\_auth\_passkeys](https://github.com/enclaive/vault_plugin_auth_passkeys/) and needs to be registered in the plugin catalog before usage.
{% endhint %}

This documentation assumes the passkey method is mounted at the `/auth/passkey` path in Vault. Since it is possible to enable auth methods at any location, please update your API calls accordingly.

A policy according to [Passwordless](/vault/tutorials/ui/authentication/passwordless.md) is created and named passkey\_policy.

## Passkey Configuration

The passkey configuration is needed to set up the origins, the relying party ID, the relying party displayname and attached policies.

### Read Passkey Configuration

Returns the set up configuration.

| Method | Path                   |
| ------ | ---------------------- |
| `GET`  | `/auth/passkey/config` |

#### Sample request

```shell-session
$ curl \
    --header "X-Vault-Token: ..." \
    https://vault-passkeys.com:8200/v1/auth/passkey/config
```

#### Sample response

```json
{
    "data": {
        "config": {
            "policies": [
                "default"
            ],
            "rp_displayname": "Example Coorp",
            "rp_id": "example.com",
            "rp_origins": [
                "https://example.com:443"
            ]
        }
    },
}
```

### Set Passkey Configuration

Set up the configuration to enable users to authenticate.

| Method | Path                   |
| ------ | ---------------------- |
| `POST` | `/auth/passkey/config` |

#### Parameters

* `policies` `(Array<string>)` - Array of all policies which will be attached to each authenticated user.
* `rp_displayname` `(string)` - A human readable Displayname for your project or website. It is used to enhance user experience and has not technical importance.
* `rp_id` `( string)` - The ID of the relying party. This must be set to your domain without scheme and port (e.g. vault-passkeys.com). It will be checked technically by the browser and the auth mechanism. The RP ID is used to identify entries in the authenticator.
* `rp_origins` `(Array<string>)` - An origin must be a Fully Qualified Domain Name (FQDN). Only request from this URL are allowed. The origin is technically checked and must be set correctly.

#### Sample payload

```json
{
    "rp_displayname":"Vault Passkeys",
    "rp_id":"vault-passkeys.com",
    "rp_origins":["https://vault-passkeys.com:8200"],
    "policies":["default","passkey_policy"]
}
```

#### Sample request

```shell-session
$ curl \
 --header "X-Vault-Token: ..." \
 --request POST \
 --data @payload.json \
 https://vault-passkeys.com:8200/v1/auth/passkey/config
```

#### Sample response

```json
{
    "data": {
        "config":{ 
            "policies":["default","passkey_policy"],
            "rp_displayname":"Vault Passkeys",
            "rp_id":"vault-passkeys.com",
            "rp_origins":["https://vault-passkeys.com:8200"]
        }
    }
}
```

## User management

A user object needs to be either created by an administrator and the one-time-password has to be supplied to the user or an already authenticated user (e.g. via userpass) may use the `/create` endpoint for self-registration.

### List users

List all users that are created at the plugin.

| Method | Path                  |
| ------ | --------------------- |
| `LIST` | `/auth/passkey/users` |

#### Sample request

```shell-session
$ curl \
    --header "X-Vault-Token: ..." \
    --request LIST \
    https://vault-passkeys.com:8200/v1/auth/passkey/users
```

#### Sample response

```json
{
    "data": {
        "keys": ["janedoe","johndoe"]
    }
}
```

### Read user

Retrieve user object information like the one-time-password needed for registration.

| Method | Path                            |
| ------ | ------------------------------- |
| `GET`  | `/auth/passkey/users/:username` |

#### Parameters

* `username` `(string: <required>)` - Name of the user.

#### Sample request

```shell-session
$ curl \
    --header "X-Vault-Token: ..." \
    --request GET \
    https://vault-passkeys.com:8200/v1/auth/passkey/users/johndoe
```

#### Sample response

```json
{
    "data": {
        "credentials": null,
        "otp": "8AE4IASG",
        "otp_timestamp": "2024-08-04T21:21:31.605972419Z",
        "username": "johndoe"
    }
}
```

### Create user

Create a pending user object for a user to register with a one-time-password.

| Method | Path                            |
| ------ | ------------------------------- |
| `POST` | `/auth/passkey/users/:username` |

#### Parameters

* `username` `(string: <required>)` - Name of the user.

#### Sample request

```shell-session
$ curl \
    --header "X-Vault-Token: ..." \
    --request POST \
    https://vault-passkeys.com:8200/v1/auth/passkey/users/johndoe
```

### Delete user

Delete a user object.

| Method   | Path                            |
| -------- | ------------------------------- |
| `DELETE` | `/auth/passkey/users/:username` |

#### Sample request

```shell-session
$ curl \
    --header "X-Vault-Token: ..." \
    --request DELETE \
    https://vault-passkeys.com:8200/v1/auth/passkey/users/johndoe
```

### Reset user

This endpoint is used to reset the one-time-password and timestamp of the validation time.

<table><thead><tr><th width="365">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>POST</code></td><td><code>/auth/passkey/users/:username/reset</code></td></tr></tbody></table>

#### Parameters

* `username` `(string: <required>)` - Name of the user.
* `minutes` `(number)` - Number of minutes that determine how long it is possible to use the one-time-password.

#### Sample request

```shell-session
$ curl \
    --header "X-Vault-Token: ..." \
    --request POST \
    --data @payload.json \
    https://vault-passkeys.com:8200/v1/auth/passkey/users/johndoe/reset
```

#### Sample response

```json
{
    "data": {
        "VerificationTimestamp":"2024-08-04T22:01:41.372579174Z",
        "VerificationToken":"U7TBKBBP"
    }
}
```

## Authentication

These endpoints operate one a challenge and response sequenze. First the ceremony needs to be started at the Vault system and the returned information must be used to make the WebAuthn API calls at the client. All data used for the WebAuthn calls are url safe encoded via [Base64](https://developer.mozilla.org/en-US/docs/Glossary/Base64) (`-_` are used instead of `+/`) for transmission. The values must be decoded into ArrayBuffer for the WebAuthn API calls.

Since a browser is needed for the WebAuthn API calls, the samples only show responses.

### Registraion Init

<table><thead><tr><th width="365">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>POST</code></td><td><code>/auth/passkey/register</code></td></tr></tbody></table>

#### Parameters

* `operation` `(string: "init")` - The operation must be set to `init` to initiate the registration ceremony.
* `otp` `(string: <required>)` - The valid one-time-password provided by an administrator.
* `username` `(string: <required>)` - Name of the user provided by an administrator.

#### Sample response

```json
"data": {
    "creationOptions": {
        "publicKey": {
            "attestation": "direct",
            "authenticatorSelection": {
            "requireResidentKey": true,
            "residentKey": "required",
            "userVerification": "preferred"
        },
        "challenge": "bSrBa-4hIMg9_BKwxxY4-YpZ85caSG8vR5V2VfP8v-w",
        "pubKeyCredParams": [
            {"alg": -7, "type": "public-key"},
            {"alg": -35,"type": "public-key"},
            {"alg": -36,"type": "public-key"},
            {"alg": -257,"type": "public-key"},
            {"alg": -258,"type": "public-key"},
            {"alg": -259,"type": "public-key"},
            {"alg": -37,"type": "public-key"},
            {"alg": -38,"type": "public-key"},
            {"alg": -39,"type": "public-key"},
            {"alg": -8,"type": "public-key"}
        ],
        "rp": {
            "id": "vault-passkeys.com",
            "name": "Vault Passkeys"
        },
        "timeout": 300000,
        "user": {
            "displayName": "johndoe",
            "id": "YjIzMTcwYjItMGNiOC00ZWUyLTc3YzktMjQzYTBhMTdiMTVk",
            "name": "johndoe"
        }
    }
}
```

The response data must be decoded and passed to the `navigator.credentials.create()` as parameter. The response of this call needs to be encoded and sent back to the Vault endpoint.

### Registration Finish

<table><thead><tr><th width="365">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>POST</code></td><td><code>/auth/passkey/register</code></td></tr></tbody></table>

#### Parameters

* `operation` `(string: "finish")` - The operation must be set to `finish` to finalzie the registration ceremony.
* `otp` `(string: <required>)` - The valid one-time-password provided by an administrator.
* `username` `(string: <required>)` - Name of the user provided by an administrator.
* `credentialData` `(object: <required>)` - This is the response from the authenticator, containing information like the public key of the newly created key pair.

#### Sample payload

```json
{
    "operation":"finish",
    "username":"johndoe",
    "otp":"FK9B0A40",
    "credentialData": {
        "id":"5f1MJBPlSZRnMef2Cg1rHZBVFtPkbEMafbRFZq921DU",
        "rawId":"5f1MJBPlSZRnMef2Cg1rHZBVFtPkbEMafbRFZq921DU",
        "type":"public-key",
        "response": {
            "attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN...",
            "clientDataJSON":"eyJ0eXBlIjoid2ViY..."
        }
    }
}
```

#### Sample response

```json
{
    "auth": {
        "client_token": "hvs.CAESIPciW_aRF93_PmbUo-eGOfr0A27NAhinor_rVOXUFbjjGh4KHGh2cy5xOEJpUk8wZ3hneFhRZEdSekJuRWdXZXg",
        "accessor": "dDddMVta3LZlfniFU1aRxb7D",
        "policies": [
            "default",
            "passkey_policy"
        ],
        "token_policies": [
            "default",
            "passkey_policy"
        ],
        "metadata": {
            "passkey_username": "johndoe"
        },
        "lease_duration": 2764800,
        "renewable": true,
        "entity_id": "86439772-48c7-496c-3d62-ae45c6f07365",
        "token_type": "service",
        "orphan": true,
        "mfa_requirement": null,
        "num_uses": 0
    }
}
```

After successful registration the user is logged in and the client token is returned.

### Login Init

<table><thead><tr><th width="365">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>POST</code></td><td><code>/auth/passkey/login</code></td></tr></tbody></table>

#### Parameters

* `operation` `(string: "init")` - The operation must be set to `init` to initiate the login ceremony.

#### Sample response

```json
"data": {
    "requestOptions": {
        "publicKey": {
            "challenge": "esqj2ECh6dxaJ_d5KLPqMDqTu3_t--O-CrpPPF-mlos",
            "rpId": "vault-passkeys.com",
            "timeout": 300000,
            "userVerification": "preferred"
        }
    }
}
```

The response data must be decoded and passed to the `navigator.credentials.get()` as parameter. The response of this call needs to be encoded and sent back to the Vault endpoint.

### Login Finish

<table><thead><tr><th width="365">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>POST</code></td><td><code>/auth/passkey/login</code></td></tr></tbody></table>

#### Parameters

* `operation` `(string: "finish")` - The operation must be set to `finish` to finalzie the login ceremony.
* `credentialData` `(object: <required>)` - This is the response from the authenticator, containing information like the signature which will be validated by the plugin with the stored public key.

#### Sample payload

```json
{
    "operation":"finish",
    "credentialData": {
        "id":"5f1MJBPlSZRnMef2Cg1rHZBVFtPkbEMafbRFZq921DU",
        "rawId":"5f1MJBPlSZRnMef2Cg1rHZBVFtPkbEMafbRFZq921DU",
        "type":"public-key",
        "response": {
            "authenticatorData":"rBBE1FnK9RzomGX2_aa4jJMS3er7x6FjQkZqmFrsDeoFAAAAAg",
            "clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4...",
            "signature":"MEUCIEex-XnVHBqnDeE4egS66Ne060t7N...",
            "userHandle":"YjIzMTcwYjItMGNiOC00ZWUyLTc3YzktMjQzYTBhMTdiMTVk"
        }
    }
}
```

#### Sample response

```json
{
    "auth": {
        "client_token": "hvs.CAESIKy-z5Ar7TFGXXCrdTgxOWeKs_0vOQW2iXso3fn8wteSGh4KHGh2cy5xU2t5M0dBa3g1VUl0c00yM0dia2FjY3o",
        "accessor": "4hwbmpS76olQWr1lNaSQY3X3",
        "policies": [
            "default",
            "passkey_policy"
        ],
        "token_policies": [
            "default",
            "passkey_policy"
        ],
        "metadata": {
            "passkey_username": "johndoe"
        },
        "lease_duration": 2764800,
        "renewable": true,
        "entity_id": "86439772-48c7-496c-3d62-ae45c6f07365",
        "token_type": "service",
        "orphan": true,
        "mfa_requirement": null,
        "num_uses": 0
    }
}
```

After successful validation the user is logged in and the client token is returned.

## Self-Registration

The self-registration can be performed to create a passkey account without administrator interaction. The user must be authenticated in Vault and needs the permission for this endpoint to use.

{% hint style="info" %}
The administrator should merge the newly created passkey entitiy/alias with the one which is used to create the passkey user account.
{% endhint %}

These endpoints operate one a challenge and response sequenze. First the ceremony needs to be started at the Vault system and the returned information must be used to make the WebAuthn API calls at the client. All data used for the WebAuthn calls are url safe encoded via [Base64](https://developer.mozilla.org/en-US/docs/Glossary/Base64) (`-_` are used instead of `+/`) for transmission. The values must be decoded into ArrayBuffer for the WebAuthn API calls.

Since a browser is needed for the WebAuthn API calls, the samples only show responses.

### Init

<table><thead><tr><th width="365">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>POST</code></td><td><code>/auth/passkey/create</code></td></tr></tbody></table>

#### Parameters

* `operation` `(string: "init")` - The operation must be set to `init` to initiate the registration ceremony.
* `username` `(string: <required>)` - A unique username must be provided to create a new account.

#### Sample response

```json
"data": {
    "creationOptions": {
        "publicKey": {
            "attestation": "direct",
            "authenticatorSelection": {
            "requireResidentKey": true,
            "residentKey": "required",
            "userVerification": "preferred"
        },
        "challenge": "axVrF0oAcrDoPcOm9AWuSS1Mq5sx4hwvcQEcVpe8MHE",
        "pubKeyCredParams": [
            {"alg": -7, "type": "public-key"},
            {"alg": -35,"type": "public-key"},
            {"alg": -36,"type": "public-key"},
            {"alg": -257,"type": "public-key"},
            {"alg": -258,"type": "public-key"},
            {"alg": -259,"type": "public-key"},
            {"alg": -37,"type": "public-key"},
            {"alg": -38,"type": "public-key"},
            {"alg": -39,"type": "public-key"},
            {"alg": -8,"type": "public-key"}
        ],
        "rp": {
            "id": "vault-passkeys.com",
            "name": "Vault Passkeys"
        },
        "timeout": 300000,
        "user": {
            "displayName": "jdoe",
            "id": "NTBjNzg4NDQtYzg3Yy00ODFkLTk0ZDAtZWQ5ODkxMDZiMWZl",
            "name": "jdoe"
        }
    }
}
```

The response data must be decoded and passed to the `navigator.credentials.create()` as parameter. The response of this call needs to be encoded and sent back to the Vault endpoint.

### Finish

<table><thead><tr><th width="365">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>POST</code></td><td><code>/auth/passkey/create</code></td></tr></tbody></table>

#### Parameters

* `operation` `(string: "finish")` - The operation must be set to `finish` to finalize the registration ceremony.
* `username` `(string: <required>)` - A unique username must be provided to create a new account.
* `credentialData` `(object: <required>)` - This is the response from the authenticator, containing information like the public key of the newly created key pair.

#### Sample payload

```json
{
    "operation":"finish",
    "username":"jdoe",
    "credentialData": {
        "id":"9eM0tq-WQp3cz8JRFVvpoT_yoiFaRjWURleeT5X8NNE",
        "rawId":"9eM0tq-WQp3cz8JRFVvpoT_yoiFaRjWURleeT5X8NNE",
        "type":"public-key",
        "response": {
            "attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSj...",
            "clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwi..."
        }
    }
}
```

#### Sample response

```json
"data": {
        "success": "true"
}
```

After successful registration the newly created passkey can be used and an Vault entitiy will be created at first login.

## Credential Management

A user may add or delete passkeys or rename them on the server side for simplified identifiability.

{% hint style="warning" %}
Many authenticators only support one passkey for one relying party. If a new passkey is created the old one may be deleted on the authenticator side.
{% endhint %}

### Add Passkey Init

<table><thead><tr><th width="365">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>POST</code></td><td><code>/auth/passkey/:username/credentials</code></td></tr></tbody></table>

#### Parameters

* `username` `(string: <required>)` - The users existing username.
* `operation` `(string: "init")` - The operation must be set to `init` to initiate the registration ceremony.

#### Sample response

```json
"data": {
    "creationOptions": {
        "publicKey": {
            "attestation": "direct",
            "authenticatorSelection": {
            "requireResidentKey": true,
            "residentKey": "required",
            "userVerification": "preferred"
        },
        "challenge": "axVrF0oAcrDoPcOm9AWuSS1Mq5sx4hwvcQEcVpe8MHE",
        "pubKeyCredParams": [
            {"alg": -7, "type": "public-key"},
            {"alg": -35,"type": "public-key"},
            {"alg": -36,"type": "public-key"},
            {"alg": -257,"type": "public-key"},
            {"alg": -258,"type": "public-key"},
            {"alg": -259,"type": "public-key"},
            {"alg": -37,"type": "public-key"},
            {"alg": -38,"type": "public-key"},
            {"alg": -39,"type": "public-key"},
            {"alg": -8,"type": "public-key"}
        ],
        "rp": {
            "id": "vault-passkeys.com",
            "name": "Vault Passkeys"
        },
        "timeout": 300000,
        "user": {
            "displayName": "johndoe",
            "id": "YjIzMTcwYjItMGNiOC00ZWUyLTc3YzktMjQzYTBhMTdiMTVk",
            "name": "johndoe"
        }
    }
}
```

The response data must be decoded and passed to the `navigator.credentials.create()` as parameter. The response of this call needs to be encoded and sent back to the Vault endpoint.

### Add Passkey Finish

<table><thead><tr><th width="365">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>POST</code></td><td><code>/auth/passkey/:username/credentials</code></td></tr></tbody></table>

#### Parameters

* `username` `(string: <required>)` - The users existing username.
* `operation` `(string: "finish")` - The operation must be set to `finish` to finalize the registration ceremony.
* `credentialData` `(object: <required>)` - This is the response from the authenticator, containing information like the public key of the newly created key pair.

#### Sample payload

```json
{
    "operation":"finish",
    "credentialData": {
        "id":"s103DfxxiJRKLaciMZbOW9iZlplH7IyBRUoUrvVFC0E",
        "rawId":"s103DfxxiJRKLaciMZbOW9iZlplH7IyBRUoUrvVFC0E",
        "type":"public-key",
        "response": {
            "attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2...",
            "clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlY..."
        }
    }
}
```

#### Sample response

```json
"data": {
    "credentials": {
        "CreationTime": "2024-08-04T22:27:32.356255938Z",
        "Credential": {
            "attestationType": "packed",
            "authenticator": {
                "AAGUID": "AQIDBAUGBwgBAgMEBQYHCA==",
                "attachment": "",
                "cloneWarning": false,
                "signCount": 1
            },
            "flags": {
                "backupEligible": false,
                "backupState": false,
                "userPresent": true,
                "userVerified": true
            },
            "id": "s103DfxxiJRKLaciMZbOW9iZlplH7IyBRUoUrvVFC0E=",
            "publicKey": "pQECAyYgASFYIJubBAf6hF+iJiBvmDJC4g5IR7vsM8Hf/ZFKHWw3cuhEIlgg7vfnKI6MPhg2EbZxGbc/+QwEPzEjudD/7FBd4bvNVsM=",
            "transport": null
        },
        "Displayname": "Passkey-NM9I20FR",
        "LastUsed": "0001-01-01T00:00:00Z"
    }
}
```

### Delete Passkey

A user may delete its registered passkeys at the plugin.

<table><thead><tr><th width="198">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>DELETE</code></td><td><code>/auth/passkey/:username/credentials/:credentialID</code></td></tr></tbody></table>

#### Parameters

* `username` `(string: <required>)` - The users existing username.
* `credentialID` `(string: <required>)` - The ID of the passkey entry.

#### Sample response

```json
"data": {
   "message": "credential deleted"
}
```

### Rename Passkey

{% hint style="info" %}
Displaynames of passkeys are not synced between clients and servers.
{% endhint %}

<table><thead><tr><th width="198">Method</th><th>Path</th></tr></thead><tbody><tr><td><code>POST</code></td><td><code>/auth/passkey/:username/credentials/:credentialID</code></td></tr></tbody></table>

#### Parameters

* `username` `(string: <required>)` - The users existing username.
* `credentialID` `(string: <required>)` - The ID of the passkey entry.
* `displayName` `(string: <required>)` - The new name of the passkey entry.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.enclaive.cloud/vault/api/auth-engines/passwordless-auth-method-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
