MachineMachine
MachineMachine
MachineGetting startedQuickstartAccounts & access
Your project
AgentsLegacy kortix.tomlManifest referenceModelsAgent permissionsSecrets
Running work
Change requestsRuntime & sandboxSessions
Connect & automate
ComputersConnectorsInkbox: iMessage, SMS, email & callsMCP serverPixio: images, video & audioRemindersSlack & channelsMicrosoft TeamsTriggers
Feature flags
Apps

Develop

CLI
TypeScript SDKFull exampleAuthenticationSign in with KortixSessionsAppsReact hooksSDK reference
Machine as a BackendAPI reference
GitHub
Your project

Agent permissions

What an agent may do, who decides it, and what the person who runs it contributes.

An agent acts on your project through the CLI, the API, git, connectors, and Apps. This page explains how Kortix decides what an agent may do.

An agent acts as itself, not as the person who started it. Its authority is its Machine permissions ∩ its ceiling role. Permissions alone decide, the same way they do for a person. Nobody lends an agent their own role, so the agent does the same thing whoever runs it.

The agent is the acting principal

Every agent session has two identities:

IdentityWhat it decides
Acting principal — the agentEverything on shared resources: project permissions, shared connector accounts, project secrets, Apps, git.
On behalf of — the personOnly that person's own resources, and only in that person's own private session.

Each agent has one identity per project: a service account that Kortix creates for it. You never hold a credential for it.

Kortix permissions — the manifest decides

Each agent declares its Kortix permissions in kortix.yaml, under agents.<name>.kortix_permissions. The manifest on the default branch is the source of truth.

yaml
agents:
  report-writer:
    kortix_permissions: [project.file.read, project.connector.read, project.app.read]
    connectors: [reports-dashboard-api]
    secrets: [REPORTS_API_KEY]
    apps: [reports-dashboard]
  • The list is deny-by-default. An agent without kortix_permissions gets none.
  • all grants every project permission, still capped by the ceiling.
  • kortix_cli is the deprecated spelling. It still validates, with a warning. Both keys with different values on one agent is a validation error.

Edit the list in Customize → Agents → the agent → Kortix permissions. A save commits kortix.yaml. See the manifest reference.

The ceiling — an admin decides

The ceiling is a project role that an admin binds to the agent's service account. The agent's Kortix permissions never exceed it.

  • No role bound: the default agent ceiling applies. It is every project permission except project.credentials.issue.
  • A role bound: built-in member or manager, or a custom role. The agent keeps only the Kortix permissions that the role also grants.
  • A ceiling never adds a permission. A manager ceiling does not give an agent a permission its manifest does not list.

Set the ceiling in the Access hub → Projects → the project → Add. Pick the agent under Agents and choose a role. Only admins who manage roles see agents in the picker. The project's access list shows each agent ceiling with an Agent badge.

all means every permission

kortix_permissions: all, "*", and any list that contains "*" mean the same thing: every project permission. That includes project.members.manage (add, change, or remove project members and grants) and project.delete.

One permission stays with people: project.credentials.issue (mint a project token or a project-scoped PAT). A token an agent minted would carry no agent permissions, so it would act outside them. The refusal answers 403 with code: "agent_human_only_action".

An entry that is not a grantable permission is ignored at runtime and the rest of the list still applies. kortix validate and a change request merge report it as an error.

project.read is the reverse: an agent always holds it inside its own project.

Running an agent lends its authority

The person who runs an agent does not cap it. So the right to run an agent is the delegation. Kortix checks "may this person run this agent" at every entry point:

Entry pointRequired
Create, start, or prompt a session; switch its agentThe person may run the agent
Fire a trigger by handThe person who fires it may run the trigger's agent
Start a child session from an agent sessionThe person behind the parent may run the child's agent. With no person behind it, only the same agent.

Grant "may run" on the agent's People tab, or in the Access hub. Agents are closed by default: a member runs an agent only when an assignment names them or one of their groups.

Personal resources stay personal

An agent session reaches a resource that one person owns only when both are true:

  1. The session runs on behalf of that person.
  2. The session is private.

Personal resources are member-owned connector connections, personal project secrets, personal provider keys, and the person's own computer. A shared session, a trigger or channel session, and an unattended run reach none of them.

When another person prompts a private session — for example an account admin who can open members' private sessions — the session stops acting on behalf of its creator, for good. The agent keeps its own permissions. The person who prompts never acts through someone else's accounts.

Apps

An agent opens a restricted or private App only when its apps: grant names the App's slug, or is all, and its effective permissions include project.app.read.

App access modeThe agent is admitted when
PublicAlways
Projectproject.app.read is effective
Restricted or privateThe slug is in apps: and project.app.read is effective
PasswordNever

The App's Access dialog lists the agents with access, read from agents.<name>.apps. Change the list on the agent's Apps page (Customize → Agents → the agent → Apps), with kortix agents scope <agent> --apps <slug,slug>, or with a change request to kortix.yaml. The Apps page appears only when the project has the Apps feature flag on.

Changing agents and triggers

kortix.yaml shapes what agents may do, so whoever lands a change on the default branch shapes agents. The same permissions decide for an agent and for a person:

  1. Merging a change request needs project.gitops.merge.
  2. A merge that changes kortix.yaml also needs the permission the direct route for that change needs: agents.* → project.agent.write; triggers → project.trigger.create, .update, or .delete; default_agent → project.agent.write. The Manager role holds these, and the role editor adds them to any role that gets project.gitops.merge. An agent's kortix_permissions must list them, or be all. So an agent that may only merge cannot widen itself.
  3. An agent grants only what it holds. When an agent writes any agent's grant (the agent editor, the scope and secret-grant routes, or a change request it merges), every permission, connector, secret and App the write adds must be in the writing agent's own effective grant. Granting all needs every one of them. Narrowing or removing a grant is always allowed. A refusal answers 403 with code: "agent_grant_escalation".
  4. A push straight to the default branch skips the change request. An agent session needs project.gitops.ref.any and every permission in item 2. The pushed manifest cannot be checked before it lands, so the agent must also hold every grant (all permissions, connectors, secrets and Apps). Otherwise it opens a change request.
  5. A refusal answers 403 with code: "agent_scope_insufficient" (agent) or "project_role_insufficient" (person) and the missing action. When the manifest cannot be read, the merge answers 503 with code: "CR_GOVERNANCE_UNVERIFIED" and Retry-After. Retry it.
  6. The ceiling is admin-only IAM state. The manifest never exceeds it.

Read a denial

Every 403 from an authorization check carries code and action:

codeMeaningFix
agent_scope_insufficientaction is not in the agent's Kortix permissionsAdd it to agents.<name>.kortix_permissions
agent_ceiling_insufficientaction is outside the agent's ceiling roleAn admin raises the ceiling
agent_not_accessibleThe person may not run this agentGrant them the agent
agent_grant_escalationThe write gives an agent something the writing agent does not holdGrant only what the writer holds, or have a person make the change
project_role_insufficientThe person's own role denies actionChange their project role

Audit

Every agent action records three fields: actor is the agent, on_behalf_of is the person or null, and initiator is human, trigger, or channel. A trigger run records no person.

See it in the dashboard

Open Customize → Agents → the agent → Kortix permissions. The What this agent can do panel shows:

  • the Kortix permissions declared in kortix.yaml,
  • the ceiling role, or Default agent ceiling,
  • the one human-only permission, project.credentials.issue,
  • the effective permissions: "People who may run this agent act with these permissions."

Scope

This page applies to every agent a project declares under agents: in kortix.yaml. A project with no agents: map declares no governed agent, so there is nothing to switch on. There is no switch back to the old launcher-role model.

PreviousModelsNextSecrets

On this page

The agent is the acting principalKortix permissions — the manifest decidesThe ceiling — an admin decidesall means every permissionRunning an agent lends its authorityPersonal resources stay personalAppsChanging agents and triggersRead a denialAuditSee it in the dashboardScope