Historical Keys should show validaty status
Keys might have been rotated because the private key has leaked. That makes anything signed with that key untrustworthy. Hence I think it is probably good to distinguish between normal expiry and revocation and for the latter include the time of revocation.
In principle this could be done using expiry and the `exp` claim, but revoked keys can no longer reliably be used for anything unlike normally rotated and expired keys. The latter can in principle be used to confirm that a chain was valid before it’s expiry date.
See also e.g. https://pki-tutorial.readthedocs.io/en/latest/cadb.html for OpenSSL’s index.txt format, which has a flag for valid, revoked and expired and a timestamp for revocation or expiration.
Comments (20)
-
-
reporter That sounds reasonable.
Also, thinking again, I’d say we should have a separate claim for the revocation time and not re-use theexp
claim for that. That claim would of course only make sense when the status is revoked, so perhaps they should be bundled into an array?And should we include the reason? That could be sensitive information, so perhaps we don’t want to expose that?
-
Your reasoning makes sense.
We can create a new claim attesting, in an array, the properties of the revocation, such the revocation time.
or, differently, we can define the revocation time claim independently of the revocation json object, if adopted.
Do you have a proposal for this brand new claim name?
I'll reach out the other authors of the specs to work on this, meanwhile if you can do a proposal for the claim name, or for the schema of the revocation object, it would be great
-
reporter I think the easiest is to just add a single revocation time claim. For example
rat
orrevoked_at
?Not sure actually we need the status claim. Other than for the revoked, the status follows (currently) from the
iat
,exp
andnbf
claims. And the revoked status would follow from the presence of the revocation time claim.If we also need the reason, we could then bundle them in something like
"revoked": { "revoked_at": 1672392712, "reason": "keyCompromise", }
or we could make also that into a separate claim, something like
revocation_reason
. That is probably easier, in case we don’t always want to add a reason. So personally I think 1 or two extra simple claims is probably the easiest. -
I personally think that your proposal definitively wins.
I'm for revoked_at with the json object
We should define the set of values for the claim “reason”
-
reporter For CRLs in PKIX the list is defined in rfc5280 section-5.3.1 but most of those don’t make much sense for us probably. See also https://wiki.mozilla.org/CA/Revocation_Reasons
Unless we also (in future?) use the revocation for the entity statements (which already are quite similar to certificates) not just for the keys?
-
Hi Misha,
I agree for the adoption of the same values we have in rfc5280 (even if not snake cased, it’s not relevant)
To date I have not matured any interest in an entity statement revocation mechanism because with a request to the fetch endpoint we can get the status of a descendant in realtime (or even a 404, which indicates exclusion). We could rather enable the historical register of the jwks also for the intermediaries, to manage historical episodes which concern the compromise of a key used to sign an entity statement.
please feel free to put your notes here, I’ll discuss these with the other authors, and thank you for this precious issue!
-
- changed status to open
-
Some relevant discussion may be found here as well re: credential issuance → https://github.com/oauth-wg/oauth-selective-disclosure-jwt/pull/195
-
What are your thoughts on publishing the revoked keys at a new, separate endpoint?
Open Banking UK has taken this approach for the members of its “federation”. There is an
org_jwks_endpoint
where the good keys are published. And then, there is anorg_jwks_revoked_endpoint
where revoked keys are placed (but there is no reason metadata).The main argument for having a separate endpoint is that client code that uses the
org_jwks_endpoint
cannot accidentally pull in revoked keys and somehow end up using them to verify a signature. The JWK RFC also says this about JWK params:https://www.rfc-editor.org/rfc/rfc7517#section-4
Additional members can be present in the JWK; if not understood by
implementations encountering them, they MUST be ignored.The JWK spec defines no
crit
parameter (like the JWS spec does to designate “MUST understand” headers), meaning that all currently available JWT libs will simply ignore arevoked
JWK parameter. Updating all those libs to support the newrevoked
parameter could take a long time, which means that some OIDC Federation developers may simply end up using JWT libs with their default settings. A separate JWKs endpoint seems the safer choice for me.
-
PS following a chat with Giuseppe:
I wasn't aware this was intended for the historical JWKs endpoint. I thought it was meant for the entity statements in general :)
-
reporter considering this is primarily about the
jwks
claim in the well known endpointopenid-federation-historical-jwks
response, perhaps it would then be better to make it two claimsjwks
andjwks_revoked
?I do agree with your reasoning that we need to ensure that clients don’t accidentally use them. In principle the same is true for expired keys: people will not usually revoke an expired key in case of leaks. So you cannot trust expired keys either.
Also, I think it would be good to use the same setup as others, but I’m not sure that works here, the Open Banking spec has current and revoked keys, not past (rolled-over or expired but not necessarily revoked), while fed now has current and historic.
-
With the clarification that the revoked keys will only appear in the response from the historical JWKs endpoint - placing them together with the expired keys seems okay to me, because as you say, they are all keys that should be no longer in use (whatever the reason).
How is the endpoint going to find out or become updated that a key is revoked?
For the
iat
andexp
there is a method - whenever an subordinate entity enrols a new JWK set it can be diffed against the previous version. But how can this work with a revoked key?
-
I’m wondering if there may be some cases where an already expired key is found as leaked in the past, so it should be revoked in the present even if it is expired.
In this case an expired key should be also revoked to tell to all the participants in the federation that the historical trust chains, validated with that key, may be unsafe.I would not create a separate schema or top-claim for the revoked keys but just the json object carrying the revocation properties (revocation reason, date of revocation)
How is the endpoint going to find out or become updated that a key is revoked?
Administrative process, federation operators that handles the responsible disclosure of the leakages will remove the leaked jwks fron the TA’s entity configuration and move these in the historical endpoint, with the reason of the revocation.
a TA only publish in its EC the jwks intended for the validation of the signatures issued by it.
All the expired and revoked jwks should be published in the historical jwks registry.considering that historical has a meaning more closer to “expired” I’m wondering if, considering how we increase the awareness on the revocation ops and the scope of this endpoint, we should rename this endpoint.
the discussion is open and I hope to resolve this feature in the current draft if the authors agree.
-
I’d proceed with a PR with the solution below:
"revoked": { "revoked_at": 1672392712, "reason": "keyCompromise", "reason_code": 1 }
-
-
assigned issue to
-
assigned issue to
-
I’m wondering if there may be some cases where an already expired key is found as leaked in the past, so it should be revoked in the present even if it is expired.
In this case an expired key should be also revoked to tell to all the participants in the federation that the historical trust chains, validated with that key, may be unsafe.This is an entirely plausible scenario. Very often incidents are discovered after the fact.
How is the endpoint going to find out or become updated that a key is revoked?
Administrative process, federation operators that handles the responsible disclosure of the leakages will remove the leaked jwks fron the TA’s entity configuration and move these in the historical endpoint, with the reason of the revocation.
My concern was chiefly about incidents at entities below the TA. Whether this can be automated, to a good effect. Because with X.509 certs, revocation, as a whole, seldom works well in practice.
I’d proceed with a PR with the solution below:
Looking forward to it!
-
My concern was chiefly about incidents at entities below the TA. Whether this can be automated, to a good effect. Because with X.509 certs, revocation, as a whole, seldom works well in practice.
@Vladimir Dzhuvinov that’s why I would like to purpose in the PR, if you agree, to enable this endpoint for all the federation_entity (TA and intermediaries)
-
The PR below resolves this issue
https://bitbucket.org/openid/connect/pull-requests/421@Misha please feel free to put your kindly revision
-
- changed status to resolved
- Log in to comment
Thanks, useful tip. We should start with a proposal to discuss
A solution could be to introduce the claim
status
with a set("v", "r", "e")where (v=valid, r=revoked, e=expired)