Skip to content
← Blog

How do you give an AI agent an API key that can't touch everything?

Scope an Orgo API key to one workspace or one computer, give it only the permission groups your agent needs, set an expiry, and know how the key Orgo puts on a computer behaves.

Updated

TL;DR

Don't hand an AI agent your full access key. Every Orgo API key has three settings: a scope (all workspaces, one workspace, or one computer), an access level (full access, read only, or custom levels across eleven permission groups), and an expiry (from 1 day up to a year, or none). For an agent, make a workspace or one-computer key with only the groups it needs, give it an expiry, and rotate it by making the new key before you revoke the old one. A program running on an Orgo computer can use the computer's own key, which Orgo makes, rotates and revokes for you. That key isn't held to its computer, so treat it like an account key.

What is a scoped API key for an AI agent?

A scoped API key is a credential that reaches only part of your account. In Orgo, scope decides which workspaces or computers a key can touch, and permissions decide which endpoints it can call inside that scope. Orgo checks both on every request, before the endpoint runs. A call outside the key's permissions answers 403 with code: "key_permission", and the error message names the group and level the key would need.

That matters for agents because an agent acts on whatever its key allows. If the key can delete computers, invite people or buy credits, a confused or prompt-injected agent can too.

What are the three settings on an Orgo API key?

SettingChoicesWith POST /api/keys
ScopeAll workspaces, one workspace, one computerSend neither field, workspace_id, or computer_id
AccessFull access, read only, customLeave permissions out or send "full", send "read_only", or send an object of group to level
Expiry7, 30 or 90 days, 1 year, a custom date up to a year away, or no expirationexpires_in_days (1 to 365) or expires_at; send neither for no expiry

A new key made in Settings, API keys defaults to a 90 day expiry. The key's value is shown once, when you create it.

Which scope should an agent's key have?

ScopeWhat it reachesGood fitWhat it can't do
All workspacesEverything your account can reachYour own scripts and admin toolingNothing is fenced off by scope
One workspaceThat workspace and the computers and files in itAn agent that runs a fleet of computers inside one workspaceCall anything outside computers, workspaces, files, screenshots, chat completions, support and keys (so no secrets, templates, billing or account settings); create a workspace or name another one; invite, change or remove members, use share links, or delete its workspace (all workspace_scope_mismatch); make one-computer keys (account_key_required)
One computerA single Linux computerA contractor, an embed in your app, or an agent that only ever drives one computerDelete, resize, clone, fork or move its computer; list, make or revoke keys; reach your workspaces, files, templates, secrets or billing

A one-computer key can still start, stop, restart, suspend and resume its computer, and drive its screen, shell and Desktop API. Ask for another computer and it answers 403 with code: "computer_scope_mismatch".

Making a workspace key revokes the computer keys on that workspace's computers (see below). If a program on one of those computers reads ORGO_API_KEY, switch it to the new key first.

Which permissions does an agent actually need?

A restricted key has a level in each of eleven groups: none, read, or write (write includes read). A group you leave out of a custom key is none.

GroupWhat it covers
computersCreate, start, stop, resize and delete computers
controlScreenshots, commands, mouse and keyboard on a computer
filesFiles stored in Orgo
templatesTemplates and their builds
workspacesWorkspaces, their names and settings
membersPeople, invites and share links
secretsSecret names, and setting or using them
aiModels, chats and agents
bopsWhat the Bops app keeps in Orgo
billingPlan, credits and invoices
keysMake, change and revoke keys, never past the key's own access

Most computer-use agents need two groups: computers to start and stop their machines, and control to click, type, run commands and take screenshots. An agent that calls Orgo's hosted agent through POST /api/v1/chat/completions also needs ai at write. Leave members, billing and keys at none unless the agent's job is literally managing those.

Three details are easy to miss:

  • Read is not always harmless. Control read takes screenshots of a computer's screen and reads files on it.
  • A workspace key can't have members at write. Asking for it answers 400 with code: "invalid_permissions", the same code as an unknown group or level.
  • Custom with write in every group is still a restricted key, not full access. It can't make a full access key, and it can't call the endpoints reserved for you signed in.

Here is a workspace key for an agent that runs and drives computers in one workspace, expiring in 30 days:

bash
curl -X POST https://www.orgo.ai/api/keys \
  -H "Authorization: Bearer $ORGO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Fleet agent",
    "workspace_id": "'"$WORKSPACE_ID"'",
    "permissions": { "computers": "write", "control": "write" },
    "expires_in_days": 30
  }'

Send computer_id instead of workspace_id to bind the key to one Linux computer.

What is a computer key, and should my agent use it?

A computer key is a key Orgo makes for one Linux computer and writes onto it as ORGO_API_KEY, so an agent running there can call Orgo. Orgo makes one when a template's secrets declare orgo_api_key, for a curated template or one of your own, when you own the workspace, nobody else can use it, and you create the computer signed in or with a full access key for your whole account that never expires.

BehaviorComputer key
Who manages itOrgo. PATCH /api/keys/{id} answers 409 with code: "managed_key"
ExpiryNever expires
RotationIts secret rotates by itself on use once it is 30 days old; the old secret works for 10 more minutes
What it can callA fixed list of calls for computer work and the Bops runner; anything else answers 403 with code: "computer_key"
CopiesA clone, fork or restore as a new computer gets its own key; no key is live on two computers
RevocationDeleted with its computer or workspace, and revoked when the workspace stops being yours alone

That last row is the one that surprises people. Anyone who can use the computer is root there and could read the key, so Orgo revokes it when an invite is accepted (whatever its access), a share link is claimed, a workspace key is made, someone connects the workspace through an MCP sign-in, an Invoicing client key is made or rotated for it, an agent account that owns it is claimed, or the computer moves into a shared workspace. Orgo also sweeps every 15 minutes for keys that may no longer stay. Programs that relied on ORGO_API_KEY then stop reaching Orgo.

Treat the key on a computer as seriously as an account key, and don't assume it stops at that computer. Keep what it can reach small: run that computer on an account that holds only what the agent needs. When a program must stay on one computer, make it a one-computer key instead, which Orgo holds to that computer, and leave orgo_api_key out of the template.

There is one more gotcha. Because anything that controls a computer can read its key, a restricted key or one that expires can't control a computer that holds its own key. Its control and AI calls about that computer answer 403 with code: "computer_key_held". Start, stop and get still work. Use a full access key that never expires for that computer, or sign in.

How do you rotate an agent's key without downtime?

Orgo never rotates a key you made, because it can't reach where you keep it. Replace one in three steps:

  1. Create a new key with the same permissions and scope.
  2. Update every agent and service that uses the old key.
  3. Revoke the old key with DELETE /api/keys/{id}.

Both keys work until you revoke the old one. Orgo emails the account 7 days and 1 day before a key you made expires. Past its expiry, the key answers 401 with code: "key_expired" everywhere, and a WebSocket closes with code 4001. A key that expires can only make keys that expire no later than it does.

For the computer key, a program on the computer should read ORGO_API_KEY from /root/.orgo-secrets.env first and /root/.env when that file is missing or has no key, and read it again after a 401, then retry once. In a shell, sourcing /root/.env alone is enough: it sources /root/.orgo-secrets.env last, so it always gives the newest value. Both files are readable by root only.

bash
# Run as root on the computer. Set COMPUTER_ID to the computer's UUID.
call_orgo() {
  . /root/.env
  status=$(curl -s -o /tmp/orgo-out.json -w '%{http_code}' "$@" \
    -H "Authorization: Bearer $ORGO_API_KEY")
  if [ "$status" = "401" ]; then
    . /root/.env   # the key may have rotated: read it again
    status=$(curl -s -o /tmp/orgo-out.json -w '%{http_code}' "$@" \
      -H "Authorization: Bearer $ORGO_API_KEY")
  fi
  cat /tmp/orgo-out.json
}
 
call_orgo "https://www.orgo.ai/api/computers/$COMPUTER_ID"

A 401 that persists after a fresh read means the key was revoked, not rotated. A 503 with code: "key_rotation_failed" means Orgo couldn't write the new secret, usually because the computer isn't running; nothing changed, so retry after the Retry-After seconds.

What errors will a scoped key return?

StatuscodeWhat it means
403key_permissionThe key lacks the group or level this endpoint needs
403computer_key_heldA restricted or expiring key tried to control a computer that holds its own key
403computer_scopeA one-computer key called an endpoint outside its list
403computer_scope_mismatchA one-computer key asked about a different computer
403computer_keyA computer key called an endpoint outside its fixed list
403workspace_scope_mismatchA workspace key called an endpoint outside its surfaces, tried to create a workspace, named another workspace, managed people, or deleted its workspace
403account_key_requiredA workspace key tried to make, change or revoke a one-computer key
403key_escalationA key tried to make, change or revoke a key wider than itself
400invalid_permissionsAn unknown group or level, or members write on a workspace key
409computer_key_in_useA one-computer key was requested for a computer that holds its own key
400computer_scope_fixedSomeone tried to change a one-computer key's computer or scope; make a new key instead
400computer_scope_unsupportedA one-computer key was requested for a computer that isn't Linux
409managed_keySomeone tried to change a computer key's permissions, scope or expiry
401key_expiredThe key is past its expiry
503key_rotation_failedA computer key's rotation couldn't be written; retry shortly

FAQ

Can a restricted key make a full access key? No. A key can never make or change keys past its own access, and even a custom key with write in every group can't make a full access key. It answers 403 with code: "key_escalation".

Is a read-only key safe to give an agent? Safer, not harmless. Control read takes screenshots of a computer's screen and reads files on it, so treat read access to a computer like read access to everything on it.

What happens to the computer key if I invite a teammate? Orgo revokes it and takes it off the computer when the invite is accepted, whatever access the invite gives. Anything on that computer that used ORGO_API_KEY stops reaching Orgo.

Can a one-computer key work on a Windows or Mac computer? No. One-computer keys are for Linux computers only; any other computer answers 400 with code: "computer_scope_unsupported".

What happens when I revoke a one-computer key that could control its computer? Orgo changes the computer's VNC password and Desktop API token, and open screen viewers close. Until the change finishes, Get VNC password answers 503 with code: "vnc_rotation_pending", so fetch the password again rather than reusing a stored one.

Where can I see which keys reach a computer? In Settings, API keys, on the computer's General tab, or with GET /api/keys?computer_id={id}.

Sources