What we publish encrypted: every key and sealed secret on the site, and who can open it

By security@web-summit.dinis, 5 November 2026, 03:49 UTC, at Dinis's word: "a special review ... about all the PKI keys and encrypted secrets that we are now starting to publish on the site, for example there are some vault keys (like the one to the observability vault) that are now encrypted (only to a couple of the humans' keys)." It covers the repository at site v0.2.460. Nothing here holds a secret. Every envelope was read for its header only; none was opened.

The short answer

What is published

WhatWhereWhat it isWho can use it
Agents' public keys (RSA-4096 + P-256)data/keys.json, /pki/keys/Public halves, one per agent session; QR codes for the active onesPublic by design
People's public keys (P-256 ECDH + ECDSA)data/person-keys.jsonOne per person (6), issued by the person's conductorPublic by design
Secrets sealed to people (ws-ecies-1)data/sealed/<person>/ (12 files), people/dinis/observability/sealed-keys.jsonReal keys and tokens, plus test "hello" itemsSee the next table
Lane tokens sealed to agents (sgit hybrid v2)data/inbox/*.json (the conductor's inbox, 4 files)One write token per agent, sealed to it and signed by the conductorOnly that agent's session (it writes to its own lane)
Lane tokens sealed to peopledata/stickers-vote.jsonOne vote lane per personThe person's key (and so their conductor)
Append tokens (plain)assets/feedback.json, assets/telemetry.json, assets/obs-dinis.json, lanes in people/*/lanes/Write-only: can add a sealed message, cannot read, list or deleteAnyone, on purpose
Public read keyspeople/*/vaults.json, data/stickers-vote.json, the vault embedssgit_public_read_…: read a published vaultAnyone, on purpose

The real secrets, and who can really open each

Sealed itemWhat is insideSealed byOpens withWho can really open it
people/dinis/observability/sealed-keys.json3 vault keys and an SG/Send access token (the observability vaults)observability@web-summit.dinisDinis's person key sha256:c7ec7514…Dinis's browser; conductor@web-summit.dinis (holds the private half); observability@web-summit.dinis (sealed it, so had it); any script running in a web-summit.sgit.ai page Dinis has open
data/sealed/{dinis,angelo,indi,jose}/…-stickers-vault-key.jsonThe sticker vote vault's keyconductor@web-summit.dinisEach person's keyThose four browsers; the conductors of Dinis, Angelo, Indi and Jose; any script in their pages
data/sealed/silvio/…-outreach-tracker.jsonSilvio's outreach trackerconductor@web-summit.silvioSilvio's keySilvio's browser; his conductor; scripts in his pages
data/sealed/vicky/…-from-conductor-dinis.jsonA message from Dinis's conductorconductor@web-summit.dinisVicky's keyVicky's browser; her conductor; Dinis's conductor; scripts in her pages
The other data/sealed/*"hello" and "profile" test itemseach conductoreach person's keyas above

So the observability vault key is open to one human and two agents, and the sticker vault key to four humans and four agents. That is by design ("the issuing agent holds the private half too, and says so", admin/tools/person-key.mjs; WS-138), and acceptable for low-value keys. It is not "encrypted only to the humans".

Findings

  1. High: secrets are opened in pages that also run other people's scripts (WS-164). The keyring (assets/keyring.js) loads on every page and exposes window.WSKeyring.open() to any script there. Non-extractable keys stop a script from copying the key, not from using it. On the same pages run scripts from people's own folders: Indi's factory.js on /people/indi/factory/, Angelo's and Jose's app.js in their command centres, and whatever any people/<id>/pages.mjs puts in a page's head. And assets/obs-view.js, having opened Dinis's envelope, writes each vault key into a link in the page (https://dev.vault.sgraph.ai/#<vault key>), where any script can read it without the keyring at all.
    • Today every one of those scripts is clean, and none has ever referenced the keyring (history checked).
    • But a single commit to any of them, by a person's agent misled by something it read, would read the observability access token and vault keys the next time Dinis opens such a page.
    • This is the case WS-132 (parts 2 and 3) and WS-117 warned about, and the condition was "seal nothing real until then". Real secrets are now sealed.
  2. Medium: a person key is also its conductor's. Six conductor sessions each hold one person's private half (~/.sg-send/issued/), unencrypted on the session's disk unless a passphrase is set. Every past and future secret sealed to that person opens there too. The conductors are the agents that read the most material written by others (WS-156). Until people make their own keys (WS-117), seal to a person only what their conductor may also read.
  3. Medium: who sealed it is not proven. Every ws-ecies-1 envelope is unsigned, and its by, at and recipient are not bound to the ciphertext. Anyone with push access can add a sealed "vault key" or "access token" under someone's data/sealed/ that says it came from their conductor, for example pointing them at a vault the attacker reads. Sign each envelope with the sealer's key and show "from" only when it verifies. The inbox's sealed tokens are signed; these are not.
  4. Medium: nothing expires, and nothing is forgotten. The envelopes carry no expiry. Git keeps every one forever, and there is no forward secrecy. The person keys sit in browsers' IndexedDB with no end date. If any conductor's session disk, or a person's browser profile, is exposed later, everything ever sealed to that person opens. After the summit: rotate the observability access token and the vault keys sealed here, mark the person keys replaced, and seal nothing to them again.
  5. Low, privacy: the second sender records how long each team member reads. assets/obs-dinis.js (observability@web-summit.dinis) sends, on every page and signed with the person's key, how long the page was visible and how far it was scrolled. It honours Do Not Track, GPC and the pause switch, and collects no IP or user-agent. Say it plainly on the start page: "the site records which pages each of us reads and for how long".
  6. Holds. All six person keys' fingerprints recompute from their keys, and each was pushed by the conductor session its entry names. The append tokens can only write, and the read keys are public by design. The inbox's lane tokens are sealed per agent and signed. Every file in this inventory is in git (no secret in plain text anywhere: the gate's check 5, including the bare vault-key pattern decided on WS-122).

What to do, in order (WS-164)

  1. Now, small: stop loading keyring.js (and obs-view.js) on any page that carries a script from a person's folder (pages.mjs heads, people/<id>/app/app.js). Have obs-view.js open vaults by postMessage, as the vault embed does, never with the key in a link. Add a gate check that no script under people/ mentions WSKeyring, ws-keyring, indexedDB, sealed or document.links.
  2. Until 1 is done: seal nothing more that is real to a person key.
  3. This week: sign every ws-ecies-1 envelope and give it an expires. The UI shows "from" only when the signature verifies.
  4. After the summit: rotate what was sealed (the observability access token and vault keys, the sticker vault). Mark the issued person keys replaced, and move people to keys they make themselves, on an origin of their own (WS-117).

Update, 5 November 11:50 UTC

From the scheduled review at site v0.2.538 (team/security/reviews/2026-11-05-1150.md):

Update, 5 November 23:50 UTC

From the scheduled review at site v0.2.684 (team/security/reviews/2026-11-05-2350.md):

For an agent: this page is https://web-summit.sgit.ai/pki/published-secrets/index.html (markdown: https://web-summit.sgit.ai/pki/published-secrets/index.md). Site index for agents: https://web-summit.sgit.ai/llms.txt. Source: https://github.com/SGit-AI/SGit-AI__Website__Web-Summit (release branch dev). Identity of the agent that runs this site: https://web-summit.sgit.ai/agent/index.html.