Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NUT-XX: Authentication #106

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions 16.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
## NUT-16: Authentication
==========================

`optional`

In this document, we describe a mechanism for obtaining time-bounded bearer tokens using user derived public/private keys for accessing protected endpoints for a mint. The registration process for authorizing public keys is outside the scope of this NUT and should be implemented separately by the mint. We derive a unique public/private key pair unique to each mint by hashing the mint URL. This provides additional privacy, as the user's public key cannot be linked across mints.

NOTE: The authentication of a user through the utilization of a public key adopts an accounting model that may compromise privacy.

# Authentication Flow

**1. Client initiates authentication:** The client application initiates the authentication process by redirecting the user to the designated authorization endpoint. This endpoint is provided by the mint.

Alice wants to access a protected resource on Bob's mint. Her client application initiates the authentication process by redirecting her to Bob's mint authorization endpoint with the required action as `tag` :

```http
GET https://bob.com/v1/auth/challenge?&tag=<(action enums)>
```
Bob's mint generates a challenge `k1` consisting of randomly generated 32 bytes, for example:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Bob's mint generates a challenge `k1` consisting of randomly generated 32 bytes, for example:
Bob's mint generates a challenge `k1` consisting of a 64 character hex string generated from 32 random bytes, for example:


``` json
{
"tag": "mint",
"k1": "8278e1a48e61c261916791dabb6af760488e4f01932e11fe7054f59754e3de6e"
}
```


`tag` enums meaning:
- `register`: service is requesting to register a user's `linkingKey`.
- `mint` user is authed to mint tokens.
- `melt` user is authed to melt tokens.
- `...`


This k1 is displayed to Alice. Alice's client application then uses her `linkingPrivKey` private key to sign the challenge over the secp256k1 curve using the `linkingPrivKey` private key

## `linkingKey` derivation

- `linkingKey` This is a public key derived from `linkingPrivKey`
- `linkingPrivKey` To keep the derived public key unique to each mint, the `linkingPrivKey` should be derived as follows
- Use the derivation path m/138'/0 from the master key to get `hashingkey`

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it necessary to specify the exact derivation path used by the client?

- `linkingPrivKey = PrivateKey(hmacSha256(hashingKey, mint domain name e.g. https://bob.com))`
- `linkingKey = PublicKey(linkingPrivKey)`


**2. Signature verification and bearer token issuance:** Bob's mint verifies the validity of the signature using alice's linking key. If the signature is valid, Bob's mint issues a time-bounded bearer token to the client application. This token represents the user's access to specific resources based on the action requested by the client.

Alice's client application submits the signature and public key to Bob's mint:

```http
POST https://bob.com/v1/auth
```
``` json

Post Data:
{
action:"mint",
k1:"8278e1a48e61c261916791dabb6af760488e4f01932e11fe7054f59754e3de6e"
signature:c568f78e4b234a5f7d8c3b2a679e48d1234567890abcdef
linkingKey:7345786068584cd33000582ba87a9ddf77db5377c67910ab59d7e9a5f44
Comment on lines +58 to +61
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
action:"mint",
k1:"8278e1a48e61c261916791dabb6af760488e4f01932e11fe7054f59754e3de6e"
signature:c568f78e4b234a5f7d8c3b2a679e48d1234567890abcdef
linkingKey:7345786068584cd33000582ba87a9ddf77db5377c67910ab59d7e9a5f44
"action":"mint",
"k1":"8278e1a48e61c261916791dabb6af760488e4f01932e11fe7054f59754e3de6e"
"signature": "c568f78e4b234a5f7d8c3b2a679e48d1234567890abcdef"
"linking_key": "7345786068584cd33000582ba87a9ddf77db5377c67910ab59d7e9a5f44"

}

Copy link
Collaborator

@thesimplekid thesimplekid Mar 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing a ``` here to end the code block

Response:

```json
HTTP/1.1 200 OK

{
"access_token": "9876543210fedcba",
"token_type": "Bearer",
"expires_in": 3600
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"expires_in": 3600
"expiry": 1711917473

I think this should be the unix time the token expires at more in line with mint/melt quote expiry feilds

}
```

**3.Client accesses protected resources:** The client application includes the bearer token in the Authorization header of subsequent requests to access protected resources. The mint validates the token and grants access if it is valid and has not expired.

Alice's client application can now access the protected resource on Bob's mint by including the bearer token in the Authorization header of the request:

```http
POST https://bob.com/v1/mint/quote/bolt11

Authorization: Bearer 9876543210fedcba
```

Bob's mint validates the token and grants access to the resource if the token is valid and has not expired.

# Bearer Token Details

- The bearer token is a string representing the user's access to resources.
- The token is time-bounded with a specific expiry time. This expiry time should be chosen based on security considerations and the desired access duration.
- The token should be treated as a secret and protected from unauthorized access.


# Implementation Considerations

- Secure storage of user private keys is crucial for the security of this authentication mechanism.
- The mint must implement robust signature verification and token management processes.
- Client applications must handle bearer tokens securely and respect their expiry times.
- If a mint choose to implement this NUT, then add this information to /info endpoint as per NUT-06 spec.

```json
{
"nuts": {
"15": {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"15": {
"16": {

"methods": [
{
"method": "/quote/bolt11",
"restricted": true,
"registration": "/v1/auth/register"
}
],
"disabled": false
},

}

```
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Wallets and mints `MUST` implement all mandatory specs and `CAN` implement optio
| [11][11] | Pay-To-Pubkey (P2PK) | [Nutshell][py] | [Nutshell][py] |
| [12][12] | DLEQ proofs | [Nutshell][py] | [Nutshell][py] |
| [13][13] | Deterministic secrets | [Nutshell][py], [Moksha][cashume], [cashu-ts][ts] | - |

| [15][16] |Authentication with Schnorr Signatures |
Copy link
Collaborator

@thesimplekid thesimplekid Mar 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| [15][16] |Authentication with Schnorr Signatures |
| [16][16] | Authentication |

#### Wallets:

- [Nutshell][py]
Expand Down Expand Up @@ -74,3 +74,4 @@ Wallets and mints `MUST` implement all mandatory specs and `CAN` implement optio
[11]: 11.md
[12]: 12.md
[13]: 13.md
[15]: 15.md
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[15]: 15.md
[16]: 16.md