---
sidebar_position: 9
---
# Permissions

CoderFlow uses scoped role-based access control. A role is a named set of
permission strings, and a binding grants that role to a user or team on a
specific resource.

Use this page when you need to answer questions like:

- Who can run tasks in an environment?
- Why can this user see one environment but not another?
- How do I grant one extra capability without making someone a Server Admin?
- Which predefined role should I bind to a team?

For day-to-day user and team management, start with
[People & Access](/admin/users-and-roles). This page goes deeper into the
binding model and permission strings.

## The Binding Model

Every access grant has three parts:

```text
subject -> resource -> role
```

| Part | Meaning | Examples |
|------|---------|----------|
| Subject | The principal receiving access | A user or a team |
| Resource | The thing access applies to | An environment, team, or the server |
| Role | The permission set granted on that resource | Viewer, Developer, Environment Admin, Team Admin, Server Admin, or a custom role |

Team membership is additive. A user gets the union of direct user bindings and
bindings granted through every team they belong to.

## Resource Scopes

Bindings can target three resource types.

| Resource type | What it controls | Common roles |
|---------------|------------------|--------------|
| Environment | Tasks, deployments, environment settings, secrets, builds, and environment access | Viewer, Developer, Environment Admin |
| Team | Team lifecycle and team membership | Team Admin |
| Server | Server-wide administration | Server Admin |

Environment and team bindings normally target a specific resource. The data
model also supports `*` as a wildcard resource ID for all environments or all
teams. Server bindings do not use a resource ID.

Permission scope comes from the permission string, not from the page where you
grant it. For example, `tasks:create` is environment-scoped, while
`users:create` is server-scoped. Server-scoped permissions can appear in an
environment or team role; they are still enforced as server-wide capabilities.
This is why the Developer role can include `jira:read_and_comment` and the Team
Admin role can include `users:create`.

## People & Access Pages

Open **Administration -> People & Access** to manage the model.

- **Users** creates and edits users, resets passwords, and opens per-user access
  controls.
- **Teams** manages team membership and team-level access.
- **Roles** shows predefined and custom role definitions. This page is available
  to Server Admins only, who can create, edit, and delete custom roles from it.
- **Access** shows bindings across subjects, resources, and roles. Users with
  delegated access-management permissions see the bindings they can manage;
  Server Admins see all bindings.

The **Roles** page is intentionally separate from the **Users** page. Roles
define capability sets. Bindings decide who receives those capability sets and
where.

Comment `@`-mention autocomplete also uses the user directory. In the current
server routes, the full user directory is mounted behind Server Admin access
before the endpoint-level `users:view` check runs. If a non-Server Admin cannot
populate the mention dropdown, have a Server Admin confirm the user exists and
review the relevant access binding.

## Predefined Roles

CoderFlow ships five predefined roles. They are seeded by the server, kept in
sync on startup, and cannot be deleted.

### Viewer

Read-only environment access.

Permissions:

- `tasks:view`
- `environments:view`
- `environments:view_details`
- `teams:view`
- `deployments:view`
- `skills:view`

Use Viewer for people who need to follow task progress, inspect results, or
review deployment history without starting work.

### Developer

Standard environment access for creating and running tasks.

Permissions:

- `tasks:view`
- `tasks:create`
- `tasks:change`
- `tasks:execute`
- `tasks:delete`
- `tasks:approve`
- `environments:view`
- `environments:view_details`
- `teams:view`
- `containers:shell`
- `deployments:view`
- `deployments:execute`
- `skills:view`
- `jira:read_and_comment`
- `qa:access`

Use Developer for users who should create tasks, run agents, use terminals,
approve task changes, and run deployment profiles in the environments where
they are bound.

### Environment Admin

Full environment administration for bound environments.

Permissions:

- `tasks:view`
- `tasks:view_any`
- `tasks:create`
- `tasks:change`
- `tasks:change_any`
- `tasks:execute`
- `tasks:execute_any`
- `tasks:delete`
- `tasks:delete_any`
- `tasks:approve`
- `tasks:approve_any`
- `tasks:comment_delete_any`
- `environments:manage_access`
- `environments:view`
- `environments:view_details`
- `teams:view`
- `environments:manage`
- `environments:build`
- `environments:files`
- `environments:git`
- `environments:secrets`
- `environments:mcp-servers`
- `environments:instructions`
- `environments:templates`
- `containers:shell`
- `deployments:view`
- `deployments:execute`
- `deployments:manage`
- `skills:view`
- `skills:task-edit`
- `jira:read_and_comment`
- `qa:access`
- `environments:ibmi_import`

Use Environment Admin for owners of an environment. They can change environment
configuration, manage secrets and build files, manage deployment profiles, and
grant environment access to other users or teams.

### Team Admin

Team administration and onboarding.

Permissions:

- `teams:manage`
- `teams:manage_membership`
- `teams:view`
- `users:view`
- `users:create`

Use Team Admin when someone should manage team lifecycle and membership without
receiving full server administration. Team Admin does not grant task or
environment access by itself; grant those with separate environment bindings.

Current builds still expose the full user-list and user-create routes only to
Server Admins, even though the Team Admin permission catalog includes
`users:view` and `users:create`. Treat new-user creation and global user search
as Server Admin flows; use Team Admin for team lifecycle and membership work on
existing users.

### Server Admin

Full system access across all resources.

Permissions:

- `*`

Use Server Admin sparingly. A Server Admin can manage settings, users, teams,
roles, bindings, environments, provider authentication, logs, and every task.
The first user on a fresh server is automatically granted a Server Admin binding
so the installation is not left without an administrator.

## Custom Roles

Create a custom role when a predefined role is close but not exact.

1. Open **Administration -> People & Access -> Roles**.
2. Click **Create Role**.
3. Give the role a specific name, such as `Developer + Private-task Review`.
4. Select the permission strings to include.
5. Save the role.
6. Open **Access** and bind the role to the user or team on the intended
   resource.

Custom roles must use valid permission strings from the permission catalog. A
role cannot mix environment-scoped and team-scoped permissions. Server-scoped
permissions can be combined with either environment or team permissions.

The binding API prevents privilege escalation. A delegated Environment Admin can
grant a role only when the role's permissions are a subset of their own effective
permissions on that environment. Server Admins can grant any role.

## Example: Add Private-task Review

There is no standalone `tasks:judge` permission in the current catalog. Judge
work uses the same task permissions as other task flows.

Shared tasks in the same environment can be viewed and judged with the base
`tasks:view` and `tasks:create` permissions. If a Developer also needs to review
private or locked tasks created by other users in one environment without
receiving full Environment Admin access:

1. Create a custom role based on Developer.
2. Add `tasks:view_any`.
3. Keep the other Developer permissions unchanged.
4. Bind that custom role to the user or team on the target environment.

Add only the `_any` permissions the person actually needs:

- `tasks:view_any` lets them view private or locked tasks owned by other users.
- `tasks:change_any` lets them modify private or locked tasks owned by other
  users.
- `tasks:execute_any` lets them run or interrupt private or locked task
  operations owned by other users.
- `tasks:approve_any` lets them approve private or locked task changes owned by
  other users.
- `tasks:delete_any` lets them delete tasks owned by other users.

For most reviewers, start with `tasks:view_any` only.

## Access Binding Examples

Grant a team Developer access to one environment:

```json
{
  "subject_type": "team",
  "subject_id": "team_app_devs",
  "role_id": "role_predefined_developer",
  "resource_type": "environment",
  "resource_id": "app"
}
```

Grant one user Environment Admin access to one environment:

```json
{
  "subject_type": "user",
  "subject_id": "user_alice",
  "role_id": "role_predefined_env_admin",
  "resource_type": "environment",
  "resource_id": "app"
}
```

Grant one user Team Admin access to one team:

```json
{
  "subject_type": "user",
  "subject_id": "user_sam",
  "role_id": "role_predefined_team_admin",
  "resource_type": "team",
  "resource_id": "team_app_devs"
}
```

Grant one user Server Admin access:

```json
{
  "subject_type": "user",
  "subject_id": "user_owner",
  "role_id": "role_predefined_server_admin",
  "resource_type": "server"
}
```

The UI handles these shapes for you. The JSON examples are useful when reading
API responses or debugging access data.

## Permission Resolution

When a request needs permission, CoderFlow resolves access in this order:

1. Identify the permission's scope from the permission catalog.
2. Collect bindings for the user and for every team the user belongs to.
3. For environment-scoped checks, include bindings for the target environment,
   wildcard environment bindings, and Server Admin bindings.
4. For team-scoped checks, include bindings for the target team, wildcard team
   bindings, and Server Admin bindings.
5. For server-scoped checks, inspect all user and team bindings for
   server-scoped permissions.
6. Union all permissions from matching roles.
7. Grant access when the union contains the required permission, a category
   wildcard such as `tasks:*`, or the global wildcard `*`.

The `/auth/me` response returns the resolved permission map used by the web UI:

```json
{
  "permissions": {
    "server": ["settings:view"],
    "environments": {
      "app": ["tasks:create", "tasks:view"]
    },
    "teams": {
      "team_app_devs": ["teams:manage_membership"]
    }
  }
}
```

Server Admins are represented as:

```json
{
  "permissions": {
    "server": ["*"],
    "environments": {},
    "teams": {}
  }
}
```

## Troubleshooting

**A user can log in but sees no environments**

They have a valid account but no environment binding, no team membership with an
environment binding, and no Server Admin binding. Add them to a team or create a
direct environment binding.

**A Team Admin cannot run tasks**

Team Admin manages teams only. Add a separate Viewer, Developer, or custom
environment binding for the environment where they need task access.

**An Environment Admin cannot create a custom role**

Custom role management is a server-level operation. It requires Server Admin
access through the Roles page.

**A delegated admin cannot assign a role**

The role may contain permissions the delegated admin does not have. Create a
smaller custom role or ask a Server Admin to make the binding.

**An API key authenticates but an operation returns `Forbidden`**

API keys authenticate as their owning user. Check that user's resolved
permissions and bindings. See [API Keys](/admin/api-keys).
