Protocol Model

The four-layer architecture of the SIG protocol.

The SIG protocol is organized into four distinct layers. Each layer has a single responsibility and a well-defined interface to the layers above and below it.

Layer 1: Identity

Every issuer in SIG is identified by a canonical did:web Decentralized Identifier. The DID is derived from the issuer’s domain name, establishing a direct binding between organizational identity and DNS ownership. For example, the organization at acme.example would use the identifier:

did:web:acme.example

The did:web method leverages existing DNS and TLS infrastructure to establish issuer identity without requiring a blockchain or separate registry. Domain ownership serves as the root of trust: if you control the domain, you control the identity. Subjects (the entities that relationships are issued about) are also identified by did:web identifiers, though the protocol does not require subjects to publish their own SIG feeds.

Layer 2: Trust / Key Management

The issuer publishes a JSON Web Key Set (JWKS) containing one or more Ed25519 public signing keys. This key set is served at a well-known URL:

https://acme.example/.well-known/jwks.json

Each key in the JWKS includes a kid (Key ID) that uniquely identifies it. Verifiers retrieve this key set to validate event signatures. Key properties:

  • Algorithm: Ed25519 (EdDSA in JWA terminology) is required. The algorithms_supported field in issuer metadata must include "EdDSA".
  • Key rotation: Issuers may add new keys to the JWKS at any time. Old keys should be retained as long as events signed by them need to be verifiable.
  • Key compromise: If a key is compromised, the issuer should remove it from the JWKS and re-issue any affected events with a new key. Verifiers that encounter a kid not present in the current JWKS should treat the corresponding events as unverifiable.

Layer 3: Relationship Attestation

The core of the protocol. Issuers emit signed events that create or revoke relationships between the issuer and a subject. There are two event types:

  • relationship.upsert — Creates or updates a relationship. Contains the relationship type, roles, validity window, and optional display metadata.
  • relationship.revoke — Revokes a previously attested relationship. References the original relationship by ID and includes a reason code.

Each event is serialized as a JWS (JSON Web Signature) using the Flattened Serialization format. This format consists of three base64url-encoded components:

FieldContents
protectedHeader with alg, kid, and typ fields
payloadThe event body (all common + type-specific fields)
signatureEd25519 signature over the protected header and payload

Events are ordered by a monotonically increasing sequence number (starting at 1) and carry a unique event_id. The event log is append-only: entries are never modified or deleted.

Layer 4: Distribution

Issuers expose two .well-known endpoints for discovery and consumption:

Metadata Endpoint

https://acme.example/.well-known/sig-metadata.json

Returns an SigMetadata object describing the issuer’s SIG configuration, including the spec version, issuer DID, JWKS URI, events URI, supported algorithms, and visibility settings.

Events Feed

https://acme.example/.well-known/sig-events.ndjson

Returns the full event log as Newline-Delimited JSON (NDJSON). Each line is a complete JWS Flattened Serialization object representing one signed event. Events are ordered by sequence number.

Consumers read the feed, verify each event’s signature against the issuer’s JWKS, and compute the current relationship state by replaying events in sequence order.

How the Layers Interact

The layers compose into a verification pipeline:

  1. Discovery — A verifier starts at the Distribution Layer. It fetches /.well-known/sig-metadata.json to learn the issuer’s DID, key location, and feed location.
  2. Key retrieval — The verifier fetches the JWKS from the Trust Layer (/.well-known/jwks.json) and caches the issuer’s public keys.
  3. Feed consumption — The verifier fetches the event feed from the Distribution Layer and iterates through each JWS envelope.
  4. Signature verification — For each event, the verifier uses the kid in the protected header to look up the corresponding public key from the JWKS, then verifies the Ed25519 signature against the protected header and payload.
  5. State derivation — Verified events from the Attestation Layer are replayed in sequence order to derive the current state of each relationship. Upserts create or update relationships; revocations mark them as revoked.
  6. Identity binding — The issuer field in each verified event is checked against the Identity Layer’s did:web identifier to confirm the event was issued by the expected organization. This layered design means each concern can evolve independently. Key rotation does not affect event format. New event types can be added without changing discovery. Distribution mechanisms can change (for example, adding webhook push) without altering how events are signed or verified.