Shared Signals in your tenant
Your tenant can tell the applications that rely on it when something changes about a person's security, so they can act without waiting for a token to expire.
The transmitter
Turn on Send security events to applications in Flow Policy, choose the events to send, and choose whether new streams start with every user or none. Your tenant then publishes its transmitter metadata at /.well-known/ssf-configuration (OpenID Shared Signals Framework 1.0) and accepts stream requests. While it is off, no events are raised at all.
Streams for applications
An application that should receive events is one of your tenant's OAuth clients, confidential, with the client credentials grant and the ssf:manage scope assigned. With a client credentials token carrying that scope, it creates a stream:
POST /ssf/streams
Authorization: Bearer <client credentials token>
Content-Type: application/json
{"delivery": {"method": "urn:ietf:rfc:8936"},
"events_requested": ["https://schemas.openid.net/secevent/caep/event-type/session-revoked"]}An administrator can also create a stream for the application: under Shared Signals streams in Flow Policy, Create stream asks for the receiving application (one assigned ssf:manage), push to your tenant's lab receiver, push to an address, or poll, the events and an optional description. The stream belongs to the application as if it had created it, so it can read, change and delete it through the API. A push that needs an Authorization value is created through the API instead, so the page never handles a receiver's secret.
An application manages only its own streams: read them at GET /ssf/streams, change their events with PATCH, delete them with DELETE /ssf/streams?stream_id=, pause or resume them at /ssf/status, stop or restart events about one person at /ssf/subjects/remove and /ssf/subjects/add (a subject is {"format": "iss_sub", "iss": ..., "sub": ...}, with the sub the application received), and ask for a verification event with its own state at /ssf/verify. New streams start with in Flow Policy decides which people a new stream covers, and your transmitter metadata says so as default_subjects. With Every user (ALL, the default), removing a subject stops its events and adding it again restarts them; adding never narrows the stream. With No users (NONE), a stream sends events only about the subjects added to it, until they are removed. Adding answers 200 and removing 204. A stream keeps the choice it was created with. A stream accepts one verification request every 10 seconds, its min_verification_interval; one sooner is refused with 429 and Retry-After. A stream's delivery method and endpoint are fixed; create a new stream to change them. Administrators see every stream under Shared Signals streams on the Flow Policy page and can pause, resume, disable or remove one. A stream an administrator paused or disabled stays that way until an administrator resumes it, and the application's own status requests are refused with 403 meanwhile. The application can still delete it and create a new stream, so to stop an application receiving events, remove its ssf:manage scope.
Events
- Session revoked (CAEP
session-revoked): a person signed out their other browsers, or an administrator ended their sessions.initiating_entitysays which. Ordinary sign-outs and idle timeouts are not revocations. - Credential changed (CAEP
credential-change): a password was set, changed or removed, or an authenticator app or passkey was added or removed, withcredential_typeandchange_type. - Account disabled, Account enabled and Account deleted (RISC
account-disabled,account-enabled,account-purged): a user was locked, unlocked or deleted.
These are raised however the change was made: on the person's own pages, by an administrator, through SCIM, or on the Beyond the Login site for a BTL user. Each event is a Security Event Token (RFC 8417) with typ secevent+jwt, signed with the key of the application's ID tokens, addressed to the application's client ID, and naming the person by the sub that application knows, pairwise or not.
Push and poll
With push (RFC 8935), your tenant POSTs each token to the stream's endpoint, which must be https on a public host name outside Beyond the Login, with an Authorization value the application chose, if any. A 2xx answer is delivered, a 4xx other than 408 and 429 is refused and not retried, and anything else is retried after 30 seconds, 2 minutes, 10 minutes and an hour, then abandoned. A paused stream holds its events.
With poll (RFC 8936), the application POSTs to the stream's /ssf/poll/ address with maxEvents and the ack list of events it has handled. Unacknowledged events wait for seven days, at most 1000 per stream. The answer always returns at once; long polling is not offered.
The lab receiver
Learners' tenants can use the lab receiver's Shared Signals endpoint, /lab-receiver/ssf, as a push endpoint. Your tenant delivers to it without a network request; it checks each token as a receiving application should and lists the result on the Sample API page, never the token. It answers a good token with 202 and a bad one with 400 and an RFC 8935 error: JSON with err (such as invalid_key, invalid_issuer or invalid_audience) and a description.
Settings, Audit and limits
Reading streams needs tenant.ssf.read, and creating them in the portal and changing them tenant.ssf.manage; Tenant Admin holds both. Creating one is recorded in Audit as tenant.ssf.create with the application, the delivery method and the events, never the push address. Each stream request is recorded in protocol Audit (ssf.stream, ssf.status, ssf.subjects, ssf.verify, ssf.poll) under the application, and each push attempt as ssf.delivery with the user, the stream and the answer. A tenant can keep 20 streams and push 600 events an hour; over the hour's limit, events wait. Each stream can ask for one verification event every 10 seconds. All three appear in the tenant's usage view. The BTL organization has the same transmitter.