Privacy Model

Public vs private visibility and privacy considerations.

Visibility

Every relationship event includes a visibility field with one of two values:

ValueMeaning
"public"The event may appear in publicly accessible feeds.
"private"The event should only appear in access-controlled feeds.

Visibility is set per-event at the time of issuance. A relationship.upsert can change the visibility of an existing relationship by issuing a new upsert with a different visibility value.

Public Feeds

When an issuer’s SIG metadata sets public_only: true, the event feed must contain only events with visibility: "public". This signals to consumers that the feed is safe to index and cache without access control.

Issuers operating public feeds must not include "private" events. Consumers encountering a private event in a public_only: true feed should treat it as a protocol violation and may reject the feed.

Privacy Leakage

Even in public feeds, operators should be aware of information that may be exposed:

  • Subject identifiersdid:key values in public events can be correlated across issuers. If the same subject DID appears in multiple issuers’ feeds, observers can infer that the subject has relationships with all of those organizations.
  • Relationship metadata — fields like relationship_type, roles, valid_from, and valid_until reveal details about the nature and duration of the relationship.
  • Revocation signals — the presence of a relationship.revoke event reveals that a relationship ended, and reason_code may disclose why.
  • Timing informationissued_at, valid_from, valid_until, and effective_at timestamps can reveal organizational patterns.

Issuers should carefully consider what information they include in public events and whether subjects have consented to public disclosure.

Security Considerations

Algorithm Downgrade

Consumers must reject any alg value other than "EdDSA". Accepting "none" or weaker algorithms would allow attackers to forge events. Implementations must not negotiate or fall back to alternative algorithms.

Key Rotation

Issuers may rotate signing keys by adding new keys to the JWKS and using the new kid in subsequent events. Old keys should remain in the JWKS for as long as consumers may need to verify historical events. Removing a key from the JWKS invalidates all events signed with that key.

Sequence Integrity

The append-only event log relies on strictly increasing sequence numbers. Consumers must reject feeds with duplicate sequence numbers and treat gaps as incomplete data. An attacker who can modify the feed could remove events (creating gaps) or reorder them (creating duplicates) to manipulate derived state.

Feed Incompleteness

A feed with sequence gaps cannot produce trustworthy derived state. A missing relationship.revoke event would cause a consumer to incorrectly treat a revoked relationship as active. Consumers should refuse to make authorization decisions from incomplete feeds and return exit code 2 (error).

Strict Timestamps

All timestamps must be valid ISO 8601 strings in UTC. Consumers should validate timestamp formats and reject events with malformed or missing timestamps. Clock skew between issuer and consumer systems is outside the scope of the protocol, but implementations should be aware of it.

DID/Domain Binding

The did:web method binds a DID to a specific domain. The issuer field in events must match the DID resolved from the domain serving the feed. If an event claims issuer: "did:web:example.com" but is served from other.com, consumers must reject it.

Future Extensions

The following capabilities are anticipated for future protocol versions:

  • Private feed authentication — a standardized chain for access-controlled feeds, allowing issuers to serve private events over authenticated HTTPS endpoints with bearer tokens or mutual TLS.
  • Subject countersignatures — allowing subjects to countersign relationship events, providing proof that the subject acknowledges and consents to the attested relationship.