# Manage permissions

import { Steps } from "@astrojs/starlight/components"
import Prereqs from "@docs/Prereqs.astro"
import UiWalkthrough from "@docs/UiWalkthrough.astro"
import ClientTabs from "@docs/ClientTabs.astro"

Permissions control what an agent is allowed to do inside its sandbox: read files, run bash commands, make web requests, and more. You set permissions at the project level and can override them per agent version.

<Prereqs>
  - A Ren account with write access to the project or agent - [The CLI installed](/docs/developers/cli/) (for CLI steps)
</Prereqs>

## How permissions work

A permission config is either a single action (`"allow"`, `"deny"`, `"ask"`) or an object with granular keys. Agent-level permissions override project-level permissions. An explicit `deny` always wins over `allow`.

The available permission keys are:

| Key                  | Controls                                     |
| -------------------- | -------------------------------------------- |
| `read`               | Read files in the sandbox                    |
| `edit`               | Write or modify files                        |
| `glob`               | Search files by pattern                      |
| `grep`               | Search file contents                         |
| `list`               | List directory contents                      |
| `bash`               | Run shell commands                           |
| `task`               | Create and manage sub-tasks                  |
| `external_directory` | Access directories outside the project       |
| `todowrite`          | Write to the todo list                       |
| `question`           | Ask clarifying questions                     |
| `webfetch`           | Fetch external URLs                          |
| `websearch`          | Search the web                               |
| `codesearch`         | Search code with semantic search             |
| `lsp`                | Use language server features                 |
| `doom_loop`          | Allow the agent to loop without intervention |
| `skill`              | Load and execute skills                      |

See [Permissions](/docs/deep-dives/concepts/sharing/permissions/) for the full concept.

## In the UI

<UiWalkthrough>
  {/* TODO(demo): screen recording – editing project and agent permissions in the dashboard, ~10s loop */}
</UiWalkthrough>

<Steps>

1. Open a project and go to **Settings → Permissions**.

2. Set the default policy for each capability: **Allow**, **Deny**, or **Ask**.

3. To override for a specific agent, open the agent's version settings and adjust the permissions there.

4. Click **Save**.

</Steps>

## Programmatically

<ClientTabs clients={["cli", "api", "typescript"]}>

<Fragment slot="cli">
  **Set project-level permissions**

```bash
ren projects update prj_def456 \
  --permission '{"read": "allow", "edit": "allow", "bash": "ask"}'
```

**Set agent-version-level permissions**

```bash
ren agents versions create agt_abc123 \
  --permission '{"bash": "deny", "webfetch": "deny"}'
```

</Fragment>

<Fragment slot="api">
  **Set project-level permissions**

```bash
curl -X PATCH "https://api.renai.build/api/projects/prj_def456" \
  -H "Authorization: Bearer $REN_PAT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "permission": {
      "read": "allow",
      "edit": "allow",
      "bash": "ask"
    }
  }'
```

**Set agent-version-level permissions**

```bash
curl -X POST "https://api.renai.build/api/agents/agt_abc123/versions" \
  -H "Authorization: Bearer $REN_PAT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "permission": {
      "bash": "deny",
      "webfetch": "deny"
    }
  }'
```

</Fragment>

<Fragment slot="typescript">
  ```ts
  import { createRenClient, pat } from "@renai-labs/sdk"

const client = createRenClient({
baseUrl: "https://api.renai.build",
auth: pat(process.env.REN_PAT_TOKEN!),
})

// Set project-level permissions
await client.project.update({
path: { id: "prj_def456" },
body: { permission: { read: "allow", edit: "allow", bash: "ask" } },
})

// Override on a new agent version
await client.agent.version.create({
path: { id: "agt_abc123" },
body: { version: "minor", permission: { bash: "deny", webfetch: "deny" } },
})

```
</Fragment>

</ClientTabs>
```