Skip to content

Latest commit

 

History

30 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTMLTrust CMS Reference

Reference WordPress and Hugo integrations for HTMLTrust content signing. They prepare published content for canonical hashing and embed signatures that browsers and crawlers can verify.

This is a companion to the HTMLTrust specification.

Current status

The WordPress plugin and Hugo build integration are runnable. Drupal, Joomla, and Craft integrations are planned but have no code in this repository yet.

WordPress prerequisites

The plugin's Composer runtime constraint is PHP >=7.2. Development and test dependencies are newer: the lock file currently resolves PHPUnit 9.6.34, which requires PHP >=7.3. The Docker test image uses PHP 8.3 as the supported test baseline.

Quick start

WordPress

cd wordpress/
composer install

Symlink the wordpress/ directory into wp-content/plugins/, or zip it and install it through the WordPress admin. Configure a server profile, link a WordPress user to a registered author identity, and enable signing for the post types you want to publish.

Hugo

Copy the partials from hugo/layouts/partials/ into your Hugo project, then follow the Hugo integration guide to wrap selected pages and run the optional post-build signer.

What It Does

When an author publishes content, the plugin:

  • Canonicalizes rendered content, including signed semantic attributes, and computes a SHA-256 content hash
  • Builds direct-child claims, computes their canonical claims hash, and binds both hashes to the publication origin and signed-at timestamp
  • Requests a compatibility signature from the HTMLTrust trust directory using the configured author API credential; the server performs signing for the registered author identity
  • Embeds the signature, key reference, algorithm, content hash, signed-at claim, and direct-child claims into the published HTML
  • Supports multiple author profiles, endorser profiles, and claim metadata (content type, license, AI involvement, etc.)
  • Displays signature status on the frontend with verification controls

Architecture

The repo is structured for multiple CMS implementations sharing common documentation and API contracts:

htmltrust-cms-reference/
├── README.md
├── docs/                     # Shared across all CMS implementations
│   ├── developer-guide.md    # Integration guide for building new CMS plugins
│   ├── user-guide.md         # End-user documentation
│   └── html-protocol.md      # The sig-* HTML attribute protocol specification
├── shared/
│   └── openapi.yaml          # API contract that all CMS plugins implement against
├── wordpress/                # WordPress plugin implementation
│   ├── content-signing.php   # Plugin entry point
│   ├── admin/                # WP admin pages (settings, profiles, meta boxes)
│   ├── includes/             # Core logic (API client, signing service, DB, hooks)
│   ├── public/               # Frontend display and verification UI
│   ├── tests/                # PHPUnit test suite
│   ├── languages/            # i18n translation templates
│   └── bin/                  # Test environment setup scripts
└── (future: drupal/, joomla/, craft/, etc.)

Adding a New CMS Plugin

  1. Create a new directory at the root (e.g., drupal/)
  2. Implement against the API contract in shared/openapi.yaml
  3. Follow the HTML protocol in docs/html-protocol.md for embedding signatures
  4. Refer to docs/developer-guide.md for integration patterns

WordPress Plugin

Installation

cd wordpress/
composer install    # Install dev dependencies (PHPUnit, PHPCS)

Then either:

  • Symlink the wordpress/ directory into your WP wp-content/plugins/ folder, or
  • Zip the wordpress/ directory and install via the WordPress admin

Configuration

  1. Navigate to Settings → Content Signing in the WordPress admin
  2. Add a Server Profile pointing to your HTMLTrust trust directory server URL
  3. Create Author Profiles linking WordPress users to server-side author identities
  4. Enable signing for your desired post types
  5. Publish a post — it will be automatically signed

Running Tests

The reproducible test path needs Docker and Docker Compose v2. From the repository root, run:

./wordpress/bin/test-docker.sh

This builds a PHP 8.3 test image, starts MariaDB 11.8.2, waits for its health check, installs the exact Composer lock file, downloads the WordPress 6.9.4 core and test suite into Docker-managed volumes, then runs PHPUnit. The image and database tags are pinned by digest. Generated WordPress assets and Composer dependencies stay in Docker volumes, so the command does not write build artifacts to /tmp or require a host PHP installation.

Run the coding-standard check separately, or remove the cached test assets:

./wordpress/bin/test-docker.sh --lint
./wordpress/bin/test-docker.sh --clean

The lock file resolves htmltrust/canonicalization v0.2.2. That is the currently supported compatibility release for this plugin and is the version covered by the Docker test path.

The current checkout contains existing WordPress Coding Standards violations, so --lint reports a nonzero result after PHPUnit completes. Keeping that check explicit makes the default test command a reliable pass/fail signal for the 55-test suite.

Manual test setup

cd wordpress/
export TEST_TMP_DIR="${HOME}/tmp/htmltrust-cms-tests"
mkdir -p "$TEST_TMP_DIR"
TMPDIR="$TEST_TMP_DIR" \
WP_TESTS_DIR="$TEST_TMP_DIR/wordpress-tests-lib" \
WP_CORE_DIR="$TEST_TMP_DIR/wordpress" \
bin/install-wp-tests.sh wordpress_test root '' localhost 6.9.4
TMPDIR="$TEST_TMP_DIR" \
WP_TESTS_DIR="$TEST_TMP_DIR/wordpress-tests-lib" \
WP_CORE_DIR="$TEST_TMP_DIR/wordpress" \
composer test

The installer downloads WordPress and the WordPress test library into the disposable directory under $HOME/tmp. Set DB_HOST in the installer command when MySQL or MariaDB is running in a container. The test suite expects the database named by the first argument to exist or for the database user to be allowed to create it.

For a development container, open this repository in VS Code Dev Containers. The configuration provides PHP 8.3, Composer, Node 22, Go 1.25, and Hugo Extended 0.161.1. Run the same commands above from wordpress/ after the container starts.

Using the reference server

The WordPress plugin's signing client is compatible with the Node reference server in htmltrust-server-reference. Start that server at http://localhost:3000, then configure the plugin's server profile with that URL. The plugin uses the server's author API key for POST /api/content/sign and sends the publication origin as the domain field. Use an origin such as https://example.com, including the scheme and optional port.

The HTML Protocol

Signed content is embedded with a <signed-section> wrapper around the actual signed content:

<signed-section keyid="did:web:author.example"
    signature="BASE64_SIG" algorithm="ed25519"
    content-hash="sha256:47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU">
  <meta name="author" content="Alice Example">
  <meta name="signed-at" content="2026-05-01T10:30:00Z">
  <meta name="claim:ContentType" content="Article">
  <article>
    <h1>Verifiable Web Content</h1>
    <p>Content should be provable...</p>
  </article>
</signed-section>

See docs/html-protocol.md for the full specification.

Companion Repositories

Repository Description
htmltrust-spec The HTMLTrust specification and paper
htmltrust-server-reference Reference trust directory API server
htmltrust-browser-reference Reference browser extension for signature validation
htmltrust-website Project website

License

This project is licensed under the PolyForm Noncommercial License 1.0.0. You may use, modify, and share the software for any noncommercial purpose with attribution. Commercial use requires a separate agreement with the licensor.

Origin & Contributions

HTMLTrust is an idea I (Jason Grey) have been chewing on since 2024. I'm not an academic — I'm an engineer with a day job and a family — so the spec, the reference implementations, and most of this prose have been written with significant help from AI tools acting as research assistant, technical writer, and pair programmer. I wrote the original architectural sketches and reviewed every line; the assistants filled in the gaps and saved me from re-typing the same explanation for the hundredth time.

Contributions are welcome — human or AI-assisted, doesn't matter to me. What matters is whether the code, the spec text, or the conformance vectors move the project forward. Open a PR.

What this project is not a forum for:

  • Debates about whether AI should be used to write code or specifications.
  • Opinions on who is or isn't trustworthy on the web.
  • Politics, religion, professional practice, or personal philosophy.

HTMLTrust is a mechanism — a way for anyone to sign content they publish and for anyone to decide whom they trust, on their own terms. The project takes no position on what the right answers are; it just provides the tools. If you want to debate the answers, there are entire continents of the internet better suited to it.

If this work is useful to you and you'd like to support it, see GitHub Sponsors or the other channels in .github/FUNDING.yml.

About

Reference CMS integrations for signing HTMLTrust content at publish time — WordPress plugin + Hugo partial.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages