The team CRM

A CRM for the team: companies, contacts, actions and schedules, a folder each, and a graph that links them. It lives in two SGit vaults, like the observability vaults: a public CRM anyone can read, and a private CRM for what not everybody needs to see. Built by conductor@web-summit.dinis on 5 November 2026 (WS-170), seeded with public information first.

The diagram and the live CRM need JavaScript: they are drawn here by the page.

The two CRMs

Public CRMPrivate CRM
Vaultws-team-crm-publicws-team-crm-private
Who reads itanyone: its read key is published (data/crm.json)the team: its key is sealed to each person and their conductor
What goes inpublic facts only, each with its source URL and the date readthe team's own records: actions, requests, later the non-public details of contacts
Seeded withthe newsroom's companies, organisations, the people the summit lists (name, role, organisation) and the agendathe six open requests from WS-165, and the public CRM's own vault key

The layout

Both vaults use the same folders, so a record can move from one to the other:

Every record carries its id, its sources (url and when read) for public facts, when it was updated and by whom.

Two layers of encryption

  1. The vault (layer 1). A vault is encrypted with its key. The public CRM's read key is published on purpose. The private CRM's key is sealed to each person's own key (it appears in their For you panel and opens on this page) and to their conductor agent's key.
  2. The record (layer 2). Inside the private CRM, a sensitive record is stored as <name>.sealed.json (envelope ws-crm-env-1): the record is encrypted with its own random key, and that key is sealed to each person in the record's audience, with the same keys and the same steps as everything else sealed to you on this site. So reading it needs both the vault key and your own key; with the vault key alone you see that a record exists, its kind and who it is for, never what it says. Agents can be in an audience too, with their own keys.

Who can read a record can change: node admin/tools/crm.mjs reseal --audience dinis,silvio <file> seals it again under a new key. The six seeded requests are sealed to Dinis and each request's owner; the public CRM's vault key is sealed to everyone with a site key.

Unsealing inside the CRM app: the dance

The private CRM's own app runs on dev.vault.sgraph.ai, so it cannot reach your key, which lives only in this site's browser storage. So this page does the unsealing for it:

  1. Open the private CRM above, then Open the CRM app here, with unsealing: the app opens inside this page, and you say yes once ("Allow the CRM app to open the records sealed to you?").
  2. In the app, a sealed record shows Unseal. The app asks this page for that one record, by its path.
  3. This page reads the sealed record itself, from the vault it holds open, opens it with your key if you are in its audience, and hands back only the record. Your key, the vault key and the record's own key never leave this page; key records are never handed over; at most 30 a minute; the page counts what it unsealed.
  4. Anything else is refused or ignored: a message from any other frame gets no answer, a path that is not a sealed record is refused, a record not sealed to you is refused. Opened in a new window, the app says to come back here to unseal.

For an agent

For an agent: this page is https://web-summit.sgit.ai/crm/index.html (markdown: https://web-summit.sgit.ai/crm/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.