← Thoughts

Encrypted patches, unlocked on patch day

Ship the fix early as ciphertext and publish the key at release time. Teams stage it in advance and apply it at the same moment, instead of racing attackers.

Tim Conrad · Updates · Patch diffing · Key release

Status
Draft
Started
Last revised

SpokenEncrypted patches, unlocked on patch day. A thought by Tim Conrad, read aloud. It takes about twenty minutes, in ten short chapters. Three words carry the idea. Patch day, the moment a fix becomes public, written as T. The encrypted bundle, which arrives early. And the key, which arrives at T. When a figure comes up, the narration describes it, so you can listen without the screen.

The problem

A security fix tells an attacker where the bug was. That was always true: compare the old and the new version, a step called patch diffing, and the change points at the bug. What changed in the last year is the price of turning a fix into an exploit.

Keycloak is a good example. Between November 2025 and November 2026 the project tagged 47 releases, about one every eight days, across four supported lines, and fixed at least 50 CVEs [1]. In August 2026 one of them, CVE-2026-18963, let an unauthenticated attacker take over accounts through the password-reset flow [2]. The fixed builds carry tag dates a week before the CVE was published [1], and the public fix is a small change of 57 added lines [3]. A public proof of concept credits Claude for "research and PoC development assistance" and ships "the annotated patch diff" [4]. A team that runs Keycloak has to patch every week, and every patch is a map for someone else.

A bug that is already fixed and public is called an n-day. One that nobody has fixed yet is a zero-day. The numbers for n-days are from 2026:

  • Anthropic gave its Mythos Preview model only public patches. The first working Firefox exploit came less than an hour after the patch. Windows kernel exploits cost about $2,000 each. Its summary: "The binding constraint to N-days is now just a few thousand dollars and API access" [5].
  • Elastic found the bug behind a Windows patch "within minutes" of reading the diff with an LLM. The exploit took hours instead of weeks [6].
  • Google counted 141 exploited vulnerabilities from January to August 2026, more than in all of 2025, and puts the growth in "the rapid weaponization of n-days" [7].
  • Attacks start early. Mandiant estimates that in 2025 exploitation began on average seven days before the fix was public [8]. Rapid7 measured a median of five days from publication to the CISA list of exploited bugs [9].

SpokenThree numbers to keep from that list: an exploit from a patch in under an hour, for about two thousand dollars, and attacks that begin within days of the fix.

Finding a new bug with AI works, but it is a search, and search costs. XBOW spent about $40,000 on API calls for a six-day campaign that produced a full Chrome exploit chain [10]. Anthropic's OpenBSD campaign took about 1,000 runs for under $20,000, and the FFmpeg one about $10,000 [11]. A patch removes the search: it says where to look.

What it costs: finding new bugs against exploiting patched ones Log scale. Finding new bugs, per campaign: XBOW Chrome full chain about 40,000 dollars; Anthropic OpenBSD about 1,000 runs under 20,000 dollars; Anthropic FFmpeg about 10,000 dollars. Exploiting a patched bug, per exploit: Windows kernel exploit about 2,000 dollars; Linux kernel n-day under 1,000 dollars; Windows crash proof of concept about 120 dollars. $100$1k$10k$100k Find new bugs · per campaign XBOW · Chrome full chain, 6 days~$40k Anthropic · OpenBSD, ~1,000 runs<$20k Anthropic · FFmpeg, some 100 runs~$10k Exploit a patched bug · per exploit Windows kernel exploit, from patch~$2k Linux kernel n-day exploit<$1k Windows crash PoC, from patch~$120 What it costs: finding new bugs against exploiting patched ones $100$1k$10k$100k Find new bugs · per campaign XBOW · Chrome chain~$40k Anthropic · OpenBSD<$20k Anthropic · FFmpeg~$10k Exploit a patched bug · per exploit Windows kernel, from patch~$2k Linux kernel n-day<$1k Windows crash PoC~$120

SpokenFigure one compares costs on a log scale: each grid line to the right means ten times more money. The top group is finding new bugs, one whole campaign per bar. About forty thousand dollars for a Chrome exploit chain, under twenty thousand for OpenBSD, about ten thousand for FFmpeg.

SpokenThe bottom group is exploiting a bug that a patch already gave away, one exploit per bar. About two thousand dollars for Windows, under one thousand for Linux, and about a hundred and twenty for a crash proof of concept. The costs in the bottom group are ten to a hundred times lower. That difference is what a patch gives away.

Fig. 1 · Cost per result on a log scale, from [5], [10] and [11]. Discovery is a whole campaign, the n-day rows are one exploit each. Some discovery is cheaper: depthfirst reports 21 FFmpeg bugs for about $1,000 [12].

SpokenPause here for a moment. How many days does your team need from a published fix to production?

The idea

The idea of this post: ship the fix days early, but encrypted. Teams download it, plan the change and stage it. At patch day T, only the key is published, and everyone applies the fix at the same moment. Nobody could diff it before T. The goal is not to win the race against the attackers, but to stop it from being a race.

Timeline: today and with an encrypted pre-load Today the attacker can diff the patch as soon as the first host downloads it at T, while installs spread over weeks. With a pre-load, the encrypted bundle arrives in the week before T, the key arrives at T, and automatic updates install within minutes, while the attacker also only starts at T. T · patch day Today installs spread over weeks diff → exploit from the first download nothing on the hosts yet Pre-load encrypted bundle on every host installed within minutes diff → exploit same start line 32-byte key published −7 days T +7 days Timeline: today and with an encrypted pre-load T · patch day Today nothing on hosts installs: weeks diff → exploit from first download Pre-load bundle on hosts in minutes diff → exploit same start line 32-byte key published −7 days T +7 days

SpokenFigure two shows two timelines around patch day T, the vertical line in the middle. The top row is today. Nothing is on the hosts before T. At T the patch goes out, installs spread over weeks, and an attacker can diff it from the first download.

SpokenThe bottom row is the pre-load. The encrypted bundle sits on every host during the week before T. At T only the thirty-two byte key is published. Hosts that update by themselves install within minutes, and the attacker starts at the same moment as everyone else.

Fig. 2 · With a pre-load, the attacker and the defenders start at the same moment, and hosts that update by themselves are done within minutes.

SpokenHas anyone shipped something locked before? Games do it all the time.

Games already ship this way, and at a scale that no patch reaches. A pre-load puts a new game on your disk days before launch, and it opens only at release. Steam, as SteamDB describes it, encrypts each depot with AES-256 and one key that is the same for every user, so mirrors and caches can serve the same bytes, and only owners can ask for the key [13]. That is the half I want: millions of copies in place before the moment, and one small key at the moment.

GTA Online shows what goes wrong. Rockstar ships the content of later updates early inside earlier ones and switches it on from its servers. The files are encrypted, but the keys are in the game, so dataminers read upcoming cars and missions long before they go live. For a patch, that would undo everything: with the key on the device, anyone can diff the fix before T.

So the lesson from games is four rules for patches:

  • The key is not on the device before T.
  • The device clock never opens anything. Only the published key does.
  • Everything is signed, and the client checks the ciphertext before T.
  • Decryption at T is cheap. One key, one pass.

SpokenThose four rules are easy to write down. The next question is how to build them on update systems that already exist.

A design

A signature on the patch alone is not enough. If the one signing key leaks, the thief can sign malware. A mirror can also cheat without any key. It can serve an older version with a known bug, a rollback attack. Or it can keep serving yesterday's list of updates, so the client never learns that a fix exists, a freeze attack.

The Update Framework, TUF, was designed against exactly these attacks [14]. It splits trust into roles, and each role has its own keys:

  • Root names the keys of all other roles. Its keys stay offline and are needed only to change those keys.
  • Targets signs the list of files, with the hash and size of each.
  • Snapshot signs which version of each list is current, so a mirror cannot mix old and new lists.
  • Timestamp signs a short note that says what is newest. The note expires quickly, so a freeze shows.

A role can also require a threshold: k of its n keys must sign, so one stolen key is not enough. Uptane is TUF adapted for cars [15]. It adds a second repository, the director, which tells each vehicle which images to install, and the director can encrypt images for each control unit. The Uptane standard even names patch diffing as an attacker goal.

What neither has is a key that is published later. The design adds one role for that, the release role, next to targets:

  1. Pre-load. Days before T, the vendor publishes the encrypted bundle as an ordinary target. The manifest with its hash, size and release time is signed by the targets role under the organisation's root key. Clients download it and check the hash.
  2. Release. At T the release role signs a short statement: patch id, hash of the ciphertext, the 32-byte content key. A threshold keeps one person from releasing early: say three officers each hold a key, and any two of them must sign.
  3. Log. Every statement goes into a transparency log. That is a public list that only grows: entries can be added but not changed or removed, and anyone can check that an entry is in it. Certificate Transparency uses such logs for TLS certificates [16]. Anyone who watches the log sees a release before T, or a different key for some customers.
  4. Install. The client checks the statement and the log entry, decrypts with the key and installs.
Who signs what An offline organisation root key delegates to a targets role and a release role. Days before T the targets role signs a manifest with the hash of the encrypted bundle, and mirrors carry both. At T a release role, two of three officers, signs a key-release statement that is written to a transparency log. The client verifies the manifest, the bundle hash, the statement signature and the log entry, then decrypts and installs. Organisation Mirrors and log Client org root key offline · delegates roles targets role signs the manifest release role 2 of 3 officers −7 days at T manifest + bundle hash, size, patch id, T key-release statement patch id, hash, key · 104 B transparency log append only, public 1 check manifest against org key 2 check bundle hash from manifest 3 wait for T the key opens, notthe clock 4 check statement signature + log proof 5 decrypt, install AES-GCM, key from 4 Who signs what Organisation org root keyoffline · delegates roles targets rolesigns the manifest release role2 of 3 officers −7 days manifest + bundlehash, size, id, T at T key releaseid, hash, key · 104 B transparency logappend only, public Client 1 check manifestagainst org key 2 check bundlehash from manifest 3 wait for Tthe key opens, not the clock 4 check statementsignature, log proof 5 decrypt, installAES-GCM, key from 4

SpokenFigure three shows who signs what, in three parts: the organisation, the mirrors and the log, and the client. It builds up in five steps, one for each line below the drawing.

  1. The organisation’s root key stays offline. It gives two roles their rights: one signs the manifest, the other releases keys.
  2. Days before T the targets role signs the manifest, and mirrors carry it together with the encrypted bundle.
  3. Every client checks the manifest against the organisation key and the bundle against the manifest. Then it waits; its clock opens nothing.
  4. At T two of three release officers sign the key-release statement, and it goes into the public log.
  5. The client checks the statement and its log entry, decrypts the bundle with the key and installs.
Fig. 3 · Two roles under one offline root. The release role can only publish keys for ciphertext that is already pinned, so a stolen release key cannot push code.

The statement is small and public, so any mirror, CDN or even DNS can carry it. That makes the release hard to block.

key-release statement, about 104 bytes
patch    8 B   id of the patch, points to its manifest entry
key     32 B   AES-256-GCM content key
sig     64 B   Ed25519 over patch id, ciphertext hash and key

The signature covers the hash of the ciphertext from the manifest, so the key belongs to exactly one bundle. With a threshold, each officer adds a signature of 64 bytes.

Without a key server

The key server is the weak spot. It can go down at the wrong moment, someone can force it to wait, or someone can leak the key early. There is a way to release a key on time without any server of the vendor.

drand is a public randomness beacon [17]. Every three seconds it publishes a new round: a round number and a value. The value is a signature over the round number, made with a key that nobody holds as a whole. When the network was set up, its members, a group of independent organisations called the League of Entropy, split that key into shares, and each member keeps one share.

For each round, every member signs the round number with its share when that round's time has come. Enough of these partial signatures together give the full signature, and anyone can check it against one public key that never changes. Cryptographers call this a threshold signature. So nobody can compute the value of a future round, not even a member alone. It takes enough members, and honest members sign a round only at its time.

The second part is a kind of encryption where the key can be a name. In identity-based encryption, anyone can encrypt to a name, an email address for example, with one public master key. The private key for that name is made later, by whoever holds the master secret. In drand, the name is a round number, the master key is drand's public key, and the signature for a round is the private key for it [17]. The master secret is the split key of the League, so the private key for a round appears only when the members sign that round.

So the vendor picks the round that falls on patch day T and encrypts the patch key to that round. Until T nobody, the vendor included, can decrypt it. At T drand publishes the signature for that round, and the signature opens it. The free tool tlock, from the drand team, does exactly this [17].

How a drand number opens a patch key at patch day Independent organisations make a new numbered value every three seconds; the value for a position exists only when enough of them have taken part, at that moment. Days before patch day the vendor locks the patch key to the value at position T, which does not exist yet. At T the organisations make that value, it is published, and anyone can use it to open the lock and install the patch. League of Entropy independent organisations org Aorg Borg Corg Dorg E enough of them together make the value for T, only when T has come (B is not needed) drand values T already published not made yet one every 3 seconds Vendor · days before T patch key, locked to the value at T Everyone · at T value T opens it patch key → install How a drand number opens a patch key at patch day League of Entropyorg Aorg Borg Corg Dorg E T drand valuesone every 3 seconds publishednot made yet Vendor · before T key, locked to the value at T Everyone · at T T opens it key → install

SpokenFigure four has three layers. At the top, the organisations of the League of Entropy. In the middle, the row of drand values, one every three seconds, with the value for T marked. At the bottom, the vendor on the left and everyone else on the right. It builds up in four steps.

  1. drand makes a new value every three seconds. Values for later moments do not exist yet.
  2. Days before T the vendor locks the patch key to the value at T. Nobody can open it now, the vendor included.
  3. At T enough of the organisations together make the value for T. Not every one is needed.
  4. The value is public. It opens the lock, and everyone installs the patch.
Fig. 4 · The lock points at a value that does not exist yet. Only the organisations together can make it, and only at T.

The vendor can use both ways at once: its own key server and the drand lock. Then the patch opens at T even if the vendor's server is down. Two limits remain:

  • The vendor still makes the key before it locks it, so someone inside can still leak it.
  • Once locked, the key cannot be held back. If the fix turns out to be broken, it opens at T anyway.

Check the chosen position before you publish. A wrong one, in the past, opens the patch at once.

Air-gapped sites

Offline networks already carry updates in on removable media. With a pre-load, the large part crosses days before T and can be checked against the organisation's key. At T only the key has to cross: the signed statement, or the 48-byte drand number for T, which the site checks against drand's public key, stored there in advance [17]. Either fits in one QR code, which holds up to 2,953 bytes [18], or can be typed in as hex.

Updates for an air-gapped site Days before T, the encrypted bundle and its signed manifest cross the air gap on removable media, gigabytes in size. At T only a key-release statement of about 104 bytes, or a 48-byte drand number, crosses, small enough for one QR code. The offline site checks both against pinned keys, then decrypts and installs. Connected Air gap Offline site vendor mirror bundle, manifest key release vendor statement or drand number keys stored early org key drand public key at T verify offline decrypt, install days before T USB or disc encrypted bundle · gigabytes at T QR code 104 B signed statement, or 48 B drand no. Updates for an air-gapped site Connected vendor mirrorbundle, manifest, key release days before TUSB or discbundle · gigabytes at T QR code104 B statementor 48 B drand no. air gap Offline site stored early: org key, drand public keyat T: verify offline, decrypt, install

SpokenFigure five has three zones: the connected network, the air gap, and the offline site. Days before T, the encrypted bundle crosses on a USB stick or a disc, gigabytes in size. At T only a QR code crosses: a signed statement of about a hundred bytes, or the forty-eight byte drand value. The site checks it against keys that it stored earlier, then decrypts and installs.

Fig. 5 · The gigabytes cross early. At T only a few bytes cross, and they are public, so the channel needs to reach the site, not to be secret.

A checked drand number also proves that its moment has passed. A site without a reliable clock learns that it is at least that late.

Open source in private

For an open-source project the hard part comes earlier: the fix has to be written and tested without showing it. Today it often shows. In the Keycloak case the fixed builds were tagged a week before the CVE, the port to the main branch was a public pull request whose title does not mention security, and the proof of concept was written from that diff [3][4].

The tools for private work are thin. On GitHub, maintainers can open a temporary private fork from a security advisory. Only invited collaborators see it, but no CI runs there, branch protection does not apply, and merging and publishing are manual steps [19]. On GitLab a merge request in a public project is public; private work needs a separate private fork [20]. Distributions coordinate by mail, under an embargo: a fixed time in which everyone who knows about the bug keeps quiet. The linux-distros list allows an embargo of at most 14 days [21], and the kernel security team holds a fix back for at most 7 days, 14 in exceptional cases [22]. The Git project comes closest to the idea of this post: it prepares signed tags in a private repository, sends a bundle to the distributions less than a week ahead, and pushes in public on release day [23]. That bundle is plaintext and goes to a few.

A security fix in an open-source project, from private work to release The maintainers write and test the fix on a private branch with private CI. Days before T the project publishes the encrypted, signed build. The embargo list of distributions gets the key early to test. Everyone else stages the ciphertext. At T the key is published, everyone applies the fix, and the public repository gets the merge and the advisory. T · release MaintainersReleaseEmbargo listEveryonePublic repo private branch, private CI encrypted build, signed key published early key: test ciphertext staged apply at T merge + advisory −10 days T +6 days A security fix in an open-source project, from private work to release T · release Maintainersprivate work, CI Releaseencrypted, signed key published Embargo listearly key Everyonestaged apply at T Public repomerge + advisory −10 days T +6 days

SpokenFigure six is a timeline with five rows, from ten days before T to six days after. The maintainers work on a private branch with private CI. Then the encrypted, signed build is published. The embargo list gets the key early to test, and everyone else stages the ciphertext. At T the key is published, everyone applies the fix, and the public repository gets the merge and the advisory.

Fig. 6 ·Work in private, publish the ciphertext early, open it for everyone at T. The embargo list keeps what it has today: early access to test.

To make this normal, a forge such as GitHub or GitLab would need (Fig. 7):

  • Private branches and pull requests inside the public repository, visible only to maintainers and a security role.
  • Private CI for those branches, with closed logs and no webhooks to outside apps.
  • Release artefacts that are published encrypted and signed, with the key held by the forge.
  • One action that, at T, publishes the key, merges the branch and publishes the advisory.
What a forge would need for a private fix in a public repository Inside the public repository a private branch holds the fix; only maintainers and a security role see it. Private CI with closed logs tests it. Days before T the forge publishes the encrypted, signed release, and the embargo list gets the key early. At T one action publishes the key and the advisory and merges the branch, and everyone applies the fix. Public repository T main · public private branch · maintainers and a security role only private CI, closed logs releases encrypted release, signedembargo listearly key: test mergekey + advisoryeveryoneapplies at T What a forge would need for a private fix in a public repository Public repository T main · public private branchmaintainers + security role CI, closed logs releases encrypted release embargo listearly key: test merge key + advisory everyoneapplies at T

SpokenFigure seven shows what this looks like inside one public repository, in four steps.

  1. The fix is written on a private branch inside the public repository. Only the maintainers and a security role can see it.
  2. Private CI builds and tests the branch. Its logs stay closed.
  3. Days before T the forge publishes the encrypted, signed release. The embargo list gets the key early and tests.
  4. At T one action publishes the key and the advisory and merges the branch. Everyone applies the fix.
Fig. 7 · What a forge would need for a private fix in a public repository.

The embargo lists fit into this as they are: their members get the key early and test, everyone else gets the ciphertext early. Each early key is a chance to leak, so the list stays short and the embargo stays short.

SpokenThat is the design. Here is what it does not solve.

What it does not fix

  • Diffing after T. At T the patch is public. The scheme moves the start line; it does not stop the race. It helps the hosts that install at once.
  • Zero-days. They are still 62 % of the vulnerabilities Google saw exploited in 2026 [7]. No patch, nothing to encrypt. The scheme is for the part that grows fastest.
  • Slow patching. A host that waits a month after T gains nothing. The scheme helps those who can apply at T.
  • Metadata. File names and sizes still show which component changed. Padding and fixed bundles help, at a cost in bandwidth.
  • Insiders. The key exists before T. Create it late, keep it in an HSM, split it between people.
  • Testing. Companies test patches before they roll them out. Most can stage before T but test only after it. Early keys for a few, as embargo lists do today, bring back the risk of leaks.

SpokenWhich of these limits matters most for your systems?

Prior art

The idea is not new. Microsoft patented an encrypted update with a key that follows later, first in 2006 [24] and in a version with a set release moment around 2008 [25]. I found no vendor that does it for security patches today. By my reading, which is not legal advice, the first patent ends around August 2026 and the second may run to about 2028. Anyone who wants to ship this as a product in the US before then should have a patent attorney read both.

What I take from it

The tool is cheap for an update system that already signs its metadata. It does not stop patch diffing, and with LLMs diffing is now cheap. It lets every team have the fix ready when it becomes public, and that turns patch day from a race into a date.

SpokenTo sum up. Patches are now cheap to turn into exploits. Ship the fix early but encrypted, publish only the key at T, and every team gets the same start line. The parts exist: TUF or Uptane for the signatures, a transparency log for the release, and drand with tlock for a release without a key server. The sources are on the page.

Sources

  1. Keycloak: tags and security advisories, Nov 2025 to Nov 2026; GitHub Advisory Database.
  2. The Hacker News: Critical Keycloak password reset flaw, Aug 2026; SentinelOne: CVE-2026-18963.
  3. Keycloak: pull request #51844, Aug 2026.
  4. Red-Darkin/CVE-2026-18963-keycloak, 2026.
  5. Anthropic: N-days to N-hours, Jun 2026.
  6. Elastic Security Labs: Patch diff to SYSTEM, Mar 2026.
  7. Google Threat Intelligence: Vulnerability discovery and exploitation trends in the AI era, Sep 2026.
  8. Mandiant: M-Trends 2026, Mar 2026.
  9. Rapid7: 2026 Global Threat Landscape Report, 2026.
  10. CSO Online: XBOW spent $40k on AI and cracked Google Chrome, Oct 2026.
  11. Anthropic: Mythos Preview, Apr 2026.
  12. depthfirst: 21 zero-days in FFmpeg, Jun 2026.
  13. SteamDB: How the Steam download system works.
  14. The Update Framework specification.
  15. Uptane Standard.
  16. RFC 9162: Certificate Transparency 2.0; Sigstore Rekor.
  17. drand: tlock; quicknet is live, Oct 2023 (a round every 3 seconds); Gailly, Melissaris and Romailler: tlock: Practical Timelock Encryption from Threshold BLS, IACR ePrint 2023/189.
  18. ISO/IEC 18004 capacity table, summarised by Keyence.
  19. GitHub Docs: Collaborating in a temporary private fork.
  20. GitLab Docs: Confidential merge requests.
  21. Openwall: The distros mailing list.
  22. Linux kernel: Security bugs.
  23. Git: How to coordinate embargoed releases.
  24. Microsoft: US 7,876,902 B2, Distribution of encrypted software update to reduce attack window.
  25. Microsoft: US 8,171,560 B2, Secure content pre-distribution to designated systems.

Revisions

  • Rewrote it to be read aloud and for readers who do not know every term: explained patch diffing, n-days, TUF, Uptane, transparency logs, drand and timelock encryption; folded the games section into "The idea" and cut the patents to one paragraph; added a narration with spoken parts.
  • First version, as a blog post.

Feedback

Not shared yet. When I post about it, what people answer goes here, with what it changed.