Skip to content

Security

An agent does the work. A person stays in charge.

Not a policy page. Each rule below names the code path that enforces it.

The promises are in the code.

Each rule, and where it is enforced. Choose one to see the places that hold it.

Model-agnostic on purpose. The agent login is one setting in the organization, and nothing below depends on which one it is. The platform is the product, not the model.

01 of 7 promises

Where it is enforced

Enforced at: In the box, DevBench server, Your git provider.

In the box (enforced here)

The git shim sets the author; a commit-msg hook catches what it cannot parse

DevBench server (enforced here)

DevBench's own commits apply the same identity and trailer

The owners

The audit log and the owners' Inbox

Your git provider (enforced here)

The author is the person who asked; the committer stays DevBench

Every commit is authored as the person who asked for it.

The git shim in the box sets the author from whoever's message reached the agent, or whoever pressed the button, or the creator of the schedule. DevBench is the committer and the one co-author; any other trailer is removed. A commit-msg hook catches what the shim cannot parse.

Read the detail

Authorship

Every commit is by the person who asked for it.

One rule now applies to every commit a box makes.

  1. 1

    The author is the person who asked

    Written into the box whenever their message reaches the agent, when they press a button that commits, and when a scheduled task fires (its creator). The shim turns that into GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL.

  2. 2

    Every other co-author is removed

    Any Co-authored-by: trailer in the message goes, in any case or position.

  3. 3

    DevBench is added as the co-author, exactly once

    The committer stays DevBench, which is the distinction git's author/committer split has always drawn.

Every commit a box makes

One rule, whoever or whatever typed it

Author
The person who asked
Committer
DevBench
Co-author
DevBench, exactly once
Any other Co-authored-by:
Removed, in any case or position
The same shape as “GitHub committed on behalf of X”. git log --author used to answer “whose work is this?” with the name of a machine.

Where it is enforced

The git shim

Installed as the box's git, it rewrites -m messages in every form git accepts them, drops --author, and drops --no-verify.

A commit-msg hook

Covers what the shim cannot parse: a message written in an editor or passed with -F. It is installed per repo, and only where the repo has no commit-msg hook of its own, so a workspace's husky or commitlint hook is never replaced.

Push all

DevBench's own commits, the tidy-up behind Push all, apply the same identity and trailer directly.

Merge request descriptions

Strip Co-authored-by: lines and “Generated with” credits from commit titles and the summary, so reviewers read the change, not the credit. The commits keep their trailer; that is where the answer belongs.

An identity already in the environment wins. A person committing their own work from the box's terminal keeps their name; the co-author trailer is applied either way.

Refused in the box. Refused again on the server.

The agent's git is scoped to the workspace's repos, always allows the workspace's own branch, and refuses every branch in your git flow.

  1. The agent

    git push to a flow branch

    Its git is scoped to the workspace's repos and always allows the workspace's own branch.

  2. In the box

    The git shim, refuses

    Refuses first.

  3. On the server

    The push relay, refuses

    Refuses again, at discovery, before any objects move.

  4. Your git provider

    main

    Reached through a merge request or a release, never a raw push.

Two refusals, not one

The shim inside the box refuses first. The push relay on the server refuses again, at discovery, before any objects move, so a box that got around the shim, an edited policy file, a different git binary, still cannot reach the provider. Reaching main happens through a merge request or a release, never a raw push.

Owner-edited

Per repo, an owner can switch pushing off entirely or add extra branches the agent may push, globs like release/* included. The box picks the change up immediately. Guardrails are owner-edited and enforced server-side too, so loosening one is a real decision, not a suggestion to the agent.

No token in the box

A box holds no GitHub or GitLab token of its own. Clones and pushes go through DevBench with a credential helper, so the token never lands on the box's disk, and gh and glab have nothing to work with.

For work that reads code and never changes it.

An audit, a performance review, an investigation. The repos are cloned so the agent can read them, and every path by which code could leave the box is closed. Chosen at creation and fixed afterwards.

  1. The clone

    Each repo is checked out on the base branch. No working branch is created and nothing is pushed, not even the empty branch a normal workspace publishes at creation.

  2. The git shim

    push is refused for every repo and every branch, tags included. Clone, fetch, commit and diff are untouched.

  3. The push relay

    Refuses first and unconditionally, before any objects move, so a box that got past the shim still cannot reach the provider.

  4. Merge requests

    Opening one and landing one are both refused, with an audit entry. Self-merge cannot be switched on.

  5. Backups

    Skipped by the push half of a backup. “Nothing is ever pushed from here” is a promise, and a backup is not a reason to break it.

The box is told, too

Its instructions carry a read-only note pointing at four commands: the deliverable is what was found, not a diff. Scheduled prompts may run inside an info-only workspace, and only inside one, because a prompt typed into a normal workspace's live session would interrupt whoever is working there, in a box that can push.

the read-only note
  • $ devbench doc create

  • $ devbench media put

  • $ devbench task add

  • $ devbench notify

Who sees what

The rule is in the query, not the screen.

Access is a person's role plus a workspace's assignees, applied at the queryset rather than in a check that runs after the object has been fetched.

Show the access of

Can manage deployments

A separate flag that no role implies, not even owner.

Members reach only the workspaces they are assigned to, plus any they created.

CapabilityOwnerMaintainerMember
Workspaces
Every workspace in the organizationYesYesNo
The workspaces they are assigned to, plus any they createdYesYesYes
Change the assignees of a workspace they are onYesYesYes
The organization
Roles, invite codes, API keys and organization settingsYesNoNo
Edit a repo's guardrails: switch pushing off, add branches the agent may pushYesNoNo
Switch on self-merge for a workspaceYesNoNo
Re-trust a changed host key, a logged actYesNoNo
Organization backupsYesNoNo
Told of repeated refusals at the container or chat gateYesNoNo
Deployments
Deploy a previewYesYesYes
Cloud accounts, deploy recipes, seed data, where an environment pointsOnly with Can manage deploymentsOnly with Can manage deploymentsOnly with Can manage deployments
Deploy or stop anywhere but DevBench computeOnly with Can manage deploymentsOnly with Can manage deploymentsOnly with Can manage deployments

Not found, not forbidden

A member asking for someone else's workspace by id gets a plain “not found”, and no view can leak one by forgetting a check. The same rule guards the two things that are not JSON: the editor container, behind the proxy, and the chat socket. A member kept out of a workspace's API but able to load its IDE would not be kept out of it at all.

Assignees

Anyone on a workspace can change its assignees. That is not weaker than it looks: the only people it grants access to are members, being invited onto a workspace by somebody already on it.

Refusals reach an owner

Repeated refusals at the container or chat gate, five for one person on one workspace inside 15 minutes, notify the owners once. A workspace accidentally hidden from someone looks identical, from the server's side, to somebody trying ids at random, and only an owner can tell which it was.

Can manage deployments

A separate flag that no role implies, not even owner. It gates cloud accounts, deploy recipes, seed data, where an environment points, and deploying or stopping anywhere but DevBench compute. Reads are gated too, and the surfaces behind it are hidden rather than disabled.

Encrypted at rest. No read path.

Every secret DevBench holds is encrypted with one key you generate, and nothing in the API hands it back.

One key, yours. Encrypted at rest, never returned.

Cloud credentials

Organization-scoped, because a bucket a workspace is served from should not become unreachable when whoever pasted the key leaves. The secret has no read path; the access key id and account id are returned, because that is how you tell two credentials apart mid-rotation.

Git tokens

Validated against the provider before they are stored, so a bad paste fails at sign-up rather than at the first clone. Encrypted at rest, never returned.

Credential profiles

A tool's staging and prod variables are decrypted inside the box for one run, picked with --env. Never in the prompt, never returned by the API.

Host keys are verified, not accepted

The first SSH connection records the fingerprint. Every one after requires a match, and a mismatch fails loudly with both fingerprints rather than connecting. Re-trusting is an owner-only, logged act, because a host key changes when a box is rebuilt and when someone is intercepting you.

The box never holds cloud keys

devbench cloud call makes one AWS call through DevBench. Destructive calls, Delete, Terminate, Stop and IAM changes, are refused unless the workspace's grant allows them.

Backups carry ciphertext

With secrets switched on, each one travels as the ciphertext already in the database. Usable only on an install with the same key, which is what makes it safe to leave one in a bucket.

API keys are your account

No narrower scope exists, so a key is treated as a password. Each box's own key is agent-scoped and can be revoked on its own, which stops that box's CLI.

Failures reach the people who can act

Credentials are re-verified on a schedule. A key that stops working reaches the owners' Inbox, throttled per account; a key that starts authenticating as a different AWS account bypasses the throttle entirely.

What an agent may do, in one table.

The line between the agent's work and a person's decision, as the code draws it.

What an agent may do, beside what a person may do
Action An agent A person
Push the workspace's own branch
YesYes
YesYes
Push a branch in the git flow
NoRefused in the box and on the server
Through a merge request or a release
Open a merge request
YesYes
YesYes
Merge
NoUnless self-merge is on for that workspace; then audited and announced
YesYes
Deploy a preview on DevBench compute
YesYes
YesYes
Deploy or stop an environment
NoNo
With Can manage deployments
Run a scheduled prompt inside a workspace's box
Only an info-only workspace
Not applicable
Boot a persona inside a workspace's box
NoNo
Not applicable
Push anything out of an info-only workspace
NoNo
NoNo
Read a stored secret back
NoNo
NoNothing in the API returns one
Author a commit as itself
NoThe author is the person who asked
YesFrom the box's terminal with an identity exported

Trust

Where your data is, and who can reach it.

The four questions a procurement review asks first, answered before the product ones. The detail is on the privacy, terms and DPA pages.

Hosting model

Two kinds of data, two places.

Account data

Who you are, which organization you belong to, roles, API keys and billing. Held by Vesprr on a host in the European Union.

Workspace data

Repository clones, chat, notes, recordings, docs, media, previews and deployments. Held on the host your organization chose: DevBench compute in the EU, or a host you run. On a host you run, your code never passes through a machine Vesprr operates.

Where each kind of data is at rest, and who can see it
DataAt restWho can see it
Account dataVesprr's host in the EU, on the hosting provider's encrypted volumesYou and your owners; Vesprr staff for support and billing
Workspace data on DevBench computeOne volume per workspace on encrypted storage in the EU; media in an EU bucketYour members by role; Vesprr staff only for support you asked for, and logged
Workspace data on your hostYour disk, your encryption, your backupsYour members by role. Vesprr has no access
Provider tokens, cloud credentials, secretsEncrypted at rest with a key the operator holdsNobody through the API. The server uses them to clone, push and deploy
Organization backupsEncrypted archives; never contain repository codeOwners
Isolation
Each workspace runs in its own container with its own volume. A box holds no provider token; clones and pushes go through DevBench with a credential helper, so the token never lands on its disk.
Audit
Every action in a workspace is in the audit log: who, what, when. Self-merges are announced to the organization.
Staff access
Named people, keys not passwords, production access logged. Support access to a workspace on DevBench compute happens only when you ask for it, and shows up in the audit log like any other action.
Subprocessors
Listed in the privacy policy with the job each one does. Customers on a DPA are told of a change 30 days ahead and may object.
Retention
Account data 30 days after the account closes. Workspace data on DevBench compute until the workspace is deleted. Invoices for as long as tax law requires.
Location
Vesprr LLC is a US company. Account data and DevBench compute are on servers in Germany, in the EU. Deployments go to the cloud accounts you hold, wherever you put them.

Reporting a security issue

We acknowledge within one working day, keep you informed while we fix it, and credit you if you want that. Do not test against organizations you do not own.

If there is a breach

If we learn of a breach affecting your data, your organization's owners hear from us within 48 hours of us knowing, with what we know and what we have done.

Invite only

We set your organization up with you.

Tell us about your team and the repositories you would bring; we reply within a working day.