diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4344cc5..1b76508 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,58 +8,44 @@ on: jobs: build: - name: Build and sign + name: Build Site runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - with: - submodules: true - name: Setup Hugo uses: peaceiris/actions-hugo@v3 with: - hugo-version: "latest" + hugo-version: "0.161.1" extended: true - name: Setup Go + # Required by Hugo Modules to fetch the Hugo Blox theme on first build. uses: actions/setup-go@v5 with: - go-version: '1.22' - - - name: Build - run: hugo --minify + go-version: "1.22" - - name: Verify placeholder signed-sections exist - run: | - count=$(grep -rl ' placeholders" - if [ "$count" -lt 4 ]; then - echo "ERROR: Expected at least 4 pages with signed-section placeholders" - exit 1 - fi + - name: Setup Node.js + # Hugo Blox needs preact + tailwindcss + pagefind at build time. + uses: actions/setup-node@v4 + with: + node-version: "22" - - name: Install htmltrust-sign - run: go install github.com/HTMLTrust/htmltrust-hugo/cmd/htmltrust-sign@latest + - name: Install npm deps + run: npm install - - name: Sign content - env: - HTMLTRUST_SIGNING_KEY: ${{ secrets.HTMLTRUST_SIGNING_KEY }} + - name: Build site + # node_modules/.bin must be on PATH so the tailwindcss CLI resolves. run: | - htmltrust-sign --dir public --keyid did:web:jason-grey.com --domain www.htmltrust.org -v + export PATH="$PWD/node_modules/.bin:$PATH" + hugo --minify - - name: Verify signed sections are complete - run: | - if grep -rq 'data-htmltrust-placeholder' public/; then - echo "ERROR: placeholder markers remain - signer did not run on all sections" - exit 1 - fi - for f in $(grep -rl '` elements during the normal Hugo build — no external tools required. - -## Prerequisites - -- [Hugo](https://gohugo.io/installation/) (extended edition, v0.128.0+) - -## Local Development - -```sh -git clone https://github.com/ArcadeLabsInc/htmltrust-website.git -cd htmltrust-website -hugo server -D -``` - -The site will be available at `http://localhost:1313/`. The `-D` flag includes draft posts. - -## Build for Production - -```sh -hugo --minify -``` - -Output is written to `public/`. Every page with `htmltrust.sign: true` in its frontmatter automatically gets a `` element with a SHA-256 content hash and claim metadata — computed entirely by Hugo's template engine. - -## How Signing Works - -Each content page includes HTMLTrust metadata in its frontmatter: - -```yaml -htmltrust: - sign: true - claims: - ContentType: "Article" - License: "MIT" - AIAssistance: "Human+AI" -``` - -During `hugo build`, the `htmltrust-signed-section.html` partial: - -1. Canonicalizes the page content (strip HTML, collapse whitespace, trim) -2. Computes a SHA-256 hash using Hugo's built-in `sha256` function -3. Outputs a `` element after the article with the hash, author, timestamp, and claims - -The generated HTML looks like: - -```html - - - - - - -``` - -For full cryptographic signing (adding `signature`, `keyid`, and `algorithm` attributes), see the optional post-build script in the [Hugo CMS integration](https://github.com/ArcadeLabsInc/htmltrust-cms-reference/tree/main/hugo). - -## Content Structure - -``` -content/ -├── _index.md # Homepage -├── about/index.md # About HTMLTrust -├── architecture/index.md # System architecture overview -├── faq/index.md # Frequently asked questions -├── use-cases/index.md # Real-world application scenarios -└── posts/ # Blog posts -``` - -## Project Structure - -``` -├── hugo.toml # Site configuration -├── layouts/ -│ ├── _default/single.html # Override: adds signed-section after content -│ ├── page/single.html # Override: adds signed-section after content -│ └── partials/ -│ ├── head-additions.html # Injects HTMLTrust meta tags + CSS into -│ ├── htmltrust-meta.html # Reads htmltrust frontmatter → tags -│ └── htmltrust-signed-section.html # Core: computes hash, outputs -├── static/ -│ ├── css/custom.css # Custom styles (hero, features, signed-section) -│ └── images/architecture1.png # System architecture diagram -├── content/ # See "Content Structure" above -└── themes/ananke/ # Ananke theme (git submodule) -``` - -## Adding Content - -### New page - -```sh -hugo new content/my-page/index.md -``` - -### New blog post - -```sh -hugo new content/posts/my-post.md -``` - -Edit the frontmatter to set `draft: false` when ready to publish, and add `htmltrust.sign: true` to enable signing. - -## Theme - -The site uses the [Ananke](https://github.com/theNewDynamic/gohugo-theme-ananke) theme, installed as a Git submodule. To update: - -```sh -git submodule update --remote themes/ananke -``` - -## Companion Repositories - -| Repository | Description | -|---|---| -| [htmltrust-spec](https://github.com/ArcadeLabsInc/htmltrust-spec) | The HTMLTrust specification and paper | -| [htmltrust-server-reference](https://github.com/ArcadeLabsInc/htmltrust-server-reference) | Reference trust directory API server | -| [htmltrust-browser-reference](https://github.com/ArcadeLabsInc/htmltrust-browser-reference) | Reference browser extension for signature validation | -| [htmltrust-cms-reference](https://github.com/ArcadeLabsInc/htmltrust-cms-reference) | Reference CMS plugins (WordPress, Hugo) | - -## License - -MIT \ No newline at end of file diff --git a/archetypes/default.md b/archetypes/default.md deleted file mode 100644 index 25b6752..0000000 --- a/archetypes/default.md +++ /dev/null @@ -1,5 +0,0 @@ -+++ -date = '{{ .Date }}' -draft = true -title = '{{ replace .File.ContentBaseName "-" " " | title }}' -+++ diff --git a/assets/js/hb-mermaid-config.js b/assets/js/hb-mermaid-config.js new file mode 100644 index 0000000..069b50a --- /dev/null +++ b/assets/js/hb-mermaid-config.js @@ -0,0 +1,62 @@ +// HTMLTrust mermaid config — overrides Hugo Blox default. +// Blox's default reads Tailwind v4 CSS vars and wraps them in `rgb(...)`, +// producing `rgb(oklch(...))` which mermaid cannot parse. We use static hex +// values that read clearly on the dark site palette. + +window.mermaid.initialize({ + startOnLoad: true, + theme: "base", + themeVariables: { + // node backgrounds + text + background: "#0d1620", + primaryColor: "#142231", + primaryTextColor: "#e6edf3", + primaryBorderColor: "#4ca1af", + + secondaryColor: "#1f3346", + secondaryTextColor: "#e6edf3", + secondaryBorderColor:"#4ca1af", + + tertiaryColor: "#0a1018", + tertiaryTextColor: "#aab4be", + tertiaryBorderColor: "#2a3a4a", + + // flowchart specifics + mainBkg: "#142231", + nodeBorder: "#4ca1af", + clusterBkg: "#0a1018", + clusterBorder: "#2a3a4a", + titleColor: "#e6edf3", + lineColor: "#7a8aa0", + textColor: "#e6edf3", + edgeLabelBackground: "#0d1620", + + // sequence diagram specifics + actorBkg: "#142231", + actorBorder: "#4ca1af", + actorTextColor: "#e6edf3", + actorLineColor: "#7a8aa0", + signalColor: "#aab4be", + signalTextColor: "#e6edf3", + labelBoxBkgColor: "#1f3346", + labelBoxBorderColor: "#4ca1af", + labelTextColor: "#e6edf3", + loopTextColor: "#e6edf3", + noteBkgColor: "#1f3346", + noteTextColor: "#e6edf3", + noteBorderColor: "#4ca1af", + + fontFamily: getComputedStyle(document.documentElement).getPropertyValue("font-family"), + fontSize: "16px", + }, + flowchart: { + curve: "basis", + htmlLabels: true, + padding: 12, + }, + sequence: { + actorMargin: 50, + messageAlign: "center", + mirrorActors: false, + }, +}); diff --git a/assets/jsconfig.json b/assets/jsconfig.json new file mode 100644 index 0000000..6637a47 --- /dev/null +++ b/assets/jsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "*": [ + "../../../../../../.cache/hugo_cache/modules/filecache/modules/pkg/mod/github.com/!hugo!blox/kit/modules/blox@v0.0.0-20260502203050-b8ad5540288a/assets/*", + "../../../../../../.cache/hugo_cache/modules/filecache/modules/pkg/mod/github.com/!hugo!blox/kit/modules/blox@v0.0.0-20260502203050-b8ad5540288a/blox/*", + "../../../../../../.cache/hugo_cache/modules/filecache/modules/pkg/mod/github.com/!hugo!blox/kit/modules/blox@v0.0.0-20260502203050-b8ad5540288a/blox/shared/js/*" + ] + } + } +} \ No newline at end of file diff --git a/assets/media/authors/me.jpg b/assets/media/authors/me.jpg new file mode 100644 index 0000000..49337e4 Binary files /dev/null and b/assets/media/authors/me.jpg differ diff --git a/assets/media/icon.png b/assets/media/icon.png new file mode 100644 index 0000000..c0c5a39 Binary files /dev/null and b/assets/media/icon.png differ diff --git a/assets/media/icons/custom/.gitkeep b/assets/media/icons/custom/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/_default/hugo.yaml b/config/_default/hugo.yaml new file mode 100644 index 0000000..052a5fb --- /dev/null +++ b/config/_default/hugo.yaml @@ -0,0 +1,97 @@ +# Configuration of Hugo +# Guide: https://docs.hugoblox.com/tutorial/ +# Hugo Documentation: https://gohugo.io/getting-started/configuration/#all-configuration-settings +# This file is formatted using YAML syntax - learn more at https://learnxinyminutes.com/docs/yaml/ + +# Website name (set in params.yaml under hugoblox.branding.name) +title: '' +baseURL: 'https://example.com/' # Website URL + +############################ +## PAGE OPTIONS +############################ + +cascade: + # Docs folder options + - target: + path: /docs/** + editable: true + show_breadcrumb: true + # Hide date from Next In Series + show_date: false + # Show date modified at end of content + show_date_updated: true + # Blog post options + - target: + path: /blog/** + kind: page + pager: true + editable: true + show_date: true + show_date_updated: true + reading_time: true + commentable: true + show_related: true + share: true + # Just use Breadcrumb for navigation on blog post pages? + show_breadcrumb: false + header: + navbar: + enable: true + +############################ +## LANGUAGE +############################ + +defaultContentLanguage: en +hasCJKLanguage: false +defaultContentLanguageInSubdir: false +removePathAccents: true + +############################ +## ADVANCED +############################ + +build: + writeStats: true +enableGitInfo: false +summaryLength: 30 +pagination: + pagerSize: 10 +enableEmoji: true +enableRobotsTXT: true +footnotereturnlinkcontents: ^ +ignoreFiles: [".ipynb_checkpoints$", "\\.Rmd$", "\\.Rmarkdown$", "_cache$"] +enableInlineShortcodes: true +disableAliases: true +outputs: + home: [HTML, RSS, WebAppManifest, headers, redirects, backlinks] + page: [HTML] + section: [HTML, RSS] +imaging: + resampleFilter: lanczos + quality: 90 + anchor: smart + hint: picture +timeout: 600000 +taxonomies: + tag: tags + category: categories + author: authors +markup: + _merge: deep +related: + threshold: 80 + includeNewer: true + toLower: true + indices: + - name: tags + weight: 100 + - name: categories + weight: 70 +security: + _merge: deep +sitemap: + _merge: deep +minify: + _merge: deep diff --git a/config/_default/languages.yaml b/config/_default/languages.yaml new file mode 100644 index 0000000..11a461f --- /dev/null +++ b/config/_default/languages.yaml @@ -0,0 +1,22 @@ +# Languages +# Create a section for each of your site's languages. +# Documentation: https://docs.hugoblox.com/reference/language/ + +# Default language +en: + locale: en-us + # Uncomment for multi-lingual sites, and move English content into `en` sub-folder. + #contentDir: content/en + +# Uncomment the lines below to configure your website in a second language. +#zh: +# locale: zh-Hans +# contentDir: content/zh +# title: Chinese website title... +# params: +# description: Site description in Chinese... +# menu: +# main: +# - name: 传 +# url: '#about' +# weight: 1 diff --git a/config/_default/menus.yaml b/config/_default/menus.yaml new file mode 100644 index 0000000..f293577 --- /dev/null +++ b/config/_default/menus.yaml @@ -0,0 +1,28 @@ +main: + - name: Home + url: / + weight: 10 + - name: Spec + url: /spec/ + weight: 20 + - name: Architecture + url: /architecture/ + weight: 30 + - name: Implementation + url: /implementation/ + weight: 40 + - name: Use Cases + url: /use-cases/ + weight: 50 + - name: FAQ + url: /faq/ + weight: 60 + - name: Blog + url: /blog/ + weight: 70 + +sidebar: + - identifier: github + name: "GitHub ↗" + url: "https://github.com/HTMLTrust" + weight: 1 diff --git a/config/_default/module.yaml b/config/_default/module.yaml new file mode 100644 index 0000000..d404ab8 --- /dev/null +++ b/config/_default/module.yaml @@ -0,0 +1,28 @@ +############################ +## HUGO MODULES +## Install or uninstall themes and plugins here. +## Docs: https://gohugo.io/hugo-modules/ +############################ + +imports: + - path: github.com/HugoBlox/kit/modules/integrations/netlify + - path: github.com/HugoBlox/kit/modules/blox + +# Install any Hugo Blox within the `hugo-blox/blox/` folder +mounts: + - source: hugo-blox/blox/community + target: layouts/_partials/blox/community/ + files: + - '**.html' + - source: hugo-blox/blox/all-access + target: layouts/_partials/blox/ + files: + - '**.html' + - source: hugo-blox/blox + target: assets/dist/community/blox/ + files: + - '**.css' + - source: layouts + target: layouts + - source: assets + target: assets diff --git a/config/_default/params.yaml b/config/_default/params.yaml new file mode 100644 index 0000000..04eeb8b --- /dev/null +++ b/config/_default/params.yaml @@ -0,0 +1,279 @@ +# ══════════════════════════════════════════════════════════════════════════════ +# HUGO BLOX CONFIGURATION +# Schema: hugoblox.com/schema/v2 +# Tutorial: https://docs.hugoblox.com/tutorial/ +# Documentation: https://docs.hugoblox.com/ +# ══════════════════════════════════════════════════════════════════════════════ +hugoblox: + schema: "2.0" + + # ──────────────────────────────────────────────────────────────────────────── + # IDENTITY + # Site-level branding (for people/profiles, use the author system in content/authors/) + # ──────────────────────────────────────────────────────────────────────────── + identity: + name: "HTMLTrust" + organization: "HTMLTrust" + type: organization + tagline: "Decentralized trust and verifiable content on the web" + description: "HTMLTrust is a decentralized, standards-aligned framework for embedding cryptographic trust directly into HTML content. Authors sign blocks of HTML; browsers verify them locally; trust is a user-controlled, federated decision." + social: + twitter: "" + + # ──────────────────────────────────────────────────────────────────────────── + # THEME + # Color and visual design system + # ──────────────────────────────────────────────────────────────────────────── + theme: + # Mode: 'light', 'dark', or 'system' (follows OS preference) + mode: dark + pack: "default" + colors: + primary: "teal" # matches the deck's #4ca1af accent + secondary: "amber" + neutral: "slate" + # Optional: Mode-specific color overrides + colors_light: {} + colors_dark: {} + # Optional: Semantic surface color overrides + surfaces: + background: "" + foreground: "" + header: + background: "" + foreground: "" + footer: + background: "" + foreground: "" + + # ──────────────────────────────────────────────────────────────────────────── + # TYPOGRAPHY + # Font and text sizing + # ──────────────────────────────────────────────────────────────────────────── + typography: + # Theme pack: name from data/fonts/ + pack: "modern" + + # ──────────────────────────────────────────────────────────────────────────── + # LAYOUT + # Spacing and shape tokens + # ──────────────────────────────────────────────────────────────────────────── + layout: + # Border radius: 'none', 'sm', 'md', 'lg', or 'full' + radius: "md" + # Spacing density: 'compact', 'comfortable', or 'spacious' + spacing: "spacious" + # Avatar shape in author profiles + avatar_shape: circle # circle | square | rounded + + # ──────────────────────────────────────────────────────────────────────────── + # HEADER + # Site header and navigation bar + # ──────────────────────────────────────────────────────────────────────────── + header: + enable: true + # Header style variant + style: navbar # navbar | navbar-simple | minimal + # Stick to top on scroll + sticky: true + # Menu alignment + align: center # left | center | right + # Feature toggles + search: true + theme_toggle: true + theme_picker: false + language_switcher: true + # Call-to-action button + cta: + enable: false + text: "" + url: "" + + # ──────────────────────────────────────────────────────────────────────────── + # FOOTER + # Site footer + # ──────────────────────────────────────────────────────────────────────────── + footer: + style: minimal + language_switcher: false + text: 'Created by Jason Grey. Source on GitHub.' + + # ──────────────────────────────────────────────────────────────────────────── + # COPYRIGHT + # Legal notices and licensing + # ──────────────────────────────────────────────────────────────────────────── + copyright: + # Copyright notice - supports {year}, {name}, {license} placeholders + notice: "© {year} {name}. This work is licensed under {license}" + license: + type: cc # cc | custom + allow_derivatives: false + share_alike: true + allow_commercial: false + + # ──────────────────────────────────────────────────────────────────────────── + # SEO + # Search engine optimization - overrides and technical settings + # ──────────────────────────────────────────────────────────────────────────── + seo: + # Browser tab title override (defaults to identity.name if not set) + title: "" + # For local_business identity type only + location: + address: + street: "" + city: "" + region: "" + postal_code: "" + country: "" + coordinates: + latitude: null + longitude: null + phone: "" + # AI/LLM crawler guidance (llms.txt) + ai: + allow: + - / + disallow: [] + note: "Guidance for AI crawlers - customize to match your public content." + contact: "" + + # ──────────────────────────────────────────────────────────────────────────── + # CONTENT + # Content rendering and behavior + # ──────────────────────────────────────────────────────────────────────────── + content: + # Math rendering + math: + enable: false + # Table of contents + toc: + enable: true + # Reading time estimates + reading_time: + enable: true + # Academic citations + citations: + style: apa # apa | mla | chicago | ieee + + # ──────────────────────────────────────────────────────────────────────────── + # SEARCH + # Site search + # ──────────────────────────────────────────────────────────────────────────── + search: + enable: true + # Trending/suggested search terms + suggestions: [] + # Quick action shortcuts in search modal + quick_actions: [] + + # ──────────────────────────────────────────────────────────────────────────── + # COMMENTS + # User comments system + # ──────────────────────────────────────────────────────────────────────────── + comments: + enable: false + provider: "" # giscus | disqus + giscus: + repo: "" + repo_id: "" + category: "" + category_id: "" + disqus: + shortname: "" + + # ──────────────────────────────────────────────────────────────────────────── + # ANALYTICS + # Traffic and behavior analytics + # ──────────────────────────────────────────────────────────────────────────── + analytics: + google: + measurement_id: "" # Google Analytics 4: G-XXXXXXXXXX + google_tag_manager: + container_id: "" # GTM-XXXXXXX + plausible: + domain: "" + fathom: + site_id: "" + pirsch: + site_id: "" + clarity: + project_id: "" + baidu: + site_id: "" + + # ──────────────────────────────────────────────────────────────────────────── + # VERIFICATION + # Search engine site verification codes + # ──────────────────────────────────────────────────────────────────────────── + verification: + google: "" + bing: "" + baidu: "" + yandex: "" + pinterest: "" + naver: "" + + # ──────────────────────────────────────────────────────────────────────────── + # REPOSITORY + # Source code repository for "Edit this page" links + # ──────────────────────────────────────────────────────────────────────────── + repository: + enable: false + url: "" # e.g., https://github.com/username/repo + branch: main + content_dir: content + + # ──────────────────────────────────────────────────────────────────────────── + # LOCALE + # Regional formatting preferences + # ──────────────────────────────────────────────────────────────────────────── + locale: + date_format: "Jan 2, 2006" # Go time format + time_format: "3:04 PM" + address_format: en-us + + # ──────────────────────────────────────────────────────────────────────────── + # SECURITY + # Security headers and policies (requires Netlify integration) + # ──────────────────────────────────────────────────────────────────────────── + security: + csp: + policy: "" + report_only: false + frame_options: allow # deny | sameorigin | allow - allow enables iframe embedding + permissions_policy: "" + + # ──────────────────────────────────────────────────────────────────────────── + # PRIVACY + # Privacy and compliance features + # ──────────────────────────────────────────────────────────────────────────── + privacy: + enable: false + anonymize_analytics: true + + # ──────────────────────────────────────────────────────────────────────────── + # DEBUG + # Development and debugging (hidden in production) + # ──────────────────────────────────────────────────────────────────────────── + debug: + enable: false + hud: + position: bottom-left # top-left | top-right | bottom-left | bottom-right + opacity: 1.0 + export_logs: true + + # ──────────────────────────────────────────────────────────────────────────── + # PREMIUM + # Premium features and creator program (affiliates) + # ──────────────────────────────────────────────────────────────────────────── + pro: + # Hide "Powered by HugoBlox" attribution + # Requires: HugoBlox Premium to support HugoBlox via alternative means + # Note: Even with Premium, you can keep this false to support open source! + # Get Premium: https://hugoblox.com/premium + hide_attribution: false + + # Affiliate referral code for rewards program + # Join affiliate program: https://hugoblox.com/affiliates + affiliate_code: "" diff --git a/content/_index.md b/content/_index.md index 43c7c1e..bf59fa6 100644 --- a/content/_index.md +++ b/content/_index.md @@ -1,88 +1,191 @@ --- -title: "HTMLTrust" -description: "Decentralized Trust and Verifiable Content on the Web" -date: 2025-05-12 -draft: false -htmltrust: - sign: true - claims: - ContentType: "Information" - License: "MIT" - AIAssistance: "Human+AI" ---- - - +title: 'HTMLTrust' +date: 2026-05-13 +type: landing -
-

HTMLTrust

-

Decentralized trust and verifiable content on the web

- -
+sections: + # ───────────────────────────────────────────────────────────────────────────── + # 1. HERO — the pitch + # ───────────────────────────────────────────────────────────────────────────── + - block: hero + content: + title: 'Cryptographic authorship for the open web' + text: 'HTMLTrust embeds cryptographic trust directly into HTML. Authors sign blocks of content; browsers verify them locally; trust is a user-controlled, federated decision. Lightweight, browser-native, and standards-aligned.' + primary_action: + text: 'Read the spec' + url: /spec/ + icon: document-text + secondary_action: + text: 'GitHub' + url: https://github.com/HTMLTrust + icon: code-bracket + announcement: + text: 'A proposal for the open web · 2026.' + link: + text: 'Read the announcement' + url: /blog/paper-published/ + design: + spacing: + padding: [0, 0, 0, 0] + margin: [0, 0, 0, 0] + css_class: '' -
-

Verify Content Authenticity

-

HTMLTrust allows content creators to cryptographically sign regions of web pages and include identity-linked metadata in-band. It's lightweight, browser-compatible, and web-native — designed to scale across publishing workflows, civic media, and knowledge networks.

-
+ # ───────────────────────────────────────────────────────────────────────────── + # 2. STATS — quick facts + # ───────────────────────────────────────────────────────────────────────────── + - block: stats + content: + items: + - statistic: '0' + description: | + Central + authorities + - statistic: '8' + description: | + Canonicalization + phases + - statistic: '4+' + description: | + Reference + implementations + - statistic: '∞' + description: | + Federated + trust directories + design: + css_class: 'bg-gray-100 dark:bg-gray-800' + spacing: + padding: ['2rem', 0, '2rem', 0] -
-
-
🔏
-

Signed Sections

-

Embed cryptographic trust directly into HTML with the proposed <signed-section> element.

-
+ # ───────────────────────────────────────────────────────────────────────────── + # 3. THE PROBLEM + # ───────────────────────────────────────────────────────────────────────────── + - block: features + id: problem + content: + title: 'The problem' + text: 'TLS certifies the domain. Nothing on the web certifies the **author**. As generative AI makes plausible-looking text effectively free and content travels faster than corrections, the cost of not being able to verify authorship keeps rising.' + items: + - name: 'TLS proves the domain, not the author' + icon: lock-closed + description: 'A green padlock means the bytes came from the claimed server. It says nothing about who wrote them.' + - name: 'AI-generated text is everywhere' + icon: cpu-chip + description: 'Plausible-sounding prose is now effectively free. Readers cannot tell human writing from synthetic on the page alone.' + - name: 'Republishing strips attribution' + icon: arrow-path + description: 'Articles are scraped, mirrored, and screenshotted. The original author and the original site routinely get lost.' + - name: 'Mirror sites travel faster than corrections' + icon: bolt + description: 'By the time a piece is updated or retracted, copies have already spread to dozens of other hosts.' + design: + layout: grid -
-
🔗
-

Decentralized Identity

-

Signatures validated using public key infrastructure (PKI) such as DIDs — no central authority required.

-
+ # ───────────────────────────────────────────────────────────────────────────── + # 4. WHAT WE ARE NOT + # ───────────────────────────────────────────────────────────────────────────── + - block: features + id: not + content: + title: 'What HTMLTrust is *not*' + text: 'Clear scope is half of any good standard. Here is what we are deliberately not doing.' + items: + - name: 'Not DRM' + icon: x-mark + description: 'We do not restrict access, copying, or display. Content stays open. Signatures are inert metadata.' + - name: 'Not anti-AI' + icon: x-mark + description: 'Signed metadata describes AI involvement; it does not ban it. Authors choose what to disclose.' + - name: 'Not blockchain' + icon: x-mark + description: 'Standard public-key cryptography. No ledger, no tokens, no consensus, no proof-of-anything.' + - name: 'Not a gatekeeper' + icon: x-mark + description: 'No central authority. No verified-checkmark monopoly. Trust is local to each user agent.' + - name: 'Not a truth oracle' + icon: x-mark + description: 'A signature proves *who said it*, not that *it is true*. Trust is a continuum, not a verdict.' + design: + layout: grid + css_class: 'bg-gray-50 dark:bg-gray-900/40' -
-
-

Trust Directories

-

Optional federated directories for third-party endorsements, key discovery, and reputation tracking.

-
-
+ # ───────────────────────────────────────────────────────────────────────────── + # 5. CORE PRINCIPLES + # ───────────────────────────────────────────────────────────────────────────── + - block: features + id: principles + content: + title: 'Five principles' + text: 'A handful of decisions shape everything else.' + items: + - name: 'Sign blocks, not pages' + icon: code-bracket-square + description: 'A single page can host many signed regions from many different authors. Forums, collaborative articles, mixed editorial content — all work.' + - name: 'Pluggable identity' + icon: identification + description: 'DIDs, key URLs, directory references — implementations must accept multiple methods. No canonical identity provider.' + - name: 'Client-side trust' + icon: user-circle + description: 'The user agent decides. A signature either verifies cryptographically or it does not, but trust is a matter of degree set by the reader.' + - name: 'Federated directories' + icon: globe-alt + description: 'Trust directories are optional, multiple, and never required to verify. Users choose which ones to consult and at what weight.' + - name: 'Web-native' + icon: document-check + description: 'A standard HTML element, graceful fallback in unaware browsers, no plug-in lock-in. Layered on the web as it exists.' + design: + layout: grid -
-

The Problem

-

The web lacks a standardized mechanism for proving who wrote a given piece of content. TLS certifies the domain, but not the author. As AI-generated and republished material becomes ubiquitous, users face increasing difficulty determining what content is trustworthy.

+ # ───────────────────────────────────────────────────────────────────────────── + # 6. HOW IT FITS WITH PRIOR ART + # ───────────────────────────────────────────────────────────────────────────── + - block: comparison-table + id: standards + content: + subtitle: 'Prior art' + title: 'How HTMLTrust fits in' + text: 'HTMLTrust borrows from decades of cryptographic and content-integrity work. It does not replace any of it.' + competitors: + - name: 'HTMLTrust' + tagline: 'HTML blocks' + is_you: true + badge: 'this work' + - name: 'TLS' + tagline: 'Channel' + - name: 'DKIM' + tagline: 'Email' + - name: 'PGP' + tagline: 'Identity' + - name: 'C2PA' + tagline: 'Media' + rows: + - feature: 'Proves authorship of HTML content' + values: [true, false, false, 'partial', false] + - feature: 'Web-native (renders in browsers)' + values: [true, true, false, false, 'partial'] + - feature: 'Block-level granularity' + values: [true, false, false, false, false] + - feature: 'No central authority' + values: [true, false, true, true, true] + - feature: 'Optional federated reputation' + values: [true, false, false, false, false] + - feature: 'Graceful degradation in unaware clients' + values: [true, 'partial', true, false, 'partial'] + design: + row_striping: true -
-
-

Content Producers

-

Need to protect their work from theft and misuse

-
-
-

Content Consumers

-

Need to trust the content they read

-
-
-

LLM Builders

-

Need high-quality, human-generated training data — and to respect author preferences

-
-
-

Web Researchers

-

Need to distinguish between human and AI-generated content

-
-
-
- -
-

How It Works

-
-
<signed-section keyid="did:web:author.example"
-    signature="BASE64_SIG" algorithm="ed25519"
-    content-hash="sha256:abc123...">
-  <meta name="author" content="Alice Example">
-  <article>
-    <h1>Verifiable Web Content</h1>
-    <p>Content should be provable...</p>
-  </article>
-</signed-section>
-
-

Authors sign content blocks. Browsers verify signatures. Trust directories track reputation. Learn more →

-
\ No newline at end of file + # ───────────────────────────────────────────────────────────────────────────── + # 7. CTA + # ───────────────────────────────────────────────────────────────────────────── + - block: cta-card + content: + title: 'Ready to look under the hood?' + text: 'The spec defines a single new HTML element, four required attributes, an 8-phase canonicalization algorithm, and a federation model for optional trust directories. Reference implementations exist for browsers, CMSes, and trust directory servers.' + button: + text: 'Read the spec' + url: /spec/ + design: + card: + css_class: 'bg-primary-700' + css_style: '' +--- diff --git a/content/about/index.md b/content/about/index.md deleted file mode 100644 index 651fbe4..0000000 --- a/content/about/index.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: "About HTMLTrust" -description: "A decentralized framework for embedding cryptographic trust directly into HTML content" -date: 2025-05-12 -draft: false -htmltrust: - sign: true - claims: - ContentType: "Information" - License: "MIT" - AIAssistance: "Human+AI" ---- - -## What Is HTMLTrust? - -HTMLTrust is a decentralized, standards-aligned framework for embedding cryptographic trust directly into HTML content. Using a proposed `` element, content creators and publishing platforms can sign semantically meaningful regions of web pages and include identity-linked metadata in-band. - -Signatures are validated using public key infrastructure (PKI) such as [DIDs](https://www.w3.org/TR/did-core/), and can be enhanced with third-party endorsements submitted to optional, federated trust directories. - -Unlike blockchain-based or DRM-centric systems, HTMLTrust is **lightweight, browser-compatible, and web-native** — designed to scale across publishing workflows, civic media, and knowledge networks. - -## Why Is This Needed? - -The web lacks a standardized mechanism for proving who wrote a given piece of content. TLS certifies the domain, but not the author. As AI-generated and republished material becomes ubiquitous, users face increasing difficulty determining what content is trustworthy. - -Existing methods like digital signatures (e.g., DKIM, PGP) and content fingerprinting (e.g., ISCC) offer pieces of the solution but do not integrate cleanly with web-native publishing workflows or browser verification. - -## Who Benefits? - -- **Content producers** who need to protect their work from theft and misuse -- **Content consumers** who need to trust the content they read -- **LLM builders** who need high-quality, human-generated training data and want to respect author preferences -- **Web researchers** who need to distinguish between human and AI-generated content -- **Journalists and news organizations** who need to verify sources and track article spread -- **Academic institutions** who need to detect plagiarism and verify research materials - -## How It Works - -1. **Authors sign content** — A CMS or publishing tool normalizes the content, computes a hash, and signs it with the author's private key -2. **Signatures are embedded in HTML** — The `` element wraps the content with the signature, author key reference, and content hash -3. **Browsers verify** — Browser extensions (or eventually native browser support) validate signatures and display trust indicators -4. **Trust directories track reputation** — Optional federated servers index signatures, serve endorsements, and support key discovery - -## Project Status - -HTMLTrust is an early-stage open-source project. The current state: - -- ✅ [Specification / research paper](https://github.com/ArcadeLabsInc/htmltrust-spec) published -- ✅ [Reference trust directory server](https://github.com/ArcadeLabsInc/htmltrust-server-reference) (Node.js + MongoDB) -- ✅ [Reference browser extension](https://github.com/ArcadeLabsInc/htmltrust-browser-reference) (Chrome — Firefox and Safari planned) -- ✅ [CMS plugins](https://github.com/ArcadeLabsInc/htmltrust-cms-reference) (WordPress — Hugo and others planned) -- ⬜ Formal W3C proposal for extending HTML with signed sections -- ⬜ Standardized canonicalization algorithm -- ⬜ Production-ready trust directory network - -## Planned Work - -- Research on metadata schema and cryptographic primitives -- Further refinement of canonicalization algorithms -- A formal proposal to the W3C for extending HTML with signed sections -- Additional browser and CMS integrations -- Research into implementing this framework in news feeds and aggregation platforms - -## Author - -HTMLTrust was created by **Jason Grey** ([jason@jason-grey.com](mailto:jason@jason-grey.com)). - -Contributions are welcome — visit the [GitHub repositories](https://github.com/ArcadeLabsInc) to get involved. \ No newline at end of file diff --git a/content/architecture/_index.md b/content/architecture/_index.md new file mode 100644 index 0000000..94483da --- /dev/null +++ b/content/architecture/_index.md @@ -0,0 +1,122 @@ +--- +title: 'System architecture' +description: 'How authors, CMSes, browsers, crawlers, and federated trust directories interact.' +date: 2026-05-13 +--- + +HTMLTrust is a system of small, independent pieces. Authors sign content. CMSes embed signatures. Browsers verify locally. Optional directories store endorsements and surface reputation. No piece is required for verification to work. + +## The whole system, one diagram + +```mermaid +flowchart TD + A((Author)) -->|manage keys| B[Web browser] + A -->|author content| C[CMS] + B -->|provide public key| C + C -->|request signature| B + C -->|deliver page| P[/"Pages with
signed blocks"/] + P -->|viewed| Br[Reader's browser] + P -->|crawled| Cr[Crawler] + Br -->|verify locally| Val{{Trust score}} + Cr -->|extract & verify| Re[Researcher] + C -. publish keys & hashes .-> Dir[(Trust directories)] + Br -. query reputation .-> Dir + Re -. flag bad keys .-> Dir +``` + +## Two layers, kept separate + +```mermaid +flowchart TB + subgraph L1["🔒 Layer 1 — Cryptographic verification (local)"] + C1[Canonicalize content] --> H1[Hash] + H1 --> S1[Verify signature against resolved key] + S1 --> R1{Valid?} + end + subgraph L2["⚖️ Layer 2 — Trust decision (user policy)"] + P1[Trust list] --> D1[Score] + P2[Endorsements] --> D1 + P3[Directory reputation] --> D1 + D1 --> UI[UI indicator] + end + R1 -- "yes" --> L2 + R1 -- "no" --> X[Reject] +``` + +A signature either verifies cryptographically or it does not — that part is binary, local, and identical across implementations. **Trust** is a matter of degree, and each user agent applies its own policy on top. + +## Author flow — signing + +```mermaid +sequenceDiagram + autonumber + participant A as Author + participant B as Browser (key holder) + participant C as CMS + participant D as Directory (optional) + A->>C: Write content + C->>C: Canonicalize text + C->>C: Compute content-hash + claims-hash + C->>B: Request signature over payload + B->>B: Sign with private key + B-->>C: signature + C->>C: Embed + C-->>A: Publish page + C-->>D: Publish hash + keyid (optional) +``` + +The private key never leaves the author's browser. The CMS asks the browser to sign a canonical payload, receives the signature, and embeds it in the published HTML. + +## Reader flow — verifying + +```mermaid +sequenceDiagram + autonumber + participant U as Reader's browser + participant P as Page origin + participant K as Key resolver + participant D as Directory (optional) + U->>P: GET page + P-->>U: HTML with + U->>U: Canonicalize text → hash + U->>K: Resolve keyid + K-->>U: Public key + U->>U: Verify signature (local) + U->>D: Query reputation / endorsements (optional) + D-->>U: Endorsements + reputation + U->>U: Apply user trust policy → score +``` + +Cryptographic verification is offline-capable once the public key is cached. The directory query is optional and only feeds the *trust score*, not the signature check. + +## Domain binding + +```mermaid +flowchart LR + O["`author.com + *signed content*`"] -. "mirror without permission" .-> M[scraper.com] + M --> X["`❌ Signature + fails domain bind`"] + O --> R["`republisher.com + *wraps with own sig*`"] --> V[✅ Attribution chain] + style X stroke:#ef4444,color:#ef4444 + style V stroke:#4ade80,color:#4ade80 +``` + +A signature is bound to a publication origin via the canonical payload. Scrapers and mirror sites can copy the bytes, but the signature will not validate at a different origin. Legitimate republishing is supported via a separate mechanism: a republisher wraps the original `` in their own outer signature, preserving the original while adding an attribution chain. + +## The directory's role + +A trust directory MAY: + +- **Index** content hashes and signers for discovery +- **Serve** endorsements submitted by third parties +- **Resolve** keys for authors who don't self-host (`keyid` can point at a directory entry) +- **Surface** reputation signals computed from its own curated trust graph + +Federation means **many directories can coexist**, users choose which they trust at the higher level, and verification of a signature never requires contacting one. A directory is a convenience, never an authority. + +## Next + +- **[Spec details](/spec/)** — element, attributes, canonicalization +- **[Reference implementations](/implementation/)** — what's running today diff --git a/content/architecture/index.md b/content/architecture/index.md deleted file mode 100644 index 79c5eed..0000000 --- a/content/architecture/index.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: "System Architecture" -description: "How the HTMLTrust system components work together" -date: 2025-05-12 -draft: false -htmltrust: - sign: true - claims: - ContentType: "Technical" - License: "MIT" - AIAssistance: "Human+AI" ---- - -## Overview - -HTMLTrust is a system for decentralized content authenticity, authorship claims, and endorsement. It defines a method for authors to sign content blocks in HTML, supported by canonicalization rules and cryptographic integrity checks, along with an endorsement and discovery model via public trust directories. - -![HTMLTrust System Architecture](/images/architecture1.png) - -## Signed HTML Blocks - -A proposed new tag, ``, encapsulates a signed region of a page. This tag includes: - -- **Canonicalized content** — e.g., a blog post or paragraph -- **Metadata** — author identity (e.g., via [DID](https://www.w3.org/TR/did-core/)), timestamp, content hash -- **Signature** — Base64-encoded digital signature of content + metadata - -```html - - - -
-

Verifiable Web Content

-

Content should be provable...

-
-
-``` - -## Canonicalization - -To ensure consistent signing and verification, content is canonicalized before hashing: - -1. Normalize whitespace, strip extra line breaks -2. Sort HTML attributes and metadata -3. Minify and serialize as a UTF-8 string -4. Generate both SHA-256 hash and SimHash for similarity detection - -## Trust Directory (Optional) - -Signed content MAY be submitted to one or more trust directories that: - -- Index content hashes and associated signers -- Store and serve third-party endorsements -- Support key resolution and optional revocation - -## Endorsements - -Third parties (publishers, experts, other users) can issue signed JSON endorsements of specific content hashes: - -```json -{ - "endorser": "did:web:publisher.org", - "endorsement": "sha256-XYZ", - "signature": "BASE64_SIG", - "timestamp": "2025-05-01T00:00Z" -} -``` - -## Browser Integration - -Browser extensions (and eventually native browser support) verify: - -- Signature validity via embedded or discovered public key -- Match of content hash to canonicalized DOM -- Trust status of signer and any endorsements - -Trust configuration is client-side. UI indicators reflect verification status (e.g., a verified badge or a warning tooltip). - -## CMS Integration - -Content management systems generate: - -- Canonicalized content blocks -- Embedded signatures from author keys -- Optional submissions to trust directories - -Reference implementations are available for [WordPress](https://github.com/ArcadeLabsInc/htmltrust-cms-reference) with Hugo and other CMS support planned. - -## Reference Implementations - -| Component | Repository | Status | -|---|---|---| -| Specification | [htmltrust-spec](https://github.com/ArcadeLabsInc/htmltrust-spec) | ✅ Published | -| Trust Directory Server | [htmltrust-server-reference](https://github.com/ArcadeLabsInc/htmltrust-server-reference) | ✅ Reference implementation | -| Browser Extension | [htmltrust-browser-reference](https://github.com/ArcadeLabsInc/htmltrust-browser-reference) | ✅ Chrome (Firefox/Safari planned) | -| CMS Plugins | [htmltrust-cms-reference](https://github.com/ArcadeLabsInc/htmltrust-cms-reference) | ✅ WordPress (Hugo planned) | \ No newline at end of file diff --git a/content/authors/_index.md b/content/authors/_index.md new file mode 100644 index 0000000..853f3ed --- /dev/null +++ b/content/authors/_index.md @@ -0,0 +1,9 @@ +--- +# To publish author profile pages, remove all the `build` and `cascade` settings below. +build: + render: never +cascade: + build: + render: never + list: always +--- diff --git a/content/blog/_index.md b/content/blog/_index.md new file mode 100644 index 0000000..f040c7e --- /dev/null +++ b/content/blog/_index.md @@ -0,0 +1,5 @@ +--- +title: Blog +view: date-title-summary +url: /blog/ +--- diff --git a/content/posts/paper-published.md b/content/blog/paper-published/index.md similarity index 50% rename from content/posts/paper-published.md rename to content/blog/paper-published/index.md index 818f441..f52b046 100644 --- a/content/posts/paper-published.md +++ b/content/blog/paper-published/index.md @@ -1,42 +1,39 @@ --- -title: "Research Paper Published: Toward Decentralized Trust and Verifiable Content on the Web" -description: "The foundational HTMLTrust research paper is now available" -date: 2025-05-12 -draft: true -tags: ["paper", "specification", "announcement"] -htmltrust: - sign: true - claims: - ContentType: "Article" - License: "MIT" - AIAssistance: "Human+AI" +title: 'Research paper published: Toward Decentralized Trust and Verifiable Content on the Web' +summary: 'The foundational HTMLTrust research paper is now available.' +date: 2026-04-01 +authors: + - jason +tags: + - paper + - specification + - announcement --- -We're pleased to share the publication of our research paper, *Toward Decentralized Trust and Verifiable Content on the Web*, which lays out the technical foundation for the HTMLTrust project. +We're pleased to share the publication of *Toward Decentralized Trust and Verifiable Content on the Web*, the paper that lays out the technical foundation for the HTMLTrust project. -## Paper Abstract +## Abstract > We propose a decentralized, standards-aligned framework for embedding cryptographic trust directly into HTML content. Using a new `` element, content creators and publishing platforms can sign semantically meaningful regions of web pages and include identity-linked metadata in-band. Signatures are validated using public key infrastructure (PKI) such as DIDs, and can be enhanced with third-party endorsements submitted to optional, federated trust directories. We introduce a simple canonicalization method for content normalization and outline how browsers and CMS systems can support user-configured web-of-trust policies for live content validation. Unlike blockchain-based or DRM-centric systems, our approach is lightweight, browser-compatible, and web-native — designed to scale across publishing workflows, civic media, and knowledge networks. -## Key Contributions - -The paper introduces: +## Key contributions 1. A proposed `` HTML element for encapsulating signed regions of a page 2. A canonicalization algorithm for consistent content normalization 3. A trust model supporting both direct signature verification and third-party endorsements 4. Integration paths for browsers and content management systems -## Reference Implementations +## Reference implementations Alongside the paper, we've published reference implementations: -- **[Trust Directory Server](https://github.com/ArcadeLabsInc/htmltrust-server-reference)** — Node.js + MongoDB API for author management, content signing, verification, and reputation tracking -- **[Browser Extension](https://github.com/ArcadeLabsInc/htmltrust-browser-reference)** — Chrome extension for client-side signature validation -- **[CMS Plugins](https://github.com/ArcadeLabsInc/htmltrust-cms-reference)** — WordPress plugin and Hugo integration for server-side content signing +- **[Trust Directory Server](https://github.com/HTMLTrust/htmltrust-server-reference)** — Node.js + MongoDB API for author management, content signing, verification, and reputation tracking +- **[Browser Extension](https://github.com/HTMLTrust/htmltrust-browser-reference)** — Chrome extension for client-side signature validation +- **[CMS Plugins](https://github.com/HTMLTrust/htmltrust-cms-reference)** — WordPress plugin and Hugo integration for server-side content signing +- **[Canonicalization Libraries](https://github.com/HTMLTrust/htmltrust-canonicalization)** — JavaScript, Go, and PHP implementations, all passing the same conformance suite -## Read the Paper +## Read the paper -The paper and its LaTeX source are available in the [htmltrust-spec](https://github.com/ArcadeLabsInc/htmltrust-spec) repository. +The paper and its LaTeX source are available in the [htmltrust-spec](https://github.com/HTMLTrust/htmltrust-spec) repository. -We welcome feedback and contributions. Visit the [GitHub repositories](https://github.com/ArcadeLabsInc) to get involved, or reach out at [jason@jason-grey.com](mailto:jason@jason-grey.com). \ No newline at end of file +We welcome feedback and contributions. Visit the [GitHub repositories](https://github.com/HTMLTrust) to get involved, or reach out at [jason@jason-grey.com](mailto:jason@jason-grey.com). diff --git a/content/faq/index.md b/content/faq/_index.md similarity index 73% rename from content/faq/index.md rename to content/faq/_index.md index 438e3cd..48789cd 100644 --- a/content/faq/index.md +++ b/content/faq/_index.md @@ -1,14 +1,7 @@ --- -title: "Frequently Asked Questions" -description: "Common questions about HTMLTrust and content verification" -date: 2025-05-12 -draft: false -htmltrust: - sign: true - claims: - ContentType: "Information" - License: "MIT" - AIAssistance: "Human+AI" +title: 'Frequently asked questions' +description: 'Common questions about HTMLTrust and content verification.' +date: 2026-05-13 --- ## What is HTMLTrust? @@ -35,7 +28,7 @@ HTMLTrust proposes a new HTML element, ``, that wraps a signed r 2. Metadata (author identity via DID, timestamp, content hash) 3. A Base64-encoded digital signature -Browsers (via extensions) verify the signature against the author's public key and display trust indicators. +Browsers (via extensions) verify the signature against the author's public key and display trust indicators. See the [spec](/spec/) for the exact attribute schema. ## What cryptographic algorithms are supported? @@ -45,15 +38,15 @@ The system supports multiple algorithms: - **RSA** (2048-bit+) - **ECDSA** (secp256k1) -The system is algorithm-agnostic and specified via the `algorithm` attribute. +The system is algorithm-agnostic and specified via the `algorithm` attribute on each ``. ## Does it require blockchain? -No. HTMLTrust uses standard public key cryptography and works with existing web infrastructure. It can optionally integrate with decentralized identity systems like DIDs, but blockchain is not required. +No. HTMLTrust uses standard public-key cryptography and works with existing web infrastructure. It can optionally integrate with decentralized identity systems like DIDs, but blockchain is not required, used, or planned. ## Can I sign only parts of a page? -Yes — that's a core feature. Each `` is independent, so a single page can have multiple signed blocks from different authors (e.g., a forum, a collaborative article, or a page with editorial and user-generated content). +Yes — that is a core feature. Each `` is independent, so a single page can have multiple signed blocks from different authors (e.g., a forum, a collaborative article, or a page with editorial and user-generated content). ## What happens in browsers that don't support it? @@ -65,7 +58,7 @@ A reference browser extension is available for **Chrome** (and Chromium-based br ## What CMS platforms are supported? -A reference plugin exists for **WordPress**. Hugo integration is planned, and the architecture supports any CMS that can call an HTTP API and embed HTML attributes. See the [CMS reference repository](https://github.com/ArcadeLabsInc/htmltrust-cms-reference) for details. +A reference plugin exists for **WordPress**. Hugo integration is planned, and the architecture supports any CMS that can call an HTTP API and embed HTML attributes. See the [CMS reference repository](https://github.com/HTMLTrust/htmltrust-cms-reference) for details. ## How does HTMLTrust handle AI-generated content? @@ -80,7 +73,7 @@ These claims are signed by the author, providing a cryptographically verifiable ## Can HTMLTrust prevent AI training on my content? -HTMLTrust metadata can include explicit AI training preferences (aligned with emerging standards like [Content Preferences](https://datatracker.ietf.org/doc/draft-vaughan-aipref-vocab/)). While technical enforcement depends on AI developers respecting these signals, HTMLTrust provides a standardized, cryptographically signed way to express creator preferences. +HTMLTrust metadata can include explicit AI training preferences (aligned with emerging standards like [Content Preferences](https://datatracker.ietf.org/doc/draft-vaughan-aipref-vocab/)). Technical enforcement depends on AI developers respecting the signals, but HTMLTrust provides a standardized, cryptographically signed way to express creator preferences — distinct from a `robots.txt` that can be silently stripped. ## Is HTMLTrust an official web standard? @@ -88,7 +81,7 @@ Not yet. A formal proposal to the W3C for extending HTML with signed sections is ## How can I get involved? -- Browse the [GitHub repositories](https://github.com/ArcadeLabsInc) for the spec, server, browser extension, and CMS plugins +- Browse the [GitHub repositories](https://github.com/HTMLTrust) for the spec, server, browser extension, and CMS plugins - Open issues or pull requests -- Try the reference implementations and provide feedback -- Contact [jason@jason-grey.com](mailto:jason@jason-grey.com) with questions or collaboration ideas \ No newline at end of file +- Try the [reference implementations](/implementation/) and provide feedback +- Contact [jason@jason-grey.com](mailto:jason@jason-grey.com) with questions or collaboration ideas diff --git a/content/implementation/_index.md b/content/implementation/_index.md new file mode 100644 index 0000000..53a8726 --- /dev/null +++ b/content/implementation/_index.md @@ -0,0 +1,127 @@ +--- +title: 'Reference implementations' +description: 'Open-source code for every layer — browser, CMS, server, canonicalization.' +date: 2026-05-13 +--- + +Reference implementations exist for every layer of the system. All are MIT-licensed and live under the [HTMLTrust GitHub organization](https://github.com/HTMLTrust). + +## Canonicalization libraries + +Same canonical output across languages — every implementation passes the same conformance corpus. + +| Language | Repo | Dependencies | Used by | +|---|---|---|---| +| JavaScript | [htmltrust-canonicalization/javascript](https://github.com/HTMLTrust/htmltrust-canonicalization/tree/main/javascript) | None (browser + Node) | Browser extension, Hugo signing script | +| Go | [htmltrust-canonicalization/go](https://github.com/HTMLTrust/htmltrust-canonicalization/tree/main/go) | `golang.org/x/text` (NFKC) | Hugo module | +| PHP | [htmltrust-canonicalization/php](https://github.com/HTMLTrust/htmltrust-canonicalization/tree/main/php) | `ext-intl`, `ext-mbstring` | WordPress plugin | + +Rust and Python ports are in progress. The shared conformance suite ensures byte-identical output for the same input across every implementation. + +```js +// JavaScript +import { normalizeText } from '@htmltrust/canonicalization'; +const canonical = normalizeText('He said, "Hello…"'); +// → 'He said, "Hello..."' +``` + +## Trust directory server + +**[htmltrust-server-reference](https://github.com/HTMLTrust/htmltrust-server-reference)** + +- **Stack:** Node.js, OpenAPI-first, MongoDB +- **Endpoints:** keys, content hashes, endorsements, reputation +- **Federation:** directories can mirror and cross-reference each other +- **Conformance suite** for interop with other directory implementations +- **Second-language port** (Rust/Python) in tree + +A directory is optional infrastructure. Verifying a signature never requires contacting one — only key resolution (when the `keyid` points at a directory) and reputation lookup do. + +## Browser extension + +**[htmltrust-browser-reference](https://github.com/HTMLTrust/htmltrust-browser-reference)** + +Chrome (Chromium-based browsers including Edge). Firefox and Safari ports planned. + +- Scans every page for `` elements +- Canonicalizes and hashes locally — no network call for verification +- Resolves `keyid` by the configured method (DID, URL, directory) +- Renders a per-block trust badge with hover detail +- User trust policy editable in the options page + +The eventual goal is native browser support via a W3C standard. The extension is the stepping stone. + +## CMS plugins + +**[htmltrust-cms-reference](https://github.com/HTMLTrust/htmltrust-cms-reference)** + +- **WordPress** — production-ready reference plugin +- **Hugo** — module + signing script +- Architecture supports any CMS that can call an HTTP API and embed HTML attributes + +Author workflow: + +1. Write a post normally +2. Plugin canonicalizes the post body +3. Browser-side key signs the canonical payload +4. Plugin wraps the body in `` with the attributes +5. Optional: post hash + keyid to a configured directory + +## Verifying in code + +```js +async function verifySignedSection(el) { + const keyid = el.getAttribute('keyid'); + const sig = el.getAttribute('signature'); + const algorithm = el.getAttribute('algorithm'); + const claimedHash = el.getAttribute('content-hash'); + + // 1. Canonicalize & hash inner text + const text = extractCanonicalText(el); + const computedHash = await sha256(normalizeText(text)); + if (computedHash !== claimedHash) return { ok: false, reason: 'hash' }; + + // 2. Build the binding payload + const claimsHash = await hashClaims(el.querySelectorAll(':scope > meta')); + const domain = location.host; + const signedAt = el.querySelector('meta[name=signed-at]').content; + const payload = `${claimedHash}:${claimsHash}:${domain}:${signedAt}`; + + // 3. Resolve key & verify + const pubKey = await resolveKey(keyid); + return await verify(algorithm, pubKey, sig, payload) + ? { ok: true, keyid } + : { ok: false, reason: 'signature' }; +} +``` + +## Status & roadmap + +| Component | Status | +|---|---| +| Specification | ✅ Published | +| Trust directory server | ✅ Reference implementation | +| Browser extension (Chrome) | ✅ Available | +| Browser extension (Firefox, Safari) | ⬜ Planned | +| WordPress plugin | ✅ Available | +| Hugo module | ⬜ Planned | +| Canonicalization (JS, Go, PHP) | ✅ Available, conformant | +| Canonicalization (Rust, Python) | ⬜ In progress | +| W3C proposal | ⬜ Planned | + +## Open design questions + +We have strong preferences but have not yet committed normatively. Community feedback welcome. + +- **HTML-to-text extraction (Stage 1 canonicalization)** — the [spec](/spec/#stage-1--extract-canonical-text-from-html) currently sketches the rules: DOM walk, skip `` claims and `