
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
nostr-access-control
Advanced tools
This proposal specifies how to implement decentralized access control with Nostr.
This library implements a decentralized identity model focused on access control with Nostr.
See Decentralized Digital Identity with Nostr for a descriptive overview.
See nac-demo-app for a reference implemention app, which is also useful to get events for debugging.
Import as npm package:
npm -i nostr-access-controlRun tests (after cloning and npm install):
npm run test or npm run test -t "sample" to run single testComplile using just
event-functions folder contains simple functions that return unsigned Nostr events.event-classes folder contains TypeScript classes, where methods toUnsignedEvent() and toSignedEvent() return Nostr events.verification folder contains the verifyEligibility(...) function which determines a user's eligibility based on our model.You can create Badge Definition, Badge Award, and Classified Listing events using either event-functions or event-classes. Attestation event only exists in event-classes.
event-functions minimally implement possible event values, and are meant to be copied and expanded in your own project.event-classes are more flexible, and are meant to be used as imported classes within your project.For these example events, a Nostr client can check if a user has been awarded an Over 21 badge, issued by a indepdendent service (badge issuer), before showing certain content.
Classified Listing
{
"kind": 30402,
"created_at": 1675238400,
"tags": [
["d", "sensitive-content"],
["title", "Sensitive Content"],
["image", "https://ipsum.com/rated-r.png", "256x256"],
["summary", "To view this content, you require an Over 21 badge."],
["a", "30009:<badge issuer pubkey>:over21", "wss://relay"]
],
"pubkey": "<resource owner pubkey>",
"id": "...",
"sig": "..."
}
Badge Definition
{
"kind": 30009,
"created_at": 1672560000,
"tags": [
["d", "over21"],
["name", "Over 21"],
["image", "https://ageverifier.com/images/over21.png", "256x256"],
["description", "User is over 21 years of age."]
],
"pubkey": "<badge issuer pubkey>",
"id": "...",
"sig": "..."
}
Badge Award
{
"kind": 8,
"created_at": 1677657600,
"tags": [
["a", "30009:<badge issuer pubkey>:over21"],
["p", "<user pubkey>", "wss://relay"]
],
"pubkey": "<badge issuer pubkey>",
"id": "...",
"sig": "..."
}
Attestation Event
{
"kind": 1,
"created_at": 1677657600,
"tags": [
["e", "<referenced event id>"],
["a", "30009:<badge issuer pubkey>:over21"]
],
"content": "Attestation for badge definition event (Over 21). Signed on Fri, 17 Nov 2023 09:51:57 GMT",
"pubkey": "<attester pubkey>",
"id": "...",
"sig": "..."
}
An Attestation Event is a Kind 1 note, which references another event via e and a tags.
Signed by an application/platform key to attest the information in the referenced event was processed by the application and is correct. Alternative to NIP-03 based on centralized trust.
The verification folder contain the verifyEligibility(...) function which determines a user's eligibility based on events passed in.
Also returns errors detected during validation of events.
Can run with command: jest -t "sample"
const result = verifyEligibility({
userPublicKey: userPublicKey,
classifiedListingEvent: classifiedListingTemplate,
badgeAwardEvents: [badgeAwardTemplate]
})
const {isEligible, badges, errors} = result
if (isEligible)
{
console.log('user is eligible to access the resource')
}
else {
console.log('user is not eligible to access the resource')
}
type EligibilityResult = {
isEligible: boolean
badges?: ValidateBadgeAwardResult[]
errors?: string[]
}
const verifyEligibility = (props: {
userPublicKey: string
eventWithCriteria: Event
badgeAwardEvents: Event[]
}): EligibilityResult => {...}
The verifyEligibility function determines if user with userPublicKey is eligible for eventWithCriteria, based on badgeAwardEvents.
The verifyEligibility function returns result as EligilibityResult.
isEligible boolean is the overall resulterrors is a string array of non-badge specific reasons why the user is not eligible.badges is an array of ValidateBadgeAwardResult objects, which contain the reasons why a required badge in the eligibility criteria is not considered awarded.If isEligible is true, you should expect a ValidateBadgeAwardResult item in badges for each required badge, where isValid is true.
When isElibile is not true, you can check errors in EligibilityResult or ValidateBadgeAwardResult items for the reason why user is not eligible.
It is possible that isEligible is true, but there exists a ValidateBadgeAwardResult where isValid is not true, when the badgeAwardEvents parameter contains a non-relevant badge award event.
FAQs
This proposal specifies how to implement decentralized access control with Nostr.
We found that nostr-access-control demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.