Skip to content

Witness node

witness-node is the per-witness signing service. A network operator runs one instance for each configured witness identity. The node holds the private key; the gateway holds the corresponding public key and an authentication token.

gateway                              witness-node
   |  Authorization: Bearer token          |
   |  POST /v1/sign {attestation}          |
   |--------------------------------------->|
   |                                       | auth, rate, time, network checks
   |<---------------------------------------| signature + witness_id

Keys and schemes

The node supports the scheme selected in its configuration:

  • Ed25519: signs the canonical Attestation::to_bytes() message and returns a 64-byte signature.
  • BLS12-381: signs the same attestation message using a BLS secret key share. The gateway later aggregates valid BLS responses.

The node does not perform threshold aggregation or consensus. It signs as one configured witness. The gateway's threshold policy determines whether enough independent responses form a confirmed result.

Private keys and signing tokens are read from the witness configuration and are marked not to serialize. The configuration zeroizes key and token material on drop. Operators must still protect the configuration file and its storage.

HTTP surface

The node exposes:

  • GET /health for liveness;
  • GET /v1/info for the witness ID, public key, and network ID; and
  • POST /v1/sign for authenticated signing.

The signing handler authenticates before applying its per-IP limit. It accepts the current signing bearer token and, during rotation, an optional previous token. Token comparison is constant-time. The endpoint is limited to 60 requests per minute per IP as an additional defense layer.

Before signing, the node checks that the timestamp is within max_clock_skew (the default is 300 seconds) and that the attestation's network_id matches its configured network. These checks do not replace gateway-side signature verification.

Network placement

Witness nodes should not be public signing endpoints. The repository's nginx template restricts /v1/sign to localhost and declared gateway peers, while the bearer token is a second control. /health and /v1/info can be exposed for liveness and public-key discovery where that is appropriate.

Failure behavior

A node can be unavailable, reject a request, exceed its rate limit, or return a scheme-specific signing error. The gateway treats unavailable or invalid responses as non-contributing and retries the durable job when the threshold is not met. A single node's response is not a confirmed attestation.

The node is intentionally small: it does not persist attestations, batches, or anchor proofs, and it does not contact clients or auditors directly.