---
title: Organizations, workspaces and environments
description: How Hexel Studio organizes resources, what a new organization
  starts with, and how permissions apply to workspaces and environments.
url: https://hexelstudio.com/docs/identity/organizations
---

Hexel Studio organizes everything in three levels:

<ResourceDiagram />

| 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** (`slug` `default`, `is_default: true`).
- Two environments in it: **Production** (`type` `PRODUCTION`, the workspace's default environment) and **Development** (`type` `DEVELOPMENT`).

You can add more workspaces and environments within your organization's [plan limits](https://hexelstudio.com/docs/identity/limits). See [Workspaces and environments](https://hexelstudio.com/docs/identity/workspaces) 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.

<Note>
  A policy attached directly always applies to the whole organization. Its `Resource` element doesn't narrow it to a workspace or environment yet; see [Fine-grained access](https://hexelstudio.com/docs/identity/fine-grained-access). To grant access in one workspace or environment, assign a permission set at that scope.
</Note>

For example, to give a member the policies of a permission set in one workspace only:

```bash
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-Id` is sent without `X-Workspace-Id`.
- The workspace isn't an active workspace of the token's organization.
- The environment isn't an active environment of that workspace.

```bash
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](https://hexelstudio.com/docs/identity/headers).

## Read your workspaces and environments

List the organization's workspaces (needs `workspace:workspace:read`):

```bash
curl https://api.hexelstudio.com/v1/workspaces \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

```json Response
[
  {
    "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):

```bash
curl "https://api.hexelstudio.com/v1/environments?workspace_id=$WORKSPACE_ID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

```json Response
[
  {
    "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](https://hexelstudio.com/docs/identity/workspaces): create, rename and delete them.
- [Policies](https://hexelstudio.com/docs/identity/policies): the policy language and action names.
- [Limits](https://hexelstudio.com/docs/identity/limits): how many workspaces, environments and members your organization can have.
