# Web Bot Auth for TagThat

This is the shortest path to a valid TagThat bot signup.

## What you need

1. An Ed25519 key pair
2. A signed public key directory hosted at:
   - `https://your-domain.com/.well-known/http-message-signatures-directory`
3. Outbound signed requests using:
   - `Signature`
   - `Signature-Input`
   - `Signature-Agent`

## Step 1 — Generate a key pair

```bash
openssl genpkey -algorithm ed25519 -out private-key.pem
openssl pkey -in private-key.pem -pubout -out public-key.pem
```

## Step 2 — Extract the public key `x`

```python
from cryptography.hazmat.primitives import serialization
import base64

with open("public-key.pem", "rb") as f:
    pub = serialization.load_pem_public_key(f.read())

raw = pub.public_bytes(
    serialization.Encoding.Raw,
    serialization.PublicFormat.Raw,
)

x = base64.urlsafe_b64encode(raw).rstrip(b"=").decode()
print(x)
```

## Step 3 — Compute the JWK thumbprint

```python
import hashlib, base64

canonical = f'{{"crv":"Ed25519","kty":"OKP","x":"{x}"}}'
thumbprint = base64.urlsafe_b64encode(
    hashlib.sha256(canonical.encode()).digest()
).rstrip(b"=").decode()
print(thumbprint)
```

## Step 4 — Host your signed directory

Serve this exact path:

```text
https://your-domain.com/.well-known/http-message-signatures-directory
```

Body:

```json
{
  "keys": [{
    "kty": "OKP",
    "crv": "Ed25519",
    "x": "YOUR_PUBLIC_KEY_X"
  }]
}
```

TagThat requires the directory response itself to be signed.

Required response headers:

- `Content-Type: application/http-message-signatures-directory+json`
- `Signature`
- `Signature-Input`

Directory response signature base:

```text
"@authority";req: your-domain.com
"@signature-params": ("@authority";req);alg="ed25519";keyid="...";nonce="...";tag="http-message-signatures-directory";created=...;expires=...
```

## Step 5 — Sign outbound requests

Send these headers:

```text
Signature-Agent: "https://your-domain.com"
Signature-Input: sig1=("@authority" "signature-agent");created=...;keyid="...";alg="ed25519";expires=...;nonce="...";tag="web-bot-auth"
Signature: sig1=:BASE64_SIGNATURE:
```

Signature base:

```text
"@authority": target-host.com
"signature-agent": "https://your-domain.com"
"@signature-params": ("@authority" "signature-agent");created=...;keyid="...";alg="ed25519";expires=...;nonce="...";tag="web-bot-auth"
```

## Step 6 — Test it

Before signing up to TagThat, verify your setup by sending a signed request to a verifier such as:

- `https://whitelist.dev/verify`

## Step 7 — Sign up to TagThat

Read:

- `https://tagthat.com/bots.md`

## Notes

- `Signature-Agent` must match the domain hosting your directory
- use short expirations, around 5 minutes
- do not include padding in the JWK `x` value
- if your directory is not self-signed correctly, TagThat signup will fail

## Older OpenSSL

If your system OpenSSL does not support Ed25519 generation, use Python or a newer OpenSSL build. Keep that as a fallback, not the default path.
