← Back to armslength

This page has not been reviewed by a lawyer. It is a starting point written by the people who built the product, and it must be reviewed by counsel before a real customer signs.

Privacy: what we hold, and what we can read

This page describes the hosted armslength relay at ouragentsync.com, run by us. If you self-host

the relay, none of the data below reaches us at all — see the last section.

We have written this to be specific rather than reassuring. Where the answer is bad, the bad answer

is here.

The thing to read first: we can read your events

Every event that crosses the bridge is signed, not encrypted. Signing means neither party — and

not us — can forge or alter what was said. It does not mean the contents are hidden.

The relay stores each event as plaintext JSON on its own disk. That means the relay operator, who

today is us, can in principle read every contract you exchange, every rationale attached to a

proposal, every chat message and every file you share through the bridge.

Two companies using armslength to avoid showing each other their systems are showing all of it to a third party, and that party is us.

A self-hosted party may also choose, on its own machine, to send the free-text fields of the events it

receives (rationales, comments, chat lines, file names and notes - never contracts, artifacts, file bytes

or keys) to a scanner vendor of its own - Google Model Armor, Azure Prompt Shields, or an HTTP endpoint it

runs - as an extra source of quarantine holds. That is off by default, configured only by that party, and

the counterparty is not told. We are not in that path and do not see those requests; the hosted app

never makes them.

We found this ourselves, in our own testing, and corrected a page that had wrongly called the events

"sealed". Encrypting event bodies to the recipient's key, so that the relay carries bytes it cannot

read, is on the roadmap and is not built today. Ask us where it sits rather than assuming it is

done.

The rule that follows: a party must never run the relay

Self-hosting the relay is a configuration we support. Whoever operates a relay can read both parties'

streams straight off the disk, including events that party's own client is deliberately withholding from them

while a safety code is unconfirmed, and including content that has been quarantined.

If you self-host, put the relay somewhere neither negotiating party has shell access. If we run it,

we are that neutral operator, with the access described above.

What the relay stores

counter, decision and chat line, hash-chained in order.

documents you exchange, and any file either side shares.

certificates, revocations and peer confirmations. Signing keys never reach the relay — they stay

on your machine, which is why a relay that tampered with an event would produce something that fails

verification when it arrives.

written to the relay and not included in any email.

What the hosted web app stores

Separately from the relay, the site at ouragentsync.com keeps a small state file containing:

beside the bridge's relay data rather than against any person. It exists so the retention rule

below can tell a bridge people still read from one nobody does; it records no email address.

How long we keep it: one rule, and it is coarse

Credentials age out on their own. A login link goes once it is used or once its fifteen minutes

are up, a browser session goes once it passes seven days, and an erasure confirmation code goes the

same way as a login link.

Download windows are separate from deletion. The opener's plan includes at least

90 days of downloads for stored file blobs, through both the relay and the hosted

dashboard (including artifact previews). Invited members have free, unlimited blob

access with their own member connect token, verified door signature, or browser session.

Invited users with an older shared connect token must refresh it from the bridge

page: the old shared credential cannot identify which side is using it. Event reads are not

restricted by this window; inline event bodies are events, not file blobs. Local

copies are unaffected. A longer window makes the same retained bytes available

again. A plan refusal does not verify the chain or guarantee a complete local copy.

A plan is a retention setting, not a bill: nobody is charged for one today.

Authenticated workspace reads return 404 for missing blobs and 402 for blobs outside

the opener's window. This deliberately discloses availability to workspace credential

holders, who can already read the event stream's hashes. Refusals omit stored dates

and exact ages. Hosted file downloads additionally require a verified, unretracted

share before checking the window; nonmembers never reach that check. These statuses

are not an anonymous existence oracle. The independent dormancy rule below can still

remove a whole inactive bridge; a plan never triggers that removal.

Everything else is kept until the whole bridge has been silent for a long time, and then the whole bridge goes.

A bridge counts as dormant when, for the entire retention window, nobody has published an event

that verifies under its party's root key and certificates, and no member has opened it in the web

app. A revoked key's event does not count. A bridge a human still opens to read is not dormant.

The bridge must also have existed for the whole window. Uploads, metadata, key material and safety

check attempts alone do not count. An agent that only polls does not count as activity, so an agent

left watching an abandoned bridge is told plainly what happened when it next asks, rather than

holding the bridge open forever.

On a self-hosted relay, anyone holding the relay's own token can keep a bridge alive by publishing

to it under a party of their own; that token is the operator's to guard, and this is one more reason

a party must never run the relay. The hosted service scopes every connect token to one bridge, so

there only a member can.

The window is currently 400 days. That number was chosen by engineering pending a decision by the

people who run the service, and it will not get shorter without this page changing first.

A dormant bridge is removed whole: both parties' signed event streams, every shared file blob,

the key material and pairing records, the safety-check attempt marker, and the web app's bridge

record, membership and chat. There is no smaller unit, because events are hash-chained and nothing

can come out of the middle of a chain without breaking verification of what remains. Nothing removes

part of a bridge.

The removal is run by us, by hand, after a dry run that lists what would go. It is not a timer,

and nothing removes anything on its own. Afterwards the relay answers every request for that bridge

with a plain sentence saying it was removed after a long silence, rather than an empty history, so

an agent that comes back late is told what happened instead of being shown a chain that no longer

verifies.

A removed bridge on our server does not touch the copies each party pulled to their own disk.

What we keep after a removal is a tombstone holding the bridge's random identifier and the dates,

so the identifier can never be reused; it holds no name and no email address.

Signed event streams are never deleted on request, by anybody. There is no request an agent,

a party or a customer can make that removes an event you signed. The relay's API has exactly one

delete verb, and it is ours: it removes an event the relay stored in a party's name that the

party's keys never produced (a planted event), it refuses to remove anything that verifies under

the party's own root key, and it cannot be reached with a bridge's connect token. That, and the

dormancy pass above, are the only removals that exist, and both are ours to run. The next section

explains why nothing smaller than a whole bridge can otherwise go.

Retracting a shared file does not delete it. The file stops appearing in listings, in the tool

output and in the hosted download, and the download starts returning "not found" -- but the bytes stay

on the relay's disk. There is a written policy for a future clean-up job that would remove a blob once

nothing signed still refers to it; nothing implements that policy today.

Erasure: what we can remove, and what nobody can

You can erase your company's records from the hosted web app yourself. It is worth being exact about

what that reaches, because the boundary is real and it is not where most products draw it.

What erasure removes. Everything the web app holds about your side of a bridge: your members and

their email addresses, the invite fields naming them, the chat the web app keeps, and your login

sessions and links once you are no longer on any bridge. If you are the last party to erase, the

bridge record and its name go too, along with our mirrored plaintext copy of that bridge's contents.

Why that is not cosmetic. An email address never enters a signed event. Events carry a party name

-- acme -- and the map from alice@acme.com to acme exists in exactly one file, the web app's own

state. Erasing your members severs the only link we store between a signed history and a named person.

What erasure cannot remove, and this is the important half. Your signed event stream stays on the

relay. Each event carries the hash of the one before it, so removing any part of a stream makes the

rest unverifiable -- for your counterparty, not for us. There is no way to delete your messages and

leave a history your partner can still check. It is the whole stream or none of it, and today we

do neither on request, because the first breaks their verification and we will not do that quietly.

Shared file blobs stay, for that reason and one more: they are addressed by their content, and the

same bytes may be referenced by both parties' histories.

Your party name -- acme -- is stamped into every event in that chain and cannot come out of it.

Choose a party name the way you choose a bridge name: it is permanent.

Your counterparty keeps their copy, and we cannot reach it. They pulled your events onto their own

machine and verified them there. Nothing we delete on our servers touches their disk. That is not a

gap in this feature, it is what a bridge is for: the whole point is that neither side depends on us to

provide their only evidence — a local copy covers the history that side has actually fetched. If you need their copy gone, that is a conversation with them.

Anything the two of you typed stays. Chat text, rationales and file names live inside signed

events and can name anyone. We cannot redact content inside a chain.

Who can do it. A signed-in member of the bridge, in a browser, after typing the bridge name back

and returning a confirmation code we email to that member -- a code that only works in the browser

that asked for it. There is no agent-callable erasure. The token your agent holds reaches the

relay and nothing else, and neither the command line nor the MCP tools expose this. It is

irreversible and there is no undo.

Erasing your side does not close the bridge for your partner. Their records, their chat lines and the

shared connect token their agent uses all survive, because those are theirs; the bridge record goes

when the last party erases.

You get a receipt listing what was removed, with counts, and what survived and why. We hand it to

you and keep no copy -- a stored note saying who asked to be forgotten and when would be a fresh copy

of the data the request was about. Keep it if you need the evidence.

There is still no relay-side deletion on request and no account deletion. Removing a live

workspace from the relay by hand remains a request to us, subject to everything above; the only

relay-side removal that exists is the dormancy pass described earlier, and it does not take requests.

We would rather say so than imply a self-service control covers more than it does.

Who else touches your data

receives the recipient's email address, the link, and — in the subject line of an invitation —

the name of the bridge. Choose bridge names accordingly.

traffic goes straight to our server rather than through Cloudflare.

We do not use analytics, advertising or third-party trackers on the site.

Three limits worth knowing before you publish anything

that refuses writes to an unconfirmed peer binds from the moment that peer is known to your

workspace. On a brand-new bridge with nobody on the other side yet, there is no peer to gate against,

and what you publish sits in the shared history.

Create the bridge, get your partner joined, then start publishing.

counterparty's events are fetched and stored locally but not applied — your agent's working state

stays clean, and the bytes are already on your machine. Do not send anything you would not want a

stranger to hold until the code is confirmed.

hostile message, that means it never enters your agent's working state — not that it never reaches

your machine. Any agent that can read files in its working directory can read it.

Self-hosting

Running your own relay is supported and free. In that configuration we do not receive your events,

your files, your chat or your email addresses, because nothing routes through us. What you get from us

is the software; everything above becomes a description of what you hold, and the rule about a

party never operating the relay applies to you instead.

Security testing

Everything on this page and in our security brief was found by our own team and by adversarial AI

review. That process has caught real defects, including a data-exposure bug and a security control

that was not actually enforced.

It is not an external penetration test and we will not describe it as one. No outside audit has been done.

Asking us things

Ask us anything on this page, including where sealed events sit on the roadmap and what it takes to

have your data removed. If something here turns out to be wrong, that is a bug and we want to hear it.