Shared Signals

To make Zero Trust work, we have to talk to each other.

There are thousands of brilliant vendors in the security space.

But the siloed nature of security stacks is inhibiting the adoption of Zero Trust.

IT and Security professionals have more choice than ever in how to secure their environments. At the same time, complexity in integration and communication has exploded. Security vendors, even if they solve a particular problem flawlessly, often can't communicate their information effectively to other parts of the IT environment. This lack of communication limits value, increases security risk, and encumbers the adoption of Zero Trust. If an endpoint detection solution notices a problem with a user's device but can't easily share that information with the control plane, how can it stop the problem from spreading?

Real-time communication between security solutions should be easy.

A standardized approach is required to simplify communication.

Traditionally, if vendors grant access to their security signals at all, they do it via a solution-specific API. To consume signals from multiple security vendors, IT professionals must wire up custom connections with each one. It's as if some vendors deliver their information in freight cars, others in container ships, and others by plane. This means organizations need to build a train station, a shipyard, and an airport! A standardized transport specification across security solutions makes it easy to incorporate new signals.

By building to an open standard, we can simply, consistently, and scalably share events, making security easier and more robust for our customers.

It's time to share signals.

Shared Signals and Events Framework

The Shared Signals and Events (SSE) Framework is a new standard currently being developed by the OpenID Foundation. Its purpose is to make it easy for companies to share security events related to the users who are using their systems. As stated on the working group's page:

The goal of the SSE Working Group is to enable the sharing of security events, state changes, and other signals between related and/or dependent systems in order to:

  1. Manage access to resources and enforce access control restrictions across distributed services operating in a dynamic environment.
  2. Prevent malicious actors from leveraging compromises of accounts, devices, services, endpoints, or other principals or resources to gain unauthorized access to additional systems or resources.
  3. Enable users, administrators, and service providers to coordinate in order to detect and respond to incidents.

Concepts and Definitions

The SSE Framework relies on five primary concepts:

a graph showing different types of subjects: a user, a group, an organization, and a device

Subject

A person, device, group, or organization about whom we want to communicate security events. The format of a Subject is described in this open source documentation.

a sheet of paper, with the message "security event" scribbled on it

Event

A security-related occurrence pertaining to a subject. Examples of events are when a user's session is revoked or their device goes out of compliance. These events are sent between parties as Security Event Tokens (SET) which are a type of JSON Web Token (JWT).

a person throwing a paper airplane, representing an event transmitter

Transmitter

A transmitter is a vendor that is broadcasting events to other vendors. In order to be a transmitter, you must define a set of API endpoints that fulfills the stream management spec described by this OpenAPI specification..

a person who just caught a paper airplaine, representing an event receiver

Receiver

A receiver is a security vendor that receives and acts on events. Receivers can configure what subjects they are interested in and how they would like to receive events by using the Stream Management API provided by a transmitter.

two paper airplanes in flight, representing events passing between transmitter and receiver

Stream

A stream is an abstraction for how events flow from a transmitter to a receiver. There can be a single stream between a transmitter and receiver, or there can be multiple streams. The transmitter advertises whether it supports PUSHing events to the receiver or being POLLed for events, or both. The receiver can choose which of the supported methods it prefers for communication.

Setting Up a Receiver

Please note: The Shared Signals and Events specfication is still under active development. The information shown here is correct as of November 2021, but we are aware of several changes that will be added soon – specifically around the creation and identification of streams. We will update this site as new information is published. Please check back frequently.

In the following sections we will walk you through how to configure an Event Receiver. You can run any of the following code snippets against a locally running version of our example Event Transmitter.

The spec does not describe how streams should be created. Our How to Create a Stream document discusses some potential methods, but for the purposes of these examples, assume a stream has already been instantiated.

Imagine you're a developer at PopularApp, a SaaS company that cares about the security of its users. You've learned that MostSecure, a well-established security company that monitors the web for breaches and password dumps, has set up an Event Transmitter that can share security signals about PopularApp users. In order to consume these signals and protect your users, you'll need to set up an Event Receiver.

As an event receiver, PopularApp will request a list of stream management endpoints from the transmitter, MostSecure. It will then use those endpoints to tell MostSecure what kinds of events it is interested in, how it wants to receive them, and which subjects it cares about. Finally, PopularApp can ask for a verification event to ensure the stream is configured correctly.

Hey, I heard you broadcast security events!
I sure do! Here's all the info you'll need to manage a stream.
Excellent. Sign me up for Device Compliance Change events. I'd like to poll for them.
Done. Here's the URL you'll use for polling.
Can I subscribe to events for Reginold Jones?
Okie dokie.
Can you queue up a verification event so that I can be sure it's all working?
Sure! If you poll for events, I'll have one waiting for you in no time.

Get the Stream Management Endpoints

The first thing PopularApp's receiver needs to do is to discover the endpoints it can use to manage the event stream hosted by MostSecure.

The receiver makes an HTTPS GET request to the transmitter's SSE configuration endpoint.

# In this and the following example python snippets, we're using the
# requests library to issue basic HTTPS requests to an example Event
# Transmitter. Note that for this sse-configuration request, no
# authorization is needed.
sse_config_response = requests.get(
  "https://transmitter.most-secure.com/.well-known/sse-configuration"
)
sse_config = sse_config_response.json()

In the response, the receiver will find all of the various endpoints needed to configure their stream. We will describe how these endpoints get used in the sections below.

{
  # This endpoint will be used by the receiver to view or update
  # the configuration of their stream.
  "configuration_endpoint": "https://transmitter.most-secure.com/stream",
  # This endpoint will be used by the receiver to add subjects to their stream.
  "add_subject_endpoint": "https://transmitter.most-secure.com/add-subject",
  # This endpoint will be used by the receiver to remove subjects from their stream.
  "remove_subject_endpoint": "https://transmitter.most-secure.com/remove-subject",
  # This endpoint will be used by the receiver to request a verification event,
  # so that the receiver can have confidence that the stream is working as intended.
  "verification_endpoint": "https://transmitter.most-secure.com/verification",
  # This endpoint will be used by the receiver to get or set the
  # status for the stream as a whole, or for individual subjects on the stream.
  "status_endpoint": "https://transmitter.most-secure.com/status",
  # This is the URL identifier of the transmitter; it matches the iss claim
  # in all events issued by this transmitter.
  "issuer": "https://most-secure.com/",
  # This is the URL of the transmitter's JSON Web Key Set. You can use
  # this to validate and decode the events sent by the transmitter.
  "jwks_uri": "https://transmitter.most-secure.com/jwks.json",
  # This attribute lets the transmitter declare which means of event
  # delivery it supports: pushing, polling, or both.
  "delivery_methods_supported": [
    "https://schemas.openid.net/secevent/risc/delivery-method/push",
    "https://schemas.openid.net/secevent/risc/delivery-method/poll"
  ],
  # This attribute comes into play when Complex Subjects are used.
  # A critical member is one that, if present, must be interpreted by the receiver.
  "critical_subject_members": [
    "user"
  ]
}

Update the Stream Configuration

Next, the receiver can use the configuration endpoint to read, update, or delete the configuration of its stream. Note that most pieces of stream configuration are read-only – that is, they are either set by the transmitter, or set out-of-band from these endpoints.

To update the stream config, the receiver makes an HTTP POST request to the configuration endpoint. Let's set the "delivery", "events_requested", and "format" arguments.

Since PopularApp is relying on MostSecure to find out if their users' passwords were leaked, it will request the RISC Credential Compromise event.

stream_config_response = requests.post(
  # Note that this request posts to the configuration_endpoint of the sse_config
  # returned in the last example.
  url=sse_config["configuration_endpoint"],
  json={
    # The receiver specifies how it would like to receive events, polling or pushing.
    "delivery": {
      # We are choosing the Polling method.
      "method": "https://schemas.openid.net/secevent/risc/delivery-method/poll",
      # In this example, because we're choosing Polling as our delivery method,
      # we can leave delivery.endpoint_url blank, as it is the Transmitter's
      # responsibility to specify that. If we had chosen Push, we would use this
      # value to tell the Transmitter where to send the events.
      "endpoint_url": None
    },
    # The receiver tells the transmitter what types of events it is interested in
    # getting on this stream by listing the URIs of the event types. The full list
    # of CAEP and RISC events are detailed in the Events section below, however the
    # SSE standard is general enough to cover any kind of event type. In our
    # imaginary scenario, PopularApp only cares about the Credential Compromise event.
    "events_requested": [
      "https://schemas.openid.net/secevent/risc/event-type/credential-compromise",
    ]
    # The receiver tells the transmitter its preferred subject identifier format.
    "format": "email"
  },
  # For this and all remaining requests, we need to include an Authorization header
  # with a Bearer token that the transmitter will be able to use to uniquely identify
  # us as a receiver. 
  # These examples use a "secret" that our transmitter maps to PopularApp.
  headers={
    "Authorization": "Bearer 49e5e7785e4e4f688aa49e2585970370",
  }
)
stream_config = stream_config_response.json()

The request body may contain all of the information shown in the response below. Our request only includes the read-write values because the transmitter will ignore any read-only values that were included. Leaving any read-write values out of the request will cause the transmitter to delete them from the stream configuration.

The JSON response will show the stream's updated configuration.

{
  # Read-Only. This URI is the issuer claim identifying the transmitter. 
  # It will be included in all events set on this stream. The receiver can
  # check this value to ensure that the event was sent by the expected party.
  "iss": "https://most-secure.com/",
  # Read-Only. This URI or list of URIs is the audience claim identifying 
  # the receiver. It will be included in all events sent on this stream.
  # The receiver can check this value to ensure the event is meant for them.
  "aud": "https://popular-app.com",
  # Read-Write. This indicates how events will be shared. If the push delivery
  # method is configured, the URL specified is where the receiver wants the
  # transmitter to push events. If the polling delivery method is configured,
  # the URL specified is the transmitter endpoint where the receiver can poll
  # for events.
  "delivery": {
    "endpoint_url": "https://transmitter.most-secure.com/poll",
    "method": "https://schemas.openid.net/secevent/risc/delivery-method/poll"
  },
  # Read-Only. These are the event types the transmitter supports.
  "events_supported": [
    "https://schemas.openid.net/secevent/caep/event-type/session-revoked",
    "https://schemas.openid.net/secevent/risc/event-type/credential-compromise",
  ],
  # Read-Write. These are the event types that the receiver is interested in.
  "events_requested": [
    "https://schemas.openid.net/secevent/risc/event-type/credential-compromise"
  ],
  # Read-Only. The intersection of events_requested and events_supported.
  "events_delivered": [
    "https://schemas.openid.net/secevent/risc/event-type/credential-compromise"
  ],
  # Read-Write. This optional setting indicates the subject format the receiver
  # wants for events.
  "format": "email",
  # Read-Only. This is the minimum time, in seconds, that a receiver must wait
  # in between verification requests.
  "min_verification_interval": 60
}

Add a Subject

With the stream configured, the receiver can now tell the transmitter which subjects it is interested in. For a closer look at how subjects work, see our guide on subjects in the SSE Framework.

For our example, we'll just focus on a Simple Subject identifying a user by email address.

{
  "format": "email",
  "email": "user@example.com"
}

Let's add one of PopularApp's users, Reginold Jones, to the event stream. To add a subject, the receiver makes an HTTPS POST request to the add subject endpoint.

add_subject_response = requests.post(
  # note that this request posts to the add_subject_endpoint of
  # the sse_config returned in the first example
  url=sse_config["add_subject_endpoint"],
  json={
    # There are many different types of subject identifiers, but for this example we’ll
    # use the email format to identify a user by their email address.
    "subject": {
      "format": "email",
      "email": "reginold@popular-app.com"
    }
  },
  headers = {
    "Authorization": "Bearer 49e5e7785e4e4f688aa49e2585970370"
  }
)

The transmitter will reply with a 200 OK response. Now any events that MostSecure sees that reference Reginold will be added to the stream.

Request a Verification Event

It's time to make sure everything is wired up correctly!

The receiver can make an HTTPS POST request to the transmitter's verification endpoint to ask for an example Security Event Token to be sent over the stream.

verification_response = requests.post(
  # Note that the request posts to the verification_endpoint of the sse_config 
  # returned in the first example.
  url=sse_config["verification_endpoint"],
  json={
    # This optional attribute, if included, ensures that the verification event 
    # generated by this request will also include the state in the event data.
    "state": "VGhpcyBpcyBhbiBleG"
  },
  headers={
    "Authorization": "Bearer 49e5e7785e4e4f688aa49e2585970370"
  }
)

The transmitter will reply with an empty 204 response, indicating the request came through loud and clear, and a verification event will be queued up for delivery.

Poll For Events

At this point we’ve got a fully configured event stream, and there’s an event waiting for us. We’ve configured the stream to use the polling delivery method, so let’s make an HTTPS POST request to the transmitter’s polling endpoint to retrieve that event now.

polling_response = requests.post(
  # Note that this request posts to the delivery endpoint returned when we configured
  # the stream, not to one of the initial set of well-known endpoints we've been
  # using until now.
  url=stream_config["delivery"]["endpoint_url"],
  json={
    # An optional integer value indicating the maximum number of events to be returned.
    # If more than the maximum number of events are available, the event transmitter
    # determines an appropriate algorithm by which to return them. If this parameter is
    # omitted, the transmitter may return any number of events.
    "maxEvents": 1,
    # An optional boolean value that indicates the transmitter should return an
    # immediate response even if fewer than maxEvents results are available
    # (short polling). The default value is false, which indicates the request is to
    # be treated as an HTTP long poll. A long polling request will always return 1 or
    # more events, unless a timeout is reached.
    "returnImmediately": True
  },
  headers={
    "Authorization": "Bearer 49e5e7785e4e4f688aa49e2585970370"
  }
)
events = polling_response.json()

In a polling configuration, the event transmitter queues events in a buffer so that a recipient can poll for them using HTTPS POST requests to a pre-arranged endpoint. The request parameters can be configured to customize the response into a short-polling response or a long-polling response.

Alternatively, we could have set up the delivery to use a push configuration, in which the transmitter sends events one-at-a-time to an endpoint configured by the receiver. To read more about this stream strategy, see our tutorial on Setting Up PUSH Delivery.

When PopularApp calls MostSecure's polling endpoint, any available events are returned in a JSON document.

{
  # A JSON object containing zero or more Security Event Tokens (SETs).
  # Each member name is the jti (a unique identifier for the event) of an event,
  # and its value is a string representing the event as an encoded JWT.
  "sets": {
    "1767b10443e511eca7740242ac120002": "eyJ0eXAiOiJzZWNldmVudCtqd..."
  },
  # A boolean value that indicates if more unacknowledged events are available
  # to be returned. If omitted, the receiver may assume no more events are available.
  "moreAvailable": false
}

The SET in this response has been encoded as a JSON Web Token (JWT) with the ES256 algorithm. To view the technical details of decoding with the ES256, see our tutorial document on Decoding SETs. Here's what it looks like after decoding.

{
  # Short for 'JWT ID', this is a unique identifier for the SET.
  # It allows receivers to determine whether they have already processed
  # this SET. Notice that it matches the key in the 'sets' object returned
  # from the polling endpoint.
  "jti": "1767b10443e511eca7740242ac120002",
  # This stands for "issued at" and describes the timestamp (in
  # seconds since the epoch) that the SET was issued.
  "iat": 1636741176,
  # Identifies the issuer of the SET. It should uniquely identify the
  # vendor that observed the security event. Notice that it matches the
  # issuer in the stream configuration.
  "iss": "https://most-secure.com/",
  # This is an identifier that the receiver can use to ensure
  # the SET is meant for them to process. The value can be a single URI or a
  # list of URIs. If it is present and the receiver cannot find themselves
  # in the values, the receiver should NOT process the SET.
  "aud": "https://popular-app.com",
  # A map of event URIs to event details. If multiple keys exist, they must
  # all be describing a single logical event. For instance, if the device
  # compliance change event also triggered a session revocation in the issuer,
  # you could potentially bundle those events together in this SET.
  # The common case will be to have one event per SET though. The event details
  # JSON will vary depending on event type. The keys used to indicate
  # the events are standardized and described in the CAEP and RISC specs.
  "events": {
    "https://schemas.openid.net/secevent/sse/event-type/verification": {
      # If the verification request included a state value, it will appear
      # here in the event. Note that this matches the state value sent to
      # the verification endpoint above.
      "state": "VGhpcyBpcyBhbiBleG"
    }
  }
}

Finally, let's acknowledge that we received the event successfully by making another polling request.

 # Grab the jtis that we want to acknowledge from the response json in "events"
jtis_to_ack = list(events["sets"].keys())
requests.post(
  # Acknowledgement of the events and requesting new events both use the same endpoint.
  url=stream_config["delivery"]["endpoint_url"],
  json={
    # An optional array of strings whose values are the jti values of successfully
    # received events that are being acknowledged. Once an event has been acknowledged,
    # the transmitter is released from any obligation to retain the event.
    "acks": jtis_to_ack,
    # The acknowledgement payload doubles in purpose as the subsequent
    # request payload. In this example, we’d like to “disconnect” from the event stream
    # at this point, so we set this value to 0, meaning 0 events will be returned.
    # If we wanted to continue receiving events, we could set this to a non-zero value.
    "maxEvents": 0,
    "returnImmediately": True,
  },
  headers={
    "Authorization": "Bearer 49e5e7785e4e4f688aa49e2585970370",
  }
)

You now know how to retrieve events from the stream. If you poll at regular intervals, you are sure to see some events from MostSecure about your user reginold@popular-app.com. When you get those events, you can take the appropriate actions to make sure your users maintain the high security that makes PopularApp so... popular.

Looking Forward

The SSE standard is still very new, but its potential impact is vast. In the coming years, the standard could provide the foundation for novel and innovative approaches to access management, session revocation, and detection and response. By implementing the standard now, companies can lay the groundwork for more continuous and dynamic implementations of Zero Trust.

Event Type Definitions

The SSE Framework is currently designed to send two kinds of events across these streams: CAEP Events and RISC Events. CAEP Events generally describe changes to a subject's session, while RISC events describe changes to a subject's account. Events are listed in the "events" claim of a SET as a JSON object that maps event URIs to JSON objects of event claims.

CAEP Events

All CAEP events have five generic event claims and zero or more event-specific claims. The generic event claims are:

  • subject: [REQUIRED] Indicates who or what the event is about. Uses one of the subject formats (described here).
  • initiating_entity: [OPTIONAL] The entity that invoked the event. Must be one of "admin", "user", "policy", or "system".
  • reason_admin: [OPTIONAL] A mapping of language codes to free-form text giving administrative explanations of the event for logging or auditing.
  • reason_user: [OPTIONAL] A mapping of language codes to free-form text giving user-friendly explanations of the event for displaying to the end-user.
  • event_timestamp: [OPTIONAL] The timestamp (in seconds since the epoch) at which the event described by this SET occurred. Note that this can be different from "iat" which describes the time the SET was added to the stream.
Session Revoked [spec]+

URI: https://schemas.openid.net/secevent/caep/event-type/session-revoked

This event indicates that a subject's session has been revoked for some reason.

Event specific claims:

It does not have any event-specific claims

Token Claims Change [spec]+

URI: https://schemas.openid.net/secevent/caep/event-type/token-claims-change

This event indicates that one or more of the claims in a subject's token has changed. For instance, this could indicate that the role granted to a user in their access token has changed.

Event specific claims:

  • claim: [REQUIRED] A JSON object containing one or more claims and their new values.
Credential Change [spec]+

URI: https://schemas.openid.net/secevent/caep/event-type/credential-change

This event indicates that a credential was created, changed, revoked or deleted. For example a password reset, a certificate renewal, or two factor enrollment.

Event specific claims:

  • credential_type: [REQUIRED] A string identifying the credential type. This must be one of the following values, or any other credential type supported mutually by the Transmitter and the Receiver:
    • password
    • pin
    • x509
    • fido2-platform
    • fido2-roaming
    • fido-u2f
    • verifiable-credential
    • phone-voice
    • phone-sms
    • app
  • change_type: [REQUIRED] A string that must be one of the following values:
    • create
    • revoke
    • update
    • delete
  • friendly_name: [OPTIONAL] A string indicating the credential friendly name
  • x509_issuer: [OPTIONAL] A string indicating issuer of the X.509 certificate as defined in [RFC5280], if applicable
  • x509_serial: [OPTIONAL] A string indicating the serial number of the X.509 certificate as defined in [RFC5280], if applicable
  • fido2_aaguid: [OPTIONAL] A string indicating the FIDO2 Authenticator Attestation GUID as defined in [WebAuthn], if applicable
Assurance Level Change [spec]+

URI: https://schemas.openid.net/secevent/caep/event-type/assurance-level-change

This event indicates that there has been a change in authentication method since the initial user login. This change can be from a weak authentication method to a strong authentication method, or vice versa. For example, if a user authenticates to Service Provider A using password, then authenticates to Service Provider B using two-factor authentication, an assurance level change should be sent to Service Provider A to inform them of the increased assurance level.

Event specific claims:

  • current_level: [REQUIRED] A string indicating the current NIST Authenticator Assurance Level (AAL) as defined in [SP800-63R3]. It must be one of the following strings:
    • nist-aal1
    • nist-aal2
    • nist-aal3
  • previous_level: [REQUIRED] A string indicating the previous NIST AAL. It shares the same value constraints as current_level
  • change_direction: [REQUIRED] A string indicating the AAL increased or decreased. Its value must be “increase” or “decrease”
Device Compliance Change [spec]+

URI: https://schemas.openid.net/secevent/caep/event-type/device-compliance-change

This event indicates that a device's compliance status has changed. The actual reason why the status change occurred might be specified with the core CAEP event claims reason_admin and/or reason_user

Event specific claims:

  • previous_status: [REQUIRED] A string indicating the compliance status prior to the change that triggered the event. Its value must be “compliant” or “not-compliant”
  • current_status: [REQUIRED] A string indicating the current status that triggered the event. Its value must be “compliant” or “not-compliant”

RISC Events

RISC and CAEP events share structural similarities since both event types are represented as SETs. Unlike CAEP, RISC events do not have any common optional claims -- each event type has a unique set of claims. RISC does include a required "subject" claim, like CAEP events. The generic event claims are:

  • subject: [REQUIRED] Indicates who or what the event is about. Uses one of the subject formats (described here).
Account Credential Change Required [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required

This event indicates that the account identified by the subject was required to change a credential. For example the user was required to go through a password change

Event specific claims:

It does not have any event-specific claims

Account Purged [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/account-purged

This event indicates that the account identified by the subject has been permanently deleted.

Event specific claims:

It does not have any event-specific claims

Account Disabled [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/account-disabled

This event indicates that the account identified by the subject has been disabled. The actual reason why the account was disabled might be specified with the nested reason attribute described below. The account may be enabled in the future.

Event specific claims:

  • reason: [OPTIONAL] A string indicating why the account was disabled. Possible values include but are not limited to
    • hijacking
    • bulk-account
Account Enabled [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/account-enabled

This event indicates that the account identified by the subject has been enabled.

Event specific claims:

It does not have any event-specific claims

Identifier Changed [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/identifier-changed

This event indicates that an email or phone identifier has changed.

Event specific claims:

  • new-value: [OPTIONAL] A string indicating the new value of the identifier
Identifier Recycled [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/identifier-recycled

This event indicates that an email or phone identifier has been recycled and now belongs to a new user.

Event specific claims:

It does not have any event-specific claims

Credential Compromise [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/credential-compromise

This event indicates that the identifier specified in the subject was found to be compromised.

Event specific claims:

  • credential_type: [REQUIRED] A string that must be one of the following strings, or any other credential type supported mutually by the Transmitter and the Receiver:
    • password
    • pin
    • x509
    • fido2-platform
    • fido2-roaming
    • fido-u2f
    • verifiable-credential
    • phone-voice
    • phone-sms
    • app
  • reason_admin: [OPTIONAL] The reason why the credential compromised event was generated, intended for administrators
  • reason_user: [OPTIONAL] The reason why the credential compromised event was generated, intended for end-users
Opt In [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/opt-in

This event indicates that the account identified by the subject opted into RISC event exchanges.

Event specific claims:

It does not have any event-specific claims

Opt Out Initiated [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/opt-out-initiated

This event indicates that the account identified by the subject initiated to opt out from RISC event exchanges

Event specific claims:

It does not have any event-specific claims

Opt Out Cancelled [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/opt-out-cancelled

This event indicates that the account identified by the subject cancelled the opt out from RISC event exchanges.

Event specific claims:

It does not have any event-specific claims

Opt Out Effective [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/opt-out-effective

This event indicates that the account identified by the subject was effectively opted out from RISC event exchanges.

Event specific claims:

It does not have any event-specific claims

Recovery Activated [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/recovery-activated

This event indicates that the account identified by the subject activated a recovery flow.

Event specific claims:

It does not have any event-specific claims

Recovery Information Changed [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/recovery-information-changed

This event indicates that the account identified by the subject has changed some of its recovery information. For example a recovery email address was added or removed.

Event specific claims:

It does not have any event-specific claims

Sessions Revoked [spec]+

URI: https://schemas.openid.net/secevent/risc/event-type/sessions-revoked

This event indicates that all the sessions for the account identified by the subject have been revoked. This event type may be removed soon, so it is not recommended to rely on it. Instead, use the CAEP Session Revoked message.

Event specific claims:

It does not have any event-specific claims

About the Authors

Picture of website contributor Shayne Miel

Shayne is an architect at Cisco, working in Duo Security's Data Science and Engineering group. He has helped drive Risk Based Authentication and Continuous Trusted Access development at Duo.

Gloomhaven, Azul, Breath of the Wild

Picture of website contributor Josh Matz

Josh is a software engineer at Cisco, working on Duo Security's Admin Platform team. He strives to bring an excellent user experience to the Duo Admin Panel.

Catan, Coup, Rocket League

Picture of website contributor CJ Linton

CJ is a software engineer at Cisco, on Duo Security’s Customer Systems Platform team, creating solutions that help scale business.

Magic: the Gathering, Sushi GO, Slay the Spire

Picture of website contributor Ted Kietzman

Ted is on the Product Team at Duo Security. He focuses on new forms of authentication and the role of analytics in access management.

Wingspan, Everdell, Pokemon Red

Picture of website contributor Emily Rosen

Emily is a designer on the Cisco Secure Brand Team. She creates pretty pictures that tell stories about security.

Hades, Risk of Rain 2, Ocarina of Time