feat: [Federation] endoint for historical federation jwks

Issue #1641 resolved
Giuseppe De Marco created an issue

In italy we analyzed the problem of the historical authentications and the problem of the repudiation if in a federation we haven't a registry of the historical public keys of the participants.

Having defined how a trust chain makes the proof of the validity of all the statements in it, we may only need an historical registry of the TA’s public keys, published by TA to a specialized endpoint.

scenario
An RP has authenticated a user to an OP, in a second moment both RP and TA change their keys and the RP repudiates the authorization made to the OP.

I’d like to start a discussion with you about the possibility to have an jwks historical registry in the Federation specs.

We may consider a new endpoint, mandatory for the TA, that publishes all the federation jwks used in its ECs during time:

Request

GET /.well-known/openid-federation-jwks HTTP/1.1 
Host: ta.example.it

Response

HTTP/1.1 200 OK
Last-Modified: Wed, 22 Jul 2018 19:15:56 GMT
Content-Type: application/jose

{
    "alg":"RS256",
    "kid":"2HnoFS3YnC9tjiCaivhWLVUJ3AxwGGz_98uRFaqMEEs",
    "typ":"federation-jwks+jwt"
}
.
{
    "keys":
    [
            {
                "kty":"RSA",
                "n":"5s4qi …",
                "e":"AQAB",
                "kid":"2HnoFS3YnC9tjiCaivhWLVUJ3AxwGGz_98uRFaqMEEs",
                "iat": 123972394872,
                "nbf": 123972394872
            },
            {
                "kty":"RSA",
                "n":"ng5jr …",
                "e":"AQAB",
                "kid":"8KnoFS3YnC9tjiCaivhWLVUJ3AxwGGz_98uRFaqMJJr",
                "iat": 123972394872,
                "nbf": 123972394872,
                "exp": 123974394972
            }
    ]
}

Comments (53)

  1. David W Chadwick

    Actually I think we can do better than simply publish a historical record of past keys. If the TA, when it first starts operations, publishes its current public key and next public key, this will also support key rotation. Therefore the TA should publish:
    - historical public key certificates, along with their validity times (validFrom, and validTo), as well as
    - the current public key certificate with the validFrom date/time, and
    - the next public key certificate that will be used once the current key expires or is compromised.

    Verifiers can then download the published list of keys, and store these along with the date/time they performed the download.

  2. Roland Hedberg

    We should not bring public key certificates into the mix.

    What we have is JWKSs who according to the standard RFC 7517 has no validFrom and validTo attributes.

  3. David W Chadwick

    Agreed, but according to RFC 7517 “For instance, the creator of a JWK can include a PKIX certificate in the JWK's "x5c" member. If the application validates the certificate and verifies that the JWK corresponds to the subject public key in the certificate, then the JWK can be associated with the attributes in the certificate, such as the subject name, subject alternative names, extended key usages, and its signature chain." So this would be one way of doing it as PKCs do have validity times.

    Another way would be to publish JWTs instead of JWKs as these also have validity times.

    Also from RFC 7517 “As another example, a JWT can be used to associate attributes with a JWK by referencing the JWK as a claim in the JWT. The JWK can be included directly as a claim value or the JWT can include a TLS- secured URI from which to retrieve the JWK value. Either way, an application that gets a JWK via a JWT claim can associate it with the JWT's cryptographic properties and use these and possibly additional claims in deciding whether to trust the key.”

    So I think it would be possible to include validity times if we wanted to do this.

  4. Giuseppe De Marco reporter

    Thank you Roland and David for your feedbacks

    Well, how it will be implemented Is a detail, what I want to point out Is the requirement to have in the federation specs a registry of the public keys of the TA to enable a mechanisms to make the historical authzs to an rp/Op non repudiable when keys changes.

    Having the trust chains linked to the trust established with the TA, we only Need that a TA publishes the registry of the jwks, without require this endpoint to all the participants.

    I don't see the requirement of x5c unless we will be able to use RAW crypto materials in Federation without x.509. x.509 would be overkill but It would a (useless) implementation option (because Federation is an applicative PKI itself)

  5. David W Chadwick

    It all depends upon what the requirements are. If the requirement is only to have a list of keys, then the existing jwks construct is fine. If the requirement is to know which key was valid during which period of time, and what the next key will be (to support key rotation) then adding validity times (past and future) to the keys will be necessary.

  6. Roland Hedberg

    Not committing to adding this to the federation spec.

    I guess one wants to know when the key was used, hence something like usage_start_date/usage_end_date.

    I agree that stored JWKs must be stored as signed JWT. Typically Key N would be signed by the N-1 key.

  7. Giuseppe De Marco reporter

    I’ve updated the description of this issue with an example that may be considered for our scopes

  8. Michael Jones

    Does such an endpoint exist for the Italian federations? If so, when/how is it used and what syntax is used for it?

  9. Giuseppe De Marco reporter

    We have the definition of the requirements and we’re considering to move along the groove of Federation 1.0, considering it strategic to avoid custom APIs but rather adhere to a model that can be shared with a wider audience. We’ve defined the properties of this registry, in terms of what should be exposed in it and its scope. those properties we already have in the example above. We also discussed the possibility to have a pagination in it but I’d like to keep it as much simple as possibile, considering that a TA shouldn’t change too many keys during its life!

    considering that we’re working on implementation proposals right now, we think that it would be better to join in the discussion with the WG and the entire openid community as soon as possibile

  10. Vladimir Dzhuvinov

    Does the Italian federation establish an arbiter to handle potential disputes of the “I never had this key” kind? Is this the TA or somebody else? This is important to know before figuring out a technical solution. For this reason I also don’t think we should be defining this endpoint, because it’s too federation policy specific.

  11. Pietro Stroia

    Does such an endpoint exist for the Italian federations? If so, when/how is it used and what syntax is used for it?

    Hi Michael, no, such registry is not currently available. I can’t comment on how this proposal should be added in the Federation spec, but I can chime in from a RP perspective. Say a RP has authenticated a user through an IDToken, however later on (even years?) the OP changes its keys and the RP would like to check back the integrity of the stored IDToken, previously collected as a proof of user authentication. If the online endpoint (i.e. metadata, OIDC Discovery) replies with only the "latest" key of the OP, such check is impossibile unless the RP itself starts to collect and save historical OP keys, which introduces a lot of other problems too depending on how those keys are encoded.

  12. Vladimir Dzhuvinov

    @Pietro Stroia This is a potential issue in public systems, no doubt. Have you considered trust marking the keys in a federation? From my (limited) perspective, having the TA keep a list of all keys may not be sufficient if there is a legal dispute.

    Here is one approach I was thinking of:

    • All entities register their keys in a central registry, and the registry trust marks them
    • Entities will not use a key unless it’s also trust marked (or can be found in the registry)

  13. Francesco Marino

    I would just like to add one point: the TA has the role of establishing the trust within the federation. Currently the specification provides clear rules on how to establish the trust on time (at each authentication request) but not for past transactions. This proposal, in my opinion, only provides technical tools for the TA to fully perform its role. How this data is then handled and the decisions that are made based on it is within the specific policies of each federation.

  14. Francesco Marino

    Vladimir, why do you think that this proposal may not be sufficient in case of legal dispute? Regarding your proposal, I’m probably missing something: the trust mark is signed with a key. What happens if that key is rotated?

  15. Giuseppe De Marco reporter

    @Vladimir Dzhuvinov yes we did it and we decided that we don’t want to move this critical functionality of a federation to trust marks, considering that these are also signed with keys that can expire and therefore require a historical record of the keys.

  16. Giuseppe De Marco reporter

    @vladimir dzhuvinov

    All entities register their keys in a central registry, and the registry trust marks them

    Well, using OIDC Federation we only need to store the Trust chain linked to the authentication, the entire chain would be verified anytime using the current TA’s pub key or, if these latter have been changed during time, the TA’s pub keys published in its historical registry (that would contain also the current in production)

  17. Vladimir Dzhuvinov

    Okay, if the subordinates start archiving the resolved trust chains this will work as complete and verifiable record for the Federation entity. The TA will have in its ToS a section that it will securely archive all its keys, and even use a public ledger if greater assurance is necessary.

    But how about the OIDC Core keys, used eg to sign ID tokens authenticating the end users? Those, if they are indeed separate (as now recommended) from the Federation key set, will not be covered by the TA and the trust chain. An RP may want for extra assurance those keys to be included as well if it archives the ID token for a particular transaction. If those keys are not in the Federation trust chain and parties want to be sure the keys cannot simply disappear or be denied existence, they will need them registered somewhere centrally, perhaps additionally trust marked so that the counterparty can verify the registration of the key without querying the registry.

  18. Francesco Marino

    I think storing the entity configuration/statements is enough. In the entity configuration of a leaf we have the oidc core keys. In the entity statements of its superior we have the federation public key of the descent which can be used to verify the entity configuration, and so on until TA. Here you can verify its entity configuration by using the registry. What do you think?

  19. Giuseppe De Marco reporter

    @Vlad the oidc core keys are contained in the EC and this is verifiable within a trust chain

    Having verified the TC you have verified, and you can trust, the oidc keys as well

  20. Vladimir Dzhuvinov

    I was going to ask how can the OP core keys possibly get inlined in the EC metadata when we have the std OP jwks_uri field available, but then I realised we now have the new optional signed_jwks_uri that overrides it. With that the case for me is closed and I am happy the chain can be extended to the OIDC core keys, provided OPs make use of the signed_jwks_uri. (we haven't implemented the signed_jwks_uri yet and the std jwks metadata field is actually feature of clients only)

    Our digital minister in Bulgaria mentioned the other week the idea to establish a general purpose block chain for use by public services. If we had an OIDC Federation this could be a nice place to archive those old TA keys and not worry about them any more. BTW, in Bulgaria there is a law that prevents the opening of legal disputes on transactions after a certain number of years and one of the reasons why this was done is to not require entities to keep paper archives until the end of time :)

  21. Giuseppe De Marco reporter

    yes, considering signed_jwks_uri but also the jwks claim, we defined also for the OPs.
    In the italian specs we have deprecated the jwks_uri endpoint, moving to the signed one and jwks.

    differently we may change the scope of the registry endpoint in Federation 1.0, publishing any kind of jwk and not only whom related to Federation operations.
    the lookup key would be the kid for every key and the endpoint would be /.well-known/openid-jwks with content-type application/openid-jwks

    the question is, would we like to have it as a well-know endpoint or do we like to have it like a federation endpoint with lookup parameters as GET methods, to be allowed to ask and obtain a specific key passing the &kid= parameter in the urlencoded form?

  22. Giuseppe De Marco reporter

    @Vlad Instead of a central registry for all the oidc core keys of the leafs, what do you think if a superior, that onboarded the leaf, should publish in the entity statement related to the descendants the metadata.openid_provider.jwks with the descendant's jwks at time of the onboarding (and following updates)?

    At the same time, we may discuss about the possibility that this historical register of the jwks should be also exposed by every intermediary, related to each descendants, filtering these with the &sub= parameter?

  23. Francesco Marino

    I think that if you want to have a strong trust validation, only signed_jwks_uri or jwks should be considered. In both cases it is enaugh to have an historical registry of TA keys. The OIDC Core and federation keys are inside the EC of a leaf. This EC is signed with a fed private key of the leaf and the public one is inside the ES of the superior. This process goes on until the TA. The RP stores the trust chain (and the EC/ES) so that at any time (even in the future when the key are no longer valid) it is possible to validate with the TA’s current federation pub key or with one that is in the historical registry. Can this work for you?

  24. Giuseppe De Marco reporter

    using signed_jwks_uri or jwks in the participant’s EC we solve the problem of the trust, having trust chains fullfilled with oidc core keys, and also historical registry of the TA’s pub keys in the federation infrastructure.

    For participants that uses jwks_uri I proposed to attest their jwks in the entity statement, in the metadata.openid_provider.jwks, this has impacts to federation rules and policies. Having the jwks nailed in the entity statement of the superior that has onboarded the participant we reduce the liberty of a participant to change its jwks in any time, without passing again through the onboarding system of its superior.

    Well, I’d consider that the registry of the historical jwks of the TA should be implemented anyway, and if a Federation allows jwks_uri and wants to solve the problem of the repudiation of the historical accesses it should mandates the presence of the metadata.openid_provider.jwks in the enttiy statement issued for the participants. This will make the Trsut Chain verifiable and consistent, having the evidence of the jwks to be considered in the oidc core signature operations

  25. Vladimir Dzhuvinov

    To sum up the conversation about the OIDC Core keys so far:

    1. We agree that the ability to include the OIDC Core keys in the trust chain can be crucial for OIDC Federations and must be supported by the standard
    2. In order for this to work it must be possible to either reference a signed JWK set by URI (signed_jwks_uri) or include it directly in statements (via jwks).
    3. The ability to include the OIDC Core keys in a statement via jwks makes it possible for superiors (TAs and intermediates) to require leaves to register their OIDC Core keys.

    I read the current OIDC Federation spec in main and in order to support the above we’ll need to define jwks for OPs, because for somebody who comes from the OAuth or OIDC Core specs this parameter doesn’t exist for identity providers, only the jwks_uri . The jwks for RPs / clients is defined already.

    For (3) and to make the life of developers easier the metadata.openid_provider.jwks seems best. A signed_jwks_uri appears to make sense only if OPs and RPs are going to rotate their keys independently from the entity keys and also independently from automatic or explicit registration requests, which kind of runs contrary to the objective of introducing the signed keys in the first place. Imagine an RP registers in auto to explicit mode with an OP its signed_jwks_uri , e.g. for private_key_jwt or the mTLS profile, which means the OP must fetch it additionally. Why? The reason the jwks_uri was introduced in OIDC Core and OAuth was to enable clients to rotate their keys without having to update their registration. So I started thinking whether we still really need this signed_jwks_uri parameter in OIDC Federation? What are your thoughts on this?

    Regarding the TA and if needed a general Federation Entity key archive, am I right that the real issue here is keeping the entity statements reasonably sized? Because if statement size didn’t matter an entity could simply keep adding new keys to its jwks theoretically forever, and if somebody is interested in let's say a key from 5 years ago it will still find it there.

  26. Giuseppe De Marco reporter

    @Vladimir Dzhuvinov

    I read the current OIDC Federation spec in main and in order to support the above we’ll need to define jwks for OPs

    we have defined jwks in Federation 1.0, here:
    https://openid.net/specs/openid-connect-federation-1_0.html#section-4.1-4.6

    Section “OP Metadata” inherits the claims defined in Section 4.1, and the same also for OAuth2 AS and Clients.

    The reason the jwks_uri was introduced in OIDC Core and OAuth was to enable clients to rotate their keys without having to update their registration

    For the point (3), the signed_jwks_uri contains a JWT signed with the federation private key of the issuer of these jwks (it’s a self-signed JWT). This allow a leaf to rotate its key in every moment. So, signed_jwks_uri is not signed by a superior. It works like jwk_uri but it’s signed and verifiable within a Trust Chain.

    However, the signed_ jwks published by a Leaf may be changed, by this latter, in every moment using an historical private key. In case of legal dispute the OP should present the trust chain evaluated for the RP, and the RP the trust chain evaluated for the OP (and these should be considered within a time window that contained the moment of the Authz request/response). Having said that we don’t have the copy of the signed_jwks in the trust chain, we don’t have the proof that the jwks at that moment was the one adopted by an RP (that may change its historical jwks signing these with an historical federation jwk private key).

    Having said this, we consider that only the claim jwks fullwidth the requirements to have the attestability of the historical accesses with the TA's jwk registry.

    If we may want to solve this problem we have to decide if:

    1. consider to have the signed JWT, available at signed_jwks_uri, also in the trust chain (and this would break the design principle of having only entity statements in the TC).
    2. remove signed_jwks from the specs
    3. leave everything as it is and adopting the strategy of the certified jwks in the superior’s entity statement, issued for a descendant. This would represent an implementation option for the federation that wants to cover the requirement of non repudiability for historical accesses.

    if statement size didn’t matter an entity could simply keep adding new keys to its jwks theoretically forever, and if somebody is interested in let's say a key from 5 years ago it will still find it there.

    regarding the content of the entity statements, the strategy to get attestation of the leaf’s jwks would be an implementation option, related to the decision to support the registry of the attestable oidc core keys and the requirement to support jwks_uri for the OP, inside a Federation.

  27. Michael Jones

    Per the 23-Sep-22 Federation Editors' call, we agreed that this should not be required but individual federations could choose to use it.

  28. Michael Jones

    We discussed Vladimir’s comments about OIDC Core keys on the 23-Sep-22 Federation Editors' call. As background, OpenID Connect Core has always retrieved the keys from the “jwks_uri” in the OP’s metadata. The Federation spec doesn’t change that.

    @John Bradley wanted to know what the attack is that you were interested in mitigating, @Vladimir Dzhuvinov . That wasn’t clear to us during the call. We agreed to continue discussing Vladimir’s comments about OIDC Core keys.

  29. Giuseppe De Marco reporter

    more than an attack we’re mitigating the issue of the repudiation of the historical transactions. We want to achieve the legal requirement of the non repudiability of the transaction in a past middle period (more than two years) when keys may be rolled by one or many participants

    Federation 1.0 only covers the aspect of the mechanisms to establish the trust without touching/breaking Connect.
    Inthis issue we propose the endpoint of the historical jwks, to enable the verification of the trust chain during the years.

    in addition we know that if the participants have used the claim jwks in the OP metadata instead of jwks_uri or signed_jwks_uri, in the trust chain we would get the proof, verifiable by signature, even of the keys used in the OIDC core operations.

  30. David Waite Account Deactivated

    This seems to solve the problem when the issuer wants to allow for its historical messages to be repudiated.

    An issuer which acted maliciously could just not list the prior key used to sign the messages it wishes to dispute. To argue these, the recipient needs to save the entity statements used to retrieve the signing keys originally.

    Humorously, this can be solved with a blockchain.

  31. Giuseppe De Marco reporter

    The trust is in the Trust Anchor, whether this is/use a blockchain or not, it doesn't matter its storage mechanisms but the Federation API t be compliant to the specs.
    If the TA were distributed on different organizations that needs to establish a quorum before any write operations the blockchain would make sense, otherwise I don't understand what it would be for.

    using jwks in the metadata of the OPs in italy we also solve the problem on the jwks of oidc core, as an additional benefit.

    For the general purpose of the Federation specs the registry does not solve the repudiation problems of expired (historical) jwks of OIDC Core metadata, because the OPs can use signed_jwks_uri or simply jwks_uri. So, for the general purpose of the specs, the registry of the jwks only give to us the possibility to cover the non repudiation of the trust chain.

    the recipient needs to save the entity statements used to retrieve the signing keys originally.

    Yes, it should save the trust chain related to an entity (even because it have to update it periodically)

  32. Michael Jones

    On the 30-Sep-22 Federation Editors' call, Giuseppe proposed to obtain more feedback on the idea, both from the Italian federations, and from @Torsten Lodderstedt and Mark Haine.

    We also discussed the possibility of making this its own specification, rather than including it in the Federation spec itself.

  33. David Waite Account Deactivated

    @Giuseppe De Marco If the TA is trusted to never try to manipulate whether something is able to be validated by omitting or adding JWTs from the historical record, e.g. if you aren’t shooting for historical non-repudiation but ‘just’ the ability to rotate the trust anchor keys, then this is ok.

    My earlier point is that if you actually want non-repudiation that the TA did indeed send this mark in the past (and that it isn’t synthesized for you to look like it came from the past), or to be able to dispute the repudiation of a mark, you would need a historical record that was not mutable solely at the discretion of the TA.

    I would also add to the side discussion that key rotation does not have nearly the value if an entity would perform new actions based on potentially new information signed from historical keys would act on information from historical records. This is because the key rotation is meant to time-box a malicious party’s ability to force the key, or to have value from a key which had been previously compromised in some way. So, trust marks likely would either prefer a dynamic means to refresh marks, or prefer stronger signatures to enable longer times between rotation (and in effect, mark expiry).

  34. David W Chadwick

    @DW. If key n signs the JWT for key n+1 and multiple RPs download these trust chains of keys, then even if the trust anchor subsequently adds or removes keys from the chain, wouldn’t the fact that multiple RPs have a historical record of a different key chain (that they are not able to create) be sufficient evidence that the trust anchor has subsequently manipulated its key chain?

  35. Torsten Lodderstedt

    The use cases we came across require evidence that a certain OP signed a certain ID token (which also means had officially used that key at a certain time). If the OP rotates its keys (and removes them from the jwks uri, the only evidence binding a certain key and a particular issuer for a certain time span is gone (in standard OIDC/OAuth). Not sure how an archive of the trust anchors keys can provide the necessary evidence.

    We decided to let an observer collect, digital sign and independently store ALL key data periodically.

  36. Giuseppe De Marco reporter

    How can you prove that a Key was issued by an Op and Is not a self issued, fake or repudiable one?

    Using the jwks claim also for the Op metadata, as introduced in the federation specs, we can prove that Key Is trusted inside a trust chain with the only requirement that the ta published all its federation jwks It used for signing the statements.

    Using jwks_uri and signed_jwks_uri this wouldnt be possible because they stay outside the trust chain. In this case having all the historical TA's jwks we still have a validation of an historical statement inside a chain, but not the jwks used in the oidc core operations

  37. Giuseppe De Marco reporter

    @DW the trust Marks are signed with the federation keys used by the trust Mark issuers (defined in the TA's entity configuration) that can be rolled

    So the requirement of a registry of the federation Key, at least for the TA, seems still up

  38. Giuseppe De Marco reporter

    We decided to cover this issue with a PR. This endpoint can be included in the italian profile or can be proposed with a different draft dedicatesi to this topic.

    Considering that:
    a) the federation jwks only covers the federation ops and not the oidc core ops.
    b) the statement issued by a superior for a leaf is contained and verifiable within its trust chain.
    c) the statement related to a leaf, without any metadata or metadata policy regarding the leaf, allows the sole verification of the signature of leaf’s entity configuration
    d) a leaf can change its oidc core jwks in every moment
    e) a leaf can change an historical trust chain with a fake entity configuration, using it’s federation jwks to produce the fake entity configuration related itself. This fake entity configuration can be verified with the superior statement. This superior statement may only give the federation jwks of the descendant for the signature verification of the entity configuration, whatever it contains, considering the point c).

    We can assure that a specific jwks was used for an OIDC operation if the following assumptions are considered as implementation requirements:

    1. the participants can adopt also signed_jwks_uri and jwks_uri as defined in the specs (and not only jwks as my initial requirement).
    2. the federation intermediary that onboards a participant have to collect the oidc core jwks published in the leaf entity configuration and publish these in the statements issued for the leaf under the metadata.$role.jwks claim
    3. the participants that changes theiroidc core jwks have to submit these to the superior’s onboarding system. Every participant can always changes its oidc core jwks with the constraint to submit these in the onboarding procedure to get these updated to its superior.
    4. the Trust Chain publishes the .well-known/openid-federation-jwks to assure to all the participants that even if it changes its federation jwks the historical ones are always available online to the public, within its domain, for historical verification of the trust chains.

    requirements

    1. Trust chain federation historical jwks endpoint
    2. onboarding system with mandatory collection of oidc core jwks
    3. entity statements with metadata.$leaf-role.jwks claim, that attests along the trust chain the oidc core jwks used by a the descendants.

    this represent a way to resolve the problem of the non repudiability of the signature along time that doesn't exclude any other solution to this problem that adopts X.509 PKIs or QTSPs, in other words, it represent an implementation profile that only use oidc federation to resolve this problem.

  39. Log in to comment