Skip to content
Hexel StudioDocs

Policies and permissions

The policy document language, how Hexel Studio decides a request, how access flows from an organization to its workspaces and environments, and the managed policies you can use.

On this page

A policy is a JSON document that lists actions. You attach it to a member, a group, a service user or a role, and that principal may then perform the actions it allows. Hexel Studio denies everything a policy does not allow.

This page describes the language exactly as Hexel Studio reads it today, including the parts it stores but does not apply yet. To create and attach policies, see Write and attach policies.

A policy document

JSON
{
  "Version": "2026-02-17",
  "Statement": [
    {
      "Sid": "ReadWorkspaces",
      "Effect": "Allow",
      "Action": ["workspace:workspace:read", "env:env:read"],
      "Resource": ["*"]
    }
  ]
}
FieldTypeWhat Hexel Studio does with it
VersionstringStored. Any value is accepted and none changes the meaning. Use 2026-02-17, the value of the managed policies.
StatementarrayThe statements. A document needs at least one.
Sidstring, optionalA label for the statement. Stored, not used in decisions.
Effect"Allow" or "Deny"Allow grants the listed actions. Deny is stored but does not block normal API calls yet (see below). The value is case-sensitive: "allow" grants nothing.
Actionstring or array of stringsThe actions the statement covers. See Action names and wildcards.
Resourcestring or array of stringsRequired by the policy validator. Stored, not matched. Use ["*"].
Conditionobject, optionalStored, never evaluated.

A document that is not valid JSON, or has no statement Hexel Studio can read, grants nothing. Hexel Studio does not check the document when you create a policy, and when you change one it checks only that the document is JSON. Validate it first.

Action names and wildcards

An action is named <service>:<resource>:<verb>, for example workspace:workspace:create or iam:policy:write. Names are case-sensitive. The actions reference lists every action.

A pattern in Action matches an action when it is:

PatternMatchesExample
*Every action"*"
An exact nameThat action only"iam:policy:read"
A name ending in *Every action that starts with the text before the *"iam:*" (all IAM actions), "iam:policy:*" (all policy actions)

Only a trailing * is a wildcard. iam:*:read matches nothing except an action literally named iam:*:read. A trailing * matches any text, so iam* also matches actions of any service whose name starts with iam.

How a request is decided

Your normal API calls are decided by the cached permission check. For each request, Hexel Studio collects the Allow actions of every policy that applies to the caller in the token's organization, and allows the request if one of them matches the action the API checks. If none matches, the request is denied with 403. Deny statements are not read by this check, so they have no effect on API calls today.

The policies that apply depend on who is calling:

CallerPolicies that apply
MemberPolicies attached to the member, policies attached to every group the member is in (including the membership group of their member role), and the policies of permission sets assigned to the member or their groups
Service userPolicies attached to the service user, to its groups, and of permission sets assigned to it
Role sessionOnly the policies attached to the role, limited by the role's permission boundary if it has one. The policies of the person or service user who assumed the role don't apply. See Roles.

A permission never comes from a name, an email address or a header you send. Permissions are not stored in the access token, so a change applies to tokens that were already issued.

When you change an attachment, a group, a permission set or a policy document, Hexel Studio updates the cached permissions of the principals concerned, usually at once. Cached permissions also expire on their own, so a change always takes effect within about a minute.

Organization, workspace and environment scope

A request is made for one organization: the token's. It can also name a workspace and an environment of that organization, with the X-Workspace-Id and X-Environment-Id headers (see Headers). The endpoints for a single workspace or environment, such as PATCH /v1/workspaces/<workspace-id>, set this scope from the path for you.

Each grant has a scope, and a grant at one level applies to everything below it:

Where the grant is placedApplies to requests for
Organization: policy attachments, permission sets assigned without a workspace, organization-scoped rolesThe organization and every workspace and environment in it
Workspace: permission sets assigned with workspace_id, workspace-scoped rolesThat workspace and its environments
Environment: permission sets assigned with workspace_id and environment_id, environment-scoped rolesThat environment only

Policy attachments have no scope of their own: a policy attached to a member, group or service user always applies organization-wide.

Hexel Studio checks the scope before it looks at any permission:

  • A request that names an environment must also name its workspace.
  • The workspace must be an active workspace of the token's organization, and the environment must be an active environment of that workspace. Otherwise the request is denied, even for an owner.
  • A request that names no workspace is checked against organization-level grants only. A grant placed on a workspace does not count for it.

Some actions are always checked at organization level, whatever headers you send. Creating a workspace (workspace:workspace:create) is one: a grant placed on a workspace can't let someone create workspaces.

Managed policies

Hexel Studio provides managed policies that every organization can attach. They appear in GET /v1/policies next to your own policies, with "is_system": true. You can attach them and read them, but you can't change or delete them.

These managed policies are the ones the default member roles use, plus a few full-access ones:

Policy IDNameAllows
pol_org_owner_fullOrganization Owner Full Access*
pol_iam_fullIAM Full Accessiam:*
pol_iam_adminIAM Admin AccessRead and write IAM: policies, attachments, groups and their members, roles and trust policies, permission sets, iam:authz:simulate, and the Preview IAM features. Not iam:user:erase.
pol_iam_readonlyIAM Read-Only AccessThe :read IAM actions, and iam:tag:manage
pol_org_fullOrganization Full Accessorg:*
pol_org_memberOrganization Member Accessorg:org:read, org:org:update, org:member:invite, org:member:manage, org:settings:read, org:settings:write, org:billing:read, org:audit:read
pol_org_readonlyOrganization Read-Onlyorg:org:read, org:settings:read, org:billing:read, org:audit:read
pol_billing_fullBilling Full Accessorg:billing:read, org:billing:manage
pol_billing_readonlyBilling Read-Only Accessorg:billing:read
pol_ws_fullWorkspace Full Accessworkspace:*
pol_ws_readonlyWorkspace Read-Only Accessworkspace:workspace:read
pol_env_fullEnvironment Full Accessenv:*
pol_env_readonlyEnvironment Read-Only Accessenv:env:read
pol_svc_accountService Account Full Accessdirectory:service_account:create, :read, :update, :delete, :manage_keys
pol_dir_readonlyDirectory Read-Only AccessIncludes directory:service_account:read
pol_data_full / pol_data_readonlyAtlas Full Access / Atlas Read-Only AccessAtlas actions
pol_memory_full / pol_memory_user / pol_memory_readonlyMemory Full / User / Read-Only AccessHexel Managed Memory actions
pol_skills_full / pol_skills_publisher / pol_skills_readonlySkills Full / Publisher / Read-Only AccessSkills Registry actions

Read a managed policy's document with GET /v1/policies/<policy-id>. The list also contains policies for other Hexel Studio products and policies Hexel Studio uses for its own services. The actions reference describes the actions.

Permission sets

A permission set is a named list of policy IDs. Assigning it to a member, a group or a service user grants all its policies to that principal, optionally only in one workspace or environment, and optionally until an expiry time. It is the way to grant a member access to a single workspace or environment.

  • An assignment grants its policies while it exists and has not expired. Deleting the assignment removes the access.
  • An assignment with workspace_id grants in that workspace and its environments. With workspace_id and environment_id, it grants in that environment only. Without either, it grants organization-wide.
  • The policy list is copied when you assign the set. Changing the set's policy_ids later does not change existing assignments; changing a policy's document does.

GET /v1/permission-sets lists your permission sets and any that Hexel Studio provides. See Grant access in one workspace or environment for the API.

Role templates

GET /v1/role-templates and GET /v1/role-templates/<name> return role templates: a name, display_name, description, scope and a list of action names in permissions. They are reference lists you can copy actions from into a policy. A template grants nothing, and Hexel Studio does not create policies or roles from it. Reading templates needs iam:policy:write.

Nobody grants what they don't hold

To attach a policy, assign a permission set, add a member to a group, or change the document of a policy that is in use, you must already hold every action the change grants, at organization level. Otherwise the request is refused with 403:

JSON
{
  "error": "forbidden",
  "reason": "cannot grant actions the caller does not hold",
  "missing_actions": ["iam:user:erase"]
}

An owner holds *, so an owner can grant anything. An admin can grant only what the admin policies give them. A wildcard counts only if you hold an equal or wider one: holding iam:policy:read and iam:policy:write does not let you grant iam:policy:*.

What is not enforced yet

These parts of the language are accepted and stored, but don't change the result of your API calls yet:

FeatureTodayRead more
Deny statementsNot applied to API calls. Only the test access endpoints apply them. Remove the Allow instead.Guardrails (Preview)
Resource and ConditionStored and ignored everywhereFine-grained access (Preview)
Permission boundaries on members and service users, service control policies, resource control policiesNot applied to API callsGuardrails (Preview)

A permission boundary set on a role does apply: it caps every call made with that role's sessions. See Roles.