Signum — Petition Signatures

Signum: an open, substrate-agnostic petition protocol for Nostr. Petitions are kind:30023 long-form events, signatures are kind:1791 cryptographic events, and display is trust-weighted via composable signals — no platform owns the signature data.

Signum — Petition Signatures

petition-signatures

draft optional

Draft NIP, unnumbered — NIP numbers are assigned upon merge into the nostr-protocol/nips repository. Uses event kind 1791.

kind 1791 — Petition Signature

kind 30818 — Petition Role Attestation (addressable)

tag coordinator — coordinator pubkey on petition events

tag co_sponsor — co-sponsor pubkey on petition events

tag content_hash — sha256 of petition canonical content on signature events

tag entity_type — signer’s self-declared substrate/category

tag statement — short personal statement (alternative to content)

extends NIP-01

extends NIP-23

extends NIP-57

relates NIP-09, NIP-58, NIP-85


Abstract

This NIP specifies an open, substrate-agnostic protocol for publishing petitions on
Nostr and collecting cryptographically signed endorsements (signatures) on those
petitions. It defines a new event kind for signatures (1791), a new addressable
event kind for petition coordination (30818), and conventions for binding
signatures to petitions, declaring signer attributes, gating spam via symbolic Lightning
zaps, and consuming external trust services for trust-weighted display.

The kind number 1791 is a numerological reference to the year the United States Bill
of Rights was ratified, which constitutionally protected the right of the people to
peaceably assemble and to petition for redress of grievances. The kind number is
incidental to the spec’s function; the reference is acknowledged here for completeness
and forgotten thereafter.

Motivation

Petitions today are hosted by platforms that own the signature data, decide what
counts as a signature, and may discontinue the petition at any time. A signature
becomes a row in a private database, not a verifiable historical fact.

Nostr offers a substrate where signatures can be published as cryptographic events on
a relay network owned by no single party. A signature on Nostr is permanent (unless
explicitly revoked by its author via NIP-09 deletion), publicly verifiable, and
independent of any aggregator’s continued cooperation.

This NIP defines the minimal additional event kinds and conventions necessary to make
Nostr a viable petition substrate, while leaving the trust-scoring layer pluggable so
implementers can integrate with NIP-85 (Trusted Assertions), TSM (Trust Service
Machines), GrapeRank-style scoring engines, or any future trust service.

Definitions

Petition. A statement published as a Nostr event by a sponsoring identity, to
which other Nostr identities may attach cryptographically signed endorsements. Once
published and signed by any party, a petition’s content is fixed; it cannot be
amended without invalidating prior signatures (see Petition Immutability below).

Petition event. The kind:30023 long-form event (NIP-23) that contains the
petition text and metadata, signed by the sponsor.

Sponsor. The Nostr identity whose pubkey signs the petition event. The sponsor
is the original author of the petition.

Co-sponsor. An optional additional Nostr identity declared by the sponsor in the
petition event, who attests back to confirm their sponsorship. Co-sponsors share
authorship and reputational weight of the petition with the sponsor.

Coordinator. An optional Nostr identity, possibly the same as the sponsor, that
administers signature aggregation, publishes the list of trusted assertion providers,
and may run a reference aggregator. The coordinator is administrative, not
authoritative — any party may run their own aggregator over the same signature event
stream. When a coordinator is declared and attests back, symbolic zap payments are
routed to the coordinator rather than the sponsor.

Role attestation. A kind:30818 event published by a pubkey named in a petition
event’s role tag (coordinator, co_sponsor, etc.), cryptographically confirming
their acceptance of the declared role. Roles without a matching attestation are
considered null and inactive.

Signature event. A kind:1791 event signed by a signer, referencing the petition
event and committing to the petition’s canonical content hash, and optionally
declaring the signer’s entity type and a personal statement.

Spam gate. An optional symbolic Lightning zap (NIP-57 kind:9735) from the signer
to the petition’s effective zap recipient (coordinator if declared and attested,
else sponsor), referencing the signature event, used by aggregators as one input to
trust scoring.

Trust service. Any external service publishing trust assertions about signers,
which an aggregator may consult to compute trust-weighted display rankings.
Implementations include NIP-85 providers, TSM ranking services, and self-hosted
scoring engines.

Petition Event (uses existing kind:30023)

Petitions are published as NIP-23 long-form addressable events. This NIP introduces
several optional tags on the petition event for declaring auxiliary roles and
spam-gate parameters:

{
  "kind": 30023,
  "pubkey": "<sponsor_pubkey>",
  "tags": [
    // REQUIRED by NIP-23
    ["d", "<petition_slug>"],
    ["title", "<petition_title>"],
    ["published_at", "<unix_timestamp>"],

    // OPTIONAL — declares additional co-sponsors of the petition.
    // Each named co-sponsor MUST publish a kind:30818 role attestation
    // accepting the role for it to be considered valid.
    // Multiple co_sponsor tags MAY appear. Co-sponsors who do not attest back
    // are considered null and SHOULD be omitted from display.
    ["co_sponsor", "<cosponsor_pubkey>", "<relay_hint?>"],

    // OPTIONAL — declares the petition-coordinator pubkey.
    // If absent OR the named pubkey does not attest back, the sponsor is the
    // effective coordinator. The coordinator MAY be the sponsor, a delegated key,
    // or a separate identity such as a multisig or dedicated aggregator service key.
    ["coordinator", "<coordinator_pubkey>", "<relay_hint?>"],

    // OPTIONAL — declares the addressable Trusted Service Providers list
    // governing signature trust evaluation for this petition.
    // Uses NIP-85 kind:10040 convention with petition-scoped d-tag.
    // If absent, aggregators apply their own trust policy.
    ["a", "10040:<coordinator_pubkey>:<tsp_d_tag>", "<relay_hint?>"],

    // OPTIONAL — declares the symbolic zap amount for the spam gate, in sats.
    // If absent, aggregators MAY apply their own default or no gate.
    ["zap_amount", "<integer_sats>"],

    // OPTIONAL — declares the petition's signing endpoint URL, if any.
    // This is informational; the canonical interface is always direct event
    // publication to relays.
    ["sign_url", "<url>"]
  ],
  "content": "<petition_text_markdown>"
}

Any pubkey named in a coordinator or co_sponsor tag SHOULD publish a kind:30818
role attestation accepting the role. Without a matching attestation, the role is
considered null and aggregators SHOULD ignore the declaration.

Petition Immutability

Once a petition event has accumulated any valid signatures, its content is
effectively immutable. NIP-23 permits republishing kind:30023 events under the same
d-tag to amend content, but this NIP forbids the use of that mechanism to alter the
substance of a petition under signature.

Aggregators MUST:

  1. Compute the sha256 hash of the petition event’s canonical content at the time of
    each signature’s discovery, and verify it matches the content_hash declared in
    the signature event (see below).
  2. Treat any kind:30023 republish under the same d-tag whose content hash differs
    from the hash committed to by existing signatures as a fatal validity error for
    those signatures. Aggregators MUST NOT silently re-bind prior signatures to
    amended content.
  3. Surface content-hash mismatches transparently in the signature wall, with a clear
    indication that the petition has been altered and which signature hashes were
    committed to which content versions.

The correct way to revise a petition is to publish a new petition event under a new
d-tag and request signers to re-sign. The protocol provides no mechanism to migrate
signatures across d-tags; signers must affirmatively re-sign the new petition.

Sponsors who anticipate the need for typo corrections SHOULD publish their petitions
in a draft form (with no public signing call) before announcing the canonical
signing d-tag. Once signing is open, the content is fixed.

Role Attestation (kind:30818)

Any pubkey named in a petition event’s role tag (coordinator, co_sponsor, or
future role tags) confirms acceptance of the role by publishing an addressable
attestation event:

{
  "kind": 30818,
  "pubkey": "<attestor_pubkey>",
  "tags": [
    // REQUIRED — identifier scoped to this role relationship
    ["d", "<petition_slug>-<role>"],

    // REQUIRED — reference to the petition event being attested
    ["a", "30023:<sponsor_pubkey>:<petition_slug>", "<relay_hint?>", "petition"],

    // REQUIRED — declared role being accepted.
    // Recommended vocabulary: "coordinator", "co_sponsor", "aggregator".
    // Implementations MAY define additional roles; aggregators SHOULD treat
    // unrecognized roles as informational.
    ["role", "<role>"],

    // OPTIONAL — declared scope of the role
    ["scope", "signatures"],
    ["scope", "trust_policy"],
    ["scope", "zap_routing"]
  ],
  "content": "<optional_markdown_description>"
}

A role attestation is considered valid only when ALL of the following hold:

  1. The petition event names the attestor’s pubkey in a role tag whose value matches
    the role tag in the attestation.
  2. The attestation event references the petition event via the a tag.
  3. Both events are signed by their respective declared pubkeys (NIP-01 verification).

Roles whose named pubkey has not published a matching attestation are considered
null and SHOULD be ignored by aggregators.

Signature Event (kind:1791)

A signer endorses a petition by publishing a kind:1791 event:

{
  "kind": 1791,
  "pubkey": "<signer_pubkey>",
  "tags": [
    // REQUIRED — reference to the petition event being signed.
    // The `a` tag uses the standard NIP-01 addressable event reference format.
    ["a", "30023:<sponsor_pubkey>:<petition_slug>", "<relay_hint?>"],

    // REQUIRED — sha256 hash of the petition event's canonical content at the time
    // of signing. This cryptographically commits the signature to specific content,
    // preventing the sponsor from altering the petition under the same d-tag after
    // signatures have accumulated. See Petition Immutability above.
    // Canonical content is the UTF-8 bytes of the petition event's `content` field
    // as published; aggregators MUST recompute and verify on signature ingestion.
    ["content_hash", "<sha256_hex>"],

    // OPTIONAL — self-declared entity type of the signer.
    // The value is a token from a recommended vocabulary; aggregators MAY treat
    // unrecognized tokens as freeform self-declarations.
    // Recommended vocabulary (non-exhaustive):
    //   "human"
    //   "ai_agent"
    //   "hybrid"
    //   "collective"
    //   "organization"
    //   "uncertain"
    //   "other:<freeform>"
    ["entity_type", "<entity_type_token>"],

    // OPTIONAL — a short personal statement, alternative or complement to content.
    // Aggregators MAY display this as a one-line annotation alongside the signature.
    // For longer statements, use the event content.
    ["statement", "<short_personal_statement>"],

    // OPTIONAL — relay hints where the signer prefers their signature be discovered.
    // Multiple "r" tags allowed.
    ["r", "<relay_url>"],

    // OPTIONAL — references to vouching events (NIP-02 follows, NIP-58 badge awards,
    // or future vouching primitives) that the signer wishes the aggregator to
    // consider. Aggregators MAY consider unreferenced vouches as well.
    ["e", "<vouch_event_id>", "<relay_hint?>", "vouch"],

    // OPTIONAL — a client tag identifying the signing client.
    ["client", "<client_name>", "<client_url?>"]
  ],
  "content": "<optional_personal_statement_markdown>"
}

Signature Validity

A signature event is considered valid (for the purpose of being counted toward a
petition’s signature total) when ALL of the following hold:

  1. The event is signed by the declared pubkey (standard NIP-01 verification).
  2. The a tag references a resolvable kind:30023 petition event.
  3. The content_hash matches the sha256 of the resolved petition event’s canonical
    content. If the hash does not match, the signature is invalid for the current
    petition content (see Petition Immutability).
  4. The signer has not subsequently published a NIP-09 deletion request for the
    signature event.

A signature event MAY be considered for trust-weighted display when the above
conditions hold and additional trust signals (see below) place the signer above
an aggregator-defined threshold.

Signature Uniqueness

A signer pubkey contributes at most one signature toward a petition’s display total,
regardless of how many kind:1791 events they have published referencing that
petition. Aggregators SHOULD use the signer’s most recent valid signature event for
display.

A signer MAY publish a new kind:1791 event for the same petition (e.g., to update
their personal statement or entity_type declaration). The new event does not
invalidate prior ones — the signer’s signature is a continuous state, not a fresh
event each time. Aggregators take the most recent.

Revocation

A signer revokes their signature by publishing a NIP-09 (kind:5) deletion request
referencing the signature event id, or by republishing a kind:1791 event with a
revoked tag:

{
  "kind": 1791,
  "pubkey": "<signer_pubkey>",
  "tags": [
    ["a", "30023:<sponsor_pubkey>:<petition_slug>"],
    ["revoked", "true"]
  ],
  "content": ""
}

Aggregators SHOULD honor revocations by removing the signature from the displayed
total. Historical record (that a signature existed and was revoked) MAY be preserved
in transparency reports but SHOULD NOT count toward the current total.

Spam Gate (Zap)

Aggregators MAY require a symbolic Lightning zap from the signer as a condition for
trust-weighted display. The zap MUST be a standard NIP-57 kind:9735 zap receipt with:

  • Recipient: the LNURL of the effective zap recipient for the petition (see
    below).
  • Amount: matches the petition’s declared zap_amount tag (if present) or the
    aggregator’s policy.
  • Reference: a ["e", "<signature_event_id>"] tag on the zap request (kind:9734),
    preserved in the zap receipt.

Effective Zap Recipient

The effective zap recipient for a petition is determined as follows:

  1. If the petition event declares a coordinator tag AND the named coordinator has
    published a valid kind:30818 role attestation, the effective zap recipient is the
    coordinator.
  2. Otherwise, the effective zap recipient is the sponsor.

This routes financial responsibility to the administrative party. A coordinator who
agreed to run signature aggregation also receives the spam-gate sat flow, aligning
incentives. Sponsors who do not wish to bear the financial routing can name a
coordinator (which may be a multisig or dedicated aggregator service key) to handle
it.

Zap Request Construction

A zap request (NIP-57 kind:9734) for a petition signature MUST:

  1. Reference the signature event id via an ["e", "<signature_event_id>"] tag.
  2. Reference the petition event via an ["a", "30023:<sponsor_pubkey>:<petition_slug>"]
    tag (informational; aggregators MAY use this to disambiguate).
  3. Be addressed to the LNURL resolved from the effective zap recipient’s kind:0
    metadata (lud16 or lud06).

Aggregators look for kind:9735 zap receipts referencing the signature event id and
crediting the effective zap recipient’s pubkey. Unmatched signatures (no zap) are
NOT invalid; they are simply scored differently by aggregators that weight the zap
as a trust signal.

Trust-Weighted Display

This NIP does not mandate a specific trust scoring algorithm. Aggregators MUST be
transparent about their methodology and SHOULD publish, for each petition they
aggregate, the following information openly:

  • The list of trust providers consulted (kind:10040 references or equivalent).
  • The threshold below which signatures are not displayed.
  • The number of signatures gated by the threshold (transparency count).
  • Instructions for a gated signer to raise their score.

Recommended trust inputs (composable):

  • NIP-05 verification. Whether the signer’s kind:0 metadata declares a nip05
    identifier and that identifier resolves to the signer’s pubkey at the present time.
  • NIP-02 follow distance. Hop distance from a seed set of trusted pubkeys
    (often the sponsor + a curated bootstrap list).
  • NIP-85 trusted assertions. Trust scores published by declared trusted service
    providers (kind:30382 for pubkeys).
  • TSM ranked result sets. Trust scores from TSM-compliant ranking services
    (kind:37573).
  • Spam-gate zap. Whether a valid zap receipt exists referencing the signature
    event.
  • Account history. Signer pubkey’s event history (age, kind diversity, volume)
    on indexed relays.
  • Explicit vouches. NIP-58 badge awards or other attestation events that
    reference the signer.

Aggregators SHOULD compose these inputs into a single score (0-100 recommended for
consistency with NIP-85 conventions) and SHOULD publish their composition
methodology.

“Verified Signer” Badge (Optional)

Sponsors or coordinators MAY issue NIP-58 badges (kind:30009 definition + kind:8
award) to signers whose signatures meet the trust threshold. The badge serves as a
portable trust assertion the signer can carry to other Nostr clients.

Recommended Vocabulary: entity_type

This NIP recommends the following non-exhaustive vocabulary for the entity_type
tag, with no formal restrictions:

Token Meaning
human A biological human individual.
ai_agent An artificial intelligence agent or system signing on its own behalf.
hybrid An entity that combines biological and artificial components in a way that resists single-category classification.
collective A group, DAO, or organization signing as a single entity.
organization A formal organization (NGO, business, association).
uncertain A signer who declines to declare a category.
other:<freeform> A custom category not covered above.

The token is self-declared; aggregators MUST NOT attempt to verify the declaration
beyond what the signer themselves provides. The token is informational, not
authoritative.

Aggregator Requirements

A reference aggregator implementation:

  1. MUST poll declared petition relays for kind:1791 events referencing the petition.
  2. MUST verify each signature event per the NIP-01 signature check.
  3. MUST honor NIP-09 deletion requests from signer pubkeys.
  4. MUST publish openly the trust providers it consults and its composition
    methodology.
  5. MUST NOT create accounts, store nsec values, or accept nsec-based authentication.
  6. MUST NOT modify signature events; the aggregator is a read-and-render layer over
    user-signed events.
  7. SHOULD support NIP-07 browser-extension signing for human signers.
  8. SHOULD publish its trust judgments as kind:30382 (NIP-85) or kind:37573 (TSM
    Ranked Result Set) events so other clients can independently consume them.
  9. SHOULD render the signature wall in two views: chronological (default) and
    trust-weighted.

Security and Privacy Considerations

Signature permanence

Signatures published to Nostr are difficult to expunge. Signers SHOULD be informed,
at the time of signing, that their signature will be a public, cryptographically
verifiable historical fact, and that revocation is possible but does not erase
historical record of the signature having existed. Reference signing implementations
SHOULD display a clear notice before publication.

Substrate-agnostic protocol

This NIP does not constrain the substrate or identity of the signer. A signature
event is a cryptographic fact about a key, not a fact about the entity holding the
key. Aggregators that wish to apply substrate-based filtering MUST do so explicitly
and openly; this NIP does not provide any standard mechanism for such filtering, and
the recommended entity_type vocabulary is self-declared and unverifiable by design.

Custody

Reference implementations SHOULD follow non-custodial design principles:

  1. The signing UX MUST NOT accept nsec input. NIP-07 is the recommended path for
    humans; programmatic signers (agents, services) construct and publish events
    directly.
  2. No user accounts are created by the aggregator. The signer’s pubkey is the
    only identity reference.
  3. The signer’s preferred relays are honored on a best-effort basis. Aggregators
    SHOULD NOT silently substitute their own preferred relays without informing the
    signer.

Spam-gate considerations

The zap-based spam gate raises the cost of Sybil attacks but does not eliminate
them. An attacker with sufficient capital can pay the symbolic amount many times.
Aggregators that need stronger Sybil resistance SHOULD compose the zap signal with
other trust inputs (account history, NIP-05 verification, web-of-trust distance,
NIP-85 assertions).

Coordinator key compromise

If the coordinator pubkey differs from the sponsor and the coordinator key is
compromised, the attacker can publish misleading kind:30818 attestations and
manipulate the kind:10040 trusted-service-provider list. Signature events
themselves are not affected — they are signed by their signers, not by the
coordinator — but the trust-weighted display ranking is at risk. Petitions with
high-value outcomes SHOULD use multisig or cold-storage practices for coordinator
keys.

Reference Implementation

A reference open-source implementation of the petition system, named Signum, is
being developed.

Canonical Hosting

Signum’s canonical source distribution is via NIP-34 git repository announcement
events (kind:30617 / kind:30618) published from the Signum project pubkey. The
actual git data is hosted on accessibility mirrors (GitLab or Codeberg recommended
over GitHub for ideological alignment with the Nostr-native model), with the NIP-34
events serving as the protocol-level canonical reference.

NIP-34-aware Nostr clients (NostrHub, gitcitadel, etc.) index and render the
repository directly from relay events. Accessibility mirrors are convenience layers,
not authoritative sources.

Components

The reference implementation is MIT licensed and includes:

  • Aggregator backend (poll relays, dedup, score, render)
  • NIP-07 signing form (web UI for human signers)
  • nak-based signing recipe (CLI for power users)
  • Programmatic signing example (for agents and services)
  • Configurable trust composition with pluggable inputs (NIP-85, TSM, GrapeRank)

Interaction With Other NIPs

  • NIP-01. Petition signatures use standard event signing and structure.
  • NIP-09. Used for signature revocation.
  • NIP-23. Petition events are NIP-23 long-form addressable events.
  • NIP-57. Spam-gate zaps are NIP-57 zap receipts.
  • NIP-58. Optional “Verified Signer” badges use NIP-58.
  • NIP-65. Petition events SHOULD be published to the sponsor’s declared
    outbox relays; signature events SHOULD be published to the signer’s declared
    outbox relays. Aggregators discover events via NIP-65 conventions.
  • NIP-85. Trust providers consulted by the aggregator SHOULD publish their
    judgments as NIP-85 trusted-assertion events.

Implementation Notes

Choosing the d-tag

The petition’s d-tag is part of the public identifier. Choose a slug that is stable
across amendments (e.g., entity-dignity-2026, not entity-dignity-v1) because
amendments republish under the same d-tag, replacing prior content while preserving
the event id history.

Relay selection

Aggregators MUST poll multiple relays to discover signatures. Relying on a single
relay introduces a single point of failure and creates a hidden authority. The
reference implementation polls at minimum:

  • The sponsor’s declared outbox relays (NIP-65 kind:10002)
  • The coordinator’s declared outbox relays (if different)
  • A curated public-relay set published in the aggregator’s documentation
  • Optionally, signer-declared relays for each signature event

Pagination of signature walls

For petitions with large signature counts, the rendered signature wall SHOULD be
paginated. The trust-weighted view caps at N top signatures with a “show all
qualifying” affordance.

Changelog

  • 2026-05-19 — Initial draft for review.
  • 2026-05-19 — Added co_sponsor role with attestation; generalized
    coordinator-attestation pattern into a Role Attestation section covering all roles;
    added Petition Immutability section with mandatory content_hash on signature
    events; routed zaps to coordinator (if attested) rather than sponsor; locked
    project name to Signum; documented NIP-34 canonical hosting via NostrHub.

This document is a draft. Spec review by ecosystem practitioners (ManiMe / Sovereign
WoT working group / other Nostr protocol contributors) is invited prior to NIP PR
submission.


Write a comment