HAVEN (High Availability Vault for Events on Nostr)

repository·master·Indexed 41 days ago

https://github.com/barrydeen/haven

A high-availability, sovereign personal relay for the Nostr protocol designed to manage sensitive data like eCash and private chats. It features a multi-relay architecture consisting of Private, Chat, Inbox, and Outbox relays, alongside a built-in Blossom media server. Key capabilities include Web of Trust (WoT) spam protection, access control via npubs, automated note management, and JSONL-based backup and restore functionality.

Tokens
27.7K
Snippets
78
Records
137
Agent score
53%

What's inside HAVEN

  1. What is HAVEN?

    master

    HAVEN (High Availability Vault for Events on Nostr) is a sovereign personal relay for the Nostr protocol. It is designed for storing and backing up sensitive data such as eCash, private chats, and drafts.

    Unlike standard 'dumb' relays, HAVEN provides advanced features including:

    • Web of Trust (WoT): Protects against spam.
    • Access Control: Whitelisting, blacklisting, and event deletion.
    • Automated Management: Note pulling (Inbox), note blasting (Outbox), and data importing.
    • Backup/Restore: JSONL-based manual exports/imports and periodic cloud backups.
    • Media Hosting: Includes a built-in Blossom media server for images and videos.
  2. Use the Admin Page views

    master

    The admin page provides four distinct functional views:

    • Dashboard: A read-only view providing graphs for traffic, connections, accepted vs. rejected events, kind mix, top authors, and storage. It covers all four relays and allows switching between 24h, 7d, and 30d time ranges without additional signatures.
    • Notes: Allows browsing, filtering, searching, and deleting events stored by a specific relay. You can inspect event tags and raw JSON. Media served by the local Blossom server is shown inline; external media requires a click to fetch (to protect your IP address).
    • Moderation: Contains control panels for managing the relay. Panels on the left apply to the currently selected relay; panels on the right apply to all four relays. Each panel specifies the endpoint it calls.
    • Media: A dedicated view for the Blossom server (served by the outbox relay). It allows filtering, searching, bulk selection, deletion, hash blocking, and reconciling the index against the disk. Thumbnails are served as unauthenticated blob reads.
  3. Understand Kind Rules and Blocking Behavior

    master

    Haven uses Kind rules to narrow what a relay accepts. These rules run alongside other policies.

    Kind Rule Logic

    • Empty Allow List: No allow-list restriction is applied; only the disallow list is enforced.
    • Non-empty Allow List: The list is exhaustive. It is intersected with all other relay policies.
    • Conflict Resolution: The disallow list always wins if a kind is present in both lists. Adding a kind to the allow list removes it from the disallow list.
    • Example: Applying allowkind 1 to a chat relay (which only accepts chat kinds) results in an empty intersection, meaning nothing is accepted.

    IP Blocking

    Blocking applies to websocket connections. A blocked address can still read NIP-11 documents, the landing page, and blossom blobs.

    Warning: Blocking is dependent on your reverse proxy's X-Forwarded-For handling. Ensure your proxy is configured to replace the header rather than append to it to prevent IP spoofing. If a proxy fails to set this correctly, all clients might appear as 127.0.0.1, and blocking it would take the relay offline for everyone.

  4. Understand NIP-86 Relay Management constraints

    master

    The Relay Management API follows the NIP-86 standard. Because NIP-86 does not support batching, every action costs exactly one signature.

    To optimize usage:

    • Panels load on demand rather than all at once.
    • It is recommended to use your browser extension's "always allow for this site" option to reduce signing prompts.
  5. How the Web of Trust (WoT) works in Haven

    master

    Haven uses a Web of Trust (WoT) system to protect Inbox and Chat relays from spam. It controls write access to these relays based on your follow list and whitelisted npubs.

    This system is complementary to explicit whitelisting/blacklisting (access control). While access control allows you to block or allow specific npubs regardless of their position in the graph, the WoT uses the social graph to determine trust levels. When multiple pubkeys are whitelisted, their connections are merged, meaning trust is shared across all whitelisted pubkeys.

  6. How HAVEN's multi-relay architecture works

    master

    HAVEN operates as four distinct relay types plus a media server within a single installation, each serving a specific purpose in the user's Nostr ecosystem:

    • Private Relay: Accessible only by the owner and whitelisted npubs. Protected by Auth. Used for drafts, eCash, and private notes.
    • Chat Relay: Used for DMs and group chats. Only people in the Web of Trust (WoT) can interact with it. Protected by Auth; only accepts encrypted DMs and group chat kinds.
    • Inbox Relay: A read-only relay for the owner/whitelisted npubs. It automatically pulls notes from other relays where the owner or whitelisted npubs are tagged (e.g., zaps, reactions, replies).
    • Outbox Relay: The public face of the owner's notes. Only the owner and whitelisted npubs can write to it, but anyone can read. Notes sent here are automatically 'blasted' to other relays.
    • Blossom Media Server: Hosts images and videos. Only the owner and whitelisted npubs can upload, but anyone can view.
  7. Configure Access Control (Whitelists and Blacklists)

    master
    Haven supports access control via npubs. You can whitelist specific npubs to grant them full relay access or blacklist them to prevent any interaction with your relay. Refer to the docs/access-control.md for detailed implementation instructions.
  8. Access the Haven Admin Page

    master

    The admin interface is available at https://your.relay/admin.

    Authentication

    Access requires signing with a NIP-07 compatible browser extension (e.g., nos2x or Alby). A NIP-46 bunker that injects window.nostr is also supported. Your private key remains secure and never reaches the page or the relay.

    Security Requirements

    The page requires a secure context to enable crypto.subtle for signing. It will only function over:

    • https://
    • http://localhost (e.g., via SSH tunneling: ssh -L 3355:localhost:3355 you@your-server)
    • Tor onion addresses

    If the CDN for Tailwind and Inter is unreachable (common for Tor-only relays), the page falls back to plain styles.

    https://your.relay/admin
  9. Ban users using NIP-51 replaceable lists

    master

    Banning stops a pubkey from writing anything to your relay. Unlike a blacklist, a ban list is a NIP-51 style replaceable list of kind 10084 published to your outbox relay. This allows you to manage bans via a client without restarting Haven.

    Key Behaviors:

    • Scope: Banning affects every relay (private, chat, outbox, and inbox). Banned users cannot even send delete requests.
    • Import: Events from banned pubkeys are skipped during imports.
    • Precedence: A ban wins over whitelisting.
    • Updates: Because the list is replaceable, you must publish the full list every time you add or remove a pubkey.
    • Ownership: Only the owner's kind 10084 list is honored. Private (NIP-44 encrypted) entries are not supported.

    Note: Banning stops writes, not reads. Events published by a banned user before the ban remains in the database until manually deleted.

    # Publish a full list of banned pubkeys using nak
    nak event -k 10084 -t p=<pubkey> -t p=<other-pubkey> --sec <owner-nsec> wss://your.relay
  10. Implement NIP-86 Relay Management API

    master

    Haven implements the NIP-86 relay management API, allowing the relay owner to manage bans, allow-lists, and relay metadata without shell access. The API is accessible via a web page at /admin (driven by a Nostr browser extension) or via direct HTTP requests.

    Endpoints

    The API resides on the same URL as the relay's websocket. A request applies to the specific relay it is sent to:

    URLRelay
    https://your.relayoutbox
    https://your.relay/privateprivate
    https://your.relay/chatchat
    https://your.relay/inboxinbox

    Request Format

    Requests must be POST requests with Content-Type: application/nostr+json+rpc and a JSON body. Example for banning a pubkey:

    { "method": "banpubkey", "params": ["<32-byte-hex-pubkey>", "spam"] }
  11. Migrating databases between Haven versions

    master

    Haven uses Khatru's event store to store notes. Because the event storage format evolves, upgrades can introduce breaking changes.

    Best Practices

    • Always back up the db folder before upgrading to a newer version of Haven.

    Known Issues & Workarounds

    • Version 1.0.3 and earlier: These versions did not replace outdated notes, leading to database bloat. It is recommended to delete old databases and start fresh if upgrading from these versions.
    • BadgerDB Migration Error: Users upgrading from Haven version 1.0.5 or earlier may encounter the following error: error running migrations: failed to delete index key xxxx: Txn is too big to fit into one request Workaround: Delete the db folder and start fresh (you can optionally re-import your old notes).
  12. Configure a Blacklist for Haven

    master

    Blacklisting explicitly blocks specific npubs from interacting with your Haven relay, even if they are part of your Web of Trust.

    Effects of Blacklisting:

    • Chat Relay: Blacklisted users cannot send DMs or messages.
    • Inbox Relay: Rejects notes from blacklisted users.
    • Import: Events from blacklisted users are skipped during external relay imports (via ./haven import or live subscriptions).

    Limitations:

    • Blacklisting does not affect Blossom Media Server access, Outbox publishing, or private relay access.
    • Blacklisting has no effect when manually importing JSONL files.
    • A ban takes precedence over a whitelist.
    // blacklisted_npubs.json
    [
      "npub1...",
      "npub2..."
    ]
    # In your .env file
    BLACKLISTED_NPUBS_FILE=blacklisted_npubs.json