nips icon indicating copy to clipboard operation
nips copied to clipboard

NIP-37: Remote signing of events

Open fiatjaf opened this issue 3 years ago • 8 comments

NIP: https://github.com/nostr-protocol/nips/blob/remote-signing/37.md

fiatjaf avatar Dec 02 '22 16:12 fiatjaf

where does the signing happen? I don't follow after we call unsigned again, and why is it the same 'UNSIGNED' to send the unsigned and request it?

eskema avatar Dec 02 '22 17:12 eskema

really cool workflow!

do you think its worth supporting querying unsigned events by pubkey? this way apps not integrated with a camera could also leverage this workflow.

also could we format the unsigned event examples a bit better? maybe like:

["UNSIGNED", 
  {
    "id": "ad68ae903460554de77e397230e54343c6e1247c0c3c0bd21bb5ee968b3ec50f", 
    "pubkey": "11bd73a4b8dfe3434b83baaab1bd5cd3d4c4f63879cc35d28f1cfbaf843f7d3c", 
    "created_at": 1669995181, 
    "kind": 0, 
    "tags": [], 
    "content": "{\"name\": \"ulysses\"}"
  }
]

monlovesmango avatar Dec 02 '22 17:12 monlovesmango

where does the signing happen? I don't follow after we call unsigned again, and why is it the same 'UNSIGNED' to send the unsigned and request it?

this doesn't cover signing from my understanding. ANA first needs to query for unsigned event and once ANA has the unsigned event it will sign it normally (in standard workflow outside of this NIP)

monlovesmango avatar Dec 02 '22 17:12 monlovesmango

This could be done without change to the existing relays.

The signing app could listen for ephemeral events:

{
    "id": getId(), 
    "pubkey": freshPubkeyForMicroService, 
    "created_at": now(), 
    "kind": 23424, 
    "tags": [
        "p": ulyssesPubKey
    ],
    "content": JSON.stringify(unsignedEvent),
    "sig": getSig()
}

Giszmo avatar Dec 27 '22 23:12 Giszmo

Awesome. Let's do that.

fiatjaf avatar Dec 27 '22 23:12 fiatjaf

@fiatjaf how about you add this to OBW? ;)

Giszmo avatar Dec 29 '22 03:12 Giszmo

Not a bad idea.

fiatjaf avatar Dec 29 '22 14:12 fiatjaf

This could be done without change to the existing relays.

The signing app could listen for ephemeral events:

{
    "id": getId(), 
    "pubkey": freshPubkeyForMicroService, 
    "created_at": now(), 
    "kind": 23424, 
    "tags": [
        "p": ulyssesPubKey
    ],
    "content": JSON.stringify(unsignedEvent),
    "sig": getSig()
}

This could allow for repeated remote signing without forcing user to scan QR code on every event.

A client generates a temporary key freshPubkeyForMicroService, generates 'sign request' event as above, encrypts event-id and temporary key in the QR code, then sends the ephemeral sign request event to user's relays. Then shows QR-code to user.

User opens the signing app, scans QR-code (or clicks nostr: link), also app subscribes to sign-request event kind+user pubkey and receives sign-request matching the QR-code. QR-code/nostr:link allows to verify that request is coming from this very client, not some random spammer-impersonator.

User confirms, and if user clicks 'allow for 1 hour' then app stores in it's db: freshPubkeyForMicroService is allowed to sign events for 1 hour. App then sends ephemeral sign-reply tagging freshPubkeyForMicroService and sign-request-event. Client reads the reply from relays and does what it wanted to with the event (I think client should broadcast, not signing app).

Then when client wants to sign again it sends ephemeral sign request event, and if signing app receives it and has a record that freshPubkeyForMicroService is allowed to sign, then it signs the request w/o requiring a confirmation and sends reply back.

If freshPubkeyForMicroService is leaked then the damage is at least temporary, and key permission can be revoked in the signing app.

Any flaws here?

brugeman avatar Jan 12 '23 08:01 brugeman

Closing in favor of nostr connect/nsecbunker

staab avatar Dec 14 '23 19:12 staab