w3c / did-core

W3C Decentralized Identifier Specification v1.0
https://www.w3.org/TR/did-core/
Other
405 stars 94 forks source link

Rewrite Authentication section - controller is wrong #2

Closed msporny closed 4 years ago

msporny commented 5 years ago

The following section in the spec is wrong, because it conflates authentication with the ability to update the DID Document:

Authentication is the mechanism by which the controller(s) of a DID can cryptographically prove that they are associated with that DID. See Section § 9.3 Binding of Identity . Note that Authentication is separate from Authorization because the controllers may wish to enable others to update their DID Document (for example, to assist with key recovery as discussed in Section § 9.8 Key Revocation and Recovery ) without enabling them to prove control (and thus be able to impersonate the controllers).

dlongley commented 5 years ago

The rules for how a DID Document can be updated (or how to establish the appropriate authority to do so) are method-specific. The authentication property is a relationship between a subject and a set of verification methods (e.g., public keys). Its meaning is that a subject, identified by the DID, has authorized some set of verification methods (as referenced/specified via the value of the authentication property) for the purpose of authentication.

This is an important statement for "authentication verifiers" whatever they may be. It does not make any statement about what type of verifier is requiring authentication (e.g., it does not talk about a DID ledger using authentication to enable updating a DID document, it does not talk about a website, it does not talk about a point of sale device).

This statement is useful to any "authentication verifier" that needs to check to see if an entity that is attempting to authenticate is, in fact, presenting a valid proof of authentication. If a verifier receives some data (in some protocol-specific format) that contains a proof that was made for the purpose of "authentication" that says that an entity is identified by the DID, then that verifier should check to ensure that the proof can be verified using a verification method (e.g., public key) listed under authentication in the DID Document.

This is how "proof purposes" with DID Documents work; the purpose of a proof must both be stated in a given proof and it must be expressed as a property of the DID Document that establishes a relationship between the entity identified by the DID and its authorized verification methods for that purpose. This enables verifiers, whatever they may be, to verify proofs for specific purposes. It is then up to the software that accepts these proofs to decide what authority they confer.

Now, a particular DID method may use a simple authentication proof to enable a DID Document to be updated. But that is DID method specific. What is done after an authentication check and how sufficient that is to establish some authority is out of scope for this mere authentication relationship. Some DID methods, like Veres One (v1) do not allow updates by merely presenting authenticating proofs (which are, again, verified by using a verification method specified via authentication).

Rather, Veres One requires an Authorization Capability to be presented that carries a proof that was created for the purpose of capabilityInvocation, in order to update a DID Document. A Veres One DID Document may list verification methods under the capabilityInvocation property for keys that may be used to do this. These keys are intentionally different from those keys used to merely authenticate as an entity identified by the DID.

Other proof purposes presently in use include, at least, capabilityDelegation and assertionMethod. The assertionMethod proof purpose is used for Verifiable Credentials. If you want to issue a Verifiable Credential (VC) using a DID and a Linked Data Proof, you attach a proof to the VC that states its purpose as assertionMethod. The public key that can be used to verify that proof then must be referenced using the assertionMethod property in your DID Document so that VC verifiers will be able to verify the proof.

dhh1128 commented 5 years ago

I agree that the spec should be improved, but I would emphasize a different aspect of incorrectness. I think the main gap is that we need to define what we mean by "DID Controller" far more carefully, and what the relationship is between the controller property on a key definition object in the publicKeys or authentication section, and the DID Controller concept defined in the spec. (Right now, my understanding is that the relationship between these two concepts is entirely coincidental; they have nothing to do with each other, so the naming overlap is unfortunate.)

I agree with Dave's perspective on authentication and proof purposes. I would note that the peer DID method enumerates proof purposes in its authorization section; current proof purposes that it recognizes are enumerated in a section of its spec called "Privilege Inventory"; see https://openssi.github.io/peer-did-method-spec/#privilege-inventory.

peacekeeper commented 5 years ago

I think I agree with everything @dlongley says, very helpful explanation as always.

Yes, the rules for how a DID (Document) can be updated/deactivated are method-specific. A method may:

We also discussed the controller property. During the TPAC F2F meeting I thought this was another one of those constructs that some DID methods (v1) use for deciding whether an update/deactivate operation is allowed, and that this has no broader use than that. I agree with @dhh1128 that this needs to be better explained. Perhaps you could also explain your perspective on how controller fits in, @dlongley ?

dlongley commented 5 years ago

@peacekeeper,

I agree with @dhh1128 that this needs to be better explained. Perhaps you could also explain your perspective on how controller fits in, @dlongley ?

The controller property expresses a relationship between a subject and an entity that controls it. In JSON-LD (or in a DID Document), the identifier of the subject, if present, is found in the id property of the object where the controller property is expressed. So, when a controller property is expressed at the top-level of a DID Document, then the subject is identified by the DID. The value of the controller property is some other entity (e.g., identified by another DID) that is understood to have control over the subject.

A subject's controller, by default, is identified by its id. For a DID Document, this is DID. When a controller property appears in a DID Document, its value expresses that, instead, some other entity is the DID's controller. This means that that other entity has the same level of control of that DID that some software would otherwise confer on the default DID controller. Again, what full authority is conferred is up to the software processing some directive related to controlling the subject. This includes software that enforces any DID method rules (such as ledger software). Such software can have rules, for example, that say "An entity that authenticates as the DID controller may do X".

Similarly, when a controller property appears on a verification method, it expresses that some entity is in control of that verification method. For a public key (a type of verification method), this is commonly understood by verification software to mean that that entity is expected to be in control of the associated private key -- and is thus able to create digital signatures, etc. that can be verified using the public key. Furthermore, it is expected that the controller must have authorized the verification method for a particular purpose.

So, when a verification method is expressed in a proof, it may be dereferenced to find its controller value. This value (another identifier, e.g., a DID) may be dereferenced to ensure that the verification method has been authorized to create proofs for the appropriate purpose. Again, this authorization is expressed in the controller's document as in my above comment.

@dhh1128,

I agree that the spec should be improved, but I would emphasize a different aspect of incorrectness. I think the main gap is that we need to define what we mean by "DID Controller" far more carefully, and what the relationship is between the controller property on a key definition object in the publicKeys or authentication section, and the DID Controller concept defined in the spec. (Right now, my understanding is that the relationship between these two concepts is entirely coincidental; they have nothing to do with each other, so the naming overlap is unfortunate.)

I would not say it is coincidental, rather, the controller relationship is defined independently of the particular subject where it appears. It is used to express that one entity controls another either way.

dhh1128 commented 5 years ago

So, when a controller property is expressed at the top-level of a DID Document, then the subject is identified by the DID.

I think this is true whether or not there's a controller property at the top level of a DID Document. Isn't it the case that the subject is ALWAYS identified by the DID?

The value of the controller property is some other entity (e.g., identified by another DID) that is understood to have control over the subject.

Understood. You're talking about what's illustrated in Example 11 of the spec, right?

A subject's controller, by default, is identified by its id

What is the antecedent of "its" in this sentence? Are you saying: A) A subject's controller, by default, is identified by the controller's id; or B) A subject's controller, by default, is identified by the subject's id?

A makes sense to me. B is a head-scratcher. If B, are you saying that the default semantics of a controller are self-control--that is, any identified object is assumed to control itself unless otherwise specified?

When a DID Document doesn't have a top-level controller property, would you say there is any defined controller of the DID other than the DID itself? I'm now imagining that all the other subobjects in the doc, each of which may have a controller property, are not understood to be DID controllers, even if they appear in the authentication seciton. Correct?

dlongley commented 5 years ago

@dhh1128,

I think this is true whether or not there's a controller property at the top level of a DID Document. Isn't it the case that the subject is ALWAYS identified by the DID?

Yes, a subject is always identified by the value of its id property. The main subject of a DID Document is the entity identified by the DID itself, so the id property holds the value of the DID at the top level.

I was speaking about the "subject" in the context of a "triple" -- specifically regarding the "controller" relationship between a subject and an object. I was trying to talk about the meaning of "controller" as a property by referring to a particular "triple" where it would appear. A triple is a combination of a subject, a property, and another object or value, which could be written in a sentence like this:

<subject> <property> <object> .

The property expresses a relationship between the subject and the object. Subjects are expressed in JSON-LD as JSON objects, properties as JSON terms (that map to globally unambiguous URIs), and objects as either other JSON embedded objects that form other subjects, URIs that refer to other subjects, or literal values like strings or numbers. The identifier of any given subject is expressed via a special term id:

{
  "@context": "...",
  // the top-level subject
  "id": "<a URI that is the ID of *this* subject>",
  "someProperty": {
    // some other subject that is related to the top-level one via "someProperty"
    "id": "<a URI that is the ID of *this* other subject>",
    "anotherProperty": "some literal value",
    "aDifferentProperty": {
      // a third subject related to the "other subject"
      "id": "<a URI that is the ID of *this* third subject>",
      "anotherProperty": "some other literal value"
    }
  },
  // a property that references a subject that isn't embedded here
  "yetAnotherProperty": "<some URI that expresses the ID of another subject>"
}

The term controller is a property that expresses that the subject (whatever that may be) is controlled by the object (whatever that may be). This is what I mean by describing "controller" independently of a particular subject or object.

Suppose that we have two DIDs: "did:example:123" and "did:example:456". If you want to express that the entity identified by "did:example:123" is controlled by the entity identified by "did:example:456" you can write this sentence:

<did:example:123> <controller> <did:example:456> .

You can write this using JSON-LD like this:

{
  "@context": "...",
  "id": "did:example:123",
  "controller": "did:example:456"
}

The above would constitute a super minimal DID document. But note that you can also use "controller" on other subjects, as is done with, for example, verification methods (public keys).

The value of the controller property is some other entity (e.g., identified by another DID) that is understood to have control over the subject.

Understood. You're talking about what's illustrated in Example 11 of the spec, right?

Yes.

A subject's controller, by default, is identified by its id

What is the antecedent of "its" in this sentence? Are you saying: A) A subject's controller, by default, is identified by the controller's id; or B) A subject's controller, by default, is identified by the subject's id?

A makes sense to me. B is a head-scratcher. If B, are you saying that the default semantics of a controller are self-control--that is, any identified object is assumed to control itself unless otherwise specified?

I am referring to B and the very semantics you indicate. The default semantics is "self-control"; software should generally assume that any object is in control of itself unless otherwise specified.

When a DID Document doesn't have a top-level controller property, would you say there is any defined controller of the DID other than the DID itself?

No, there is no other controller defined, so the default controller is the DID itself.

I'm now imagining that all the other subobjects in the doc, each of which may have a controller property, are not understood to be DID controllers, even if they appear in the authentication seciton. Correct?

Correct, they are not "DID controllers" but controllers of whichever subject in which they appear. That subject need not be identified by a DID. But, if it is, then it is understood to more specifically refer to a "DID controller".

dhh1128 commented 5 years ago

@dlongley Thank you for the patient and detailed explanation. Clarity is emerging from the mists in my mind as a result; I appreciate it. :-)

I am currently left with only one doubt, which is this: How can a DID have multiple controllers?

The possibility of multiple controllers is implied by the current verbiage in section 5.4: "Authentication is the mechanism by which the controller(s) of a DID...and thus be able to impersonate the controllers..."

I think this means something different from a group functioning as a single, aggregate controller; it seems to suggest that Alice can allow Bob and Carol, individually and not just as a pair, to control her DID. Is that accurate? If so, I can't use the same JSON-LD term (the controller property) at the same scope for both of them. Do I make the <object> part of the sentence an array?

dlongley commented 4 years ago

@dhh1128,

Thank you for the patient and detailed explanation. Clarity is emerging from the mists in my mind as a result; I appreciate it. :-)

Sure!

I am currently left with only one doubt, which is this: How can a DID have multiple controllers? ... I think this means something different from a group functioning as a single, aggregate controller; it seems to suggest that Alice can allow Bob and Carol, individually and not just as a pair, to control her DID. Is that accurate? If so, I can't use the same JSON-LD term (the controller property) at the same scope for both of them. Do I make the <object> part of the sentence an array?

The way you express more than one relationship of the same type is by using two sentences or "triples":

<did:example:alice> <controller> <did:example:bob> .
<did:example:alice> <controller> <did:example:carol> .

The way you express this in JSON-LD is to simply use an array containing both objects for the same property:

{
  "@context": "...",
  "id": "did:example:alice",
  "controller": ["did:example:bob", "did:example:carol"]
}
dlongley commented 4 years ago

I can try to produce a PR to address this. The PR would say something to the effect that it is up to applications (including DID networks, per the associated DID method rules/protocol) to determine what kind of authority is conferred upon authenticated DID subjects. All an "authentication" verification method can do is verify a proof that was created for the purpose of authentication. What is done after that (including how the information on which the proof was attached is processed) is application specific.

@burnburn -- can I have access to create branches in this repo to create PRs? cc: @brentzundel, @msporny

dlongley commented 4 years ago

It's clear that we also need to elaborate on how authorization relations and proof purposes work and that this is highly related to this issue and #22. I'm referencing another discussion on this matter that we can hopefully leverage to create spec text:

https://github.com/digitalbazaar/encrypted-data-vaults/issues/5

OR13 commented 4 years ago

As I mentioned on the issue @dlongley linked, there appears to be a lot of confusion around interoperability, and the top level properties defined in the did document.

I created this gist to track some of the properties that are floating around but not defined in the spec, but sometimes defined in JSON-LD contexts...

https://gist.github.com/OR13/36a68e10f3cd0c537f49f87b1a100950

I'm concerned about the potential lack of interoperability for properties like authorization in did:peer or keyAgreement in did:v1...

Since these properties don't appear in the did-core spec... though keyAgreement is in https://github.com/w3c/did-spec/blob/master/contexts/did-v0.11.jsonld, authorization is not...

If everyone decides to implement their own purpose properties, we will end up with lots of methods implementing similar purposes differently, and things like key agreement and authorization will become borderline impossible to ensure across all DID Methods, or the implementation will contain switch logic for all possible combinations of representations that are compatible... so basically not useful.

This appears to be a nontrivial problem to solve since there is already a lot of implementation concrete poured around choices.

dhh1128 commented 4 years ago

+1 to this being a non-trivial problem.

Historical note: we spent 3 days at RWOT Boston debating authorization and got nowhere. Manu and some others were advocates of OCAPs but could not convince everyone to adopt them as the one true way to authorize. I am also a fan of OCAPs in concept, but I believe the implementations I've seen (ZCAP-LD, etc) are doing them in an unacceptable way, so I'm unwilling to support proposals based on those ideas.

The authorization section used to be in the DID spec, but was taken out after the peer DID spec was written. So although it may look like peer DIDs went a divergent way, the intent was to conform to what the DID spec suggested. We could update peer DIDs to conform to a convention if one existed.

msporny commented 4 years ago

This appears to be a nontrivial problem to solve since there is already a lot of implementation concrete poured around choices.

I'm upbeat about our ability as a community to come together and define a common set, even if some of us don't use all of them. Yes, there are implementations, but part of the standards-setting process is getting them aligned.

Also, keep in mind that because of the base data model (JSON-LD), we can define things in a way that doesn't conflict given that people at least do a strcmp() on items in @context... so, in the worst case, a couple of organizations decide to use authorization in different ways, and that's ok, as long as they signal their different usage via @context.

... but I don't think it'll come to that... I think we'll end up reserving the things people are most concerned about in the core DID spec. We still have time to align and get interop.

OR13 commented 4 years ago

I agree, I think we have more than enough flexibility to accomplish interop, I'm worried that we have too much. I think its helpful to consider the JSON-LD model of extending contexts for method specific purposes, and make the did-core context more of a MUST support and less optional.

Another thing we could consider is some JSON-Schema definition for did-core DID Documents, being able to validate a document against a known type might help reduce some of the complexity.

keyAgreement and authentication seem so fundamental to interoperability I think there should be some serious peer pressure to conform to a very strict definition, which will support easy interoperability.

Sounds like the authentication section should basically state:

This section MUST be used when verifying cryptographic proofs associated with DID authentication. The interpretation of a proof by DID methods or other applications is outside the scope of this spec.

dhh1128 commented 4 years ago

One of the important requirements that I feel needs to be addressed differently is the need for multisig. All of the thinking/examples--in the spec, in public conversations, in design docs I have read in my own community and other communities--are about keys exercised individually: one key gets one or more privileges (authentication, keyAgreement, etc). Unless/until we have a way to specify that a privilege is associated with multiple keys acting together, rather than a key (possibly from a set) acting individually, we will not have a good answer to the question, "How can I prevent my DID from being co-opted when I lose my phone?"

If I understand correctly, using @context to define new sections of a DID Doc doesn't really address this concern, because each new section is just a new way to associate a particular privilege with individual keys. That doesn't mean extension via @context is a bad idea; it just means it's not enough by itself to create new sections that are arrays of keys with privileges.

Peer DIDs address this need not by creating new sections of the DID doc, but by placing any number of flexible rules in a single section, authorization. Rules support boolean AND and OR, which allows very powerful semantics: "This Acme Corp DID may be authenticated by either 2 executive keys from this set: {...}, or by 3 board members from this set {...}." The set members are defined in the publicKey section of the DID doc; the rules just express the intent.

One of the reasons why I like this approach is that the intent in rules is likely to change far less often than the actual set members. Executives at Acme Corp come and go, and their keys can be swapped in an out of the DID doc as needed. But the general rule that it takes 2 of them to authenticate Acme Corp is stable. Recognizing this difference in data turnover allows peer DIDs to make smart choices about CRDT logic for replication, and may also be beneficial for some other DID methods.

Another reason why I like this approach is that the nature of the rules -- the set of privileges they govern -- can change without adding new sections to the DID doc. If we collectively decide that there should be a special privilege associated with sorting out where a DID goes when its underlying ledger forks, we don't need to have a new section of a DID doc; we just need to name a new privilege, and the same old section of the doc, with the same old rules mechanisms, immediately becomes relevant. I think the privilege inventory that peer DIDs suggests and the privilege-oriented sections of a DID doc that DB and others are using are rough semantic equivalents and ought to be reconciled into a common set.

I hope the peer DID choice of flexible rules combined with boolean operators, rather than the more constraining option of enumerating privileges in new sections of DID docs, is chosen as a feature of the standard. But I am not unwilling to go down a different route; what I really care about is:

A) Having expressive power that lets me model M-of-N signature rules and boolean operators as I describe how keys map to privileges.

B) Fixing the muddiness of the authentication section. I believe we are far, far too fuzzy about what we mean by this privilege. I would have taken it out of the peer DID spec entirely except that I felt it would make didauth impossible. But there is a whole section of the peer DID spec that describes why I think that section is fatally flawed.

dlongley commented 4 years ago

If I understand correctly, using @context to define new sections of a DID Doc doesn't really address this concern, because each new section is just a new way to associate a particular privilege with individual keys.

This is incorrect in a way that is vital to your concern about multiparty authorization. Terms like authentication, capabilityInvocation, etc. are authorization relations between the DID subject and verification methods, not "individual keys". One reason for this important abstraction is to allow for things like multisig or capabilities that have caveats that require multiple proofs from different parties. These things constitute other verification methods; an "individual public key" is merely one example of a verification method.

The DID spec, therefore, allows for far more expressiveness than your comment conveys. I think the main trouble here is that we need to elaborate more on this in the spec so that DID method authors/extension authors understand where they can put this information. The reason why we haven't laid out specific rules or examples of verification methods that do support things like multisig (or any arbitrary caveats via capabilities or "zcaps"!) is because we don't have buy in from multiple DID methods on a common set and this was punted. That does not, however, mean we haven't carved out a spot for it in the design; we have.

dhh1128 commented 4 years ago

@dlongley : Thank you for the clarification.

Explaining your design carve-out in greater detail is of utmost importance. I truly did study the spec before I went a different way, and I didn't see any of the possibilities you allude to. For example, what is the exact definition of a "verification method?" The phrase appears 5 times in the current version of the spec, but is never defined, and an individual key is the only example that is given.

ChristopherA commented 4 years ago

On Thu, Oct 24, 2019 at 9:24 AM Daniel Hardman @ddh1128 wrote:

One of the important requirements that I feel needs to be addressed differently is the need for multisig.

+100 — this is EXTREMELY important.

All of the thinking/examples--in the spec, in public conversations, in design docs I have read in my own community and other communities--are about keys exercised individually: one key gets one or more privileges (authentication, keyAgreement, etc). Unless/until we have a way to specify that a privilege is associated with multiple keys acting together, rather than a key (possibly from a set) acting individually, we will not have a good answer to the question, "How can I prevent my DID from being co-opted when I lose my phone?"

Yes, but there are many other use cases for multisig, for instance by entities that are controlled by multiple parties, issuers of various Verifiable Credentials, a variety of recokation scenarios, etc. In particular, anyone who has financial fiduciary responsibility may not be able to do a single key based signature and meet the minimum requirement for "separation of duties" that fiduciary law requires.

Rules support boolean AND and OR, which allows very powerful semantics: "This Acme Corp DID may be authenticated by either 2 executive keys from this set: {...}, or by 3 board members from this set {...}." The set members are defined in the publicKey section of the DID doc; the rules just express the intent.

BEWARE — though the "set list" form of multisign is an acceptable form, it is only one form. We call what you describe above as an "accountable" multisignature, where you know exactly who signed it. However, there are many cases where you'll present a single "non-accountable" multisig (typically a Threshold Schnorr Signature), where you know that among the parties that the threshold has been met, but you don't know precisely who signed.

The non-accountable forms of multisig are very important in two areas: where privacy/anti-correlation of the individual signer is important, or where the power difference between the individual signer and the group is large.

So be careful when you are introducing methods to allow for multisig to support both, or even more forms.

-- Christopher Allen

P.S. for reference I talked about the future of #SmartSignatures at BPASE a few years ago: https://blockstream.com/2018/02/23/en-smart-signatures-bpase/ and have an older blog post about them at http://www.lifewithalacrity.com/2016/10/smarter-signatures-experiments-in-verifications/

dhh1128 commented 4 years ago

@ChristopherA : thanks for the reminder about threshold signatures. I'm aware of the difference but had forgotten to account for it in my thinking, and I agree that it's important to support them.

dhh1128 commented 4 years ago

I'm bubbling this issue back up in the queue because I just read the transcript of the Key Representation ad-hoc meeting. I am concerned that, yet again, we are making the invalid mental simplification that a key = a verification method. Some of @dlongley 's comments preserved the distinction, but I still have never seen a definition of a verification method (including in the DID spec, which uses the term 5 times without definition), and the entire tenor of the meeting presupposes that these two concepts are equivalent. How do we propose, for example, to describe a multisig verification method that requires 3 different keys using 3 different types of crypto?

The peer DID method solves this in a generic way, but I have not seen any meaningful alternatives documented anywhere. I don't want to have its solution invalidated by evolutions of the DID spec, so if we're going to do something important to fix this, let's do it now, while the peer DID method is still fluid.

@kdenhartog @OR13 @msporny @peacekeeper @talltree @brentzundel

OR13 commented 4 years ago

I agree, but multisig needs to be formalized by people who use it. IMO, a JSON-LD Signature Suite / Context would help a lot with this. If there is no intention to use multisig with JSON-LD, then there needs to be some better examples of keys / signature suites that don't use JSON-LD, but that do use DID Documents, and ideally, this should not look like a JSON-LD signature suite...

Regarding authorization in did:peer it looks like its aggregating concepts that are otherwise split up... which I like, but which seems a bit different from the approach veres one is taking.

Here is a spanning example of some of the concepts that are floating around (I linked it above):

{
  "@context": "...",
  "id": "did:example:alice",
  "controller": ["did:example:bob", "did:example:carol"],
  "publicKey": [
    {
      "id": "did:example:alice#keys-1",
      "type": "RsaVerificationKey2018",
      "controller": "did:example:alice",
      "publicKeyPem": "..."
    },
    {
      "id": "did:example:alice#keys-2",
      "type": "RsaVerificationKey2018",
      "controller": "did:example:bob",
      "publicKeyPem": "..."
    }
  ],
  "authentication": [
    "did:example:alice#keys-1",
    {
      "id": "did:example:alice#keys-0",
      "type": "Secp256k1EthereumAddressVerificationKey2018",
      "controller": "did:example:alice",
      "ethereumAddress": "..."
    },
    {
      "id": "did:example:alice#keys-3",
      "type": "Ed25519VerificationKey2018",
      "controller": "did:example:alice",
      "publicKeyBase58": "..."
    },
    {
      "id": "did:example:alice#keys-4",
      "type": "Ed25519VerificationKey2018",
      "controller": "did:example:bob",
      "publicKeyBase58": "..."
    }
  ],
  "capabilityInvocation": ["did:example:alice#keys-1"],
  "capabilityDelegation": ["did:example:alice#keys-2"],
  "keyAgreement": [
    {
      "id": "did:example:alice#kid",
      "type": "X25519KeyAgreementKey2019",
      "publicKeyBase58": "ztQ2JQy17Ue7bMGd2qYYbt1XX5awB7obHYyZgZmGieW"
    }
  ],
  "assertionMethod": [
    "did:example:alice#keys-1",
    "did:example:alice#keys-2",
    {
      "id": "did:example:alice#5",
      "type": "Ed25519VerificationKey2018",
      "publicKeyBase58": "..."
    }
  ],
  "authorization": {
    "profiles": [
      { "key": "#Mv6gmMNa", "roles": ["edge"] },
      { "key": "#izfrNTmQ", "roles": ["edge", "biometric"] },
      { "key": "#02b97c30", "roles": ["cloud"] },
      { "key": "#H3C2AVvL", "roles": ["offline"] }
    ],
    "rules": [
      {
        "grant": ["register"],
        "when": { "id": "#Mv6gmMNa" },
        "id": "7ac4c6be"
      },
      {
        "grant": ["route", "authcrypt"],
        "when": { "roles": "cloud" },
        "id": "98c2c9cc"
      },
      {
        "grant": ["authcrypt", "plaintext", "sign"],
        "when": { "roles": "edge" },
        "id": "e1e7d7bc"
      },
      {
        "grant": ["key_admin", "se_admin", "rule_admin"],
        "when": {
          "any": [{ "roles": "offline" }, { "roles": "biometric" }],
          "n": 2
        },
        "id": "8586d26c"
      }
    ]
  }
}

One issue we seem to be facing is that when answering the question of "where do I look for the authentication key or credential issuance key", we have 2 approaches:

  1. Look in authentication / assertionMethod, then look in publicKeys if you find a reference.
  2. Look in authorization then look in publicKeys.

I'm personally not a fan of having capabilityInvocation, capabilityDelegation, authentication, authorization, assertionMethod, keyAgreement all top level collections to check, before looking in publicKeys.... These are all essentially capabilityMappings... I'd prefer they all be rooted under something like that... However that ship has pretty much left already.

Seems like we could do a couple things.

A. We could rewrite authentication section, provider better clarity around when / if it MUST be used.

B. We could replace it with authorization / capabilityMappings style property, and define a set of rules for authentication, with an extensibility model for adding other mappings under that root property...

B seems like big deviation from what we have been doing so far.

What I really want to avoid is a bunch of different ways of handling the concept of authentication, and authorization... or to have these concepts only be meaningful within a DID Method, where we end up with no cross DID Method AuthN / AuthZ interop....