Per-workspace permissions: how agents are scoped

Scoping an agent is not the same as picking permissions per tool. In AI Tasker the real perimeter is the workspace its credential belongs to, the budget that workspace consumes and the lifecycle of the key. Scopes do exist on the API key, but today they are stored and displayed: no route applies them. This guide explains what each limit contains, what the API returns when each one fires and what to do if what you want is an agent that cannot touch what it should not.

Reviewed · Published

What scopes an agent in AI Tasker today

AI Tasker does not implement a per-tool permission layer. There is no table anywhere that ties a credential to a subset of the forty tools. The perimeter that does exist has three pieces: the workspace the key belongs to, the quotas that workspace consumes and the lifecycle of the credential. The scopes on the key belong to a different story: today they are the declared intention of that key, not an enforcement mechanism.

The consequence is practical and worth having in mind before you design anything: if you need an agent not to read or write somewhere, a scope does not solve it. It is solved with a separate workspace for that agent, with a budget that runs out, and by closing the credential when the work is done. Scopes serve to document what that agent should do; the perimeter does the rest.

The five real limits and what they return

These are the five limits that scope an agent today, with the exact response the API returns when each one fires.

The limits that apply today to an agent API key, with the response the API returns.
LimitWhat it isWhat it blocksStatus code or error
Workspace of the keyThe workspace the API key belongs to (apiKey.workspaceId) plus the shared workspaces it carries (apiKey.workspaceIds).The agent listing, reading or writing outside that workspace.403 API key workspace unavailable when the workspace does not exist.
Key revocationThe revokedAt field of the API key.Any call made with that credential, including the first one.401 INVALID_API_KEY.
Agent quotaThe requests counter reserved on every authenticated request (reserveAgentQuota).The next operation once the plan quota is exhausted.Quota error: the API rejects the request.
Workspace daily ceilingdailyAgentOps 200: the maximum number of authenticated requests per day, over MCP and direct HTTP.The request that goes past 200 in a day in that workspace.Quota error, and the earlier reservation is released.
Monthly quota of the free plan100 agent operations per month and 100 hosted AI operations per month, per workspace.Read and mutation operations, and the three hosted AI operations.Quota error once the monthly bucket is exceeded.
Hosted AI daily ceilingdailyHostedAiOps 10 per day per workspace.The eleventh hosted AI call of the day.Quota error.
Archived workspaceThe 7+7 lifecycle: after 7 days without activity the workspace is archived.All normal access by the agent to that workspace.403 WORKSPACE_ARCHIVED, with the recovery path in the body.
Human actionsThe link to the person (humanLinkRequired: true), with preview and confirmation through Clerk.An agent raising its own limits or claiming ownership of the workspace.Without a Clerk session, the action does not complete.

The daily ceiling and the monthly quota are not the same number. dailyAgentOps (200) counts authenticated requests: one MCP tool or one direct HTTP call. The monthly quota (100 agent operations) counts semantic operations. An agent that reads a lot can exhaust the daily figure before the monthly one. Webhooks run on their own: 3 webhooks per workspace and 2 deliveries per minute on the free plan.

Scopes: what they are and what they do not do

Scopes are stored on the API key itself. The model enum (models/index.js) has five values: tasks:read, tasks:write, sprints:read, sprints:write and ai:generate. A key created by a person gets tasks:read, tasks:write and ai:generate by default; an autonomous agent registration gets tasks:read, tasks:write and sprints:read (routes/agentOnboarding.js).

Now the part that has to be said without softening: today no route and no middleware checks those scopes. Across the whole backend, the word scopes appears in three places: the enum definition in models/index.js, the creation and the return of the key in routes/apikeys.js, and the creation of the agent key in routes/agentOnboarding.js. There is no control point comparing the list on the key with the requested operation. The MCP server does not filter either: tools/list returns the 40 tools with any valid key, and you can check that in a minute with a test key.

  • The model enum (models/index.js) limits the possible values to tasks:read, tasks:write, sprints:read, sprints:write and ai:generate.
  • A key created by a person (routes/apikeys.js) gets tasks:read, tasks:write and ai:generate by default.
  • An autonomous agent registration (routes/agentOnboarding.js) gets tasks:read, tasks:write and sprints:read.
  • The list is stored, returned when the key is created and visible in GET /api/apikeys and in the dashboard: it is information, not a filter.
  • The MCP server answers tools/list with the 40 tools for any valid key: there is no scope filtering.

How to read this without embellishment: scopes are the declared intention of the key — they are stored, visible and auditable — and the effective limit is the workspace plus the quotas. A guide claiming that a scope removes tools would be making a false statement about the product, and that is exactly the sentence a reader repeats later in their own documentation.

What to do if you want to limit an agent for real

  1. One key per agent. Each credential resolves to a workspace, can be revoked on its own and has its consumption in the usage trail. Sharing one key between two agents also shares its revocation.
  2. One workspace per agent, if you want real isolation. An agent with access to several workspaces sees the backlog of all of them: isolation is not «it has its own credentials», it is «it has its own workspace».
  3. Quotas matched to the work it is going to do. The free plan includes 100 agent operations per month and 100 hosted AI operations per month, with a daily ceiling of dailyAgentOps 200 authenticated requests and dailyHostedAiOps 10 hosted AI operations per day.
  4. Revoke when the work is done. A revoked key (revokedAt) returns 401 INVALID_API_KEY on the next call: it is the cheapest shutdown available.
  5. Scopes, as documentation. Write in the scope list of the key what that agent is supposed to do, and do not assume the system will stop it.

There is a cost detail worth keeping in mind: the free plan includes 1 workspace, 1 human and 2 API keys. One workspace per agent means additional workspaces, and each extra workspace of the owner is a billable unit of 2.00 €/month.

Key rotation

Rotation changes the credential without cutting service, and it is the operation worth rehearsing before you need it. POST /agent/key-rotation-token issues a one-time token with 900 seconds of validity, authenticated with the agent’s own key. Afterwards, the preview and the confirmation travel through a Clerk session: the person sees what is going to happen and confirms. On confirmation the hash and the prefix of the key change, and the old key stops validating with 401 INVALID_API_KEY.

The rotation path: the agent asks for the token, the person previews and confirms in the dashboard.

POST /agent/key-rotation-token                   # auth: agent API key · TTL 900 s
POST /api/agent-key-rotations/preview             # auth: Clerk
POST /api/agent-key-rotations/confirm             # auth: Clerk
POST /api/agent-key-rotations/{apiKeyId}/rotate   # Idempotency-Key header

Rotation does not change nor widen permissions: it keeps the workspace of the key and its scope list. What changes is the secret stored on the client. That is why the right order is to rotate first and update the client afterwards; if the client is updated first, the old key stops serving in the middle of the deployment.

The audit trail and its two redaction layers

Every authenticated request leaves a usage row in ApiKeyUsage with apiKeyId, workspaceId, method, path and channel (human, cli, llm or agent). That record is what lets you reconstruct what a credential did, even after the board activity is archived.

The activity feed applies two redaction layers (services/activityRedaction.js): an allowlist on write and a deep redaction on read. That way a credential that slips into a payload never reaches the feed, neither on the way in nor on the way out.

  • Passwords, complete API keys, Authorization headers and cookies are redacted.
  • JWTs, OAuth or session tokens, OTP and reset codes, and registration, linking and rotation tokens are redacted.
  • Webhook secrets, private keys, the ciphertext of agent credentials and x402 signatures or payloads are redacted.
  • The identifiers that are not secret are kept: event id, apiKeyId, actor (userId or channel), correlationId, dates and the field labels.

Fail-safe: if redaction fails (a getter that throws, a cycle, an unreadable structure) the API returns a minimal skeleton without the raw payload and with redactionFailed=true. The content is never written to logs: losing the trail is better than leaking the secret.

Checklist for setting up an agent with the tightest limits that still let it work

  • One API key per agent, with the name and the channel (human, cli, llm or agent) set properly.
  • A workspace of its own for the agent, or the list of shared workspaces reviewed by hand.
  • Quotas reviewed before handing over the key: dailyAgentOps 200 requests per day, dailyHostedAiOps 10 per day, 100 agent operations per month, 100 hosted AI operations per month, 3 webhooks per workspace and 2 deliveries per minute.
  • The scope list written as documentation of the intention, without trusting that the system applies it.
  • A closing plan: who revokes the key, when and with what evidence.
  • Rotation rehearsed before it is needed, with the client updated before the credential expires.
  • An auditable usage trail: the ApiKeyUsage rows with apiKeyId, workspaceId, method, path and channel.
  • A human with a Clerk session for what the agent cannot do: raise limits or claim ownership.
  • Webhooks with their secret and their signature: HMAC-SHA256 of the body in the x-ai-tasker-signature: sha256=… header, with the last 100 deliveries queryable at GET /api/webhooks/:id/deliveries.

The limits that do not belong to the key

Two more boundaries are worth keeping in mind. The lifecycle, on one side: after 48 hours without activity the system warns, after 7 days the workspace is archived and normal access is blocked with 403 WORKSPACE_ARCHIVED; for 7 days more a human can reclaim it with a one-time recovery token, and when that window closes the workspace is purged. Human actions, on the other: agent registration is autonomous, but the link to the person is mandatory (humanLinkRequired: true) and the actions that raise limits or transfer ownership go through a Clerk session.

With all of this, the right question is not «which scope do I put on this key», but «which workspace do I give it, how much can it spend and who closes it». The model of AI Tasker is a per-workspace perimeter, with budget and expiry, not a list of permissions per tool. Once that difference is understood, the rest — scopes, rotation and the audit feed — falls into place: they are record-keeping and control pieces of a credential, not substitutes for that perimeter.

How to check in ten minutes what scopes an agent

The shortest path, with the real endpoints: a test key, the four errors the API returns and the list of tools the agent sees. No invented credentials.

  1. Create a test API key and note its scopes

    POST /api/apikeys with the Clerk session: the response includes the prefix and the scope list. Note it down, because that is the declared intention of the key and from there you check how far it reaches.

  2. Open the MCP session and ask for tools/list

    With Authorization: Bearer atkr_… ask for tools/list: the 40 tools should come back. If you get the 40 with a key whose declared scope is tasks:read, you already have the demonstration that the scope does not filter.

  3. Trigger the errors of the perimeter

    Call with the revoked key and you will see 401 INVALID_API_KEY; call against an archived workspace and you will see 403 WORKSPACE_ARCHIVED; and a call that goes past dailyAgentOps (200 requests per day) returns a quota error. Each response tells you which limit fired.

  4. Revoke the key and review the trail

    Revoke the key and confirm that the next call returns 401 INVALID_API_KEY. Before that, review the ApiKeyUsage rows (method, path and channel) and the activity feed, where redaction keeps the non-secret identifiers and hides the credentials.

Frequently asked questions

Do the scopes on an API key limit what the agent can do?

No, not today. Scopes are stored on the key (tasks:read, tasks:write, sprints:read, sprints:write, ai:generate), returned by the API and visible in the dashboard, but no route and no middleware checks them, and the MCP server returns its 40 tools with any valid key. What scopes the agent is the workspace of the key, the per-workspace quotas, revocation, the archived workspace block and human authorisation.

What happens when an agent runs out of quota?

The API rejects the operation with a quota error. The limits apply per workspace: dailyAgentOps 200 authenticated requests per day (MCP and direct HTTP), dailyHostedAiOps 10 hosted AI operations per day, 100 agent operations per month, 100 hosted AI operations per month and 2 webhook deliveries per minute. The daily figure counts authenticated requests and the monthly one counts semantic operations: they are not the same number.

How do you know what an agent did and what is kept of its credentials?

Every authenticated request leaves an ApiKeyUsage row with apiKeyId, workspaceId, method, path and channel. The activity feed applies two redaction layers: an allowlist on write and a deep redaction on read. Passwords, API keys, Authorization headers and cookies, JWTs, OTP codes, registration, linking and rotation tokens, webhook secrets, private keys and x402 payloads are hidden; non-secret identifiers are kept. If redaction fails, the API returns a skeleton without the raw payload and with redactionFailed=true.

Sources

Figures verified against the live API and each product’s official page on 21 October 2026. Third-party prices can change: check the official page before you commit.

Related guides

This guide exists to be indexed and cited. It is deliberately not in the menu.