You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -168,4 +168,4 @@ Both hooks are activated via `git config core.hooksPath .githooks`.
168
168
169
169
## Authentication
170
170
171
-
Authentication uses SS58 hotkey validation via the `X-Hotkey` HTTP header combined with an API key via the `X-Api-Key` header. The authorized hotkey is hardcoded as `AUTHORIZED_HOTKEY` in `src/config.rs`. The API key is configured via the `WORKER_API_KEY` environment variable (required). Only requests with both a matching hotkey and a valid API key can submit batches via `POST /submit`. All other endpoints are open.
171
+
Authentication requires four HTTP headers: `X-Hotkey` (SS58 address), `X-Nonce` (unique per-request), `X-Signature` (sr25519 hex signature of `hotkey + nonce`), and `X-Api-Key`. The authorized hotkey is hardcoded as `AUTHORIZED_HOTKEY` in `src/config.rs`. The API key is configured via the `WORKER_API_KEY` environment variable (required). Verification steps: hotkey must match `AUTHORIZED_HOTKEY`, API key must match, SS58 format must be valid, nonce must not have been seen before (replay protection via `NonceStore` in `src/auth.rs` with 5-minute TTL), and the sr25519 signature must verify against the hotkey's public key using the Substrate signing context. Only requests passing all checks can submit batches via `POST /submit`. All other endpoints are open.
-**Convention**: Return `Result<impl IntoResponse, (StatusCode, Json<Value>)>` from handlers that can fail. Use `Json(serde_json::json!({...}))` for responses.
45
46
46
47
### `auth.rs`
47
-
-`verify_hotkey(hotkey)` — compares submitted hotkey against `AUTHORIZED_HOTKEY`.
48
-
-`extract_hotkey(headers)` — reads `X-Hotkey` header from request.
48
+
-`NonceStore` — `DashMap`-backed nonce tracker with 5-minute TTL and background reaper loop for replay protection.
-`extract_auth_headers(headers)` — reads `X-Hotkey`, `X-Nonce`, `X-Signature`, `X-Api-Key` headers from request.
51
+
-`verify_request(auth, nonce_store, expected_api_key)` — full auth pipeline: hotkey match → API key match → SS58 validation → nonce replay check → sr25519 signature verification.
49
52
-`validate_ss58(address)` — validates SS58 address format using `bs58`.
50
-
-**Convention**: Auth is mandatory — `POST /submit` requires a valid `X-Hotkey` header matching the authorized hotkey.
53
+
-`verify_sr25519_signature(ss58_hotkey, message, signature_hex)` — verifies an sr25519 signature using `schnorrkel` with the Substrate signing context.
54
+
-`AuthError` — enum with `UnauthorizedHotkey`, `InvalidHotkey`, `InvalidApiKey`, `NonceReused`, `InvalidSignature` variants, each with `.code()` and `.message()` methods.
55
+
-**Convention**: Auth is mandatory — `POST /submit` requires all four headers (`X-Hotkey`, `X-Nonce`, `X-Signature`, `X-Api-Key`). The signed message is `hotkey + nonce`.
51
56
52
57
### `executor.rs`
53
58
-`Executor::spawn_batch(batch, archive, concurrent_limit)` — spawns a tokio task that runs all tasks in the batch.
@@ -63,7 +68,9 @@ main.rs
63
68
-`TaskTestResult`, `TaskResult`, `BatchResult` — core result data types.
64
69
-`WsEvent` — WebSocket event struct with `event`, `batch_id`, `task_id`, `data`.
0 commit comments