WP Manifestindependent plugin directory
manifest / privacy / opentrust

Open Trust Center by Ettic WP Registry grade D+. High-severity findings · 2 findingsWP RegistryHigh-severity findings · 2 findingsOpen the reportD+

A self-hosted, open-source trust center plugin for WordPress with an optional AI assistant grounded in your own policies.

★ 3stars
14release downloads
1.2.1latest · 5mo ago

Install

Download open-trust-center-by-ettic-1.2.1.zip From the 1.2.1 release on GitHub, May 22, 2026

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/etticdevelopment/opentrust/releases/download/1.2.1/open-trust-center-by-ettic-1.2.1.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Open Trust Center by Ettic

A self-hosted, open-source trust center plugin for WordPress.

Publish security policies, subprocessors, certifications, and data practices on your own site, with an optional AI assistant grounded in your policies.


Open Trust Center by Ettic is a self-hosted, open-source trust center for WordPress. Procurement teams want a URL they can read. Buyers want receipts. Auditors want a version trail. Open Trust Center by Ettic gives you all three on a branded page that lives on your own WordPress site.

What's inside

  • Security policies with auto-incrementing version numbers and archived revisions reachable at stable URLs (/trust-center/policy/{slug}/version/{n}/).
  • Subprocessors with pre-filled metadata for 200+ common cloud vendors and SaaS providers.
  • Compliance certifications with status badges (active, in progress, expired) and a bundled catalog covering SOC 2, ISO 27001, ISO 27701, HIPAA, PCI-DSS, and others.
  • Data practices organised by category — the full GDPR Article 30 surface, made public.
  • FAQ seeded with sensible defaults; edit, add, or remove freely.
  • Contact & DPO block with company description, DPO name and email, security contact, mailing address, PGP key URL, company registration, VAT/Tax ID. Renders only fields you populate.
  • Optional AI chat powered by Anthropic, OpenAI, or OpenRouter — agentic retrieval, inline citations, token budgets, rate limits.

Install

From WordPress.org: coming soon at https://wordpress.org/plugins/open-trust-center-by-ettic/ (currently in review).

Manually:

  1. Download the latest release from Releases.
  2. WP Admin → Plugins → Add New → Upload Plugin → upload the zip → Activate.
  3. Visit Open Trust Center in the admin sidebar to set your accent colour, logo, and company name.
  4. Add content under Open Trust Center → Policies / Certifications / Subprocessors / Data Practices.
  5. Visit /trust-center/ on your site.

AI chat

Add an optional chat assistant that answers visitor questions straight from your published trust center. Ask it "Where is our data hosted?" or "Are you SOC 2 certified?" and it searches your policies, certifications, subprocessors, and data practices, then answers with citations linking back to the exact source.

It only ever answers from what you've published — it can't retrieve a document you haven't given it, so it won't invent policy you don't have. Anthropic is the recommended provider because it returns native, verifiable citations; OpenAI and OpenRouter also work, using inline citation markers.

To turn it on:

  1. Open Trust Center → Settings → AI Chat
  2. Pick a provider, paste an API key (encrypted at rest with libsodium before it touches the database), and pick a model.
  3. Set the daily/monthly token budgets you're comfortable with.
  4. Optional: enable Cloudflare Turnstile in the same tab for bot defence.
  5. Visit /trust-center/ask/.

There's no SaaS subscription. You only pay your AI provider for tokens consumed (~$3–$15/month for typical traffic, hard ceilings at 500K tokens/day and 10M tokens/month by default).

Privacy by design

  • Zero telemetry, zero analytics, zero licence checks. The only outbound HTTP calls the plugin can make are AI provider requests you configure, and they go through an SSRF host allowlist.
  • No PII in logs. The optional wp_ettic_otc_chat_log table stores only short hashed identifiers — never raw IPs, emails, sessions, user agents, or referrers. The privacy posture is enforced by the schema itself.
  • Encrypted secrets. API keys and the Cloudflare Turnstile secret are encrypted at rest with libsodium secretbox, salted from wp_salt('auth'). Rotating AUTH_KEY invalidates every stored secret atomically.
  • Theme-isolated rendering. The trust center intercepts at template_redirect, outputs a complete standalone HTML document with inlined CSS, and exits. Your theme's stylesheet, header, footer, and JavaScript never load.
  • Capability-checked admin actions with nonce verification on every save handler.

Stack

  • PHP 8.1+ (strict types, match expressions, readonly properties)
  • WordPress 6.0+
  • libsodium for secret encryption (bundled with PHP 7.2+)
  • No Composer vendor tree, no build step, no Node.js
  • Vanilla JS for the frontend; jQuery only in admin (a WordPress dependency)
  • WPML / Polylang compatible out of the box

Local development

git clone https://github.com/EtticDevelopment/opentrust.git
cd opentrust

# Symlink into a local WordPress install (e.g. WP Studio, Local, Lando, etc.)
ln -s "$(pwd)" /path/to/wordpress/wp-content/plugins/opentrust

# Activate via WP-CLI
wp plugin activate opentrust --path=/path/to/wordpress

Run Plugin Check before submitting changes

wp plugin check opentrust \
  --categories=plugin_repo,security,performance,general,accessibility \
  --severity=warning \
  --exclude-directories=".claude,.git" \
  --exclude-files="CLAUDE.md,.gitignore,.distignore,.DS_Store"

Should report "No errors found." Anything else is a regression.

Build a distribution zip locally

rsync -a --exclude-from=.distignore --exclude='.git' --exclude='.claude' \
      ./ /tmp/opentrust-stage/opentrust/
cd /tmp/opentrust-stage && zip -rq opentrust.zip opentrust

Translations

Ships with a .pot template and a starter Dutch (nl_NL) translation. WPML and Polylang compatible — all four content CPTs are registered public with a wpml-config.xml declaring translatable meta fields, so policies, certifications, subprocessors, and data practices can be translated per-language.

Translators can regenerate the template from source:

wp i18n make-pot . languages/open-trust-center-by-ettic.pot --domain=open-trust-center-by-ettic

Contribute a translation at translate.wordpress.org once the plugin is live there.

Contributing

Issues and pull requests welcome. Before opening a PR:

  1. Run Plugin Check (above) — it should report zero errors.
  2. Verify the plugin still loads cleanly on a fresh WordPress install (/trust-center/ returns 200, no PHP errors in debug.log).
  3. If you're adding a user-facing string, wrap it in the opentrust text domain.
  4. Keep PHP 8.1 as the floor — match expressions and named arguments are fine.

Status

1.0.0 — first public release. Submitted to wordpress.org.

License

GPL-2.0-or-later. Same as WordPress core.

Acknowledgements

Built and maintained by Ettic.

Releases

6 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
1.2.1 latest
May 22, 2026 5mo ago
open-trust-center-by-ettic-1.2.1.zip
5
May 21, 2026 5mo ago
open-trust-center-by-ettic-1.2.0.zip
2
May 14, 2026 5mo ago
opentrust-1.1.1.zip
2
May 14, 2026 5mo ago
opentrust-1.1.0.zip
1
May 11, 2026 5mo ago
tag only
—
Apr 28, 2026 5mo ago
opentrust-1.0.0.zip
4
D+ grade

Security

Open Trust Center by Ettic 1.2.1 · audited by WP Registry

High-severity findings.

1 high 1 medium
Audited release
1.2.1
Findings
2
Worst severity
high
Content hash
381855e71901d1d5ddf6e4a0…

Findings

  • high No-JS chat POST bypasses token budget, rate limits, and Turnstile

    dos

    When AI chat is enabled, Ettic_OTC_Render::render_chat_page() handles a synchronous POST on /trust-center/ask/ (and ?ettic_otc=ask) via handle_chat_noscript_post(). The only gate is wp_verify_nonce(..., 'ettic_otc_chat_noscript'). The handler then decrypts the stored provider key and calls stream_chat() with the visitor question. Unlike POST /wp-json/ettic-otc/v1/chat — whose permission_callback enforces the REST nonce, optional Cloudflare Turnstile, and per-IP/per-session sliding windows, and whose handle_chat() reserves Ettic_OTC_Chat_Budget before the upstream call — the no-JS path never touches those helpers and never writes Ettic_OTC_Chat_Log. A logged-out nonce is shared for uid 0, so an unauthenticated attacker scrapes the nonce from the public chat page (it is emitted inside the <noscript> form) and POSTs without bound. Documented defaults (500K tokens/day, 10 req/60s/IP, Turnstile) therefore protect only the JavaScript client. Catch blocks also return $e->getMessage() to the visitor (provider error bodies).

    includes/class-ettic-otc-render.php:57-149

    Recommendation

    Run the noscript POST through the same gates as the REST handler before stream_chat: Ettic_OTC_Chat_Budget::check_ip_rate_limit / check_session_rate_limit, optional Turnstile (or a CAPTCHA that works without JS), and check_and_reserve/commit/release. Record the turn via Ettic_OTC_Chat_Log::record. Do not echo raw provider exception messages to the visitor.

  • medium Trust-center CPTs use default post capabilities and are REST-exposed

    missing_capability

    ettotc_policy, ettotc_certification, ettotc_subprocessor, ettotc_data_practice, and ettotc_faq are registered public, show_ui true, show_in_rest true, with no capability_type, capabilities, or map_meta_cap. Core therefore maps create/edit/publish to edit_posts / publish_posts. Every other plugin mutation (settings, import/export, AI keys, question log) requires manage_options, and the CPT UIs hang off a manage_options parent menu — but Authors and Editors can still open post-new.php?post_type=ettotc_policy and POST /wp-json/wp/v2/ettotc_policy. Published rows are rendered on the public trust center (Ettic_OTC_Render::gather_data and the section templates) and indexed into the AI corpus. A content author can therefore plant false certifications, policies, or subprocessors on a page buyers and auditors treat as authoritative, without ever passing manage_options.

    includes/class-ettic-otc-cpt.php:273-306

    Recommendation

    Set capability_type to a custom type (e.g. ettotc_policy) with map_meta_cap true, and grant those caps only to roles that should edit the trust center (typically manage_options). Keep show_in_rest if Gutenberg/WPML need it, but the REST permission will then follow the custom caps.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.