Git Product home page Git Product logo

sharedsignals's People

Contributors

adeinega avatar appsdesh avatar atultulshi avatar chamathns avatar fraglegs avatar matt-domsch-sp avatar mscurtescu avatar richanna avatar scvenema avatar sectim avatar timcappalli avatar tulshi avatar ycrumeyrolle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sharedsignals's Issues

Stream Status and Error Diagnosis

When updating a stream status, the requestor is able to provide a reason for the state change.

However if a receiver wants to find out why they are not getting events the status response does not include "reason", also the valid status values do not indicate an error (just enabled, paused, or disabled).

As an example if a push stream errors out because of too many delivery failures, invalid endpoint, authorization failure, the receiver might not know why the stream was paused (or errored out). Is there a problem? Or are there no events that have occurred?

Doing a periodic verify (as a health check) may help. But I wonder if connectivity reliability issues would show up here. For example, a high-rate of posts may get throttled or suffer some other issue requiring administrative intervention by the receiver.

This was a concern I recall being expressed by several orgs during the development of RFC8935.

Simple & Complex Subject Identifiers: why not use "aliases" construct defined in secevents draft spec?

A recent comment by Phil Hunt a few days ago in PR #82

The format value is an IANA registered format to avoid conflicts. The term "complex" is probably too generic.
You may want to prefix it with the spec name (e.g. caep, risc, ssf) For example "caep_complex".
Registration info is in section 8.1 of the subject identifier draft
Other than that looks good.

...caused to wonder why we are using this "Simple" and "Complex construct when the aliases subject ID type is already defined in draft-ietf-secevent-subject-identifiers-18 §3.2.8 and seems to fit our use case?

If we used aliases, then the Figure 6 example in the current draft of the Framework spec would instead look like:

{
  "iss": "https://idp.example.com/",
  "jti": "756E69717565206964656E746966696572",
  "iat": 1520364019,
  "aud": "636C69656E745F6964",
  "events": {
    "https://schemas.openid.net/secevent/caep/event-type/session-revoked": {
      "sub_id": {
          "format": "aliases",
          "identifiers": [
              "user": {
                  "format": "iss_sub",
                  "iss": "https://idp.example.com/3957ea72-1b66-44d6-a044-d805712b9288/",
                  "sub": "[email protected]"
              },
              "device": {
                  "format": "iss_sub",
                  "iss": "https://idp.example.com/3957ea72-1b66-44d6-a044-d805712b9288/",
                  "sub": "e9297990-14d2-42ec-a4a9-4036db86509a"
          ],
      },
      "initiating_entity": "policy",
      "reason_admin": "Policy Violation: C076E82F",
      "reason_user": "Landspeed violation.",
      "event_timestamp": 1600975810
    }
  }
}

I thought I brought this up on the 2022-06-20 call, but it somehow morphed into the "simple"/"complex" approach and I can't remember why. I recall @timcappalli mentioning some issue about nesting the array format being more difficult to process. I see that the aliases spec specifically precludes nesting; ** is nesting needed for some use case?** From a (de)serializing perspective, it seems like we already need to deal with this aliases type to conform with the draft IETF spec linked above so it should make things easier rather than more difficult for implementation.

Other observations:

  • For the new subject identifier types listed in §3.2 of our current draft (user, device, session, etc., shouldn't we include normative text defining the contents of each of these?
  • §3.4, "Additional Subject Identifier Formats" seems to define another subject id type. Shouldn't this just be included in the list of new subject identifier formats in §3.2?

I'm happy to do edits on the draft and open a PR if there is any consensus on these questions.

jwt-id should be jwt_id

Currently the spec uses jwt-id to describe the JWT ID simple subject format. This is at odds with all of the other simple subject formats that use underscores, like saml_assertion_id, iss_sub and phone_number.

And, in one of the CAEP examples we use the underscore as would be expected. We should update the SSF spec to use jwt_id.

Identify IANA requirements across specs

In order to potentially create IANA registries for shared/extensible elements, we need to identify requirements in a dedicated section of the spec, similar to OpenID Connect.

The SSF Spec should define standard scopes and authorization servers in the Transmitter Configuration Metadata

Since a Receiver needs to find out how to communicate with the Transmitter, it needs to know where to get an authorization token from in order to call the Transmitter endpoints, and with what scopes to request a token from that authorization server. To avoid each Transmitter having to define their own scopes for similar functionality, the spec should define a standard set of scopes that are recommended for use by Transmitters. Transmitters should be free to use other scopes if they want.

[CAEP] Credential Change event needs structure

credential_type and then all credential specific properties need to be part of a structure data model (x509_issuer, x509_serial, fido2_aaguid)

Might want to use AMR claim as a reference.

ComplexSubject clarification for incomplete info

In section 3.2.1 the SSE spec says

All members within a Complex Subject MUST represent attributes of the same Subject Principal. As a whole, the Complex Subject MUST refer to exactly one Subject Principal.

I read this to mean that when examining a new security event to determine whether it matches a subject that a receiver has added to the stream, the rule is that all of the attributes of the Complex Subject must match. That is, if the receiver added this subject:

{
    "device": {
        "format": "opaque",
        "id": "1234"
    },
    "application": {
        "format": "opaque",
        "id": "5678"
    }
}

Then in order for an event to be delivered on that stream, it must have both device 1234 and application 5678.

I have three questions:

  1. Is the interpretation above correct? Or would an event that matches any of the attributes be delivered on the stream?
  2. What happens if the event has more information than the ComplexSubject? That is, would an event with device 1234, application 5678, and user foo be delivered on this stream?
  3. What happens if the event has less information than the ComplexSubject? That is, would an event with device 1234 and no application information be delivered on this stream?

We need to come to a consensus about these cases, and then I would suggest we should add enough details to the spec to make the answers clear to readers.

ComplexSubject should have a format field

The ComplexSubject identifier type contains the following fields:

  • user
  • device
  • session
  • application
  • tenant
  • org_unit
  • group

All SimpleSubject types have a format field that identifies the type and then some number of other fields specific to the type. By not providing a format field in ComplexSubject, it has to be parsed differently. And, importantly, a Receiver has no way to request that a Stream Configuration use ComplexSubjects as the format value (see section 7.1.1 Stream Configuration).

I propose that we add a format field for ComplexSubjects and the value be complex.

What to do when stream status and subject status do not agree?

A stream can be in one of three states:

  1. enabled
  2. paused
  3. disabled

A subject that a stream is subscribed to can also be in one of those three states.

If a Receiver calls the Get Status endpoint and provides the optional subject argument, but the stream state and the subject state do not agree, what value should the Transmitter return? Same question for when the Receiver sets the status and provides the optional subject argument. My inclination is that it should work like this, but I would like to clarify in the spec:

Stream Status Subject Status Transmitter Response
enabled enabled enabled
enabled paused paused
enabled disabled disabled
paused enabled paused
paused paused paused
paused disabled disabled
disabled enabled disabled
disabled paused disabled
disabled disabled disabled

This could be expressed as an ordering where enabled < paused < disabled, and when there are disagreements the higher value wins.

Note that this could cause some confusion for the Receiver when they set the status of a stream or subject and get back a different status than they requested. However, that seems better than setting a status on one subject and having it affect other subjects (i.e. if enabling a subject also enabled a stream, for instance).

[RISC] Fix Typos

Section 2.8. Opt Out - diagram contents

via [email protected]

In the diagram, pt-out-cancelled is missing o

image

Source link: https://github.com/openid/sse/blob/c3d7dad41eb7b36a4d9a328938547887f980c959/openid-risc-profile-specification-1_0.xml#L327

Section 2.8. Opt Out - diagram caption

s/bellow/below
Source link: https://github.com/openid/sse/blob/c3d7dad41eb7b36a4d9a328938547887f980c959/openid-risc-profile-specification-1_0.xml#L322

Section 2.8. Opt Out - add comma

Add comma after opt-out: With regards to opt-out an account can be in one of these three states:

Source link: https://github.com/openid/sse/blob/c3d7dad41eb7b36a4d9a328938547887f980c959/openid-risc-profile-specification-1_0.xml#L313

Define process for creating new events

When someone has a new use case and needs a new event, how can we add those events without going through a full OpenID review process? Is the solution moving these events to a registry model?

What to do on stream PUT/PATCH if "events_delivered" is incorrect

The spec says that if any Transmitter-supplied values are present in the PUT or PATCH calls to the stream management endpoint, they should be checked against the values that the Transmitter believes are true and an error should be raised if the values don't match. We put this in so that Receivers could a) simply GET a stream, update values, and send that object to PUT/PATCH and b) confirm that their expectations from the Transmitter are correct.

However, "events_delivered" is a function of both "events_supported" (Transmitter-supplied) and "events_requested" (Receiver-supplied). It is unreasonable to ask the Receiver to guess what the "events_delivered" value will be, and it will change based on the "events_requested" that get sent up.

How should the Transmitter respond if the "events_delivered" value in the PUT/PATCH request does not match the "events_delivered" value that the Transmitter knows? Should those values be compared before or after applying the changes to "events_requested"?

Rework the "examples" sections

Some of our endpoints don't have examples. Others do. At least one of them (just below Table 6: Read Stream Status Errors) has a few examples that are general to all endpoints. Let's rework how we do examples. Maybe provide an examples section for the general ones and then make sure every endpoint has endpoint-specific examples and link to them from the examples section?

[SSE] Delivery method references

Phil Hunt has asked why the delivery methods in SSE are referenced by an OpenID Schema URI instead of direct references to the RFCs.

If a transmitter supports CAEP events, should the delivery method be CAEP specific?

I noticed that delivery methods are limited to

If a transmitter only supports CAEP events, do you suggest it uses risc specific delivery-methods, or is ok to support the following?

Both [DELIVERYPOLL] and [DELIVERYPUSH] don't provide guidance.

What happens when a paused stream is polled?

The SSF spec does not clarify what should happen when a stream that has been paused for new events is polled. Philip Hunt brought up this issue in an email: If a stream is suspended, what response should a poll request give (its not part of the poll request spec. For the moement I am requring status ok (there is nothing available because the stream is supsended) with a header indicating stream state. BadRequest Unauthorized, forbidden, or internal error all seem wrong. :)

Supply 'aud' in the stream creation POST request

I am proposing that, when creating a new stream, the receiver should pass the aud value, instead of assuming the transmitter already knows it.

This issue is specifically tied to the work being done in Issue #4 and PR #9. Prior to PR #9, a stream was created by default when the transmitter/receiver relationship was established. The mechanism by which that relationship is created is not described in the SSE spec, but it involved sharing some information between the receiver and the transmitter. Specifically, the transmitter and receiver must both know the bearer token used for authenticating requests and the aud value that is added to all events in the stream.

With PR #9 in place, there is no default stream in place between a receiver and a transmitter. Instead, a receiver creates streams by calling the configuration_endpoint [POST] endpoint. The receiver must have a bearer token in order to call that endpoint, so some out-of-band communication is still required, but we could reduce the amount of out-of-band information passing by having the aud parameter be a part of the information sent in that POST call.

How should overlapping subjects be handled?

When a Receiver adds a subject to a stream, it means that events that match that subject should get delivered on the stream. For most SimpleSubjects, this is an unambiguous mapping. But for Aliases and ComplexSubjects, things are a little less clear. What should happen if the values in the Aliases simple subject or in the ComplexSubject overlap? Here are some examples:

example 1 - overlapping Aliases

  1. Receiver adds:
{
  "format": "aliases",
  "identifiers": {
    {
      "format": "email",
      "email": "[email protected]"
    },
    {
      "format": "phone_number",
      "phone_number": "+12065550100"
    }
}
  1. Receiver adds
{
  "format": "aliases",
  "identifiers": {
    {
      "format": "email",
      "email": "[email protected]"
    },
    {
      "format": "opaque",
      "id": "12345"
    }
}

When the Transmitter wants to broadcast an event whose subject is

{
    "format": "email",
    "email": "[email protected]"
}

should it be sent to the Receiver twice?

example 2 - overlapping ComplexSubjects

  1. Receiver adds:
{
  "user": {
      "format": "email",
      "email": "[email protected]"
    },
    "device": {
      "format": "opaque",
      "id": "12345"
    }
}
  1. Receiver adds
{
  "user": {
      "format": "email",
      "email": "[email protected]"
    },
}

When the Transmitter wants to broadcast an event whose subject is

{
    "format": "email",
    "email": "[email protected]"
}

should it be sent to the Receiver twice?

add_subject_endpoint and remove_subject_endpoint endpoints

I'm curious if there is any particular reason to use the POST method in order to remove a subject from an event stream? Wouldn't it be a better choice to just use the DELETE method?

In addition to that, the specification currently uses

  "add_subject_endpoint":
    "https://tr.example.com/sse/mgmt/subject:add",
  "remove_subject_endpoint":
    "https://tr.example.com/sse/mgmt/subject:remove"

":" in both endpoints should be encoded as "%3A", this way
https://tr.example.com/sse/mgmt/subject:add becomes https://tr.example.com/sse/mgmt/subject%3Aadd, and
https://tr.example.com/sse/mgmt/subject:remove becomes https://tr.example.com/sse/mgmt/subject%3Aremove

The same applies to other examples.

Markdown source cleanup

Before the next implementer's draft, clean up the markdown source to follow up MD formatting best practices (Headings should be surrounded by blank lines, etc).

stream ID in delivery endpoints

On the 2022-06-14 call, @FragLegs brought up that the delivery endpoints need to have the stream ID either as a path component or query parameter.

We need to at least have a default pattern / parameter with a potential option to override via metadata.

SET Pull
For the pull transport (poll), the endpoint is defined by the transmitter.

SET Push
For the push transport (webhook), the endpoint is defined by the receiver.

Create Stream description lacks option for "Stream already exists"

If a Transmitter wanted to support only one stream between itself and a specific Receiver, then the Transmitter should have a way to respond to a Receiver that has already created a stream with a status 303 (see other) or some such way of indicating that a stream already exists.

How long should Transmitters hold onto a JWK used to sign a SET?

Section 11.1.5 says that the exp claim MUST NOT be used in SSF SETs. If a SET has no expiration time, does that imply that the Transmitter MUST provide the JWK used to sign/encrypt that SET forever? If not, are there expectations for how long a Transmitter SHOULD make a particular JWK available?

Adding a Stream ID

In previous discussion, it was decided that we needed a way for there to be potentially more than one stream between a transmitter and receiver. Some use cases for this were the needs of GDPR to keep data localized, having different polling frequencies for different types of events, etc. What follows is a high-level proposal for how we could add stream IDs without significantly changing the structure of the SSE framework. I would like to have some discussion here so that the high-level details can be settled before I create a pull request for the change.

Support for default and/or named streams

First of all, because stream IDs dictate something about how the data model works, transmitters should be able to decide whether they support streams with IDs or not. Currently, there is a single default stream per receiver. I propose adding a new optional property to the transmitter configuration response from /.well-known/sse-configuration:

stream_types: [
  "https://schemas.openid.net/secevent/stream_type/default",
  "https://schemas.openid.net/secevent/stream_type/named"
]

This allows the transmitter to support both default and named streams. Many, perhaps most, receivers will only care about having a single stream, so continuing to support a default stream is user friendly.

The default stream does not need to be created. It exists as soon as there is a transmitter/receiver relations if the transmitter supports default streams. Any named streams must be explicitly created.

Changes to the configuration_endpoint

Changes to the stream configuration object

The most significant changes to the spec are centered around the configuration_endpoint, in the GET, POST and DELETE verbs, as well as in a new PATCH verb (detailed below).

With the exception of DELETE, all of these verbs either take a Stream Configuration object as an argument or return a Stream Configuration object. In all cases, we would update the Stream Configuration object to include a new optional parameter, stream_id:

  • stream_id (if missing, assume default stream)
  • iss (read only)
  • aud (read only)
  • events_supported (read only)
  • events_delivered (read only)
  • min_verification_interval (read only)
  • events_requested (read/write)
  • delivery (read/write)
  • format (read/write)

In some ways, you could think of a default stream as a stream whose stream_id is null.

Create a Stream - configuration_endpoint [POST]

Creates a new stream

Arguments

  • stream configuration object
    • All attributes of the object are optional (but will raise error if stream_id is missing)

Results

  • 200: New stream created, returns stream configuration object
  • 400: Request cannot be parsed or a read-only value is present and incorrect
  • 401: Authorization failed or is missing
  • 403: Event receiver is not allowed to create a stream
  • 409: A stream with stream_id already exists. Because the default stream always exists, calling this endpoint without a stream_id will always raise a 409 (or 501 if default streams are not supported)
  • 501: Not implemented. A stream_id is present and named streams are not supported, or stream_id is missing and default streams are not supported.

Get Stream Configuration - configuration_endpoint [GET]

Gets the configuration of a stream.

Arguments

  • stream_id (optional)

Results

  • 200: If the stream_id argument is provided, returns the stream configuration object with that stream_id. Otherwise, returns the stream configuration of the default stream.
  • 401: Authorization failed or is missing
  • 403: Event receiver is not allowed to get streams
  • 404: A stream_id is present and the stream does not exist, or stream_id is missing and default streams are not supported.

Update a Stream - configuration_endpoint [PATCH]

Updates a stream's configuration.

Arguments

  • A stream configuration object

Results

  • 200: Stream updated, returns stream configuration object
  • 400: Request cannot be parsed or read only property is incorrect
  • 401: Authorization failed or is missing
  • 403: If the Event Receiver is not allowed to update a stream
  • 404: If the stream_id is present and the stream does not exist or stream_id is missing and default streams not supported

Open question

How should we treat missing read/write values in the stream configuration object?

  1. PATCH semantics imply that missing values should be interpreted as "leave the value as it is".
  2. Current SSE framework interprets missing read/write values as "delete the value". But interprets missing read-only values as "leave the value as it is".
  3. Google best practice suggests including a field mask to indicate which fields are being updated. Do we want that?

Delete a Stream - configuration_endpoint [DELETE]

Deletes a named stream or resets a default stream to its default configuration. When a stream is deleted (or reset for default streams) all subjects that have been added to the stream, events that have been enqueued in the stream, or status that has been set on the stream should also be deleted.

Arguments

  • stream_id (optional)

Results

  • 200: Success
  • 401: Authorization failed or is missing
  • 403: Event receiver is not allowed to delete streams
  • 404: A stream_id is present and the stream does not exist, or stream_id is missing and default streams are not supported.

New endpoint: list_streams_endpoint

A new endpoint will be included in the transmitter configuration response from /.well-known/sse-configuration:

list_streams_endpoint: "https://tr.example.com/sse/mgmt/list_streams"

List stream IDs - list_streams_endpoint [GET]

Returns a list of the stream IDs in use

Arguments

  • None

Results

  • 200: A list of stream IDs. Note that the default stream has a null ID and will not be present in the list.
  • 401: Authorization failed or is missing
  • 403: Event receiver is not allowed to list streams

Other changes

The following endpoints all get an optional stream_id argument, either in the body of the POST endpoints or the URL params of the GET endpoint. If the stream_id argument is missing, assume the default stream is being indicated.

All five methods get a new possible return value:

  • 404: A stream_id is present and the stream does not exist, or stream_id is missing and default streams are not supported.

What is the semantic difference between PUT and PATCH in stream management?

There does not appear to be normative text regarding the purpose and semantics of each of PUT or PATCH. Further there is no normative text explaining the differences.

The examples seem to suggest that PUT is an entire document swap, whereas PATCH only specifies changed data.

Even with PUT, there are some claims (e.g. stream identifier) which the requestor may not change (as they are immutable).

SCIM Protocol (RFC7643) ran into this and had to define what happens for differing attribute types that have differing mutability. For example, a PUT or PATCH updating a read-only attribute is ignored rather than generating an error. Similarly an attribute that was missing from PUT does not mean delete the attribute. Instead, SCIM PUT sets out what the client must do to delete or nullify an attribute. The use case in SCIM was a client GETs a resource (or a StreamConfiguration), modifies an attribute and PUTs it back.

In the case of stream management, I don't see the need for a PATCH operation. In contrast in SCIM, where groups are potentially very large objects, PATCHing them makes sense.

Stream create/update for the PUSH method to allow defining token for the receivers endpoint

Stream create/update configuration requests to allow passing token used for the authentication of the receivers API where transmitter will push the events

Create Stream example with the token as input

POST /ssf/stream HTTP/1.1
Host: transmitter.example.com
Authorization: Bearer eyJ0b2tlbiI6ImV4YW1wbGUifQo=

{
  "delivery": {
    "method": "urn:ietf:rfc:8935",
    "url": "https://receiver.example.com/events",
    "token": "Bearer 038597ojsxas9ucisdmlsudc9sj"
  },
  "events_requested": [
    "urn:example:secevent:events:type_2",
    "urn:example:secevent:events:type_3",
    "urn:example:secevent:events:type_4"
  ]
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.