Compare commits
2 Commits
66e11afdc3
...
e15e5a8038
| Author | SHA1 | Date | |
|---|---|---|---|
| e15e5a8038 | |||
|
|
a0989a3bed |
@ -0,0 +1,98 @@
|
|||||||
|
# TASK METADATA
|
||||||
|
|
||||||
|
- **Target Files:**
|
||||||
|
- `server/http_signatures.ts` (New module)
|
||||||
|
- `server/main.ts` (Update `/api/forward-auth` and add admin routes)
|
||||||
|
- `server/valkey.ts` (Ensure SISMEMBER helper exists or is exposed)
|
||||||
|
- **Core Objective:** Implement RFC 9421 HTTP Message Signatures verification
|
||||||
|
middleware using native Deno Ed25519 for headless daemons and edge nodes.
|
||||||
|
- **Dependencies:** Deno 2.x native `crypto.subtle` (Ed25519 support), Valkey
|
||||||
|
access for fingerprint sets.
|
||||||
|
- **Additional Important Notes:** Must support dual-auth in `/api/forward-auth`
|
||||||
|
(Session OR Signature). Verification must complete in <5 microseconds (mostly
|
||||||
|
$O(1)$ Valkey lookup). The `Signature-Key` uses the `hwk` parameter via
|
||||||
|
draft-hardt-httpbis-signature-key containing an OKP JWK inline.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architectural Considerations & Risks
|
||||||
|
|
||||||
|
### Risks
|
||||||
|
|
||||||
|
1. **Replay Attacks:** If the `nonce` and strict $\pm 30$s timestamp drift
|
||||||
|
(`created`/`expires`) are not strictly validated, attackers could replay
|
||||||
|
intercepted signed requests.
|
||||||
|
2. **Valkey Exhaustion/Availability:** Relying on Valkey for sub-5 microsecond
|
||||||
|
fingerprint checks is fast but introduces a hard dependency on Valkey
|
||||||
|
availability for edge authentication. If Valkey is down, headless clients
|
||||||
|
cannot authenticate.
|
||||||
|
3. **Parsing Overhead:** Parsing complex `Signature-Input` and canonicalizing
|
||||||
|
HTTP components according to RFC 9421 can be CPU intensive. The
|
||||||
|
implementation must be heavily optimized to avoid DoS vectors.
|
||||||
|
4. **Header Size Limits:** Including raw JWKs in headers (`hwk`) increases
|
||||||
|
header size, potentially hitting proxy limits if not managed carefully.
|
||||||
|
|
||||||
|
### Alternatives Evaluated
|
||||||
|
|
||||||
|
1. **mTLS (Mutual TLS):** We already use mTLS/SPIFFE internally (via
|
||||||
|
`spire_ffi.ts`). However, for edge nodes/IoT devices traversing multiple
|
||||||
|
proxies or load balancers, HTTP Message Signatures provide application-layer
|
||||||
|
end-to-end integrity that survives TLS termination, making it the superior
|
||||||
|
choice for this specific headless use case.
|
||||||
|
2. **External NPM Packages:** Libraries like `@peertube/http-signature` exist,
|
||||||
|
but adhering to the zero-dependency SDK/pure Deno backend policy dictates a
|
||||||
|
native WebCrypto approach, which is cleaner and guarantees compatibility with
|
||||||
|
Deno 2.x.
|
||||||
|
|
||||||
|
## Proposed Implementation
|
||||||
|
|
||||||
|
### Phase 1: Core Cryptography and Parsing (`server/http_signatures.ts`)
|
||||||
|
|
||||||
|
1. Create `server/http_signatures.ts`.
|
||||||
|
2. Implement parsing logic for RFC 9421 `Signature-Input` and `Signature`
|
||||||
|
headers.
|
||||||
|
3. Extract the inline `hwk` (Header Web Key) JSON Web Key (JWK) parameter.
|
||||||
|
Ensure it is of type `kty="OKP"` and `crv="Ed25519"`.
|
||||||
|
4. Generate the SHA-256 fingerprint of the `hwk` object or public key bytes.
|
||||||
|
5. Build the Canonical Signature Base string using the requested components
|
||||||
|
(`@method`, `@authority`, `@path`, `content-digest`, `created`, `expires`,
|
||||||
|
`nonce`).
|
||||||
|
6. Validate timestamps (`created`, `expires`) with a strict $\pm 30$ seconds
|
||||||
|
drift tolerance against the server's current time.
|
||||||
|
7. Use Deno's native `crypto.subtle.importKey` and
|
||||||
|
`crypto.subtle.verify({ name: "Ed25519" })` to validate the digital
|
||||||
|
signature.
|
||||||
|
|
||||||
|
### Phase 2: Valkey Integration & Middleware Export (`server/http_signatures.ts`)
|
||||||
|
|
||||||
|
1. Integrate the $O(1)$ Valkey authorized fingerprint set check.
|
||||||
|
2. Query `SISMEMBER auth:hwk:fingerprints <sha256_fingerprint>`. If the result
|
||||||
|
is `0`, deny access immediately.
|
||||||
|
3. Wrap this logic into an exportable Hono middleware or helper function
|
||||||
|
(`verifyHttpSignature`).
|
||||||
|
|
||||||
|
### Phase 3: Route Integration (`server/main.ts`)
|
||||||
|
|
||||||
|
1. Modify `/api/forward-auth`:
|
||||||
|
- Inspect headers for either a valid Session Cookie OR
|
||||||
|
`Signature`/`Signature-Input` headers.
|
||||||
|
- If signature headers exist, invoke `verifyHttpSignature`.
|
||||||
|
- If valid, treat the request as authenticated (resolve the app context
|
||||||
|
similarly to the session-based flow). Ensure scopes/roles can be inferred,
|
||||||
|
possibly by mapping the fingerprint to a specific service account or app
|
||||||
|
grant in the DB if necessary (or relying on a default edge role).
|
||||||
|
2. Implement Admin Management Routes:
|
||||||
|
- `POST /api/admin/hwk`: Accept a public key / JWK, generate its fingerprint,
|
||||||
|
and add it to `auth:hwk:fingerprints` using Valkey `SADD`.
|
||||||
|
- `DELETE /api/admin/hwk/:fingerprint`: Remove a fingerprint using Valkey
|
||||||
|
`SREM`.
|
||||||
|
- Protect these routes using the existing global admin middleware.
|
||||||
|
|
||||||
|
### Phase 4: Testing & Quality Gates
|
||||||
|
|
||||||
|
1. Write hermetic tests simulating a headless client generating an RFC 9421
|
||||||
|
signature and submitting it.
|
||||||
|
2. Mock Valkey responses to test authorized vs unauthorized fingerprint checks.
|
||||||
|
3. Validate Deno native Ed25519 verification against a known good signature
|
||||||
|
payload.
|
||||||
|
4. Run `deno fmt`, `deno task lint`, `deno task check`, and `deno task test`.
|
||||||
Loading…
x
Reference in New Issue
Block a user