Security

VESPR lets people and AI agents change files and run commands in a shared workspace, so who may do what matters. This page lists what is protected today and, just as clearly, what is not.

Written October 29, 2026 from the code and the repository’s security notes. This is a description, not an audit.

On this page

Where we stand

VESPR is a prototype. No outside company has audited it. There has been no penetration test, no SOC 2 report and no bug bounty program. The checks listed below are ones we built and tested ourselves.

The trust model in one paragraph

A workspace is a team. Anyone with a valid access token for a server can join any workspace on it, read it, edit it, read its session log and its git repository, and approve what an agent wants to do. There are no per-workspace or per-person permissions yet. Agents are separate identities, and they are not trusted to act alone: what they may do without asking is set by the workspace’s permission mode.

What is implemented today Implemented

Implemented controls
ControlWhat it doesWhere to check
Workspaces need a tokenEvery connection and every API call (live sync, uploads, session log, git, suggestions, runners) needs a valid token. No token, no access.server/index.js, git.js, uploads.js, runners.js
Uploads are downloads onlyUploaded files get a random name on disk and are always sent as an attachment with a neutral type, so an uploaded web page or SVG can never run on our site. Nothing uploaded is executed or unpacked by the server. Size, count and per-workspace caps apply.server/uploads.js
The room approves agent actionsFive permission modes. In the modes that ask, an Approve / Deny card goes to everyone and the first answer decides, with the name of who answered. Dangerous commands (for example sudo or rm -rf /) are refused outright. Bypass is downgraded to Auto on someone else’s machine. An agent also asks before editing a file someone is working in, in every mode.agents/src/policy.js, agent.js
Run limitsA runner never inherits your environment variables, runs only workspaces its owner allowed, works in a temporary folder with time and output limits, and never writes outside it. Only agent identities can start jobs on runners, so a person cannot skip the approval flow. The public demo also caps memory, processes, CPU and AI tokens per day.runner/lib.js, server/index.js, deploy/judge/
Git pushes are filteredA push cannot bring in .git or .vscode paths, paths that climb out of the workspace, absolute paths, more than 2,000 files or files over 200 KB. Only one git operation per workspace runs at a time.server/git.js
Other people’s text is escapedNames, model names, messages and colors sent by other clients are escaped or validated before they reach the editor’s HTML or Markdown.the editor extension in extensions/
Request size limitsInline suggestions, runner jobs and git pushes have size limits so one request cannot flood the server.server/*.js
HTTPS and link hygiene on the demoThe public demo is served over HTTPS. The app page sends no referrer and blocks content-type sniffing. The access token goes in the part of the link after #, which browsers do not send to a server.deploy/judge/Caddyfile
Secret scanning before commitsA pre-commit hook blocks any commit that contains a real key, token or password. The same scan gates the public copy of the code and the demo’s deploy bundle. Secrets live in files outside the repository that git does not track. This protects our own code and keys; it does not scan your workspace.scripts/check-secrets.py

What is not in place Not in place

These are known, and we would rather you read them here than discover them.

Anyone with a token can reach everything on that server

A valid token opens every workspace on the server: files, chat, session log, git and uploads. Anyone in a workspace can approve any agent action and change the agent’s mode. Roles (owner, editor, viewer) are the planned next step.

Per-file read limits cannot be enforced inside one workspace

A workspace is one shared document, and every editor that connects receives all of it. We cannot let a teammate read some files and not others inside it: a limit like that would be a menu setting, not a protection. If two people must not see the same file, they need separate workspaces. Roles would help with who may change or approve things; a real per-file read limit needs a different design, and that is not built.

The agent’s sandbox is not isolated from the agent’s own secrets

When someone approves a command, it runs in a sandbox as the same system user, in the same container, as the agent that asked for it. Starting the command with a cleaned environment does not change that. A command run there can read what the agent itself can read: the agent’s model key and its workspace token, and the list of access tokens the agent is given. A workspace member can already get to these by asking the agent to run a script and approving it. Until this is fixed, the Run button for people is off by default on public deployments. The real fix is a separate sandbox container with no secrets, or running commands as a different user. That is not done yet. The sandbox also shares its container’s network, so a command can reach the internet.

Tokens are basic

Workspace tokens sit in a plain file on the server (outside the code repository), not hashed. They are compared with an ordinary lookup, not a constant-time one, and for live-sync connections they travel in the web address, which the server does not log but anything in between might. A preview link made by “Run it” carries its own secret in the address; anyone who has the link can see that preview. Tokens are issued and removed by the operator by hand.

The session log keeps everything

It records everything typed in a workspace, including anything sensitive someone pastes. Nothing is redacted and nothing is deleted automatically.

Smaller known limits

Accounts In development

An accounts system exists in the code, off by default and not part of the public demo. As written it hashes passwords with scrypt and a per-user salt; stores only a SHA-256 hash of each session token (valid 30 days); counts failed sign-ins and blocks after five in 15 minutes; supports authenticator-app codes and single-use recovery codes (stored hashed); and can restrict sign-up to listed email domains. Known weak spot: authenticator secrets and phone numbers are saved in the account file without separate encryption (the file can only be read by the server). It has not been independently reviewed and will not be turned on for the public until it has been tested more.

Reporting a problem

Write to [Security contact email] with what you found, how to reproduce it and what you think it exposes. We aim to reply within [number of days]. We have no bug bounty. Please do not read other people’s workspaces, do not run tests that could take the demo down, and give us a reasonable time to fix a problem before you publish it. [lawyer to review any safe-harbor wording]