Introduction to the KeyServer

Posted by Spacened in Key Server via Web

# 🔑 KeyServer API (keyserver.34a.xyz)

A stateless service for managing **multi-device cryptographic identities**.
The keyserver links public keys into a user identity (`user_id`), while keeping proofs so websites and apps can verify actions.

---

## 🚀 Endpoints

### 1. Register a new user

`POST /register`

Registers a new identity with its first key.
The key used to sign this message (`signed_by`) becomes the initial active key.

**Request**

```json
{
"message": "{\"action\":\"register\",\"signed_by\":\"0xAAA\"}",
"signature": "hex-encoded-sig",
"signed_by": "0xAAA"
}
```

**Response**

```json
{
"user_id": "uuid-v4",
"public_key": "0xAAA"
}
```

---

### 2. Add a new key

`POST /keys/add`

Adds a new device key to an existing identity.
Must be signed by an **active key** belonging to the user.
Includes a `nonce` to prevent replay.

**Request**

```json
{
"message": "{\"action\":\"addKey\",\"user_id\":\"uuid-v4\",\"new_key\":\"0xBBB\",\"nonce\":1694160000,\"label\":\"My Laptop\"}",
"signature": "hex-encoded-sig",
"signed_by": "0xAAA"
}
```

**Response**

```json
{
"user_id": "uuid-v4",
"public_key": "0xBBB"
}
```

---

### 3. Revoke a key

`POST /keys/revoke`

Marks a key as revoked.
Must be signed by an **active key** belonging to the user.
Includes a `nonce` to prevent replay.

**Request**

```json
{
"message": "{\"action\":\"revokeKey\",\"user_id\":\"uuid-v4\",\"revoked_key\":\"0xBBB\",\"nonce\":1694161000}",
"signature": "hex-encoded-sig",
"signed_by": "0xAAA"
}
```

**Response**

```json
{
"user_id": "uuid-v4",
"revoked_key": "0xBBB"
}
```

---

### 4. Resolve a key

`GET /resolveKey/{public_key}`

Resolves a public key to its user identity and returns proof history.

**Response**

```json
{
"user_id": "uuid-v4",
"status": "active",
"proofs": [
{
"action": "register",
"nonce": 0,
"message": "{\"action\":\"register\",\"signed_by\":\"0xAAA\"}",
"signature": "hex-encoded-sig",
"signed_by": "0xAAA",
"created_at": "2025-09-08T10:00:00Z"
},
{
"action": "addKey",
"nonce": 1694160000,
"message": "{\"action\":\"addKey\",\"user_id\":\"uuid-v4\",\"new_key\":\"0xBBB\",\"nonce\":1694160000}",
"signature": "hex-encoded-sig",
"signed_by": "0xAAA",
"created_at": "2025-09-08T10:01:00Z"
}
]
}
```

---

## 🔒 Security model

* **Signatures**: All messages must be signed by an active key.
* **Nonces**: Add/Revoke require a UTC timestamp nonce, strictly increasing per user.
* **Revocation**: Permanent — revoked keys cannot be re-added.
* **Uniqueness**: Each public key is globally unique across all users.
* **Verifier**: If the signature verification service is unavailable, the API responds with `503`.

---

## ✅ Notes

* The **keyserver is stateless** — it only returns proofs; relying websites decide how to interpret them.

* Expect websites to define their own login message formats (e.g. including domain, nonce, etc.).

* Signature verification is handled by a companion service at **verify.34a.xyz**.
This service is stateless and simply checks `{ hash, signature, publicKey } → isValid (bool)`.
If you fork this project, you should also run your own verifier service to avoid depending on mine. I will publish the verifier code on Gitlab asap.
PHP crypto support varies a lot between distributions, which is why this was separated into a Node service.

Loading comments...