Description
TIP Protocol puts your name and the date on everything you publish with WordPress, in a way anyone can check.
When you press Publish, the plugin creates a signed public record of the post. The record says who made it, when it was published, and whether AI was involved. It also holds a fingerprint of the words, images, audio and video in the post. Anyone holding a copy can compare it with the record and see whether it was changed. Readers get a small badge under the post and can check the record in any browser, with nothing to install.
Every signed post becomes a Verifiable Asset. A Verifiable Asset is any piece of digital content that carries a CTID (Content TIP ID): a permanent, signed public record of who made it, when, how it was made, and a fingerprint that shows whether it has changed since.
Who is it for
Anyone who publishes on WordPress and wants credit for their own work.
- Songwriters and singers. Post lyrics, a demo or a release page with the audio attached. The record names you, shows the date you published, and fingerprints up to two audio files per post.
- Filmmakers and video creators. Post a trailer, a short or behind-the-scenes stills. Up to two videos and six images per post are fingerprinted along with the text.
- Journalists and newsrooms. Sign every article under the reporter’s byline and the outlet’s name, and tell readers whether AI helped write it.
- Researchers and scientists. Get a signed, dated record of when your findings, preprints or lab notes went public on your site.
- Schools, colleges and universities. Sign course pages, announcements and faculty work under the institution’s name, and label AI-assisted material openly.
- Law firms and legal publishers. Sign client alerts, articles and public notices, so anyone can later check that a copy matches what you published and when.
- Bloggers, writers and digital creators. Show readers that the post on your site is the original, signed by you.
- Brands and marketing teams. Show customers how each piece was made, including where AI helped.
- Government, nonprofit and public-interest sites. Let readers confirm a notice really came from you.
How it works
- Install the plugin and connect your TIP-ID. A person gets a personal Author ID at vp.theailab.org. An organization gets its ID from The AI Lab after a review.
- Write and publish as usual. Label the post Original Human, AI-Assisted, AI-Generated or Mixed.
- Confirm with Face ID, Touch ID, Windows Hello, a fingerprint or a security key. The plugin signs the post and records it on the TIP network.
- A badge appears under the post. Anyone can click it to see who made it, when, and how.
What it proves, and what it does not
A signed post proves who published it, when, how it was made, and whether it has changed since. It does not prove that what the post says is true, it does not stop anyone from copying your work, and it does not stop AI companies from training on it.
Under the hood
- Verifiable AI content labels. Tag every post as Original Human (OH), AI-Assisted (AA), AI-Generated (AG), or Mixed (MX). The label is cryptographically signed, so it is not a self-claim that anyone can copy. Readers, search engines, and automated verifiers can all confirm it.
- Cryptographic publisher identity. A site-level TIP-ID and optional per-author TIP-IDs sign your content with post-quantum ML-DSA-65 signatures (FIPS 204). Readers see a verified trust badge; verifiers see a tamper-proof signature trail back to your domain.
- No browser extension required. Reader-facing verification works in any modern browser through HTTP response headers, HTML meta tags, JSON-LD provenance, and an accessible bundled
<tip-badge>web component. Your audience does not need to install anything. - Plays nicely with your SEO stack. When Yoast SEO or Rank Math is active, TIP Protocol merges provenance into the existing JSON-LD graph instead of competing with it. No duplicate schema, no conflicting article markup.
- Versioned and correction-aware. Each registration is versioned. An article that gets corrected, updated, or expanded later still resolves to a clean provenance trail with a clear change history.
- Encrypted-at-rest identities. Private signing keys never leave WordPress. They are AES-256-GCM encrypted with PBKDF2-derived keys using WordPress salts as input, and the admin UI never echoes them back to the browser.
- Open, free, and global. The TIP Protocol specification is open. The plugin is GPL-2.0-or-later. The workflow is the same whether you publish from Tokyo, Berlin, Sao Paulo, Lagos, Mumbai, or New York.
Key capabilities
- Register posts, pages, news items, events, products, and other public editor-supported content types on the TIP network with one click.
- Emit TIP verification response headers and provenance meta tags from WordPress on every public page.
- Enrich article JSON-LD schema with provenance fields, with smart handoff to Yoast SEO and Rank Math when they already manage the site schema graph.
- Render accessible verification badges with a bundled local web component so no third-party CDN is required by default.
- Manage publisher and creator TIP identities with encrypted private keys stored inside WordPress.
- Import reviewed organization TIP-IDs from The AI Lab, or personal Author IDs exported from vp.theailab.org, through the built-in
.tip.jsonconnection flow. Locked files open in the browser with a date (date of birth for a person, date of incorporation for an organization). - Domain binding via
.well-known/tip-protocol.jsonor DNS TXT records so the network can confirm a publisher legitimately claims a domain. - Multi-author byline rosters with per-author roles (reporter, editor, photographer, columnist, guest, contributor) and optional per-author co-signatures.
- Audit log of registrations with CTID, change type, version history, signing officer roster, and registration status visible inside the admin.
- GDPR-friendly. Integrates with WordPress personal data export and erasure tooling.
- Biometric signing on every publish. Each signature is confirmed with Face ID, Touch ID, Windows Hello, a fingerprint or a security key (WebAuthn passkeys) on a device the writer added with their WordPress password. Publishing itself is never blocked.
How TIP Protocol differs from other provenance systems
TIP Protocol is built for the publishing surface that already exists in WordPress, not for the camera-to-cloud capture flow that systems like C2PA Content Credentials were designed around. Where C2PA focuses on signing images and videos at the moment of capture, TIP Protocol focuses on signing the final published article (text, media manifest, author roster, origin label) at the moment a publisher hits Publish in WordPress. Both approaches can coexist; TIP Protocol fills the editorial gap.
About the AI Trust Council
The AI Trust Council is the governance body that maintains the Trust Identity Protocol specification, sets the criteria for the Global Seal of Trust certification, and curates the AI Trust Registry of verified publishers. Operated under The AI Lab Intelligence Unobscured, the AI Trust Council keeps AI disclosure standards, content provenance methods, and reader-facing trust signals open, auditable, and aligned with how content actually moves across the modern internet. Specification updates, scoring rule changes, and Global Seal of Trust certification announcements are coordinated through the AI Trust Council and published on theailab.org.
About The AI Lab
The AI Lab Intelligence Unobscured is the research and standards organization behind Trust Identity Protocol, the AI Trust Council, the AI Trust Registry, and the Global Seal of Trust certification program. Founded by Dinesh Mendhe, The AI Lab builds open infrastructure for the AI-native internet: cryptographic content provenance, verified human identity, AI disclosure labeling, and the verification systems that make those signals trustworthy to readers, search engines, and platforms worldwide. The #HumanOrAI public campaign extends the same goal into everyday discourse: every published piece should answer “human or AI?” with a verifiable signal, not a self-claim. Learn more at theailab.org.
Integrations and compatibility
- Yoast SEO and Rank Math: TIP Protocol detects either plugin and merges provenance into its existing JSON-LD schema graph instead of emitting a competing article schema block. No duplicate markup, no schema conflict.
- WooCommerce: works with WooCommerce product pages and any other public editor-supported custom post type. Sign product descriptions, sponsored articles, and editorial product reviews with the same workflow as regular posts.
- Page builders: Elementor, Beaver Builder, Bricks, Divi, and similar tools render TIP-signed content correctly because the badge web component and provenance meta tags emit at the WordPress template layer, beneath the page builder’s rendering pipeline.
- Multisite: tested with both subdomain and subdirectory multisite installations. Each subsite manages its own publisher TIP-ID and contributor registry independently.
- Caching plugins: WP Rocket, W3 Total Cache, LiteSpeed Cache, WP Super Cache, and similar work without configuration. The bundled trust badge is a small web component that caches cleanly along with the rest of the page.
- Block editor and classic editor: both editors are fully supported with sidebar and metabox controls for AI origin labels and multi-author bylines.
- WebAuthn-capable browsers: biometric confirmation before every signature, for personal and organization TIP-IDs alike (Touch ID, Face ID, Windows Hello, fingerprint readers, hardware security keys). Current Chrome, Edge, Safari and Firefox all support it. wp-admin must load over HTTPS.
TIP Protocol glossary
- TIP-ID: a unique cryptographic identifier for a verified publisher, platform, or individual author. Format: tip://id/REGION-xxxxxxxxxxxxxxxx. Used as the signing identity for every piece of registered content.
- CTID (Content TIP ID): the per-piece-of-content identifier produced when a publisher registers a post on the TIP network. Persistent across content updates so a corrected article still resolves to its original provenance trail.
- Verifiable Asset: any piece of digital content that carries a CTID. Every post signed with this plugin is one. See https://theailab.org/verifiable-assets
- CNA-2.2: the current canonical normalization algorithm that defines exactly which bytes get signed. Cross-implementation compatibility hinges on every signer (WordPress plugin, browser extension, mobile clients) producing the same canonical bytes from the same inputs.
- ML-DSA-65: the post-quantum digital signature algorithm (FIPS 204, formerly known as CRYSTALS-Dilithium) that TIP Protocol uses for content signatures. Resistant to attacks from both classical and quantum computers.
- SHAKE-256: the extendable-output hash function (FIPS 202) used to derive the canonical hash that ML-DSA-65 signs.
- Origin code / AI disclosure label: one of four labels publishers attach to every signed piece of content. Original Human (OH), AI-Assisted (AA), AI-Generated (AG), Mixed (MX). The label is part of the signed payload, so it cannot be modified after publication without invalidating the signature.
- Trust badge: the reader-facing verification element rendered as the bundled tip-badge web component. Shows the verified publisher, origin label, trust score, and verification state.
- AI Trust Registry: the public registry of verified publishers and platforms maintained by the AI Trust Council. Used by reader-side verifiers to confirm a TIP-ID maps to a known organization.
- Global Seal of Trust: the certification program publishers earn by adopting the AI Trust Council’s open verification criteria.
- Publisher Mode and Personal Mode: the two attribution patterns the plugin supports. Publisher Mode signs with an organization TIP-ID and credits an authors roster. Personal Mode signs with an individual creator’s TIP-ID under attribution self.
- Domain binding: the proof a publisher controls the domain on which signed content appears. Done via either a .well-known/tip-protocol.json endpoint or a DNS TXT record at _tip-protocol.your-domain.com.
Resources
- WordPress.org plugin page: https://wordpress.org/plugins/tip-protocol/
- The AI Lab homepage: https://theailab.org
- Personal Author TIP-IDs: https://vp.theailab.org
- Source code: https://plugins.svn.wordpress.org/tip-protocol/
- Support forum: https://wordpress.org/support/plugin/tip-protocol/
- Verifiable Assets explained: https://theailab.org/verifiable-assets
- The AI Lab on LinkedIn: https://www.linkedin.com/company/the-ai-lab-org/
- The AI Lab on YouTube: https://www.youtube.com/@TheAILabOrg
- The AI Lab on X: https://x.com/theailaborg
- The AI Lab on Instagram: https://www.instagram.com/theailaborg/
- The AI Lab on Facebook: https://www.facebook.com/profile.php?id=61589147876006
- The AI Lab on GitHub: https://github.com/theailaborg
Legal
This plugin is distributed under GPL-2.0-or-later.
Bundled legal and notice files:
* LICENSE.txt for the GPL software license notice
* NOTICE.txt for the bundle notice summary shown in the admin UI
* PATENTS.txt for informational patent disclosure
* TRADEMARKS.txt for informational trademark notice
Plugin attribution is optional and can be enabled in settings.
Accessibility
TIP Protocol includes keyboard-accessible verification badges, focus-visible controls, descriptive editor help text, semantic public trust UI, and screen-reader-friendly verification details. The public badge details panel supports keyboard open/close behavior and Escape to dismiss.
External services
This plugin connects to external TIP services to deliver its core provenance features.
TIP node API
The plugin sends registration, verification, and trust-score requests to the configured TIP node endpoint.
Data sent:
* publisher or creator TIP-ID
* content registration payloads
* canonical, exact, and perceptual hashes
* content signatures
* verification lookups for trust scores
Service provider: The AI Lab Intelligence Unobscured, Inc.
Service URLs: https://node.theailab.org by default, or your configured TIP node URL
Service purpose: content registration, provenance verification, trust score retrieval
Optional badge CDN
If you switch the badge delivery mode from Bundled local copy to CDN, reader browsers will load the public badge script from the TIP badge CDN.
Data sent:
* standard browser request metadata needed to fetch the script
Service provider: The AI Lab Intelligence Unobscured, Inc.
Service URL: https://badge.theailab.org
Service purpose: optional remote delivery of the TIP badge web component
Privacy
TIP Protocol adds suggested privacy-policy text in WordPress and integrates with WordPress personal data export and erasure tools for stored user TIP identity data.
Blocks
This plugin provides 1 block.
- TIP Verification Badge
Installation
- Upload the plugin folder to
/wp-content/plugins/. - Activate the plugin in WordPress.
- Open
TIP Protocolin the WordPress admin menu. - Import a reviewed
.tip.jsonpackage for a publisher TIP-ID or creator TIP-ID. - Verify your domain and review the publishing defaults.
- Publish content and confirm the TIP badge, headers, and provenance metadata on the front end.
FAQ
-
What is TIP Protocol and what does the plugin do?
-
TIP Protocol (Trust Identity Protocol) is an open content-provenance specification. The WordPress plugin lets publishers and creators sign their published content with a cryptographic identity, label whether AI was used to write it, and surface a verifiable trust badge to readers. It works as an editorial layer on top of WordPress without requiring a browser extension.
-
How does TIP Protocol handle AI-generated content?
-
Every post can carry one of four origin labels: Original Human (OH), AI-Assisted (AA), AI-Generated (AG), or Mixed (MX). The label is part of the cryptographically signed payload, so it cannot be modified after publication without invalidating the signature. Readers and verifiers see a verified AI-disclosure label, not a self-claim.
-
Does TIP Protocol replace C2PA or Content Credentials?
-
No. They solve adjacent problems. C2PA and Content Credentials focus on signing images and video at capture time, typically inside a camera or generative tool. TIP Protocol focuses on signing the final published article (text, media manifest, author roster, AI label) at the moment a publisher hits Publish in WordPress. They can coexist on the same site.
-
What is a TIP-ID?
-
A TIP-ID is a unique cryptographic identifier in the format
tip://id/REGION-xxxxxxxxxxxxxxxx. Publishers receive a reviewed publisher TIP-ID from The AI Lab. Individual writers can generate a personal creator TIP-ID on vp.theailab.org. Both types are imported into WordPress as a signed.tip.jsonpackage. -
Where do editors set the AI / origin label?
-
In the block editor, open the post sidebar and use the TIP Protocol panel. In the classic editor, use the TIP Origin Declaration metabox. The label can also be confirmed or changed in the biometric sign popup that opens right after you publish.
-
Why does TIP Protocol ask for Face ID, Touch ID or my fingerprint when I publish?
-
Every signature is confirmed on one of your devices with Face ID, Touch ID, Windows Hello, a fingerprint or a security key, so a signature needs both your WordPress account and a device you set up. Right after you publish, a popup asks you to confirm, then signs the post and registers it on the TIP network. The first time, the popup asks for your WordPress password and sets up the device; you are emailed whenever a device is added or removed. Your fingerprint or face never leaves the device. WordPress stores each device’s public key, its name, and when it was added and last used. You can add or remove devices in your WordPress profile, and administrators can remove a user’s device if it is lost.
When a post signs with its author’s personal TIP-ID (sites without a site-wide TIP-ID), only that author can confirm the signature. Retracting a post (moving it to the trash) and updating its address after a permalink change are signed automatically, because they add no new authorship claim.
-
What happens when I publish from the mobile app, the REST API, WP-CLI or a scheduled post?
-
The post publishes normally. It is not signed yet, because those tools cannot show a biometric prompt, so it waits as “awaiting biometric signature” and appears under Waiting for a signature in the TIP Protocol dashboard widget. The next time its author opens the post in the WordPress editor, the sign popup opens once, and the TIP Protocol panel keeps a Sign with biometrics button until it is signed. Scheduling a post from the editor opens the popup straight away and signs the post with the address it will have once live, so it is signed before it goes live. Private posts are never prompted, because signing registers a post on the public TIP network; you can still sign one from the panel.
Sites that sign in through single sign-on, where users may not know a WordPress password, can turn off the password step for adding devices with the
theailab_webauthn_require_passwordfilter. -
Does biometric signing need HTTPS?
-
Yes. Browsers only allow passkeys, Face ID, Touch ID and Windows Hello on secure pages, so wp-admin must load over HTTPS (plain http on localhost also works for development). The plugin shows an admin notice when it detects that wp-admin is not on HTTPS.
-
Yes. A site can carry a single verified publisher TIP-ID for the organization, plus per-writer creator TIP-IDs for individual bylines. The plugin supports byline ordering, multiple co-authors per post, role tagging (reporter, editor, photographer, columnist, guest, contributor), and optional per-author co-signatures.
-
Does this work with WooCommerce, multisite, custom post types, and page builders?
-
Yes. TIP Protocol registers any public editor-supported content type, which includes WooCommerce products, custom post types, news/event types, and pages built with Elementor, Beaver Builder, Bricks, and similar tools. Multisite installations are supported.
-
Does the plugin add duplicate SEO schema if I already use Yoast SEO or Rank Math?
-
No. TIP Protocol detects active major SEO plugins. When Yoast SEO or Rank Math is present, TIP Protocol merges TIP provenance into their existing JSON-LD graph instead of emitting a competing article-schema block. When neither is active, TIP Protocol emits its own complete provenance-enriched article schema.
-
Does the public verification badge require a third-party CDN?
-
No. The badge ships as a bundled local web component by default. A CDN option is available in plugin settings if you explicitly choose it, but the default works fully offline and respects strict CSP environments.
-
What happens to private signing keys stored in WordPress?
-
Private keys are encrypted at rest with AES-256-GCM. The key-derivation input includes WordPress salts plus a PBKDF2 stretch (200,000 iterations of SHA-256). The admin UI never exposes the stored encrypted private key back to the browser. Decryption only happens server-side at the moment of signing.
-
What file should I import into WordPress to connect an identity?
-
A reviewed
.tip.jsonpackage that containstip_id,public_key,private_key,algorithm,region,created_at, and (for organizational identities)vp_id. Publisher packages come from The AI Lab after organization review. Personal creator packages are exported from vp.theailab.org and can be DOB-locked for additional protection. -
Is this plugin free and open source?
-
Yes. The plugin is licensed under GPL-2.0-or-later. The TIP Protocol specification is open. The plugin can be used commercially on any number of sites.
-
Where is the TIP network and where does my data go?
-
By default the plugin talks to the TIP node at
https://node.theailab.orgfor registration and verification calls. You can configure a different node URL in plugin settings if you operate a self-hosted TIP node. Signing a post sends its address, its text, content hashes, the origin label, author TIP-IDs, and signatures to the TIP node, which uses the text to check the content (for example the AI-origin prescan). Biometric data is never sent anywhere. -
Will TIP Protocol slow down my site?
-
No. Reader-facing badges use a small bundled web component (about 8 KB), all provenance meta is emitted server-side as HTTP headers and HTML meta tags during the normal page render, and verification lookups for trust scores are cached. There is no extra browser fetch on every page load.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“TIP Protocol” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “TIP Protocol” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
2.5.1
- Fix. An organization TIP-ID with no personal byline can sign. When no writer is credited on a post, the organization is listed as its own author, the same way the TIP browser extension and the verification portal sign for an organization. Before this, the TIP network refused every such post because it requires at least one author, and the error sent publishers to an “Allow author-less posts” setting that the settings screen never showed. Posts that credit a writer are unchanged and still name that person as the byline.
- Fix. The page markup credits an organization that signed as its own author as an Organization, not as a Person named after the WordPress user who pressed Publish.
- Fix. Importing an organization TIP-ID file now asks for the organization’s date of incorporation, which is the date that locks it. The unlock screen used to describe every locked file as a personal Author ID locked with a date of birth, so organizations typed the wrong date and the file looked broken. Personal Author ID files still ask for the date of birth.
- Tests. 697 to 716 assertions across 22 files, all passing. They cover the organization-as-author context, the validators that check it, and the page markup. The signed payload for an organization signing as itself was compared byte for byte with the payload the TIP network’s own code builds from the same input, and an organization file locked with the network’s own key-file code was unlocked by the plugin’s import code.
- Verified against the TIP node repository as of 2026-10-04. No change to the signing recipe or any endpoint.
2.5.0
- New (security, behaviour change). Biometric signing on every publish. Every content signature, for personal and organization TIP-IDs alike, now requires a WebAuthn user-verification confirmation (Face ID, Touch ID, Windows Hello, a fingerprint reader or a security-key PIN) by the WordPress user who triggers it. There is no per-user or per-site switch. The earlier opt-in step-up from 2.1.0 is retired.
- New. Biometric sign popup in both the block editor and the classic editor. It opens right after a post is first published or scheduled, lets the writer confirm the AI-disclosure label, and walks first-time users through adding their device. Users who sign from a new computer can add it from the same popup. The popup is keyboard accessible, keeps focus inside, announces progress to screen readers and closes with Escape.
- New design. The popup, the editor sign panel and the profile device list follow a quiet editorial style, with one typeface, ink on light grey, hairline rules and no shadows, gradients or icons.
- Security. Signing has a single enforcement point. The registrar refuses to decrypt a private key unless the current request carries a single-use proof that the same user just passed a verified WebAuthn assertion for that exact post. Publish hooks, the legacy /register and /update REST routes, cron, WP-CLI, XML-RPC, application-password REST calls and the prescan “accept” link cannot sign. Retracting a post and updating its address after a permalink change remain automatic, because they add no new authorship claim.
- Security. Adding or removing a signing device requires the account’s WordPress password (five wrong attempts lock the step for 15 minutes), and the account owner is emailed on every change. Without this, anyone holding a session cookie could add their own authenticator. Administrators can remove a user’s device from that user’s profile. Sites that sign in through single sign-on can turn off the password step with the
theailab_webauthn_require_passwordfilter. - Security. When a post signs with its author’s personal TIP-ID (no site-wide TIP-ID), only that author can confirm the signature. An editor’s confirmation no longer authorizes another person’s key.
- Security. Challenges and tickets are now claimed atomically, so two concurrent requests can never spend the same one. Several challenges can be open at once, so two editor tabs no longer cancel each other. A signature counter that drops back to 0 is treated as a possible cloned key. Device data from the browser is size-limited, and only P-256 and 2048 to 4096-bit RSA keys are accepted. The biometric REST routes require the content-signing capability.
- Publishing is never blocked. Posts published from tools that cannot show a biometric prompt (mobile apps, REST integrations, WP-CLI, scheduled publishing) go live as usual, wait as “awaiting biometric signature”, and are listed under Waiting for a signature in the dashboard widget until someone signs them from the editor. Private posts are never prompted, because signing registers a post on the public TIP network.
- Fix. Scheduled posts are signed with the address they will have once live. WordPress gives scheduled posts a plain ?p=ID link, which would otherwise have been signed into the record. When a scheduled post goes live, its registered address is also checked and repaired if the slug changed.
- Fix. A label change on a registered post (accepting the AI prescan suggestion) only ever uses the lean origin update; it can no longer turn into a second full registration. The label is changed only after the signature succeeds, so cancelling leaves the post as it was and the suggestion can be accepted again.
- Fix. The label chosen in the block editor sidebar is now the one the sign popup and the pre-publish check show.
- Fix. Safari compatibility. Ceremony options are fetched before the click and refreshed before they expire, and the sign button waits until they are ready, so Safari, which only allows passkey prompts in direct response to a click, no longer refuses the confirmation. This also applies to adding a device on the profile page.
- Fix. The relying party is the wp-admin host. Each device records the address it was set up for, and devices set up for another address are listed but not offered for signing, so the popup asks to add this device instead of failing.
- Fix. The first-publish hook covers every public post type. The previous hooks only fired for posts and pages, so custom post types such as WooCommerce products never reached the publish flow. The editor panels no longer load in the site editor.
- Fix. A site with no TIP-ID connected is not asked for biometrics on publish. The editor shows a link to connect a TIP-ID instead.
- Fix. TIP-IDs with three-letter regions (for example tip://id/IND-…), which exist on the TIP network, can now be imported. The importer previously accepted only two-letter regions.
- Fix. The biometric audit record is written to the local transaction log for every signature. Earlier releases stored it in post meta that nothing read.
- Privacy. WordPress’s personal data export now includes each user’s signing devices, and erasure removes them; audit records of posts already signed are kept with the post’s transaction log. The suggested privacy policy text describes passkeys, the audit record, and that a signed post’s text is sent to the TIP node. The FAQ previously said the article body was not sent; that was wrong and is corrected.
- Improved. Plain-English messages for the TIP network’s 412 byline checks, for expired sessions, and for every WebAuthn failure. Admin notices when wp-admin is not served over HTTPS or the server lacks the OpenSSL extension. Uninstall removes passkey records network-wide on multisite, plus pending sign prompts.
- Tests. 559 to 697 assertions across 22 files, all passing. The WebAuthn verifier is driven with real P-256 keys and signatures through every rejection path, including replay, missing user verification, wrong origin or relying party, altered data, a foreign key, a cloned-key counter, password-less enrollment, unsupported key types and concurrent claims. Source contracts pin where the signing gate, the ownership check and the relabel rule sit. Key checks were confirmed by mutation testing. The flow was exercised end to end in a real WordPress install in both editors.
- Verified against the node, verification-provider and browser-extension repositories as of 2026-10-04. No contract-affecting upstream change. The canonical payload, hash and signature recipe, the author-signed actions and the .tip.json export are unchanged, and the node neither requires nor accepts any biometric field, so this release changes no signed bytes.
2.4.1
- Fix (forward-compatibility, protocol-critical): registrations of posts without attached media no longer send empty media-fingerprint fields to the TIP network. The network’s latest schema validates the media fingerprint against a strict 64-character format and treats an empty string as malformed, which would have rejected every text-only post registration once that node release deploys. The plugin now omits the media fields entirely when a post has no attached media, which the network explicitly treats as valid. Posts with attached media are unaffected, and because these fields sit outside the signed payload, no signature bytes change and all existing registrations remain exactly as they are.
- Improved: plain-English explanation for the network’s malformed-media-fingerprint rejection, pointing at the actual causes (manifest tampering by another plugin) rather than surfacing a raw error code.
- Tests: 549 to 559 assertions, all passing, including coverage that text-only registrations omit the empty media fields while media-carrying registrations preserve them byte-for-byte.
- Verified against the node and verification-provider repositories as of 2026-08-20: this schema bounding is the only contract-affecting upstream change; the signing algorithm, canonical payload, identity import format, and every endpoint the plugin calls are unchanged.
2.4.0
- New: AI-prescan verdict on the edit screen. After each registration the plugin reads back the network’s asynchronous AI check and, if the content was flagged while labeled Original Human, shows a clear warning with the network’s own explanation, the zero-penalty decision deadline, and a one-click “Change label to AI-Assisted” action. Relabeling inside the window costs nothing; ignoring a strong flag can escalate to a network reviewer, so the plugin now makes that choice visible instead of silent.
- New: near-duplicate advisory. When the network’s similarity sweep matches your newly registered post against existing registered content, a non-blocking amber notice lists the closest matches. The registration itself succeeded and keeps its own record; the notice is context, not an error, and can be dismissed.
- New: “Preview what will be signed” expander in the classic editor metabox. Shows the exact normalized text and hash that will be signed, so writers can see why smart-quote changes, markup edits, or whitespace tweaks after publishing can invalidate the badge. Read-only and loaded on demand.
- New: domain binding renewal. The plugin now re-verifies the domain binding twice daily (when due) instead of trusting a one-time check forever. A transient network blip never drops the verified state: the status only downgrades after five consecutive failures, mirroring the network’s own failure budget.
- New: share-card warming. After each registration the plugin pings the verification provider’s card renderer so findtip.org share links unfurl correctly on the very first scrape instead of showing an empty card that social platforms then cache.
- Reliability: the read-back is fully non-blocking with capped retries; every new surface is advisory and can never affect registration state or editing.
- Tests: 521 to 549 assertions across 19 files, all passing, including behavioural coverage for the read-back scheduler, retry caps, verdict projection, and the share-card ping.
- Roadmap: per-post-type default signer and the perceptual text fingerprint envelope remain planned for a future release.
2.3.2
- Fix (protocol-critical): origin updates and retractions now use the TIP node’s author-signed action contract. The node verifies these post-registration actions against a small fixed field set signed by the registering identity, with the content ID bound into the signature server-side so a captured signature cannot be replayed against different content. Earlier releases sent a differently shaped body for both actions: the node rejected every origin update and every retraction at validation, and retractions silently fell back to local-only. Both actions now reach the network correctly.
- New: automatic permalink repair. Changing a registered post’s slug or permalink now proposes an owner-signed registered-URL update to the TIP network, so the public record follows the post instead of pointing at a URL that no longer resolves. The repair compares the recorded URL against the current canonical permalink on every post update, which also heals older registrations whose stored URL predates the canonicalization fix in 2.3.1. Failures are logged and retried on the next edit; they never block editing or flip the post’s registration status.
- Compatibility: the wire envelope now explicitly tolerates the network’s new optional parent-context URL field on content records, and the drift-guard test suite locks in that tolerance. Content registered by this plugin is unaffected; the field exists for reply-type content registered by other TIP clients.
- Improved: three new plain-English error explanations, including a targeted message when the site’s current signing identity differs from the identity that originally registered a post (previously this surfaced as a misleading “session expired” message).
- Tests: 495 to 521 assertions across 18 files, all passing. New coverage pins the exact signed bytes for all three author actions so the field-set regression that motivated this release cannot return.
- Verified against the node, verification-provider, and browser-extension repositories as of 2026-08-15: the content registration contract, the .tip.json export format, and the signing algorithm are all unchanged — existing registrations and imported identities are unaffected.
2.3.1
- Fix (protocol-critical): registered URLs are now WHATWG-canonicalized before signing. The registered URL is part of the cryptographically signed payload, so the TIP node cannot normalize it and instead rejects any URL that is not already in canonical form. WordPress permalinks frequently are not: a site whose front page URL has no trailing slash, a host with any uppercase letter, an explicit :80 or :443 port, an internationalized domain, or a post slug containing non-ASCII characters would all have been refused by the network. The plugin now converts each URL to the exact same canonical form the rest of the TIP ecosystem produces, verified byte-for-byte against 32 reference cases covering Latin, accented, Cyrillic, CJK, and internationalized-domain inputs.
- Fix: identity imports no longer discard issuer data. When unlocking a date-of-birth protected .tip.json from vp.theailab.org, the plugin previously hardcoded the identity type and dropped the verification-provider ID and display name that the file actually carried. All three are now read from the file and passed through, so the issuer binding is preserved and writers appear under their real name in bylines instead of a bare TIP-ID.
- Improved: added a plain-English explanation for the network’s non-canonical-URL rejection, so the rare remaining cases (a permalink with an embedded username and password, or a non-http scheme) produce actionable guidance rather than a raw error code.
- Tests: 447 to 495 assertions across 17 files, all passing. New coverage includes a URL canonicalization suite whose expectations were generated from the reference implementation, plus explicit guards for the byte-safety bug that would silently corrupt non-ASCII permalinks.
- No changes to signing keys, the canonical payload shape, or stored data. Existing registrations are unaffected.
2.3.0
- New: Friendly error map (Theailab_Error_Map). Every user-visible error from the TIP node is now translated from opaque codes (“content_hash_mismatch”, “signature verification failed”, “url_already_registered”, 409, 429, 5xx, network failures, invalid TIP-ID format, revoked identity, missing vp_id, missing registered_urls, auth/nonce, reserved identity type) into plain English with an actionable next step. The raw node message is still preserved in the transaction log for developer debugging.
- New: Real content retraction. Prior to this release the plugin treated the node’s /v1/content/:ctid/retract endpoint as unsupported and only recorded retractions locally. When a signed post is trashed the plugin now signs a canonical CONTENT_RETRACTED payload and submits it to the node so the DAG record reflects the retraction. Local state still flips even if the network call fails, so trashing always drops the reader-facing badge.
- New: Revocation feed subscription. Hourly WP-Cron beat calls the node’s /v1/revocations?since= endpoint and, if the site’s Publisher TIP-ID or any personal Author TIP-ID in the contributor registry appears in the revocation list, marks it locally revoked. The registrar refuses to sign with a revoked identity, so publishers stop producing signatures the node would reject.
- New: Reserved-identity-type gate. Importer now correctly flags syndicator / institution / service / collective .tip.json packages as reserved for a future protocol release, with a distinct error message instead of falling through to the generic “unknown tip_id_type” branch. New THEAILAB_IDENTITY_TYPES_RESERVED constant documents the reserved set.
- New: Milestone counter. Non-blocking admin notice at the 1st, 10th, 100th, 1,000th, and 10,000th successful registration on the site.
- Improved: Tier color hex sync. Consolidated the trust-tier hex palette (Highly Trusted, Trusted, Verified, Caution, Not Trusted) into shared THEAILAB_TIER_COLOR_* constants that mirror the TIP node’s getTier() palette. The Verified tier hex now matches the node (#A88B15) instead of a locally-drifted #C9A84C. Added brand accents THEAILAB_BRAND_GOLD / THEAILAB_BRAND_GOLD_DARK / THEAILAB_BRAND_NAVY for cross-surface consistency.
- Improved: Copy pass replacing internal jargon “Origin code” with plain English “How was this written?” across the classic-editor metabox, the settings help panels, and the button strings. Consistent with the block-editor sidebar phrasing.
- Improved: Field-hint microcopy under the origin-code selector explaining that the label is part of the signed record and cannot be silently changed later.
- Reliability: Test suite grew from 406 to 444+ assertions with new test-error-map.php (18) and test-reserved-tip-id-type.php (20).
- Roadmap: Six additional concepts from the node + browser-extension survey are earmarked for follow-up releases: preview canonical form expander (v2.3.1), content read-back + near-duplicate advisory (v2.3.1), domain binding renewal cron (v2.3.2), prescan tier notice + change-origin grace CTA (v2.3.2), publisher-mode gating by post type (v2.3.3), perceptual text fingerprint envelope with MinHash (v2.3.3).
2.2.2
- Plugin-directory listing: appended five new subsections to the Description body to broaden search discoverability without changing the existing positioning. New sections: About the AI Trust Council (governance body entity), About The AI Lab (research and standards organization entity, names Dinesh Mendhe as inventor), Integrations and compatibility (Yoast SEO, Rank Math, WooCommerce, multisite, caching plugins, page builders, WebAuthn browsers), TIP Protocol glossary (11 named-term definitions covering TIP-ID, CTID, CNA-2.2, ML-DSA-65, SHAKE-256, origin codes, trust badge, AI Trust Registry, Global Seal of Trust, Publisher Mode and Personal Mode, domain binding), and Resources (4 external link targets). No code changes.
2.2.1
- Follow-up review of the 2.2.0 wire-envelope refactor caught two issues that the initial test pass missed.
- Fix: The update-content-origin path on the legacy CNA-2 signer route was missing the same legacy-required-fields fallback that the register path has. When
sign_with_context()returns an empty$signature['payload'](legacy CNA-2 case), the wire body sent to the node was missingsigner_tip_id,authors,registered_urls,content_hash, andcna_version. The update path now layers those required fields on top of the helper output exactly as the register path does — same shape, same field names. Legacy CNA-2 update calls work again. - Fix: Removed duplicate
content_hashandcna_versionfields from the update path’s auxiliary array. Both were already in the canonical signed payload for the CNA-2.2 case, and the legacy fallback supplies them for the CNA-2 case. Sourcing each field from exactly one place removes the silent-override risk that would have appeared if the canonical builder ever changed those fields’ semantics independently. - Tests: Extended
tests/test-wire-envelope-drift.phpfrom 34 to 46 assertions covering the legacy CNA-2 update fallback shape (all spec-required fields present under the new canonical names; drift-guard fields confirmed stripped even on the legacy path) and the no-aux-override invariant (canonical content_hash + cna_version win when aux tries to set them).
2.2.0
- Fix (signing): Align HTTP wire envelope sent to the TIP node with the current CONTENT_SIGNING.md spec. The update-content-origin call previously shipped three legacy fields the node now rejects on verification:
author_tip_id(replaced by canonicalsigner_tip_idplusauthors[]),public_key(node now resolves from the DAG identity record; sending it duplicates state), andregistered_urlsingular (renamed toregistered_urlsplural and already in the canonical signed payload). The new private helperTheailab_Content_Registrar::build_wire_envelope()anchors every wire body on the canonical signed payload and strips the three legacy keys regardless of caller input. Both the register and update code paths now use it. This was the silent root cause of “Content signature verification failed” reports on personal Author IDs whose verification chain was otherwise cryptographically valid. - Fix (signing): Personal-mode self-author entries now use the Phase 1 spec values
role: "byline"+key_mode: "attribution"(previouslyrole: "reporter"+key_mode: "self_signing"). The publisher’s ML-DSA signature IS the author’s signature in self-mode, so the author entry is markedattributionandsigned: false. Earlier values were a leftover from a draft spec; the node verifies signatures over signed bytes that include the authors[] entry, so the wrong role/key_mode produced silently mis-verifying signatures. - Fix (signing): 409 Conflict responses from the TIP node (signal: the same signer_tip_id + ctid pair is already in flight in the mempool) are now mapped to a distinct
theailab_api_conflict_pendingerror code and surfaced to the post asprocessingstatus, noterror. The previous behavior flipped the post status toerroron every transient mempool overlap and required an admin to manually retry. - Tests: New
tests/test-wire-envelope-drift.php(34 assertions) locks in the wire envelope contract — the three legacy keys are stripped even when callers try to pass them. Newtests/test-self-author-shape.php(12 assertions) locks inrole=byline+key_mode=attributionfor personal-mode self across all three code paths. 46 new assertions total. - No breaking changes for users. The plugin still accepts the same
.tip.jsonpackages, still emits the same admin UI, still renders the same<tip-badge>. The only behavior change is that signatures now verify against the current spec — which is what users expected to happen all along.
2.1.7
- Plugin-directory listing: removed the second Contributor handle (
theailab) that WordPress.org’s importer flagged as an unknown user. Onlytheailaborgwas the real WordPress.org account; the second handle was a leftover from an earlier intent to register a sister account. No code changes.
2.1.6
- Plugin-directory listing: complete readme rewrite to improve discoverability on WordPress.org search and external search engines. Sharper short description, new “Why publishers and creators use TIP Protocol” value-prop block, new “Who is this for” industry-targeting block, expanded FAQ with high-volume questions (AI-generated content handling, C2PA / Content Credentials comparison, multi-author and multisite workflows, security model, network endpoints), updated tag list (ai disclosure, content provenance, content authenticity, trust badge, publisher). No code changes.
- Removed the local-development / Docker section from the user-facing readme. That content now lives only in the repository docs where it belongs; it was diluting the SEO signal of the public plugin page and listed local-development credentials that should not appear on a public listing.
2.1.5
- Security: Restructured the byline metabox nonce check (admin/class-tip-metabox.php) into the canonical isset wp_verify_nonce current_user_can sequence, with each gate an independent early-return so the conditional logic cannot be bypassed. Sanitized $_POST input at the boundary with explicit wp_unslash + is_array check before the per-entry sanitize_text_field loop.
- Security: Sanitized every $_SERVER access. includes/class-tip-webauthn.php and includes/class-tip-visitor-context.php now apply sanitize_text_field( wp_unslash( … ) ) in a single expression so the WordPress coding-standard analyser sees the sanitization chain, and the phpcs:ignore comments that previously masked these reads have been removed.
- Security: Rewrote the legacy-slug admin redirect (admin/class-tip-admin.php redirect_legacy_menu_slug) to use an explicit allow-list of forwardable query params (tab, section, paged), each sanitized via sanitize_text_field and rawurlencoded before reaching add_query_arg. The previous raw $query_args = $_GET assignment is replaced. Capability check moved above all $_GET access so unauthorized requests never touch the superglobal.
- Security: Added a defence-in-depth current_user_can( theailab_set_origin ) gate to Theailab_Admin::build_editor_state() before reading $_GET[‘post’]; absint() now wraps the post-ID lookup explicitly.
- Prefix uniqueness: Removed the legacy un-prefixed shortcode registrations ([tip-badge], [download_button]) and the legacy register_block_type call for tip/verification-badge. Replaced the alias approach with a the_content filter (Theailab_Public::rewrite_legacy_tokens) that rewrites legacy tokens to their prefixed names at render time, so existing post content authored against earlier versions keeps rendering after upgrade. Updated the Gutenberg JS to register theailab/verification-badge, theailab-origin-panel, and theailab-pre-publish-check (previously tip/verification-badge, tip-origin-panel, tip-pre-publish-check).
- No functional changes for end users.
2.1.4
- Compatibility: Bump “Tested up to” header to 7.0 (current WordPress release). No code changes; the WordPress.org automated scanner blocks uploads whose declared compatibility falls below the latest WP version, and this metadata bump unblocks the resubmission of the 2.1.3 prefix-uniqueness fixes.
2.1.3
- Compliance: Address WordPress.org Plugin Directory review feedback on prefix uniqueness. Three PHP-level identifiers carried short or generic prefixes that could collide with other plugins:
- Bootstrap function
tip_protocol()renamed totheailab_tip_bootstrap(). A guarded backward-compat alias preserves the old name for any third-party code or theme snippet that referenced it. - Gutenberg block namespace
tip/verification-badgerenamed totheailab/verification-badge. The legacy block name is also re-registered as an alias so existing post content that embeds the old block continues to render unchanged. - Admin menu slug
tip-protocol(previously routed to admin.php?page=tip-protocol) was already moved totheailabin an earlier release; this version adds a 301 redirect from the legacy URL to the new one so bookmarked admin URLs keep working. - Shortcodes
[tip-badge]and[download_button]continue to render via backward-compat aliases registered alongside the canonical[theailab-tip-badge]and[theailab_download_button]names.
- Bootstrap function
- No functional changes for end users. Existing content keeps working; the renames are purely to satisfy the WordPress.org plugin uniqueness rule.
- Bump version forces a cache-buster URL refresh.
2.1.2
- UI fix: The scope picker dropdown clipped the descenders of “publishers” because the wp-components SelectControl forced a fixed height that conflicted with the picker’s padding. Replaced the height constraint with
height: auto, increased line-height to 1.5, switched to a custom-drawn navy chevron with explicit right-padding so the option text isn’t crowded, and bumped vertical padding to 12px. The dropdown now renders the full option text cleanly at any zoom level. - Sign reliability: Added a server-side self-verification step right after each ML-DSA signature is produced and before the registration request is sent to the TIP node. If the stored public key doesn’t correspond to the private key the plugin just signed with — most often because a personal Author ID was imported with a derived (not original) public key — the user gets a precise local error pointing at the cause and remediation, instead of the opaque “Content signature verification failed” the node returns.
- Sign reliability: The registration payload sent to the TIP node now includes the
public_keyfield. Without it, the node had to look up the TIP-ID’s public key on the DAG to verify, which fails for newly-imported personal Author IDs that haven’t been published to the network yet. Including the key gives the node a deterministic verification path; the node should still cross-check this against its DAG record when one exists. - Sign reliability: When the TIP node rejects a registration with a “signature verification” error AND the local self-verify passed, the editor now surfaces a guided message explaining that the TIP-ID likely isn’t yet published to the TIP DAG (and pointing the user at vp.theailab.org), instead of relaying the raw node error verbatim.
- Bump version forces a cache-buster URL refresh.
2.1.1
- UI: The “What kind of identity is this?” dropdown on the Connect-an-Identity card was easy to overlook even though it controls the most important decision in the import flow (publisher vs. personal). Wrapped it in a high-contrast picker with a colored border, gradient background, “REQUIRED” tag, large icon (🏢 / 👤), and a prominent uppercase label. The picker color-shifts to blue when “Site identity” is selected and green when “Personal Author ID” is selected, so the user gets instant visual confirmation that their choice registered.
- Bump version forces a cache-buster URL refresh.
2.1.0
- Feature: Optional WebAuthn / biometric step-up for personal-mode signing. Writers who choose to can now require a fingerprint, Face ID, Windows Hello, or hardware security-key tap before each post is signed with their personal Author TIP-ID. Configured per-user in WordPress profile, defaults OFF for everyone, and is never a barrier — publisher-mode signing, scheduled posts, WP-CLI, REST automation, and cron-driven workflows always bypass step-up. If a user enables the toggle but has no enrolled key, signing still proceeds; if they remove their last key, the toggle auto-disables.
- New REST surface under /theailab/v1/webauthn/ (status, register/begin, register/complete, auth/begin, auth/complete, required, credentials/remove). All routes are nonce-protected and operate only on the calling user’s row.
- Server-side verifier uses native PHP openssl_verify() with public keys exported directly from the browser via AuthenticatorAttestationResponse.getPublicKey() — no third-party dependency, no CBOR parser, supports ES256 and RS256 algorithms, enforces userVerified flag and signCount monotonic check.
- Editor integration: Both classic and Gutenberg editors detect a 428 Precondition-Required response from /origin/register, run the WebAuthn assertion ceremony, and retry with the resulting single-use ticket. Errors are surfaced via the existing inline-status banner with clear remediation guidance.
- Security audit: WebAuthn step-up is a defense-in-depth layer over the existing capability/nonce model — it gates the API call but does not replace any existing check, and the actual content signature remains ML-DSA-65 over the canonical hash, server-side, exactly as before.
2.0.11
- Fix: When the TIP node returned a structured error response (e.g.
{"error":{"message":"…"}}), the plugin’s API client cast the nested object to a string and surfaced the literal word “Array” in the editor — users saw “Couldn’t sign this post / Array” with no actual reason. The client now walks the common shapes (erroras string or{message,detail,description,code,reason,details[]}, top-levelmessage, pluralerrors[]) and falls back to a short raw body snippet or a status-code message, so the real reason from the node always reaches the user. - Bump version forces a cache-buster URL refresh.
2.0.10
- Fix: Personal Author IDs exported from vp.theailab.org (DOB-locked
tip-key-export-v2files) failed to import withTIP-PKG-2 packages must declare vp_id.. Personal identities are self-claimed and never carry a publisher review, so the importer no longer requiresvp_idfortip_id_type === "personal". Publisher and platform identities continue to require a well-formedvp_id, and personal exports that do include one are still validated againstTHEAILAB_VP_ID_REGEX. - Bump version forces a cache-buster URL refresh.
2.0.9
- Apply the v2.0.8 inline status …