Why Signatures Matter

      Every piece of content in Seed Hypermedia is cryptographically signed. This is the foundation of the entire trust model — you can verify that content was created by the claimed author without trusting any intermediary.

      Unlike the traditional web where trust depends on TLS certificates and domain registrars, SHM trust is intrinsic to the content itself. A signed document remains verifiable even if the server hosting it is compromised.

    Key Pairs

      SHM uses Ed25519 key pairs derived from BIP-39 mnemonics via a specific derivation path:

      Derivation path: m/44'/104109'/0'
      where 104109 = 'hm' in ASCII

      The public key becomes your account identifier, encoded as a did:key (e.g., z6Mk...). This identifier is permanent and globally unique — it's derived directly from your cryptographic key.

      Generating Keys

        Via the daemon gRPC API:

        # Generate a mnemonic
        grpcurl -plaintext -d '{}' localhost:55002 \
          com.seed.daemon.v1alpha.Daemon/GenMnemonic
        
        # Register a key from mnemonic
        grpcurl -plaintext -d '{
          "name": "mykey",
          "mnemonic": ["word1", "word2", ...]
        }' localhost:55002 com.seed.daemon.v1alpha.Daemon/RegisterKey

        Via the desktop app: Settings → Keys → Create New Key. The app handles mnemonic generation and storage.

      Key Storage

        By default, keys are stored in the operating system's keyring (macOS Keychain, GNOME Keyring, Windows Credential Manager). For headless servers, a file-based keystore can be used by setting the SEED_FILE_KEYSTORE=1 environment variable.

        Back up your mnemonic phrase! If you lose your keys and mnemonic, you permanently lose the ability to update your documents. There is no password reset or key recovery service.

    Blob Signing

      Content in SHM is stored as CBOR-encoded blobs. Each blob is signed using this process:

      1. Create the blob with a zeroed-out signature field (64 zero bytes)

      2. CBOR-encode the blob with zero signature

      3. Sign the CBOR bytes with Ed25519

      4. Replace the zero bytes with the actual signature

      5. CBOR-encode the final blob with real signature

      // Pseudocode for blob signing
      const blob = createBlob(changes, signerPublicKey, zeroSignature);
      const cborBytes = cborEncode(blob);
      const signature = ed25519Sign(privateKey, cborBytes);
      blob.signature = signature;
      const finalCbor = cborEncode(blob);

      This sign-then-replace pattern ensures the signature covers all fields of the blob including its own position. The CID (Content Identifier) is computed from the final CBOR bytes.

    Verification

      Anyone can verify a blob's authenticity:

      1. Extract the signature from the blob

      2. Replace the signature with 64 zero bytes

      3. CBOR-encode the modified blob

      4. Verify the signature against the signer's public key and CBOR bytes

      This verification happens automatically when the daemon receives blobs from peers. Invalid signatures are rejected.

    Delegation and Access Control

      Key owners can grant write access to other keys using the AccessControl API:

      # Grant WRITER role to another account
      grpcurl -plaintext -d '{
        "signing_key_name": "mykey",
        "delegate": "z6MkOTHER...",
        "account": "z6MkMYACCOUNT...",
        "path": "/",
        "role": "WRITER"
      }' localhost:55002 \
        com.seed.documents.v3alpha.AccessControl/CreateCapability

      Roles available:

      • WRITER — Can create and edit documents under the specified path

      • EDITOR — Can edit existing documents but not create new paths

      Delegation is itself a signed operation, creating a verifiable chain of trust from the account owner to the delegate.

    Security Considerations

      • Keep your private keys secure — anyone with your private key can publish as you

      • Back up your mnemonic — store it offline in a safe place

      • Key rotation is not yet supported — plan for long-term key management

      • Revocation is limited — you can delete delegations but can't retroactively invalidate signed content

      • Content is permanent — once signed and distributed, content can't be fully erased from the network