shared-signals.dev

Specs · CAEP Interoperability Profile 1.0

CAEP Interoperability Profile

SSF and CAEP leave many choices open. The Interoperability Profile picks one baseline, so a Transmitter and a Receiver built by different teams can connect without negotiating first. If you are building something new, build to this.

Status. Draft 01 was put to a 60-day public review as a proposed Final Specification on July 27, 2026. On September 15, 2026 the working group agreed to revise it in response to review feedback and restart the review, so the planned vote did not happen; a new timeline is still to be announced. The working copy has meanwhile added the Risk Level Change use case. This page follows the working copy and marks what is new since draft 01.

What it profiles

Shared Signals Framework 1.0, CAEP 1.0 and OAuth 2.0. To conform, an implementation must meet the common requirements below and support at least one of the use cases. (Earlier drafts said implementations may pick use cases; draft 01 made at least one mandatory.)

Transmitter checklist

AreaRequirement (MUST)
Discoveryspec_version present, 1_0 or greater.
Discoverydelivery_methods_supported present.
Discoveryjwks_uri present and resolving to the current signing key(s).
Discoveryconfiguration_endpoint, status_endpoint and verification_endpoint present.
Discoveryauthorization_schemes includes { "spec_urn": "urn:ietf:rfc:6749" }.
DeliveryAccept Create Stream with delivery.method of push (urn:ietf:rfc:8935) or poll (urn:ietf:rfc:8936); always return a delivery in the created stream.
StreamsSupport Create, Read Configuration, Read Status, Verification (and send the Verification event), and Delete.
SubjectsSend events using at least one of email, iss_sub (and opaque for Verification events).
SigningSign every SET with RS256, keys of at least 2048 bits.
SETsExactly one event in each SET’s events claim.
OAuthAccept bearer tokens in the Authorization header; reject tokens in query parameters (RFC 6750 §2.3).
OAuthValidate token integrity, expiry and revocation, check the token grants enough access, and return RFC 6750 §3.1 errors when it doesn’t.
TLSTLS 1.2 or later on every endpoint and outbound connection; follow RFC 9325.

Receiver checklist

AreaRequirement (MUST)
DeliveryAccept events by push (RFC 8935) or poll (RFC 8936) — at least one.
DeliveryCreate Stream with delivery.method of push or poll, or omit delivery (which means poll).
KeysFetch the Transmitter’s signing keys from jwks_uri.
OAuthUse OAuth 2.0 for every Stream Management API call.
SubjectsAssume every subject is in the stream — no Add Subject calls required.
SubjectsAccept events whose subject is email, iss_sub or opaque.
StreamsBe able to Create, Read Configuration, Read Status, request Verification (and process the Verification event), and Delete.
TLSFully validate the Transmitter’s TLS certificate (chain, expiry, revocation) per RFC 6125.

OAuth

The roles map directly: the Transmitter is the resource server, the Receiver is the client, and the authorization server is anything the Transmitter trusts to issue tokens — it doesn't have to be the Transmitter itself. How the Receiver finds that authorization server is out of scope; it may publish RFC 8414 metadata.

  • Tokens are issued with the client credentials grant or the authorization code grant (at least one).
  • Access tokens must be short-lived: 60 minutes or less.

Scopes

Scope names starting with ssf. are reserved for the SSF specifications. Authorization servers issuing tokens to Receivers must support two:

ScopeAllows
ssf.readRead Stream Configuration, Read Stream Status
ssf.manageEverything in ssf.read, plus Create Stream, Delete Stream and Stream Verification

Earlier drafts had Receivers discover scopes through OAuth Protected Resource Metadata (RFC 9728) when it was available. Draft 01 dropped that, so the two fixed scopes are now the only mechanism.

Use cases

Support at least one. In every one, Transmitters must populate reason_admin with a non-empty object (a localised message map, e.g. {"en": "Policy violation"}). Receivers must understand every allowed value of the listed fields; Transmitters may send any of them.

CAEP

Session Revocation / Logout

session-revoked

  • reason_admin: required, non-empty object
CAEP

Credential Change

credential-change

  • change_type: All values
  • credential_type: All values
  • reason_admin: required, non-empty object
CAEP

Device Compliance Change

device-compliance-change

  • previous_status: All values
  • current_status: All values
  • reason_admin: required, non-empty object
CAEP New since draft 01

Risk Level Change

risk-level-change

  • principal: All values
  • current_level: LOW, MEDIUM, HIGH
  • previous_level: All values; absent = unknown
  • reason_admin: required, non-empty object

Read the source

Checked against openid/sharedsignals @ a34d6ff (2026-09-01).