Shared Signals SSF Explorer

What is Shared Signals?

A five-minute, plain-English introduction to the Shared Signals Framework — and a guide to driving this live demo.

The Shared Signals Framework (SSF) is an open standard from the OpenID Foundation that lets services broadcast security and operational signals to one another in near‑real‑time. When something important happens in one system — a customer grants consent, a payment executes, a session is revoked — SSF lets that system instantly notify the other systems that care, instead of them polling for changes or finding out late.

Think of it as a publish/subscribe network for trustworthy security events: transmitters publish signals, receivers subscribe to the ones they want, and every signal is cryptographically signed so it can be trusted.

A signal is a signed event

Each signal is a small Security Event Token (SET) — a JSON Web Token (RFC 8417) describing exactly one event: its type, a subject it concerns, a timestamp, and a correlation id. Crucially, each SET is digitally signed (here with PS256) by the transmitter. The receiver verifies that signature against the transmitter's published public keys (its JWKS), so it knows the signal genuinely came from that transmitter and wasn't tampered with in transit.

Here is what a decoded signal looks like — exactly what you'll see when you expand an event row in the Explorer:

{
  "iss": "https://universe.demo.cba.raidiam.io",
  "aud": "ssf-subscriber",
  "iat": 1780000000,
  "jti": "set-7f3a1c",
  "txn": "auth-req-9b2e",
  "sub_id": { "format": "client_id", "client_id": "rp-demo" },
  "events": {
    "https://schemas.connectid.com.au/secevent/idp-telemetry/event-type/consent-granted": {
      "event_time": "2026-06-05T10:25:04Z"
    }
  }
}

That example is a service signal following the ConnectID transaction‑telemetry profile (subject = the relying party, payload member event_time as an RFC 3339 string). A signal about a person follows the OpenID CAEP profile instead — the subject is the user, and the payload uses event_timestamp (a numeric timestamp) plus CAEP‑specific members:

{
  "iss": "https://universe.demo.cba.raidiam.io",
  "aud": "ssf-subscriber",
  "iat": 1780000000,
  "jti": "set-2a9f04",
  "sub_id": { "format": "email", "email": "alex@example.test" },
  "events": {
    "https://schemas.openid.net/secevent/caep/event-type/session-revoked": {
      "event_timestamp": 1780000000,
      "initiating_entity": "user"
    }
  }
}

The cast — who's who

Transmitter
Emits signed SETs whenever events happen, and exposes a Management API so receivers can subscribe.In this demo: the banks (Mock Bank + Aurora), tapping a live CIBA authentication & payment flow.
Receiver
Subscribes to a transmitter, then receives, verifies and displays its SETs.In this demo: this app — the Explorer you're using.
Stream
A subscription between a receiver and a transmitter: which event types and which subjects you want, and where the transmitter should deliver them.
Topics
The kinds of signal a transmitter can emit (event types) — e.g. consent-granted payment-executed verification. A receiver picks which topics to subscribe to.
Subject
Who or what a signal is about. In SSF generally, a subject can identify a person — the Subject Identifiers for SETs spec (RFC 9493) defines formats such as email phone_number account iss_sub — so a signal can absolutely be about an end‑user. What SSF allows is not what every profile chooses.ConnectID — and this demo — deliberately make the subject the relying‑party ({"format":"client_id"}), not the end‑user. So these signals say which RP an event involved, never which customer — keeping them free of personal data. That's a profile decision, not an SSF limitation.
Management API
The receiver-driven API (OpenID SSF 1.0) on the transmitter to create, tune, pause, verify and delete its own streams. Protected with OAuth (client_credentials + private_key_jwt).
Push delivery
How SETs travel (RFC 8935): the transmitter HTTP‑POSTs each signed SET to the receiver's endpoint, authorised by a per-stream bearer token the receiver chose at subscribe time.

How a signal flows

1DiscoverReceiver reads the transmitter's /.well-known config.
2AuthenticateGets an OAuth token to call the Management API.
3Create streamChooses topics & subjects; registers a push endpoint.
4PushTransmitter signs & POSTs each SET as it happens.
5Verify & showReceiver checks the signature, stores & displays it.

Using this demo

  1. Transmitters

    Your two banks are pre-trusted. On the Explorer you'll see each transmitter's available topics (the event types it can emit), its delivery method and its signing keys. You can add another transmitter by URL.

  2. Subscribe

    Pick a transmitter, tick the event topics you want (or “all events”), then choose a scope: leave it open (firehose), pick one or more users to receive security signals about those people (CAEP mode), or list relying-party client_ids. Create stream — the Explorer mints a per-stream push token and registers the stream with the bank.

  3. Streams

    Your new stream appears here. You can pause / resume it, add or remove subjects, request verification (ask the transmitter to emit a signal right now), or delete it.

  4. Events

    Watch SETs arrive live. Expand any row to see the decoded payload — the signed header (alg/kid/typ) and the claims (iss, aud, jti, txn, sub_id, events).

Two modes — and why it matters

This demo runs both flavours of subject, so you can see the distinction live:

RP / ConnectID
Subject = relying-party client_id. Transaction-telemetry signals (consent-granted payment-executed) say which RP an event involved — no personal data. This is the ConnectID profile's deliberate choice.
User / CAEP
Subject = a user (email). CAEP security signals (session-revoked credential-change session-established) are about a person — this is the flagship "propagate security events about identities across an ecosystem" use case. It carries a user identifier by design.