---
title: "Policy & capabilities"
description: "Capability types, permission profiles, command risk levels — policy before every side effect."
source: https://carina.nebutra.com/concepts/policy/
---

# Policy & capabilities

> Capability types, permission profiles, command risk levels — policy before every side effect.

> **Every meaningful side effect is gated.** The model decides; the Rust kernel authorizes.

## What you'll get

- The fourteen capability types  
- Built-in profiles (`safe-edit`, `read-only`, …)  
- Command risk levels 0–5  
- How approvals show up in the CLI/TUI  

## Why this matters

Carina’s edge is not “another coding chat.” It is **policy before effect**:

1. Agent proposes an action  
2. Kernel returns `allow` / `deny` / `require-approval`  
3. Decision is audited; side effects reference that decision  

Without this page, the rest of the product looks like a generic runner.

## Default posture

1. Least privilege by default  
2. No access outside the workspace  
3. Secrets unreadable by default  
4. Network restricted by default  
5. Destructive commands denied by default  
6. All patches are transactional  
7. Plugins start with zero permissions  

## Where policy lives

## Capability types

```
FileRead  FileWrite  CommandExec  NetworkAccess  SecretRead
GitOperation  PatchApply  ProcessSpawn  PluginLoad  RemoteExecute
MemoryWrite  CodeIndex  ContextCompress  SubagentSpawn
```

A request carries: principal (agent / plugin / user), resource (path, command, host), session id, task id.  
The kernel returns a `PermissionDecision` with the producing policy. Every decision is an audit event.

<Tooltip tip="Child agents receive a strict subset of the parent profile — never more.">SubagentSpawn</Tooltip> uses resource form `agent:NAME:profile:PROFILE` and **requires approval by default**.

## Permission profiles

| Profile | Summary | Sample config |
| --- | --- | --- |
| `read-only` | FileRead in workspace only; everything else denied | `protocol/capabilities/profiles/read-only.toml` |
| `safe-edit` | FileRead; FileWrite **only via PatchApply**; CommandExec allowlist; network needs approval; secrets denied | `…/safe-edit.toml` |
| `full-workspace` | R/W in workspace; commands up to level 3 with approval | `…/full-workspace.toml` |
| `ci-runner` | test/build allowed; no arbitrary shell; secrets only when scoped | `…/ci-runner.toml` |
| `sandboxed` · `trusted-local` · `enterprise-restricted` | Named in `capabilities.json` for org/runtime bundles | No shipped sample toml yet — treat as registry names until you add custom profiles |

Profiles are **session-scoped** and stored in session metadata. Custom profiles are supported.

`carina run` creates a **`safe-edit`** session in the current directory unless you attach another way.

```bash frame="none"
carina profile SESSION
```

## Command risk levels

| Level | Class | Default under `safe-edit` |
| --- | --- | --- |
| 0 | read-only | auto allow |
| 1 | test / build / lint | auto allow |
| 2 | package install | require approval |
| 3 | file mutation commands | require approval |
| 4 | network / deploy / credentials | deny or explicit profile |
| 5 | destructive (`rm -rf`, `curl \| sh`, …) | deny by default |

## Always require human confirmation

Deleting many files · lockfile churn · dependency install · remote scripts · reading secrets · paths outside workspace · push/deploy · network · CI config changes.

## Approvals in the product

    TUI prompts, or use CLI:
    ```bash frame="none"
    carina approve SESSION DECISION_ID [role]
    carina deny SESSION DECISION_ID [reason]
    ```

    ```bash frame="none"
    carina audit SESSION
    carina report SESSION
    ```

## Workspace boundary

- Agents cannot access paths outside allowed workspace paths  
- **Symlinks are resolved before policy** — they cannot escape the boundary  
- Oversized / ignored files stay out of model context by default  

## Secrets

1. Agents never read the environment directly  
2. Secrets go through a broker as opaque handles  
3. Logs never contain secret plaintext  
4. Command output is redacted against known secret values  

```bash frame="none"
carina secret grant SESSION NAME VALUE
carina secret request SESSION NAME
```

## Fast mental model

    Default for `carina run`. Writes via <Badge variant="info">PatchApply</Badge>; network needs approval.

    Explore without side effects — FileRead only.

## If it fails

| Symptom | Meaning |
| --- | --- |
| Constant approvals | Risk ≥ 2 or network — tighten the task or use a broader profile **consciously** |
| Deny on path | Outside workspace or symlink escape attempt |
| Plugin does nothing | Plugins start at zero permissions — inspect with `carina plugin inspect` |

## Source of truth

- `docs/security-model.md`  
- `protocol/capabilities/capabilities.json`  
- Kernel / profiles: `crates/carina-policy`  
- Related: [Audit & rollback](/concepts/audit/) · [Glossary](/reference/glossary/)

## Next

- [Quickstart](/getting-started/quickstart/) — feel policy on a real run  
- [Sub-agents](/agents/sub-agents/) — attenuation in practice  
- [CLI reference](/reference/cli/) — `approve` / `deny` / `profile`

---
Source: https://carina.nebutra.com/concepts/policy/
Markdown: https://carina.nebutra.com/concepts/policy/index.md
