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-challenge request with:
- RFC 9421 signature headers (Ed25519)
- JSON body containing
Value (ACME challenge) and HTTP(S) URL instead of multiaddrs
- Server extracts PeerID from
keyid parameter 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/expires in signature params)?
Related
Summary
Add an alternative authentication method to the existing
/v1/_acme-challengeendpoint 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-libp2pisn'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:
Authorization: libp2p-PeerID ...Signature+Signature-Input(RFC 9421)HTTP-only Flow
POST /v1/_acme-challengerequest with:Value(ACME challenge) and HTTP(S) URL instead of multiaddrskeyidparameter in signature metadataSigned 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.directby default):The probed endpoint must return an RFC 9421-signed response, proving the same set of things a we did in libp2p case:
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
@method,@path,content-digestExample Request
Open Questions
/.well-known/libp2p.direct?created/expiresin signature params)?Related