Skip to content

Add HTTP-only registration via RFC 9421 signatures #82

@lidel

Description

@lidel

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

  1. 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
  2. Server extracts PeerID from keyid parameter in signature metadata
  3. Server verifies RFC 9421 signature against the PeerID's public key
  4. Server performs signed HTTP probe to verify endpoint ownership (see below)
  5. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium: Good to have, but can wait until someone steps up

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions