Organizations, workspaces and environments
How Hexel Studio organizes resources, what a new organization starts with, and how permissions apply to workspaces and environments.
On this page
Hexel Studio organizes everything in three levels:
| Level | What it is | ID |
|---|---|---|
| Organization | The top-level container. Members, service users, groups, roles, policies and billing belong to an organization. | org_... |
| Workspace | A group of resources inside an organization, for example one per team or product. | ws_... |
| Environment | A stage inside a workspace, such as production or development. It has a type, for example PRODUCTION or DEVELOPMENT. | env_... |
Organizations are isolated from each other. A token or API key for one organization can't read or change anything in another, and a workspace or environment of another organization answers 404, like one that doesn't exist.
What a new organization starts with
When you create an organization, Hexel Studio sets up:
- You, as the organization's owner, with full access to it.
- A workspace named Default (
slugdefault,is_default: true). - Two environments in it: Production (
typePRODUCTION, the workspace's default environment) and Development (typeDEVELOPMENT).
You can add more workspaces and environments within your organization's plan limits. See Workspaces and environments for how.
How permissions apply to workspaces and environments
Permissions come from policies. Where a policy applies depends on how it's granted:
| Granted by | Applies in |
|---|---|
| A policy attached to a member, group or service user | The whole organization: every workspace and every environment. |
A permission set assigned with a workspace_id | That workspace and all its environments. |
A permission set assigned with a workspace_id and an environment_id | That environment only. |
Access flows down, never up. An organization-wide grant covers every workspace and environment, but a grant in one workspace doesn't help in another workspace or at the organization level.
For example, to give a member the policies of a permission set in one workspace only:
curl -X POST https://api.hexelstudio.com/v1/permission-sets/<permission-set-id>/assignments \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"principal_type": "USER",
"principal_id": "<user-id>",
"workspace_id": "'"$WORKSPACE_ID"'"
}'principal_type is USER, SERVICE_USER or GROUP. The call needs iam:permission_set:write, and you can grant only permissions you hold yourself. List the available permission sets with GET /v1/permission-sets.
Which grants a request uses
Each request is checked at one level, and only the grants for that level and the levels above it count:
| The request acts on | Grants that count |
|---|---|
| The organization, for example creating a workspace | Organization-wide grants only |
A workspace, for example GET /v1/workspaces/{workspace_id} | Organization-wide grants and grants in that workspace |
An environment, for example GET /v1/environments/{environment_id} | Organization-wide grants and grants in its workspace and in that environment |
When the path names a workspace or environment, Hexel Studio takes the scope from the path. For other requests you can select a scope with headers.
Scope headers
| Header | Effect |
|---|---|
X-Workspace-Id | Also counts your grants in this workspace. |
X-Environment-Id | Also counts your grants in this environment. Send it together with X-Workspace-Id. |
The headers only choose which of your grants count; they never grant anything. A request is denied, even for an organization owner, when:
X-Environment-Idis sent withoutX-Workspace-Id.- The workspace isn't an active workspace of the token's organization.
- The environment isn't an active environment of that workspace.
curl https://api.hexelstudio.com/v1/environments \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "X-Workspace-Id: $WORKSPACE_ID"The organization never comes from a scope header. It comes from your token or API key. If you send X-Organization-Id, it must equal that organization or the request is refused. See Headers.
Read your workspaces and environments
List the organization's workspaces (needs workspace:workspace:read):
curl https://api.hexelstudio.com/v1/workspaces \
-H "Authorization: Bearer $ACCESS_TOKEN"[
{
"id": "ws_3f9c1d2e8a7b4c6d9e0f1a2b3c4d5e6f",
"organization_id": "org_7b2e4c1a9d8f4e3b8c6a5d4e3f2a1b0c",
"name": "Default",
"slug": "default",
"is_default": true,
"is_active": true,
"created_by_user_id": "5d1e9a3c-7b2f-4e8d-9c6a-1f0e2d3c4b5a",
"created_at": "2026-10-20T09:12:44.512Z",
"updated_at": "2026-10-20T09:12:44.512Z"
}
]List the environments of one workspace (needs env:env:read in that workspace):
curl "https://api.hexelstudio.com/v1/environments?workspace_id=$WORKSPACE_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN"[
{
"id": "env_9a8b7c6d5e4f40312a1b2c3d4e5f6a7b",
"workspace_id": "ws_3f9c1d2e8a7b4c6d9e0f1a2b3c4d5e6f",
"name": "Production",
"slug": "production",
"type": "PRODUCTION",
"is_default": true,
"is_protected": true,
"is_active": true,
"settings": "{}",
"created_by_user_id": "5d1e9a3c-7b2f-4e8d-9c6a-1f0e2d3c4b5a",
"created_at": "2026-10-20T09:12:44.530Z",
"updated_at": "2026-10-20T09:12:44.530Z"
},
{
"id": "env_1c2d3e4f5a6b47c8d9e0f1a2b3c4d5e6",
"workspace_id": "ws_3f9c1d2e8a7b4c6d9e0f1a2b3c4d5e6f",
"name": "Development",
"slug": "development",
"type": "DEVELOPMENT",
"is_default": false,
"is_protected": false,
"is_active": true,
"settings": "{}",
"created_by_user_id": "5d1e9a3c-7b2f-4e8d-9c6a-1f0e2d3c4b5a",
"created_at": "2026-10-20T09:12:44.536Z",
"updated_at": "2026-10-20T09:12:44.536Z"
}
]Without workspace_id, the call lists the environments of every workspace in the organization.
Related
- Workspaces and environments: create, rename and delete them.
- Policies: the policy language and action names.
- Limits: how many workspaces, environments and members your organization can have.