Projects and environments
The Projects and environments screen lets you create the projects that group agents, models and budgets, edit or
delete them, and add their dev, test, staging and prod environments. Portal path: /admin/projects. It is used
by the tenant administrators (tenant_admin); the other members of the tenant read the projects they have access to.
What the screen shows
Two blocks, one under the other.
Projects table, with Refresh and New project:
| Column | Content |
|---|---|
| Slug | Identifier of the project in the tenant (lowercase letters, digits, hyphens, 63 characters at most). |
| Name | Display name. |
| Description | Free text. |
| Created | Creation date. |
A click on a line opens a side panel with the full project read from the API (environments included). The list is paged by slug. Empty state: No project yet, "Projects scope agents, budgets and environments."
Environments of the project block, shown once at least one project exists: a Project selector (the first project is selected by default) and the table of its environments:
| Column | Content |
|---|---|
| Name | dev, test, staging or prod. |
| Created | Creation date. |
Empty state: No environment, "Add dev, test, staging or prod."
Actions
| Button or action | What it does | API call | Roles |
|---|---|---|---|
| Opening the screen, Refresh | Reads the projects; the selector reads up to 200 projects. | GET /v1/projects | Member of the tenant |
| New project then Create | Form Slug (required), Name (required), Description. | POST /v1/projects | tenant_admin |
| Click on a project line | Opens the detail panel. | GET /v1/projects/{id} | Member holding the viewer relation on the project |
| Edit | Dialog Name, Description, then Edit. | PATCH /v1/projects/{id} | tenant_admin with the editor relation on the project |
| Delete | Destructive confirmation that lists the impact (dependents read from the lineage graph), then deletion. | DELETE /v1/projects/{id} (impact: GET /v1/lineage/graph) | tenant_admin with the owner relation on the project |
| Project selector | Chooses the project whose environments are shown. | GET /v1/projects/{id}/environments | Member holding the viewer relation |
| New environment then Create | Form Name (required: dev, test, staging, prod) and Settings (JSON, {} by default). | POST /v1/projects/{id}/environments | tenant_admin with the editor relation |
Roles
From services/control-plane/src/eai/domains/tenancy/__init__.py:
- Reading the list needs a principal inside a tenant (
require_tenant); a principal without tenant getstenant_required. - Creating a project or an environment, editing and deleting require
tenant_admin(platform_adminalways passes). - On top of the role, the routes of one project check a ReBAC relation (
require_relation):viewerto read,editorto edit and add an environment,ownerto delete. The creator of a project is written as its owner.
The portal shows the buttons to every user (no role declared in projectsCfg); the server is the authority.
Delete removes the project for good. Read the impact listed by the confirmation (agents, keys, quotas that depend on the project) before you confirm.
Typical tasks
Create a project and its environments
- Create the project. Button New project: type the Slug (
risk), the Name and a Description, then Create. Expected result: the toast Created and the new line. If it fails:conflict(HTTP 409) when the slug exists in the tenant;forbiddenwhen you are nottenant_admin. - Select it. In the Environments of the project block, choose it in Project. Expected result: the empty state No environment. If it fails: the block is missing when the project list is empty; click Refresh.
- Add each environment. Button New environment, choose Name (
dev, thenprod), keep Settings at{}and Create. Environments separate the deployments of the agents and applications. Expected result: one line per environment. If it fails:conflict(HTTP 409) when the environment already exists for the project.
Rename or describe a project
- Open the action. Row menu > Edit. Expected result: a dialog filled with the current name and description.
If it fails: a
forbiddenerror at submit time means you lack theeditorrelation or thetenant_adminrole. - Change the values and submit. Button Edit. Expected result: the toast Done and the new values in the table. If it fails: read the code of the error under the form.
Delete a project
- Open the action. Row menu > Delete. The confirmation lists the dependents found in the lineage graph. Expected result: the destructive confirmation dialog. If it fails: when the graph cannot be read, the dialog keeps the default risk "Delete cannot be undone from this screen".
- Confirm. Expected result: the toast Done and the line disappears. If it fails:
forbiddenwhen you are not the owner of the project;not_foundwhen it was already deleted.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
tenant_required (HTTP 403) | The session does not act inside a tenant. | Sign in with an account that belongs to a tenant. |
forbidden (HTTP 403) on Create, Edit or Delete | Role tenant_admin missing, or ReBAC relation editor / owner missing on the project. | Ask a tenant_admin, or get the relation through Permissions (ReBAC). |
conflict (HTTP 409) | A project with this slug, or this environment of the project, already exists. | Use another slug, or keep the existing environment. |
not_found (HTTP 404) | The project was deleted or the identifier is not a UUID. | Click Refresh. |
| The Environments of the project block is missing | The tenant has no project yet. | Create a project first. |