openid / sharedsignals Goto Github PK
View Code? Open in Web Editor NEWOpenID Shared Signals Working Group Repository
OpenID Shared Signals Working Group Repository
Section 7.1.1.2 specifies that before a stream is created the response sent by the Transmitter is empty. It should be the list of events supported by the Transmitter for that Receiver.
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.
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:
I'm happy to do edits on the draft and open a PR if there is any consensus on these questions.
In order to bring consistency and reduce confusion should we align with RFC8414 to use supported_scopes
as key in the SSF config metadata?
From Phil Hunt:
IETF spec expects subject identifier to be in the top level of the JWT. SSF expects subject identifier to be embedded within the events being transmitted. Can we move subject identifier out of the events into the top level SET definition?
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
.
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.
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.
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.
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:
1234
, application 5678
, and user foo
be delivered on this stream?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.
The format
claim is not present in any of the Stream Configuration request or response examples. It would be helpful to include it at least once so that it is more obvious what that claim is supposed to contain.
Should we consider supporting RFC6920 hashes as formats for subject identifiers to allow privacy preserving subject declaration?
The ComplexSubject identifier type contains the following fields:
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
.
From @atultulshi in a comment on #9
In the Transmitter Configuration Metadata, should we modify the "delivery methods supported" to include the POLL URL if the method is POLL?
A stream can be in one of three states:
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).
The spec says that the subject
claim is REQUIRED for all SSF events but also makes the subject
OPTIONAL for StatusChanged events and doesn't mention subject
at all for the Verification event.
We need to resolve this inconsistency.
Right now, the transmitter configuration returned from /.well-known
provides both an add-subject-endpoint
and a remove-subject-endpoint
. Can we just make that a subject-endpoint
with POST and DELETE functionality?
In the diagram, pt-out-cancelled
is missing o
s/bellow/below
Source link: https://github.com/openid/sse/blob/c3d7dad41eb7b36a4d9a328938547887f980c959/openid-risc-profile-specification-1_0.xml#L322
Add comma after opt-out: With regards to opt-out an account can be in one of these three states:
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?
Example, an IdP using Connect for the sign in, then a managed device with the device compliance change event, resulting in either a session revoked or assurance level change to an RP
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"?
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?
Phil Hunt has asked why the delivery methods in SSE are referenced by an OpenID Schema URI instead of direct references to the RFCs.
Review due August 8 link here
A transmitter may not know the original assurance level, therefore the previous_level
claim should be optional in the spec
I noticed that delivery methods are limited to
If a transmitter only supports CAEP events, do you suggest it uses risc
specific delivery-method
s, or is ok to support the following?
Both [DELIVERYPOLL] and [DELIVERYPUSH] don't provide guidance.
Add blurb to SSE spec about Google's RISC implementation being pre-standard.
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. :)
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.
SSE and RISC use XML as source, CAEP uses MD as source. We need a Makefile that builds the TXT and HTML outputs from these sources.
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:
{
"format": "aliases",
"identifiers": {
{
"format": "email",
"email": "[email protected]"
},
{
"format": "phone_number",
"phone_number": "+12065550100"
}
}
{
"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?
{
"user": {
"format": "email",
"email": "[email protected]"
},
"device": {
"format": "opaque",
"id": "12345"
}
}
{
"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?
Current spec (section 6.1) has this field as "required". Since SETs produced by SSF may not always be signed, should this field be OPTIONAL instead?
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.
As explained in RFC9110 delete call to respond back with HTTP 204 if the action is successful and no further information is to be supplied.
Current SSF specification says the response should be HTTP 200 with the empty response body. The correct response code should be HTTP 204
Remove subject correctly calls out 204 as a response code
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).
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.
From rfc8651
Applications that wish to mint new well-known URIs MUST register them, following the procedures in Section 5.1, subject to the following requirements.
Already registered well-known URIs https://www.iana.org/assignments/well-known-uris/well-known-uris.xhtml
Should we add an authorization object to the transmitter metadata to describe things like token type, scopes, etc that are required?
We need a new claim that defines the namespace used for the assurance levels. Claim name TBD (example used is namespace
).
{
"namespace": "",
"previous_level": "",
"current_level": ""
}
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.
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?
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.
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.
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
:
In some ways, you could think of a default stream as a stream whose stream_id
is null
.
Creates a new stream
stream_id
is missing)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)stream_id
is present and named streams are not supported, or stream_id
is missing and default streams are not supported.Gets the configuration of a stream.
stream_id
(optional)stream_id
argument is provided, returns the stream configuration object with that stream_id
. Otherwise, returns the stream configuration of the default stream.stream_id
is present and the stream does not exist, or stream_id
is missing and default streams are not supported.Updates a stream's configuration.
stream_id
is present and the stream does not exist or stream_id
is missing and default streams not supportedHow should we treat missing read/write values in the stream configuration object?
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.
stream_id
(optional)stream_id
is present and the stream does not exist, or stream_id
is missing and default streams are not supported.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"
Returns a list of the stream IDs in use
null
ID and will not be present in the list.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:
stream_id
is present and the stream does not exist, or stream_id
is missing and default streams are not supported.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.
We currently have reason_admin
and reason_user
, there has been interest in exploring a standardized reason_code
claim.
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"
]
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.