-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Summary
Add an alternative authentication method to the existing /v1/_acme-challenge endpoint that allows proving ownership of a peer's private key via RFC 9421 HTTP Message Signatures, without requiring a libp2p connection or dial-back verification.
Motivation
In complex IPFS deployments, different components handle different responsibilities, and go-libp2p isn't always present in the service that needs to register for a TLS certificate. An HTTP-only registration path would enable these setups to use p2p-forge without spinning up a full libp2p node.
Proposed Solution
Keep the existing endpoint but detect the authentication method based on request headers:
| Headers present | Auth method | Verification |
|---|---|---|
Authorization: libp2p-PeerID ... |
Current libp2p flow | libp2p dial-back + Identify |
Signature + Signature-Input (RFC 9421) |
New HTTP-only flow | Signed registration + Signed HTTP probe back |
HTTP-only Flow
- Client creates
POST /v1/_acme-challengerequest with:- RFC 9421 signature headers (Ed25519)
- JSON body containing
Value(ACME challenge) and HTTP(S) URL instead of multiaddrs
- Server extracts PeerID from
keyidparameter in signature metadata - Server verifies RFC 9421 signature against the PeerID's public key
- Server performs signed HTTP probe to verify endpoint ownership (see below)
- On success, DNS-01 TXT record is set
Signed HTTP Probe (replaces libp2p Identify)
Instead of dialing via libp2p and running Identify protocol, the server confirms endpoint ownership by probing a well-known path for p2p-forge domain (libp2p.direct by default):
GET <provided-url>/.well-known/libp2p.direct
The probed endpoint must return an RFC 9421-signed response, proving the same set of things a we did in libp2p case:
- ability to correctly make a port publicly diallable
- proove control of the private key at that public port
The p2p-forge broker verifies this signature against the same PeerID.
TLS handling: If an https:// URL is provided, the probe is performed with TLS certificate validation disabled, since the client is presumably requesting this certificate because TLS is not yet functional.
MVP Scope
- Ed25519 keys only
- Signature must cover at minimum:
@method,@path,content-digest - Single HTTP(S) URL in request body
Example Request
curl -X POST "https://registration.libp2p.direct/v1/_acme-challenge" \
-H "Content-Type: application/json" \
-H "Content-Digest: sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:" \
-H "Signature-Input: sig1=(\"@method\" \"@path\" \"content-digest\");keyid=\"12D3KooW...\";alg=\"ed25519\";created=1704067200" \
-H "Signature: sig1=:BASE64_ED25519_SIGNATURE:" \
-d '{
"value": "acme-challenge-token",
"url": "https://my-ipfs-gateway.example.com:8080"
}'Open Questions
- Exact response body/headers for
/.well-known/libp2p.direct? - Should we support multiple URLs?
- Additional anti-replay considerations (e.g., require
created/expiresin signature params)?
Related
- RFC 9421: https://datatracker.ietf.org/doc/html/rfc9421
- Current auth: libp2p HTTP PeerID Auth Spec