{"id":"3a100283bf9e8a75676eaa1b94a4eeea64c9f85b07e279a4aeac272e90090f69","pubkey":"2b39b4ffe62933df970e19366c22c1e092f953f83fcfed754e0f04d5a3b459f9","created_at":1702052394,"kind":30817,"tags":[["d","nip-98"],["title","NIP-98: HTTP Auth"],["summary","Kind 27235, an ephemeral event signed to authorise a single HTTP request."],["s","draft"],["t","nostr"],["t","nip"],["k","27235","HTTP Auth"],["alt","A specification: NIP-98: HTTP Auth"],["client","openspecs-import"],["published_at","1683544973"],["proxy","https://github.com/nostr-protocol/nips/blob/656cecc7c0a815b6a2b218d3b5d6f078b3f4dbab/98.md","web"],["x","2ad4e547d7ce8a6e311f05480f1872953da58bac6bae92d31ec4172230b36393"]],"content":"NIP-98\n======\n\nHTTP Auth\n---------\n\n`draft` `optional`\n\nThis NIP defines an ephemeral event used to authorize requests to HTTP servers using nostr events.\n\nThis is useful for HTTP services which are built for Nostr and deal with Nostr user accounts.\n\n## Nostr event\n\nA `kind 27235` (In reference to [RFC 7235](https://www.rfc-editor.org/rfc/rfc7235)) event is used.\n\nThe `content` SHOULD be empty.\n\nThe following tags MUST be included.\n\n* `u` - absolute URL\n* `method` - HTTP Request Method\n\nExample event:\n```json\n{\n  \"id\": \"fe964e758903360f28d8424d092da8494ed207cba823110be3a57dfe4b578734\",\n  \"pubkey\": \"63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed\",\n  \"content\": \"\",\n  \"kind\": 27235,\n  \"created_at\": 1682327852,\n  \"tags\": [\n    [\"u\", \"https://api.snort.social/api/v1/n5sp/list\"],\n    [\"method\", \"GET\"]\n  ],\n  \"sig\": \"5ed9d8ec958bc854f997bdc24ac337d005af372324747efe4a00e24f4c30437ff4dd8308684bed467d9d6be3e5a517bb43b1732cc7d33949a3aaf86705c22184\"\n}\n```\n\nServers MUST perform the following checks in order to validate the event:\n1. The `kind` MUST be `27235`.\n2. The `created_at` timestamp MUST be within a reasonable time window (suggestion 60 seconds).\n3. The `u` tag MUST be exactly the same as the absolute request URL (including query parameters).\n4. The `method` tag MUST be the same HTTP method used for the requested resource.\n\nWhen the request contains a body (as in POST/PUT/PATCH methods) clients SHOULD include a SHA256 hash of the request body in a `payload` tag as hex (`[\"payload\", \"<sha256-hex>\"]`), servers MAY check this to validate that the requested payload is authorized.\n\nIf one of the checks was to fail the server SHOULD respond with a 401 Unauthorized response code.\n\nServers MAY perform additional implementation-specific validation checks.\n\n## Request Flow\n\nUsing the `Authorization` HTTP header, the `kind 27235` event MUST be `base64` encoded and use the Authorization scheme `Nostr`\n\nExample HTTP Authorization header:\n```\nAuthorization: Nostr \neyJpZCI6ImZlOTY0ZTc1ODkwMzM2MGYyOGQ4NDI0ZDA5MmRhODQ5NGVkMjA3Y2JhODIzMTEwYmUzYTU3ZGZlNGI1Nzg3MzQiLCJwdWJrZXkiOiI2M2ZlNjMxOGRjNTg1ODNjZmUxNjgxMGY4NmRkMDllMThiZmQ3NmFhYmMyNGEwMDgxY2UyODU2ZjMzMDUwNGVkIiwiY29udGVudCI6IiIsImtpbmQiOjI3MjM1LCJjcmVhdGVkX2F0IjoxNjgyMzI3ODUyLCJ0YWdzIjpbWyJ1IiwiaHR0cHM6Ly9hcGkuc25vcnQuc29jaWFsL2FwaS92MS9uNXNwL2xpc3QiXSxbIm1ldGhvZCIsIkdFVCJdXSwic2lnIjoiNWVkOWQ4ZWM5NThiYzg1NGY5OTdiZGMyNGFjMzM3ZDAwNWFmMzcyMzI0NzQ3ZWZlNGEwMGUyNGY0YzMwNDM3ZmY0ZGQ4MzA4Njg0YmVkNDY3ZDlkNmJlM2U1YTUxN2JiNDNiMTczMmNjN2QzMzk0OWEzYWFmODY3MDVjMjIxODQifQ\n```\n\n## Reference Implementations\n- C# ASP.NET `AuthenticationHandler` [NostrAuth.cs](https://gist.github.com/v0l/74346ae530896115bfe2504c8cd018d3)\n","sig":"44b1ede095fd8156635ecdfc49d980e710f6f80bd8e1665df96dbd291c16b608de1bbbb096452437d24f6ee834217aa25944c96fc9d60a28a8c3d804499572de"}