September 5, 2026

In an effort to make the web safer, Entelecheia is sharing this proposed architecture with browser developers, standards organizations, and others working on the future of the web. It addresses a fundamental weakness in the face of JavaScript backdoors: browsers verify content per domain, but not per URL. A reference implementation is at github.com/entelecheia-inc/page-integrity.

The web is already secure, but only up to a server. HTTPS confirms that the browser has reached a server authorized for a domain, but from that point the server defines the page. It can inject a JavaScript backdoor or replace the page entirely tomorrow while keeping the same URL and certificate. Alice’s pages and Bob’s pages may share a domain, as they commonly do on hosting platforms such as Netlify and GoDaddy, yet the browser has no way to distinguish their separate authorities; it simply trusts whatever the server sends. Whoever controls the server—a hosting provider, CDN, cloud account, or an attacker who has compromised it—therefore controls everything it serves.

Subresource Integrity already solves a related problem well. It was designed to ensure that files placed on a CDN cannot be changed unilaterally: the expected checksum is encoded in the HTML that references each resource. The CDN is therefore not trusted to decide what code the application delivers. A website can use SRI to distribute a complete web application through third-party infrastructure without allowing that infrastructure to introduce a JavaScript backdoor.

The user wants the same protection. He does not want the page itself—or the server that delivers it—to introduce a backdoor either. Yet SRI cannot protect the HTML containing the checksum, and the server remains free to replace that page with modified code. Against that, the user has no defense.

Other existing mechanisms do not close this gap. Immutable storage, such as WORM and Legal Hold, does not help if DNS is compromised: the browser can be directed to an impostor that answers the same URL with different content. The missing layer is integrity for navigational URLs—the pages users enter, bookmark, and follow—allowing content under the same domain to have separate authorities.

A naive approach would be to let a navigational URL embed a checksum of its content as a parameter, allowing the browser to verify that the page matches the checksum carried by the URL itself. This creates two problems. First, even a simple address such as https://example.com would become impractical to type or remember if it had to include a checksum. More importantly, it would create a phishing opportunity: anyone with control of the server—a hosting provider, a CDN administrator, or an attacker who has compromised it—could modify the page and send a victim a URL containing the checksum of the modified version. The browser would verify the page successfully, but the user would have no reason to notice that he had been given a different URL.

Page Integrity

The website publishes an integrity.log, similar to robots.txt. It is an append-only history of signing keys, URL path assignments, integrity requirements, and pins. It contains only public keys, except where a pinned path records a checksum. A key inherits the rights granted to it by an earlier valid key and retains them until its TTL expires.

Unless otherwise specified by the record type, the first applicable record wins. An A assignment cannot be overridden while it remains valid. An I or P record may add or extend protection, but cannot weaken a still-valid earlier commitment.

The browser always has the public key from the TLS certificate available as a starting point. When a signature cannot be verified through a chain already established in the log, it tries that key. A newly issued certificate, however, cannot override a path that has already been assigned to another key. Once a URL has an I line, the server also cannot simply remove its integrity protection and serve the URL unsigned. The log establishes the requirement; the page itself carries only the current checksum.

<timestamp> B
<timestamp> A <TTL> /alice/             <alice-key-1> <sig by cert-1>
<timestamp> I <TTL> /alice/article.html <sig by alice-key-1>
<timestamp> K <TTL>                     <alice-key-2> <sig by alice-key-1>
<timestamp> I <TTL> /alice/app.js       <sig by alice-key-2>
<timestamp> K <TTL>                     <cert-2>      <sig by cert-1>
<timestamp> A <TTL> /bob/               <bob-key-1>   <sig by cert-2>
<timestamp> I <TTL> /bob/index.html     <sig by bob-key-1>
<timestamp> I <TTL> /index.html         <sig by cert-2>
<timestamp> P <TTL> /index.html         <sha256-...>  <sig by cert-2>
<timestamp> I <TTL> /mail/              <sig by cert-2>
<timestamp> P <TTL> /mail/              <sha256-...>  <sig by cert-2>

Every <timestamp> is Unix epoch time in UTC. Timestamps are strictly increasing, except for the opening and closing braces of a checkpoint, which share one timestamp. B marks the creation of the log and contains nothing else.

The remaining records contain a type, TTL, path where applicable, and the key or checksum required by that record. Signatures establish authorization through the key chain already recorded in the log. The format is normalized before processing and hashing, so insignificant formatting differences do not affect the result.

  • B — marks the creation of the log.
  • K — authorizes a successor key.
  • A — assigns a signing key to a URL prefix.
  • I — requires integrity verification for a file or directory subtree.
  • P — pins a file or directory subtree to a recorded checksum.
  • { } — delimit a checkpoint.

TTLs prevent a URL from remaining permanently locked if its signing key is lost. Alice chooses the period herself and can authorize a successor key with a K record before the current key expires.

For TLS certificate keys, the TTL would normally correspond to the certificate’s validity period. Before it expires, the current key authorizes the next certificate key.

Dynamic Integrity Signatures

Dynamic integrity is useful when the person responsible for content does not control or trust the server delivering it. Alice, for example, may publish through a CDN while keeping her signing key private. She adds an I record once and signs each new version as it changes. The CDN can deliver the file, but cannot replace it without Alice’s key.

The same mechanism also supports independent verification. A security auditor could review an application and sign approved versions, allowing the browser to accept only content carrying a valid signature from that auditor.

For HTML, the integrity assertion appears as the last line of the document and contains a checksum of everything before it.

<!DOCTYPE html>
<html>
<body>...</body>
</html>
<!INTEGRITY <sha256-...> <TTL> <sig by alice-key-1>>

The integrity line itself is not included in the hash. When a current I record covers a URL and no P record supplies the checksum, the assertion is mandatory. If it is missing, stale, invalid, or does not match the document, the browser rejects the page.

Non-HTML files can use an X-Integrity header covering the entire file. When Alice changes a file, she generates a new checksum and signature; the I line in integrity.log remains unchanged.

The visitor still types the same URL, for example:

https://example.com/alice/article.html

Behind the scenes, the browser finds an A entry covering /alice/, an I entry for the requested URL or a directory that contains it, and requires a current integrity assertion signed by a key in Alice’s chain. If the assertion is missing, stale, invalid, or does not match the content, the browser shows an error similar to a certificate error.

Recovery and Replay Attacks

To prevent replay attacks while allowing legitimate recovery, the system relies on third-party witnesses. Natural witnesses include the certificate authority named in the server’s TLS certificate and the domain’s registrar, discovered independently through existing certificate and domain-registration infrastructure. The browser never asks the server which witnesses to trust.

Other organizations may also operate witnesses, including browser vendors, security companies, or independent watchdogs.

A witness does not store integrity.log. When it observes a log, it records the log’s B timestamp, the time of observation, and a cryptographic hash of the log as it existed then. Because log timestamps cannot be in the future, the observation time identifies the portion of the log covered by the hash. Witnesses retain observations for a limited period or number of versions before pruning older history.

The browser downloads the current log and compares it with witness observations. For an observation belonging to the same B generation, it hashes the portion of the received log that existed at the time of observation. Matching hashes prove continuity. A mismatch means the history was altered or rewound. A later B timestamp indicates a new log.

If no witness retains history for a domain, the site is treated as new. At that point, distinguishing a genuinely new site from a replay of sufficiently old history is intentionally impossible.

A new log may be necessary when ownership changes or when the previous log or its signing keys have been lost. It begins with a later B timestamp. During a recovery period of at least N = 1 day, new commitments cannot revoke or weaken still-valid A, I, or P records from the previous witnessed history. This prevents a compromised server from repeatedly resetting the log to escape existing integrity commitments.

Alice and Bob can also monitor the log independently with watchdog software.

Truncating the Log

The log preserves history but need not grow forever. A checkpoint restates everything needed to establish the log’s current state: its B line and every unexpired A, I, P, and K record required to establish current permissions. The records retain their original timestamps and signatures; the checkpoint itself is not separately signed.

...
<timestamp> {
<timestamp> B
<timestamp> K <TTL>                     <cert-2>      <signature>
<timestamp> A <TTL> /alice/             <alice-key-1> <signature>
...
<timestamp> P <TTL> /mail/              <sha256-...>  <signature>
<timestamp> A <TTL> /bob/               <bob-key-1>   <signature>
<timestamp> }

A checkpoint does not renew TTLs or signatures. It merely restates records that remain valid; expired records may be omitted.

A checkpoint may be witnessed immediately, but cannot become a cut point until it has coexisted with the history it replaces for at least N days—thirty days is a reasonable default. During that period, browsers can verify that the checkpoint preserves every active permission and integrity requirement without adding or altering anything.

Once the waiting period has elapsed and the checkpoint has been witnessed, everything before it may be removed. The original B line remains, so the truncated file is still the same log, with its earlier history cryptographically represented by the witnessed checkpoint.

Pinned Integrity

Not every web application has someone independent who can be trusted to approve every future version. A company may control the application, the server, and the signing key. If it introduces—or is compelled to introduce—a JavaScript backdoor—it can simply sign the modified application as valid. Pinning addresses this problem by committing a specific version of the content to integrity.log instead of trusting a key to approve whatever comes next. The server can still change files, but the browser accepts only versions already committed.

P works alongside I. The I record requires integrity verification, while P supplies the value against which the content is checked. Without an applicable I record, the browser does not perform an integrity check, even if the path is pinned. Pinning can apply to one file or an entire application. A path ending in / covers the whole subtree: I /mail/ requires integrity verification below /mail/, while P /mail/ pins the application to /mail/manifest.json. The manifest lists every permitted file and its checksum. As files are requested, the browser rejects anything missing from the manifest or whose checksum differs. The server therefore cannot selectively substitute a modified app.js for one user or introduce an unlisted backdoor.js.

Like the rest of the log, pinning follows record order and TTLs. Later records may add protection but cannot weaken an existing pin before it expires. I and P therefore solve different problems: I allows an independent author or auditor to approve future versions, while P freezes a known version when no independent party can be trusted to approve changes.

What This Protects Against

HTTPS proves that a response came from an authorized server. Page integrity adds a second question: who was authorized to define this particular URL?

An author can retain control of her content while using an untrusted hosting provider. An independent auditor can approve a software release. Where no independent signer exists, a pinned release can prevent the server from selectively modifying an application for a particular user.

The server may still deliver the content, but it can no longer silently inject JavaScript or substitute a different version for one user unless that version is authorized by the applicable key or already committed to the pinned release.

Page integrity also provides an alternative to some uses of Subresource Integrity. SRI works only when the HTML referencing a resource includes its checksum. Omit that attribute, and the browser loads whatever the CDN returns. Integrity managed outside the page—in integrity.log, manifests, and related records—does not depend on every resource reference being annotated correctly.

SRI remains useful when present: it provides an additional integrity check directly in the page. But if it is omitted, page integrity can still enforce the file’s checksum independently.

Code Samples

The precise format, witness storage rules, and other implementation details live with the reference implementation: github.com/entelecheia-inc/page-integrity.

A log writer, a verifier, a witness, and tests are there for anyone who wants to read how the format is written and checked.

Keep reading

  1. Encrypting App Data at Rest on macOS

    September 13, 2026

    Entelecheia builds software for handling confidential data, and secure local storage is foundational to that work. We’re open-sourcing our approach to storing data securely on …

    Continue reading

  2. Hiding Text in a Numeric ID

    September 2, 2026

    When designing IDs that a person may need to read, copy, type, or pass to someone else, usability matters as much as uniqueness. A lookup ID may have to be dictated over the phone, …

    Continue reading

Entelechy, (from Greek entelecheia), in philosophy, that which realizes or makes actual what is otherwise merely potential. — Encyclopedia Britannica