> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fingerprint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Web Bot Auth Implementation

> Web Bot Auth is used as a verification method for verified bots and signed agents.

This guide explains how to implement Web Bot Auth signing in your AI agent and register it with Fingerprint. Registering your bot has several advantages: it becomes an authorized bot and Fingerprint will not flag it as malicious. You can also decide how your bot is represented by Fingerprint APIs, by picking the desired bot name, category and provider.

# Web Bot Auth

Web Bot Auth is an authentication method that leverages cryptographic signatures in HTTP messages to verify that a request comes from an authorized AI Agent.

It relies on two active IETF drafts: a [directory draft ↗](https://datatracker.ietf.org/doc/html/draft-meunier-http-message-signatures-directory) allowing the agent to share their public keys, and a [protocol draft ↗](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture) defining how these keys should be used to attach agent’s identity to HTTP requests.

This documentation goes over specific integration within Fingerprint.

# **Generate a valid signing key**

You need to generate a signing key which will be used to authenticate your agent’s requests.

Generate a unique [Ed25519 ↗](https://ed25519.cr.yp.to/) private key to sign your requests. This example uses the [OpenSSL ↗](https://openssl-library.org/) `genpkey` command:

```bash theme={"theme":"github-dark-dimmed"}
openssl genpkey -algorithm ed25519 -out private-key.pem
```

**Extract your public key**

```bash theme={"theme":"github-dark-dimmed"}
openssl pkey -in private-key.pem -pubout -out public-key.pem
```

**Convert the public key to JSON Web Key (JWK) using a tool of your choice.**

This example uses [`jwker ↗`](https://github.com/jphastings/jwker) command line application.

```bash theme={"theme":"github-dark-dimmed"}
go install github.com/jphastings/jwker/cmd/jwker@latest
jwker public-key.pem public-key.jwk
```

By following these steps, you have generated a private key and a public key, then converted the public key to a JSON web key.

# Host a key directory

You need to host a key directory which creates a way for your agent to authenticate its requests to Fingerprint. This directory should follow the definition from the active IETF draft [draft-meunier-http-message-signatures-directory-05 ↗](https://datatracker.ietf.org/doc/html/draft-meunier-http-message-signatures-directory-04).

1. Host a key directory at `https://domain.com/.well-known/http-message-signatures-directory` (note that this full path is a requirement). This key directory should serve a JSON Web Key Set (JWKS) including the public key derived from your signing key.
2. Serve the directory over HTTPS (not HTTP).
3. Ensure the directory response has the `Content-Type` HTTP header value of `application/http-message-signatures-directory+json`

<Info>
  **This URL should serve a standard JSON Web Key Set.**

  Besides `x`, `crv`, `kid`, and `kty`, you can include other standard JSON Web Key parameters. Multiple Ed25519 keys are supported. Only those for which you provide a signature in the above format are going to be used. Fingerprint will ignore all other key types and key parameters except those containing `kty`, `crv`, `kid`, and `x` formatted above.
</Info>

# Register Your Agent

You can submit a request to register your agent using this form in the Fingerprint Dashboard: [Submit Your Bot](https://dashboard.fingerprint.com/workspaces/elvo/submit-bot).

After submitting all the required information, please wait 1-2 weeks for the agent registration. You’ll get a confirmation email when we have successfully registered  your agent.

# Sign Your Requests

After a successful agent registration, start signing the requests. The signature protocol is defined in [draft-meunier-web-bot-auth-architecture-04 ↗](https://datatracker.ietf.org/doc/html/draft-meunier-web-bot-auth-architecture-04).

## Choose a set of components to sign

A component is either an HTTP header, or any [derived components ↗](https://www.rfc-editor.org/rfc/rfc9421#name-derived-components) in the HTTP Message Signatures specification. Fingerprint recommends the following:

Choose at least the `@authority` and `signature-agent`  components, which represents the domain you are sending requests to and the root domain of the agent’s public key directory. For example, a request to `https://example.com` will be interpreted to have an `@authority` of `example.com`. An AI agent that’s using a domain of `https://ai-agent.fyi` to host the public key will have the `signature-agent` value of `"https://ai-agent.fyi"`.

<Note>
  **Use components with only ASCII values.**

  Fingerprint currently does not support `bs` or `sf` parameter designed to serialize non-ASCII values into ASCII equivalents.
</Note>

## Calculate the JWK thumbprint

[Calculate the base64 URL-encoded JWK thumbprint ↗](https://www.rfc-editor.org/rfc/rfc8037.html#appendix-A.3) from the public key.

## Construct the required headers

Construct the three required headers for Web Bot Auth.

**`Signature-Input header`**

Construct a [`Signature-Input header ↗`](https://www.rfc-editor.org/rfc/rfc9421#name-the-signature-input-http-fi) over your chosen components. The header must meet the following requirements.

| **Required component parameter** | **Requirement**                                                                                                                                                                                                                              |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tag`                            | web-bot-auth                                                                                                                                                                                                                                 |
| `keyid`                          | This should be equal to the JWK thumbprint computed previously                                                                                                                                                                               |
| `alg`                            | ed25519                                                                                                                                                                                                                                      |
| `created`                        | This should be equal to a `Unix` timestamp associated with when the message was sent by your agent                                                                                                                                           |
| `expires`                        | This should be equal to a `Unix` timestamp associated with when Fingerprint should no longer attempt to verify the message. A short `expires` reduces the likelihood of replay attacks, and Fingerprint recommends using a one hour duration |

**`Signature header`**

Construct a [`Signature header ↗`](https://www.rfc-editor.org/rfc/rfc9421#name-the-signature-http-field) over your chosen components.

**`Signature-Agent header`**

Construct a [`Signature-Agent header ↗`](https://www.ietf.org/archive/id/draft-meunier-http-message-signatures-directory-04.html#name-header-field-definition) that points to your key directory. Note that Fingerprint will fail to verify a message if:

* The message includes a `Signature-Agent` header that is not an `https://`
* The `Signature-Agent` is not a bare domain (paths, query params are not allowed)
* The message includes a valid URI but does not enclose it in double quotes. This is due to `Signature-Agent` being a [structured field ↗](https://www.rfc-editor.org/rfc/rfc8941.html)

**Add the headers to your agent’s requests**

Attach these three headers to your agent’s requests. Note that all requests need to be signed, including requests that make fetch requests or download static resources.

One option to attach custom headers to all requests is by using [Page.route ↗](https://playwright.dev/docs/api/class-route) functionality of Playwright.

An example request header collection may look like this:

```bash theme={"theme":"github-dark-dimmed"}
Signature-Agent: "https://ai-agent.fyi"
Signature-Input: sig1=("@authority" "signature-agent")
 ;created=1735689600;expires=1735693200
 ;keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U"
 ;alg="ed25519"
 ;tag="web-bot-auth"
Signature: sig1=:jdq0SqOwHdyHr9+r5jw3iYZH6aNGKijYp/EstF4RQTQdi5N5YYKrD+mCT1HA1nZDsi6nJKuHxUi/5Syp3rLWBA==:
```

<Info>
  **All requests**, made by your agent, must be signed, including static resource (images, javascript) and [Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) requests. If using Playwright to add custom headers is not an option, an alternative way to do it is via a browser extension.
</Info>

If you have any questions, please reach out to **`bot-registration@fingerprint.com`**

## Helpful Links

* [**Test your bot Web Bot Auth implementation ↗**](https://fingerprint.com/web-bot-auth/test)
* [**Submit a request to add your bot to Fingerprint Directory ↗**](https://dashboard.fingerprint.com/submit-bot)
* [**Example of a public key directory ↗**](https://chatgpt.com/.well-known/http-message-signatures-directory)
