-
Notifications
You must be signed in to change notification settings - Fork 52
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
base: main
Are you sure you want to change the base?
Changes from all commits
08b3d37
3a380ca
1a52fdb
0be36bc
0fa3be1
79e483b
9cb6272
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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: | ||||||||||||||||||
|
||||||||||||||||||
``` 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` | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
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": { | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
"methods": [ | ||||||||||||||||||
{ | ||||||||||||||||||
"method": "/quote/bolt11", | ||||||||||||||||||
"restricted": true, | ||||||||||||||||||
"registration": "/v1/auth/register" | ||||||||||||||||||
} | ||||||||||||||||||
], | ||||||||||||||||||
"disabled": false | ||||||||||||||||||
}, | ||||||||||||||||||
|
||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -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 | | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
#### Wallets: | ||||||
|
||||||
- [Nutshell][py] | ||||||
|
@@ -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 | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.