Viewing from the United States? See Termsroom for US teams

Termsroom, the Canadian-built software where the employer and the union work from one shared bargaining and grievance record, is now available in French. Termsroom, le logiciel conçu au Canada où l’employeur et le syndicat travaillent à partir d’un même dossier de négociation et de griefs, est maintenant offert en français.

Trust and security

Where we actually stand

Termsroom exists to hold the record of a negotiation between two parties who do not fully trust each other. That only works if neither of them has to take our word for anything. This page says what is certified, what is not yet, and how to check the rest yourself.

Certification status

Termsroom does not yet hold a SOC 2 report. Our Type I audit engagement is scheduled to begin on Thursday 11 February 2027, and we will share the report when the auditor issues it. The Type II observation window then runs to at least 11 May 2027, with the report expected in June 2027. An AI-assisted internal security review of the source code and a locally built copy of the database was completed on 30 September 2026, and the database fixes it led to are in place. We ran it ourselves using Anthropic’s Claude, so it is not independent, it did not test the live service, and it is not part of a SOC 2 report. An independent penetration test is scheduled for Thursday 5 November 2026. A SOC 2 Type II observation window is a minimum of three months and cannot be backdated, which is why no vendor can produce one faster.

What we can show you today is the controls themselves, running, and the evidence that they are. Everything below is live.

Vendor assessment

completedself-assessment, not a certification

Termsroom has completed a HECVAT 4 self-assessment, version 4.1.6. It covers security, privacy, IT accessibility and artificial intelligence, and it is available to any institution on request. We do not ask for a non-disclosure agreement first, because nothing in it is commercially sensitive and the community that maintains it takes the view that institutions should not have to sign for it.

Being precise about what that is: the Higher Education Community Vendor Assessment Toolkit is a questionnaire a vendor completes about itself. There is no auditor, no pass mark and no scoring authority, and EDUCAUSE, which maintains it, describes the answers as self-attested. It is a way to give your reviewers what they need in a format they already know, while the SOC 2 work above runs its course. It is not a certification and we will not describe it as one.

It is recognised in Canadian higher education. The University of Toronto lists a HECVAT among the vendor security documents its information risk assessment accepts, and CANARIE, the national research and education network, reviewed one during its own procurement.

What that does not mean, since this page exists to be exact rather than flattering: no institution has assessed Termsroom using ours. Toronto runs its own risk assessment under ISO 27005 and NIST 800-39, and a HECVAT is an input to it rather than a substitute for it. Naming them here says that the format is accepted, and nothing more.

To request it, or a privacy impact assessment pack for an Ontario institution: security@termsroom.com.

Controls running right now

Each of these ran a query against the live system when this page loaded at 08:09 UTC, and each could have come back red. Your own security team can run every one of them against your own data. The query is printed beneath each result.

  • No unclassified data

    OperatingCC8.1 · C1.1

    Every column in the database is declared and classified. Nothing has been added that we have not accounted for.

    Zero unclassified columns.

    select * from tr_uninventoried_columns()
  • Audit record unaltered

    OperatingCC7.2 · CC7.3

    The full history of who did what is hash-chained and append-only. If any entry had been edited or removed, this check would fail.

    93 entries verified.

    select * from tr_verify_audit_chain()
  • No cross-party access

    Not measuredCC6.1 · C1.1

    Nobody from the other side of a negotiation has ever read your caucus material. Each party can run this query against their own data.

    Sign in to run this against your own organisation.

    select * from tr_cross_party_access(:org)
  • Organisational storage only

    OperatingC1.1 · CC6.1

    Every connected storage location is a corporate, union or government tenant. Personal accounts are refused, not warned about.

    All active connections validated as organisational.

    select count(*) from storage_connections where status='active' and not is_organisational
  • Distribution records entitlement, not content

    OperatingC1.1 · CC6.1

    A recipient row says that a named person was entitled to a named document and whether they have seen it. It never carries the document.

    No distribution holds anything it should not.

    select * from tr_verify_distribution_custody()
  • Closing records reach both parties

    OperatingC1.1 · CC7.2

    When a negotiation closes, the closing record is written into each side's own storage and only a pointer and a hash are kept here. A closure marked as reported with fewer than two copies has not delivered what it claims.

    Every closed negotiation delivered a record to both sides.

    select * from tr_verify_closure_custody()
  • Sealed risks stay sealed

    OperatingC1.1 · CC6.1

    A risk raised in a caucus is visible only in that caucus. Making it visible to the other side moves it to the shared table and is recorded as a disclosure, so a risk marked as shared while still sitting in a caucus is an anomaly.

    No risk is visible anywhere it was not deliberately disclosed.

    select * from tr_verify_risk_custody()
  • Connected to the declared database

    OperatingCC6.1 · CC8.1

    This deployment is talking to the database this product is supposed to use, in the region we say it is in.

    Project xvsejdzvsyqoimxkxjxq, Supabase, ca-central-1.

    NEXT_PUBLIC_SUPABASE_URL compared against supabase/expected-project.json

Properties of how it is built

These are not measurements. They are statements about the schema and the deployment, true when written and verifiable by reading the migrations, but nothing queried them when this page loaded. We keep them in their own list so that nothing above is doing work it has not done.

  • No document content stored

    OperatingC1.1

    No clause text is stored. Numeric magnitudes extracted from a clause are: the money amounts, percentages and quantities a comparison needs in order to say that a threshold moved. Those are in the database, the sentences around them are not.

    Enforced at the schema level by a check constraint on data_inventory. Separately, clauses.features retains the money amounts, percentages and quantities extracted from a clause, and clause_changes.deltas retains their before and after values. Clause text itself is never stored.

    check constraint no_document_content on data_inventory (class <> 'content'), and clauses.features as written by lib/diff/features.ts
  • Row-level security on every table

    OperatingCC6.1 · CC6.3

    Authorisation is enforced by the database, not by the application. There is no query path that bypasses it.

    Writes go through SECURITY DEFINER functions rather than through permissive policies. The application never queries user data with the service-role key.

    alter table … enable row level security on every table in the public schema
  • Audit log is append-only

    OperatingCC7.2

    Tamper-evident: any alteration is detectable by a party holding a previously issued head hash. Before update and before delete triggers refuse every role, including ours.

    Enforced by triggers in migration 0001 and exercised by the test suite.

    before update / before delete triggers raise an exception for every role
  • Transport and browser hardening

    OperatingCC6.6 · CC6.7

    HSTS with preload, strict referrer policy, content-type and framing protection on every response.

    Applied to all routes; Teams frame policy scoped to Microsoft origins only.

    next.config.mjs security headers

What we hold, and what we never hold

We hold

  • Pointers to where a document sits in your own storage
  • SHA-256 hashes proving which bytes were tabled
  • Clause position, depth and word counts
  • Findings, such as that clause 12.4 changed substantively
  • Who did what, when, from where
  • Text you typed into Termsroom, such as a risk title
  • An encrypted credential, on the one storage path where you give us one. See the table below

We never hold

  • Document bytes, in any table, ever
  • Clause text or headings from your agreement
  • The closing record produced when a negotiation ends, which is written into both parties’ storage instead
  • A credential you did not deliberately give us
  • The keys your own storage encrypts itself with, on either path

Every column in our database carries a declared classification, and the classification that would permit document content is forbidden by a database constraint. A column added without one fails our build.

Credentials, per storage path

We used to say, flatly, that Termsroom held no credential into your storage. That was true when SharePoint was the only option and it is no longer true of every option, so the claim is now made per path rather than in general. This table is rendered from the same file the product reads, so it cannot fall behind the code.

Storage pathCredential heldWhat we holdIf you revoke
SharePoint or OneDrive for BusinessNoTenant id, site id, drive id, folder name, and the validation report. No credential of any kind.Your administrator deletes the Sites.Selected grant on the site. Access stops immediately and needs no contact with us. There is no credential left over on our side, because there never was one.
S3 compatible bucket, your keysYes, encryptedEndpoint, region, bucket, prefix, access key id, the validation report, and a vault reference to the secret access key. The secret itself is readable only by the service role.You delete or rotate the key in your own console. Access stops at once. Disconnecting in Termsroom retires the connection; ask us to purge the vault entry and we will, but rotating the key is what actually ends access and it does not need us.
Google Drivebuilt, not yet switched onYes, encryptedNothing yet. Once switched on: the folder address and a refresh token in the encrypted vault.Not applicable yet.

The two paths compared in full, including what a reviewer should check on each, are on the storage options page. A stored secret is encrypted into the database vault on arrival, is readable only by the service that moves bytes, and is never shown again, not even to the person who pasted it.

Check us yourself

Five queries either party can run against their own data, without our involvement.

What do you hold about us?

select * from tr_custody_manifest(:org)

Who has accessed our material?

select * from tr_access_report(:org)

Has the other side ever seen our caucus?

select * from tr_cross_party_access(:org) -- must return zero rows

Is every storage claim on this page still true?

select * from tr_verify_storage_claims() -- must return zero rows

Has the record been altered?

curl -O https://termsroom.com/verify.mjs && node verify.mjs <your export> --head <seq>:<hash you noted> # no account, no network; exit 3 means no head was checked

The anchor

Where every audit record begins

ebdbbaedbb881c9055d6831850ec1d6928f4ecb908dffe922f01ff434ba24ed8

Each party’s record is a chain of hashes beginning from this one value, the same for every customer. Your exported file carries an anchor of its own. Compare the two before you trust the verification, because a file with its first entries removed would still verify against the anchor it was shipped with. Checking it against a value published somewhere the file cannot reach is the whole point.

It reveals nothing. It is a hash of hashes, and no event, party or count can be recovered from it, which is why it can sit on a public page.

Compliance roadmap

These are commitments with dates, not aspirations. We are content to have them written into a contract.

  1. Security controls built into the product

    DoneComplete

    Row-level security on every table, append-only hash-chained audit log per organisation, customer-held storage, caucus separation enforced by the database rather than by the interface, organisational-account enforcement.

    Verifiable in the running system. See the live checks above.

  2. Data custody model documented and independently verifiable

    DoneComplete

    Every column classified; the verification queries published so each party can audit us without our help. Where a storage path means we hold a credential, that is stated per path rather than averaged into a general claim.

    Data custody statement, available below.

  3. Internal security review (AI-assisted), monthly

    In progressSeptember to November 2026

    We run a monthly internal review of Termsroom using Anthropic's Claude, over three consecutive months, starting before the independent penetration test on 5 November 2026. Each review covers the areas an external tester examines: authentication and session handling, access control between roles and between the two parties, database access rules, input validation and file uploads, security headers and content security policy, dependency vulnerabilities and secrets handling. It works on the source code, configuration and a locally built copy of the database; no customer data is used, and it does not test the live service. It is not independent and is not a substitute for the external test. Findings and their fixes are recorded, and the summary is available to customers on request.

    Review 1 completed 30 September 2026, against the source code and a locally built copy of the database. Its database fixes are supabase/migrations/0075_security_review_1.sql, checked by tests/security-review-1-db.test.ts, which probe the database the way a signed-in browser session reaches it.

  4. Independent penetration test

    Planned5 November 2026

    Third-party application and infrastructure test, with the summary letter available to customers under NDA.

    Date revised: Previously published for September 2026, then held back so the first internal reviews could come first. Now scheduled for Thursday 5 November 2026, so the external test examines a system whose findings from those reviews are already fixed.

  5. SOC 2 Type I report

    PlannedAudit engagement begins 11 February 2027

    An independent CPA firm attests that the controls are suitably designed as at a point in time. This is the first report we can actually hand over, and we share it when the auditor issues it.

    Date revised: Previously published for October 2026, then for Thursday 12 November 2026. Moved on 9 October 2026 to Thursday 11 February 2027, a date we judge we can meet. We do not give a report date before the auditor does.

  6. SOC 2 Type II observation window

    Planned11 February 2027 to at least 11 May 2027

    A three-month period during which the auditor observes the controls operating. It cannot be shortened or backdated, which is why Type II is not available before then.

    Date revised: Previously published as October 2026 to January 2027. It starts when the Type I audit does, so it moved with it on 9 October 2026.

  7. SOC 2 Type II report

    PlannedJune 2027

    Attestation that the controls operated effectively throughout the window. Shared with customers under NDA, then annually.

    Date revised: Previously published for February 2027. Moved with the Type I audit on 9 October 2026; the auditor confirms the date.

  8. ISO 27001 certification

    PlannedUnder review

    Assessed after Type II, subject to demand. Roughly 80% of the controls overlap, so the incremental cost is modest.

What is built

Everything here runs today, with the route, the migration and the test named beside it so you can check rather than take our word. The forward plan is not published here; ask and we will talk it through, including the dates.

  1. Drag a document in, with no terminal

    DoneSeptember 2026

    The browser fingerprints the file and sends it straight into your own storage. Termsroom reads it back and records what actually landed, so the fingerprint on the record is one we computed rather than one a party asserted. The copy into the other side's storage then happens on its own and is retried until it verifies.

    app/app/rooms/[roomId]/table-document.tsx and app/api/versions/placement. The copy into the other side’s storage is app/api/versions/[id]/mirror and lib/storage/copy-out.ts.

  2. OneDrive for Business named and accepted

    DoneSeptember 2026

    Accepted alongside a SharePoint site library, and labelled as what it is. A OneDrive drive belongs to one person, so a bargaining record placed there follows their retention and leaves when they do; the connection says so rather than leaving it to be discovered.

    lib/storage/sharepoint.ts accepts driveType "business" and writes the caution onto the connection rather than onto a screen somebody may not read.

  3. A shared view, and a view for your own side

    DoneSeptember 2026

    One screen both parties read identically: items by status, versions tabled and whether both sides hold a verified copy, sittings, protocol, what is outstanding and from whom. Separately, a sealed view of your own mandate position, costing and risks. Two routes with two data sources, because a screen that mixed them is the one place a mandate figure could reach the wrong reader.

    app/app/negotiations/[id]/dashboard and .../your-side, with tests/shared-dashboard-db.test.ts and tests/side-dashboard-db.test.ts. Shipped ahead of the published Q4 2026 date.

  4. Every bargaining unit in one place

    DoneSeptember 2026

    An institution running eight bargaining units sees all eight on one screen: unit, counterparty, agreement expiry, where each round has reached and what is outstanding. Reached from the account navigation rather than from a button partway down one negotiation.

    app/app/portfolio with tests/portfolio-db.test.ts. Shipped ahead of the published Q4 2026 date.

  5. Storage chosen per room

    DoneSeptember 2026

    A caucus can sit on a different storage location from the shared table, so an institution can put caucus material under its own retention rule or legal hold without moving the shared record. Versions already tabled stay where they were written and remain readable, so changing a room’s location affects what happens next rather than what already happened.

    supabase/migrations/0060_room_storage.sql with tests/room-storage-db.test.ts. Shipped ahead of the published Q1 2027 date.

  6. Sub-rooms inside a caucus

    DoneSeptember 2026

    An outside actuary or counsel brought in for one item joins a sub-room inside the caucus rather than the caucus itself, so they do not see the mandate discussion. The separation is a database policy on the same model as the caucus boundary, not a filter applied by a screen.

    supabase/migrations/0061_sub_rooms.sql and app/app/rooms/[roomId]/sub-rooms-panel.tsx, with tests/sub-rooms-db.test.ts. Shipped ahead of the published Q1 2027 date.

  7. Notifications in your own Microsoft Teams channel

    DoneOctober 2026

    Each side links its own Teams channel and is told there when something happens in the negotiation: a version tabled, a document requested or distributed, a bargaining session opened, closure of the agreement proposed or confirmed. A card names the negotiation, the reference, what happened and a link back into Termsroom; the document itself stays where it lives. Neither side can see where the other is notified, and the channel address is held in the database vault and never sent to a browser.

    lib/notify/teams.ts and app/app/negotiations/[id]/teams-panel.tsx, with supabase/migrations/0006_teams_webhook.sql and tests/teams-webhook-host.test.ts. Shipped, tested and working.

Sub-processors

Your documents live in storage you own. Where that is your Microsoft tenant, it is the one row below marked as holding documents. Where it is your own bucket, the provider is yours rather than ours, you contracted with them directly, and they do not appear in this table at all. The negotiation record is held in Canada. Text messages, emails and payments are processed by their own providers, Twilio, Resend and Paddle, in the locations shown.

ServiceRoleLocationAttestationHolds documents
VercelApplication hosting and delivery, and page-view counts for the public pages (no cookies, nobody identified)Configurable regionSOC 2 Type IINo
SupabaseDatabase, authentication, the negotiation recordCanada (ca-central-1)SOC 2 Type IINo
TwilioPhone verification at sign-in, and invitations and reminders by text messageUnited StatesSOC 2 Type II, ISO 27001No
ResendSending invitations and reminders by email (a reference, a name and a link, never a document), and the details entered in a request or partner application form on the websiteUnited StatesSOC 2 Type IINo
PaddlePayments and merchant of record. Billing details go to Paddle and never to usUnited Kingdom and European UnionPCI DSS Level 1, SOC 2 Type IINo
MicrosoftYour own tenant: Entra, Teams, SharePointYour tenant, your regionYour existing agreement with MicrosoftYes, yours

Four limitations we would rather you heard from us

  1. We see documents transiently. Two things need the text in server memory: comparing every version of a document, which reads the text of each to work out the differences, and indexing a tabled one, which reads the file back from your own storage. Neither writes the text to disk, to the database or to any cache, and nothing about it is kept beyond the findings and counts listed under “We hold” above. The quick “What changed since the previous version” comparison reads no file at all: it works from the clause index already on record. The process holds no state, but “never stored” is not the same as “never seen”. What you get for it is that the fingerprint on an indexed version is one we computed rather than one somebody typed, and an index is only ever built from bytes whose digest matches what was entered. A customer-side agent that does this inside your own tenant is on the roadmap.
  2. On one storage path we hold a key to your bucket. If you connect S3 compatible storage with your own API keys, we hold the secret access key, encrypted, for as long as the connection is active. Scope the key to one prefix, and rotate it when you want us out. The SharePoint path carries no such credential.
  3. We cannot trace a leaked page of your document. Per-recipient watermarking is on the roadmap and is not built. What we hold today is who was sent which version and when they acknowledged it, which tells you the population a leak came from, not the person. When watermarking ships it will be a deterrent rather than a control: it defeats the careless forward and the photographed screen, and it does not stop somebody retyping a clause.
  4. Metadata is not nothing. Clause counts, the timing of changes and who read what are genuinely informative. We hold them because the product cannot work otherwise, and we log every access to them.

How we prove a document has not changed

The checks above establish that the record has not been altered. The companion question, how anyone knows the agreement in front of them is the one that was agreed, is answered by a fingerprint recorded against every version rather than by us keeping a copy. What that is, what it does not prove, and why a reviewer in Canada, the United States or Europe accepts it, is set out on the document integrity page.

The evidence behind this page

This page states what is true and gives away nothing you would not see in the product itself.

Ask for the evidence pack

Everything on this page is public because it can be. What is behind it is not published, because we would rather know who holds it. Tell us what you need and a person will reply.

What would you like? · at least one

Optional. It decides which half of the pack is worth your time

Optional

Optional, and the most useful line on the form. A negotiation, a procurement, a review with a date on it.

We keep your name, organisation and address so we can reply, and what you asked for so we know what reviewers actually gate on. Nothing else.