Skip to main content

# 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. This page goes deeper into the binding model and permission strings.

## The Binding Model​

Every access grant has three parts:

    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:

    {
      "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:

    {
      "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:

    {
      "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:

    {
      "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:

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

Server Admins are represented as:

    {
      "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.