decentralized-identity / keri

Key Event Receipt Infrastructure - the spec and implementation of the KERI protocol
Apache License 2.0
74 stars 21 forks source link

Key rotation rules #52

Closed SmithSamuelM closed 3 years ago

SmithSamuelM commented 4 years ago

This is based on the W3C DID issue here: https://github.com/w3c/did-core/issues/386 The test is reproduced here because it references KERI and is relevant to basic use cases of KERI.

Revocation vs Rotation

The whole point of digital signatures is that they are non-repudiable; they commit the signer to a historical action in a way that they can't deny. This is the basis for holding a party accountable. It's the non-repudiation that makes them useful.

If I use the DID Doc assertionMethod to sign a mortgage, I cannot say that when I rotate my key, it invalidates my commitment to pay the mortgage. The bank gave me money, and I incurred a debt. I can certainly sign a mortgage and then rotate my key; this prevents my old key from being used to incur new debts, but it doesn't cancel my old one. Rotation cannot be retroactive, because it would give the signer unilateral power to reinterpret history.

Revocation is different. It presupposes a shared understanding between multiple parties that unambiguous history needs to be given new semantics based on future developments. With that understanding in place, it's possible to construct mechanisms that allow either party on their own, both parties together, or even third parties to apply new semantics to a historical event, no matter how strongly attested. "Yes, Fred really did sign this mortgage. No question about it. But Fred wasn't legally competent when he did so. Therefore the mortgage is invalid -- not because we deny existence of the signature, but because we are viewing the event with different semantics."

We have to be able to tell the difference between rotation (unilaterally change rules for the future) and revocation (joint agreement about how/when to change semantics we apply to the past).

If an issuer uses assertionMethod to sign a VC, the issuer cannot say that when they rotate the key, it cancels their commitment to the assertions they once stood behind. That's because an unknown number of verifiers have already made decisions based on the reputational capital the issuer staked against their assertions; allowing the issuer to back out is like letting a lender off the hook for a mortgage without any loan repayment. There exists no shared understanding that the issuer has this unilateral ability to escape accountability and reputational consequences for their actions.

Besides, if rotating a key cancelled all previous assertions, how would we do the other operation (the one that merely changes future possibilities, without attempting to apply a new lens to the past)?

I don't know what language in the spec, if any, we might want to revise to clarify this point, but I think there's no question this must be the understanding we impart.

Revocation

Yes the term revocation is used in two completely different ways in the identity space. In the key management world one may speak of revoking keys. In the statement issuance, authorization issuance, or credential issuance space one may speak of revoking an authorization or a credential or a token.

This becomes confusing when revoking keys also implicitly revokes authorizations signed with those keys.

KERI terminology usually avoids that confusion because a key rotation operation is the equivalent of a key revocation operation followed by a key replacement operation. So one operation, rotate, is implemented instead of two operations (revoke and replace). A bare revocation is indicated by replacement with a null key. So only one operation is needed, that is, rotate where a special case of rotation is to rotate to a null key.

Given the KERI definition of rotate as applied to keys, within KERI, revocation is usually unambiguous applied to mean revocation of authorization statements. When in doubt just use the modifier key revocation vs statement revocation.

I hope that clarifies my terminology better.

Key Revocation vs. Signed Statement Revocation

Key rotation versus signed statement revocation. The authority of a signed statement is imbued to it by its signature and the keys used to create the signature. Is a signed statement authoritative/authorized after the keys used to sign it have been rotated? If not then the statement is effectively revoked as not longer being an authoritative/authorized statement. If the statement is still authoritative/authorized after the keys used to sign it have been rotated then is it not effectively revoked by the rotation itself but requires a separate signed revocation statement the rescinds/revokes its authoritative/authorized status. This revocation statement is signed by the current set of authoritative keys that may be different from the keys used to sign the statement being revoked.

Authorization tokens which are a form of signed statement often employ the rule 2) that when the keys used to sign the token have been rotated that this implies that the token’s authorization is revoked. Effectively the token is always verified by the current set of signing keys so it will fail verification after rotation. Whereas in Rule 1) the verification is w.r.t the set of signing keys used to create the signature at the time the statement was issued and signed. This means the verifier has to have a way if determining what the history or lineage of control authority was via a log or ledger to know that a statement was signed with the authoritative set of keys at the time. This means that the log or ledger must not only log the lineage of keys (key rotation history) but the statements signed by those keys (a digest of statement is sufficient). Otherwise a compromise of the current signing keys (which rotation protects from) would allow an exploit to create verifiable supposedly authorized statements after the keys have been rotated. So it either must be rule 1 or 2 or 3. And non-automatic revocation of signed statements requires a log of both the key rotation history and signed statement history.

Obviously if keys are not rotatable, then any signed statement may not be revoked by merely rotating keys but instead a revocation registry may be used to determine if a signed statement has been revoked by explicitly using a revocation statement. So non-rotatable keys may use a modified rule 4) where there is no key rotation history log or signed statement log but merely a revoked statement log. Although typically non-rotatable keys are used for ephemeral identifiers, in which case, revocation log is not used. Instead of rotating keys for ephemeral identifiers you just rotate the identifier (make a new one with a new set of keys) and abandon the old identifier and all its signed statements.

This makes sense to me. I always try to map these discussions into the healthcare use case where the physician is licensed by the DEA IFF they can be held accountable for signing a (controlled substance) prescription in a non-repudiable manner and also the prescription can be revoked when dispensed or "lost".

Under the DEA rules, the physician's authority to sign that prescription, can flow one of two ways. Either the process and tech itself is certified and audited, or another DEA credentialed person (maybe another physician or notary) is held accountable for issuing the credential of the prescriber. The issuer physician as effectively a notary. They are examining the process and other claims of the would-be prescriber, signing using their non-repudiable signature AND, importantly, making a log entry that they, as the notary, will keep of this transaction. The notary binds the issuing process (typically represented by a document such as a loan) to a non-repudiable signature of the prescriber (because the prescriber shows the notary a deduplicated, legally binding credential like a drivers license.)

This use-case is relevant because it is decentralized. The self-sovereign prescriber chooses the notary. The notary's logs are not public or aggregated but they are secure and auditable. The notary's logs have a reference to the document (the digest @SmithSamuelM mentions). For some related detail, here's a link to the recent HIE of One DHS SVIP (rejected) proposal for Trustee(R) Notary which I truly hope some in our community help us with.

It's turtles all the way down in the sense that the self-sovereign prescriber then takes on the role of issuer when Alice wants her Adderall. The prescriber signs her prescription, coded as a verifiable credential, and keeps the log with the digest of the prescription in case of audit. Revocation, of this VC remains an unsolved problem and this is where the DID aspect of SSI decentralization threatens to break down because the revocation mechanism has to be centralized and incredibly privacy-invasive for Alice. It's called a prescription drug monitoring program (PDMP) and the privacy issues they raise would fill a book.

Since this issue is about revocation of a VC, I would suggest that we need to give data holders the option to avoid the centralized revocation privacy problem by letting them authorize the verifier to get the VC directly from the issuer instead of passing the VC through an intermediate store. This is a privacy compromise because it leaks information to the issuer but it avoids the rotation problem because the VC can be ephemeral. Our SSI designs #382 must not take this option away from Alice. The logic is described in #370 (comment)

SmithSamuelM commented 4 years ago

Consider that id_token signing keys are rotated regularly by OIDC providers.

https://developer.okta.com/docs/concepts/key-rotation/

^ the did document use case is identical, it just does not require HTTP or JWK/JWKs.

absence of a singing key in the expected location, implies revocation of all signatures.... you can see why caching can cause security issues.

Caution: Keys used to sign tokens automatically rotate and should always be resolved dynamically against the published JWKS. Your app might fail if you hardcode public keys in your applications. Be sure to include key rollover in your implementation. ^ this statements applies just as much to VCs as it does to id_tokens.

@or13 You are confirming that in token based security systems verification of a token is against the current set of signing keys not the keys that were authoritative when the token was issued. That is they use Rule 2). This is in direct opposition to what the normal use case for VCs which is verification is against the keys used to issue the VC not the current set of keys. That is rule 1). Hence the confusion.

OR13 commented 4 years ago

@SmithSamuelM maybe I misread your comment on https://github.com/w3c/did-core/issues/386#issuecomment-691238656

In my mind in the context of credentials / tokens, key rotation ~= key revocation, the difference is that a "revoked" key won't ever be used again by an honest issuer, but a "rotated" key, will be used to reissue id_token / vcs.... in both cases, old tokens / vcs will not verify when the key is rotated / revoked.... if the verifier chooses to ignore this, like I do when my SSL cert has not propagated yet, is a separate issue.

Not sure what part of this applies to KERI specifically.

I see KERI has defining a structure for events that support rotation and revocation....

A feature KERI may have that did documents do not require, is that it might not be possible to rotate a key, and have the identifier be stable.... for example:

did:example:123#public-key-fingerprint.... depending on the did method public-key-fingerprint ....

image

Secure did methods would not even let did controller pick ids.... because there is no point to them ever being anything but a hash of public key bytes....

SmithSamuelM commented 4 years ago

@OR13 Not sure if I understand your point exactly. But in KERI a SCID (self certifying identifier) prefixe may be declared as non-transferable at inception (means may not rotate keys) which means no key event log is needed. Or an identifier that is declared as transferable at inception (ie supports key rotation) may later be retired by rotating to a null key. After which no further events are accepted into the log. The log itself allows the controller to anchor crypto hashes of any other data to the log at a specific place in the log. Think of the log as a hash chain clock. Where in the log provides a point in hash chain time for a data item. That anchor is crypto commitment to that data. If that data is an authorization such as a VC. then the hash chain time of the VC issuance if verifiable via the log. These means that now we have a clock for determining revocation time etc for any later anchored statements that are associated with the earlier anchor. The ordering of all anchored statement may then be verifiable in order just like a ledger but without needed a ledger as the KERI log is the "micro ledger". So successive versions of a DID:Doc could be anchored so that any signatures of those did:docs can be established as authoritative wrt to the hash chain time of the anchor in the KERI log. So we can prove and verify it with any consistent copy of the log. These means that a DID:Doc could for all intents and purposes just be a verifiable credential. It doesn't need to be anything special. The DID standard then reduces to simply a protocol (KeRi like) for establishing control with a hash chain clock. Once that control authority is established then anything else anyone ever needs to authorize can be authorized in perfectly extensible fully semantically extensible form using the existing W3C VC standard. And all the registry etc all goes away. We have a handful of DID methods. Those that use ledgers as their primary root of trust and those that use SCIDs as their primary root of trust with micro ledgers as their secondary root for key rotation and anchoring. I know this is a radical suggestion and I don't expect that the community will adopt it. But just saying ....

SmithSamuelM commented 4 years ago

@OR13 The self-addressing self-certifying variant of KERI identifier prefixes is essentially locking down the identifier to the inception event. Change anything in the inception event and the identifier changes. So the identifier is not merely locked to the public key (which is the basic form of a SCID) but its locked to everything committed too in the inception event. This includes the pre-rotated key comittment, multi-sig signing threshold, all the public keys both current and pre-rotated. the witness set and threshold and any configuration traits and any other data one wants to commit to. This locks the identifier to the commitments in the inception event and only a compromise of the keys can attack it. And even then the controller may recover via a rotation unless the attacker not just compromises the authoritative set of keys but the unexposed pre-rotated set of keys as well. It's as locked down as is practically implementable.

SmithSamuelM commented 4 years ago

Because the anchors (seals in KERI terminology) are included in the event payload, when signed the controller makes a non-repudiable commitment. The next event include the hash of the prior event which means the following event also makes a non-repudiable commitment to the seal. This means that for any sealed data (anchored) the Key Event Log can answer the question. What was the authoritative set of keys for that identifier at the "time" (location) the seal (anchor) appeared in the log. This gives us linear state machine replication via anchored "operations" in the KEL. Give me a copy of a KEL and I can replicate any state machine whose operations are ordered by that KEL.

SmithSamuelM commented 4 years ago

What makes KERI Byzantine Fault Tolerant is a combination of two networks. A witness network and a watcher network. These each provides one of the the two phases of a three phase commit. We only need two phases because only the controller may create events so we don't need to provide liveness to multiple clients. There may only be one client and the client is the leader.. This simplified formulation provide similar BFT guarantees. This is the KAACE algorithm outlined in the KERI WP.

SmithSamuelM commented 4 years ago

In essence each identifier gets its own "micro ledger" called a KEL (key event log) or KERL (Key event receipt log) when using witnesses.

SmithSamuelM commented 4 years ago

Just so someone can better understand I am copying the rules here as they are originally way up in another thread.

Authorization Rules/ Models

Rule 1) Persistent Authorization Model

A signed statement using the current authoritative set of keys at the time of the signature, is valid until revoked or rescinded with another signed statement. This means that merely rotating keys does not revoke or rescind the validity of prior signed statements. Otherwise every time you rotate keys your would have to reaffirm (reissue) every prior statement signed with the now absolute keys.

Rule 2) Ephemeral Authorization Model

All statements issued/signed with a given set of keys are automatically revoked when the authoritative keys are rotated. This view (rule 2) of mandatory revocation (reissuance) is a common rule in token based security approaches where all tokens issued under a given set of keys are automatically revoked when you rotate keys.

In order for Rule 1) to be practical one needs to maintain a ledger or log of statements signed with a given set of keys or at least a cryptographic commitment to the hashes of the log of statements (merkle tree or hash chained data structure) so that one can verify that a statement was signed with the then authoritative set of keys.

So if one is not using a log (ledger, etc) of signed statements then Rule 1) is unworkable and Rule 2) is the reasonable one.

A hybrid would be:

Rule 3) Some Authorizations are Persistent and Some are Ephemeral Model.

In this model, only logged signed statements use rule 1) and all other signed statements use rule 2). Any presentation of a signed statement must include a reference to its location in the log to determine the authoritative keys at the time (location) in the log. If the log reference is absent then one checks the current authoritative keys and if they differ then the signed statement is stale (invalid).

Clearly the issuer-holder-verifier model of VCs is problematic with respect to rule 2) especially at scale because your have coupled your key management (rotation recovery) to the expiration rules for your VCs.. The issuance of large numbers of credentials especially credentials that are time expiring becomes unwieldy.

A DID method should specific which rule 1) 2) or 3) is to be used to verify signed statements associated with the keys for that DID.

The DID:Doc is one of the types of signed statements not simply VCs.

But in order to support 2) or 3) a verifiable log is required.

Each DID method should explicitly define which rule 1) 2) or 3) is to be used when verifying signed statements. As far as I know no DID method explicitly does this. Its implied.

SmithSamuelM commented 3 years ago

This discussion is captured in more detail in the following white paper:
https://github.com/SmithSamuelM/Papers/blob/master/whitepapers/IdentifierTheory_web.pdf