devboxes

Create an Organization and invite your team

An Organization is your team in devboxes.

Create an Organization

To do it yourself:

organization.json
{ "name": "My team", "slug": "my-team" }
devboxes invoke organizations.create --input @organization.json

You become the owner. The result contains the Organization's id. Most other operations take it as organizationId.

The name has at most 18 characters. The slug uses lowercase letters, digits, and hyphens, and must be unique in devboxes.

You may own one Organization on Free. To create another, first subscribe the one you own to Basic or Premium, or delete it.

organizations.list lists the Organizations you belong to.

Invite a person

To do it yourself:

invitation.json
{
  "organizationId": "<organization id>",
  "email": "[email protected]",
  "role": "member",
  "expiresInSeconds": 604800
}
devboxes invoke invitations.create --input @invitation.json

role is one of the roles. devboxes does not send an email. Tell the person that an invitation is waiting. The invitation lasts at most seven days. After it expires, invitations.list shows it as expired, and you can invite the same email address again.

The person then joins:

  1. Install the CLI as shown in Install the CLI.

  2. Sign in and accept the invitation with this prompt for a coding agent:

    Without an agent, run devboxes login. invitations.received lists the invitations, and invitations.respond accepts one.

Choose where tasks run

A Project without a Runner runs its tasks on capacity that devboxes manages. devboxes runs managed tasks in Germany (de). An Organization allows Germany, which is the default, or runs its tasks only on its own Runners. Owners and admins change the setting.

To do it yourself, run organizations.inspect. organization.managedRegions lists the regions the Organization allows, and supportedManagedRegions lists the regions devboxes offers. To run tasks only on your own Runners, set an empty list:

placement.json
{ "organizationId": "<organization id>", "managedRegions": [] }
devboxes invoke organizations.update --input @placement.json

To allow managed capacity again, set "managedRegions": ["de"].

While the Organization runs tasks only on its own Runners:

  • projects.create and projects.configure refuse "runnerMachineId": null with the error ORGANIZATION_SELF_HOSTED_ONLY. Starting, continuing, or reviewing a task in a Project without a Runner fails with the same error and creates no task. Choose a Runner for the Project, as shown in Create a Project.
  • A task that waits for managed capacity and has not started fails. A task that already started keeps running.

Choose which hosts tasks reach

A managed task reaches only the hosts its Organization allows, and the hosts its secrets are bound to. Tasks on your own Runners are not affected. Every Organization allows the default hosts: GitHub, the package registries of common languages (npm, Yarn, PyPI, crates.io, Go modules, Maven, Gradle, RubyGems, Packagist, pub.dev), and the Debian mirrors. Owners and admins add presets, such as Docker Hub or a cloud's APIs, and hosts of their own. Google Maven, Android and Go downloads, and the Dart and Flutter package files are the google preset.

To do it yourself, run organizations.inspect. egressDefaults lists the default hosts, offeredEgressPresets lists each preset with its hosts, and organization.egressPresets and organization.egressHosts show what the Organization added. Set them with organizations.update:

egress.json
{
  "organizationId": "<organization id>",
  "egressPresets": ["docker-hub"],
  "egressHosts": ["git.example.com", "*.example.org"]
}
devboxes invoke organizations.update --input @egress.json
  • A host is a lowercase name such as git.example.com. *.example.org allows each name one level below example.org, and **.example.org each name any levels below it. IP addresses and URLs are refused.
  • A task reaches an allowed host on port 443 with TLS that names the host, and on port 80 with an HTTP Host header that names it. Other ports are closed. A task with a database reaches it through a database machine of its own, which alone reaches the database's host and port. Many hosts share one address at a CDN, so a connection to an allowed host's address whose TLS or Host header names another host is refused.
  • TLS hides the request inside it, so devboxes checks only the name the connection opens with. A service that serves many sites under one name can pass a request on to another site it serves. Google's hosts do this, which is why they are a preset you choose. A task whose model runs on Google, such as Gemini or Vertex AI, reaches Google's edge through its model's API host, so the same holds for it without the preset.
  • Every other name gets no DNS answer, and an address in a private network stays unreachable even when an allowed name resolves to it.
  • devboxes adds the hosts its tasks need: where a task downloads the devboxes executor and keeps its session files (egressAddedByDevboxes), and its model's API and where it renews the provider's sign-in (providerAccountHosts, for each model account). Work on a model whose hosts devboxes can't tell is refused with MODEL_HOSTS_UNKNOWN on managed capacity. Choose another model, or run the Project on one of your Runners.
  • Integrations, web search, and Git need no hosts here: devboxes calls them for the task. The agent's own web fetch reaches only the allowed hosts.
  • A change applies to tasks that start after it. A running task keeps the hosts it started with.

Manage members

To manage members and invitations, use the member and invitation operations.

Terms of ServicePrivacy Policy

On this page