summary:

  • Password-protected AES-256-GCM pages; client-side Web Crypto API decryption.
  • Per-page password: password frontmatter.
  • Companion emitter writes encrypted shadow index for unlisted encrypted pages; graph, explorer, search reveal entries after successful decryption.

Live demo

page: EncryptedPages Demo password: quartz

Note

configuration: Configuration

Usage

frontmatter:

---
title: My Secret Page
password: mysecretpassword
---

session:

  • Passwords cache in browser session storage.

Hiding encrypted pages from discovery surfaces

default:

  • Encrypted page titles and existence appear in discovery surfaces.

hide:

  • Set unlisted: true:
---
title: My Secret Page
password: mysecretpassword
unlisted: true
---

unlisted_pages: excluded: - contentIndex.json - sitemap.xml - RSS - backlinks - recent notes - folders - tags - bases - graph - explorer - search accessible: - Direct HTML URL. metadata: - static/encryptedContentIndex.json, encrypted with page password. post_decryption: - In-memory content index updates dynamically for graph, explorer, search. - Baked HTML lists remain hidden: backlinks, tag/folder pages, bases views. site_default: - unlistWhenEncrypted: true - Per-page override: unlisted: false

Note

non_encrypted_pages: UnlistedPages

Permanently hiding encrypted pages (stealth)

purpose:

  • Prevent post-decryption discovery mapping.

enable:

  • Set stealth: true:
---
title: Deep Secret
password: mysecretpassword
stealth: true
---

stealth_pages: excluded: - All discovery surfaces. shadow_index: - Skipped from encryptedContentIndex.json. post_decryption: - Remain hidden. implication: - stealth: true implies unlisted: true. scope: - No effect on non-encrypted pages.

Configuration

scope:

  • Options apply to transformer and emitter.

options: iterations: purpose: PBKDF2 iterations. default: 600000 passwordField: purpose: Frontmatter key. default: "password" unlistWhenEncrypted: purpose: Force unlisted. default: false outputPath: purpose: Shadow index path. default: "static/encryptedContentIndex.json"

Component options

component_options: className: purpose: Wrapper class. default: "encrypted-page-wrapper"

Default options

quartz.config.yaml
- source: github:quartz-community/encrypted-pages
  enabled: true
  options:
    iterations: 600000
    passwordField: password
    unlistWhenEncrypted: false
    outputPath: static/encryptedContentIndex.json

Warning

EncryptedPages replaces the HAST tree. order:

  • Run after HTML-reading plugins (e.g., CrawlLinks) via order.

Security

security: encryption: - AES-256-GCM - PBKDF2 SHA-256 plaintext: - Omitted from search, RSS, shadow index. shadow_index: - Flat array of opaque encrypted blobs. password_hygiene: - Avoid committing frontmatter passwords to public repositories. limitation: - Client-side static decryption does not protect against source-code access.

API

api: category: - Transformer - Emitter functions: - ExternalPlugin.EncryptedPages() - ExternalPlugin.EncryptedContentIndex() source: - quartz-community/encrypted-pages install: - npx quartz plugin add github:quartz-community/encrypted-pages