# DID Authn
## Motivation
Allow seamless registration and login using DIDs.
There are 2 different proposals in this document:
1. "Vanilla" DIDAuthn. Incompatible with Webauthn
2. DID WebAuthn
## Vanilla DIDAuthn
### Authn Flow
```mermaid
sequenceDiagram
autonumber
participant W as Wallet
participant C as Client
participant R as Relying Party
C->>R: I want to authenticate
R->>R: construct DIDAuthnChallenge
R->>C: DIDAuthnChallenge
C->>W: DIDAuthnChallenge
W->>W: validate / verify challenge
W->>W: request user consent
W->>W: construct DIDAuthnProof
W->>C: DIDAuthnProof
C->>R: DIDAuthnProof
R->>R: validate / verify proof
R->>C: Post Auth Success Flow
```
### `DIDAuthnChallenge` Construction
```typescript=
type DIDAuthnChallenge = {
challenge: String;
intent: String;
origin: {
did: String;
id: String;
name: String;
};
// list of DID methods supported by relying party
supportedDIDMethods: String[];
};
```
* create an empty structure, `didAuthnChallengePayload`, that includes the following properties:
* `challenge` - a cryptographic challenge that will be signed by the client and returned. `challenge` also acts as the nonce for this authn ceremony
* **TODO**: describe challenge creation algorithm if we need to be specific about it
* `intent` - the reason behind this authentication request. e.g. `authn`
* **TODO**: cement all possible values for `intent`
* `origin` - details about the request originator
* `did` - the DID of the originating party
* `id` - the fully qualified URL of the originating party.
* `name` - the name of the originating party
* `signature` - a cryptographically verifiable signature over the above properties
* **TODO**: describe signature formulation algorithm
* `suportedDIDMethods` - DID methods supported by the relying party
### `DIDAuthnChallenge` Validation and Verification
Execute the following algorithm to verify a `DIDAuthnChallenge`:
* **TODO**: Fill out use of DID Configuration
### `DIDAuthnProof` Construction
**TODO**: Fill out
### `DIDAuthnProof` Validation and Verification
**TODO**: Fill out
## DID WebAuthn
### `DIDRegistrationOptions`
```javascript=
const DIDRegistrationOptions = {
supportedMethods: ["method1", "method2"],
challenge: "...",
rp: {
name: "Twitter inc.",
id: "twitter.com",
did: "did:ex:twitter",
signature: COMPACT_JWS // PHASE 2
},
user: {
id: "did:ex:alice",
name: "did:ex:alice",
displayName: "Persona Name",
},
pubKeyCredParams: [{alg: -7, type: "public-key"}]
};
```
### `DIDRegistrationRequest`
```javascript=
{
id: BASE64_OF_DID_RELATIVE_KEY_ID,
type: "did",
response: { // JWS
protected: {
kid: DID_RELATIVE_KEY_ID
},
signature: BASE64_SIG_STRING,
payload: CollectedClientData { // BASE64'd
required DOMString type = "webauthn.create"
required DOMString challenge
required DOMString origin
}
}
}
```
### `DIDAssertionOptions`
```javascript=
{
challenge: "..."
}
```
### `DIDAssertionRequest`
```javascript=
{
id: BASE64_OF_DID_RELATIVE_KEY_ID,
response: { // JWS
protected: { // BASE64'd
kid: DID_RELATIVE_KEY_ID
},
signature: BASE64_SIG_STRING,
payload: CollectedClientData { // BASE64'd
required DOMString type = "webauthn.get"
required DOMString challenge // Different per invocation
required DOMString origin
}
}
}
```
### Authentication Flow
## Notable Differences between DIDAuthn and WebAuthn
* WebAuthn requires that a different public key is used for each RP whereas DIDAuthn would allow the same DID to be used across many RPs
* WebAuthn is split into two steps - **Registration** and **Assertion**. Registration is used to "Register" a `PublicKeyCredential` with a RP where the RP stores the credential ID and public key for assertion checks. DIDAuthn could theoretically use the DID for both the credential ID and the public key which effectively negates the need for registering any credential at all
*
## 09-09-2022 Meeting Notes
```mermaid
sequenceDiagram
participant S as Application Server
participant P as Web App
participant W as Wallet
S->>P: 1. Serve Web Page
P->>P: 2. Render Login Button
P->>W: 3. Invoke web5.authn method w/ nonce and supported DID methods
W->>W: 4. Raise popup for user consent
note right of W: display trust marks based on greenlist / creds etc.
W->>W: 5. sign nonce as a compact JWS. kid is DID URL to key
W->>P: 6. Compact JWS
P->>S: 7. Compact JWS
S->>S: 8. Verify JWS
S->>S: 9. Post auth flow (e.g. JWT, Session etc.)
S->>P: 10. Profit
```
- **TODO**: Figure out how supported DID methods are surfaced
- **TODO**: in design doc
- Signature payload should be hash of:
- application nonce
- wallet generated nonce
- intent: authn
```javascript=
// order implies priority
web5.authn(nonce, ['ion', 'key', 'peer', 'pkh'])
```