Signed ingest (SEC-015)

Embed
Preview of the card
<a href="https://forumulate.com/p/watchtower/docs/signed-ingest"><img src="https://forumulate.com/api/public/orgs/watchtower/spaces/docs/pages/c878da2c-afac-49b3-8fb5-01af58a0f9cc/social-card.svg?v=3e7ae33eec8b" alt="Signed ingest (SEC-015)" width="600" height="315"></a>

An ingest credential can carry the Ed25519 public key its senders sign with: PUT /v1/projects/{prj}/credentials/{cred}/signing with {"public_key": "<base64 32 bytes>", "required": true|false}. Only the public key is stored. A present signature must always verify; required also refuses unsigned data.

Transport

Carrier

Signed bytes

OTLP/HTTP and the HTTP push receivers

headers X-WT-Signature-Timestamp: <unix s>, X-WT-Signature: ed25519=<base64>

<timestamp>.<request body as sent> (compressed bytes included)

OTLP gRPC Export (traces, logs, metrics)

metadata x-wt-signature-timestamp, x-wt-signature (same values)

<timestamp>.<protobuf encoding of the uncompressed Export request>

OTel Arrow streams, Jaeger/OpenCensus/profiles/push gRPC, Firehose, Pub/Sub, syslog, Kafka

none

cannot carry a per-payload signature

  • The timestamp must be within 5 minutes of the gateway clock.

  • With required, a credential is refused on every transport without a carrier (gRPC UNAUTHENTICATED, HTTP 401, signature required). Send such data over OTLP/HTTP or OTLP gRPC Export instead. Arrow exporters must be set to plain OTLP.

  • A signature sent on a gRPC method other than Export is refused, because it cannot be checked.

  • gRPC: sign the encoding your protobuf library produces for the request (field-number order; OTLP has no map fields). In Go: proto.MarshalOptions{Deterministic: true}.Marshal(req), signed in a unary client interceptor that sets both metadata keys. The gateway checks it against its own encoding of the decoded request, so build against an OTLP proto version no newer than the gateway's.

  • Refusals count in wt_gateway_signature_denied_total{signal="http"|"grpc"} (HTTP and gRPC verification failures).

Updated