> This page is for version 0.9.
> For other versions, use one of these documentation indexes:
> - Latest (default): https://docs.nvidia.com/nemo-helix/latest/llms.txt
> - 0.9: https://docs.nvidia.com/nemo-helix/v0.9/llms.txt
> - 0.8: https://docs.nvidia.com/nemo-helix/v0.8/llms.txt
> - 0.7: https://docs.nvidia.com/nemo-helix/v0.7/llms.txt
> - 0.6: https://docs.nvidia.com/nemo-helix/v0.6/llms.txt
> - 0.5: https://docs.nvidia.com/nemo-helix/v0.5/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo-helix/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo-helix/_mcp/server.

# Managing Access

Add users to workspaces, assign roles, and control who can access your resources. For background on the authorization model, refer to [Authorization Concepts](/nemo-helix/v0.9/documentation/access-control/concepts). For what each role can do, refer to [Roles & Permissions](/nemo-helix/v0.9/documentation/access-control/authorization/roles-and-permissions).

> **Note**
>
> The SDK examples on this page use `NemoClient.from_config()` with no arguments so that the client reads your active CLI context (set by `nemo auth login`). That is the right pattern for authorization workflows: you act as your logged-in identity and pass the workspace explicitly in each API call. For the standard local initialization pattern, see [CLI and SDK initialization](/nemo-helix/v0.9/documentation/get-started#nemo-setup).

## Creating Workspaces

Workspaces are the primary authorization boundary — all resources belong to a workspace, and access is controlled at the workspace level. When you create a workspace, you automatically become its Admin.

Create separate workspaces to isolate teams (`ml-research`, `nlp-team`), environments (`dev`, `staging`, `prod`), or projects. For detailed workspace management, refer to [Workspaces](/nemo-helix/v0.9/documentation/get-started/core-concepts/workspaces).

#### CLI

```bash
nemo workspaces create ml-team

# Set the workspace as your default for subsequent commands
nemo config set --workspace ml-team
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient
from nemo_helix_plugin.workspaces.types import CreateWorkspaceRequest

client = NemoClient.from_config()

workspace = client.workspaces.create_workspace(
    body=CreateWorkspaceRequest(name="ml-team", description="Machine learning team workspace")
).data()
```

## Managing Workspace Members

Members are principals that have been granted access to a workspace. A principal
can be a human user, an IdP group, the wildcard principal `*`, or a NeMo service
account such as `service-account:intake-otel-writer`. Each member has one of
three roles:

* **Viewer** — Read-only access to all resources
* **Editor** — Can create, modify, and delete resources
* **Admin** — Full control, including managing members

> **Note**
>
> **Role Propagation**
>
> When you add or change a member, the CLI and SDK wait for the change to propagate to the authorization engine before returning (up to 30 seconds). The member can use their new permissions immediately after the command completes.

### Add a Member

Grant a principal access to a workspace by adding it as a member with a specific
role. Human principals are often email addresses from your identity provider,
but the principal value does not have to be an email address.

#### CLI

```bash
nemo workspaces members create --principal alice@example.com --roles Editor --workspace ml-team
```

```json
{
  "principal": "alice@example.com",
  "roles": [
    "Editor"
  ],
  "granted_at": "2026-01-20T10:00:00Z",
  "granted_by": "admin@example.com"
}
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient
from nemo_helix_plugin.workspaces.types import CreateWorkspaceMemberRequest

client = NemoClient.from_config()

# Add a member with Editor role
client.workspaces.create_workspace_member(
    workspace="ml-team",
    body=CreateWorkspaceMemberRequest(principal="alice@example.com", roles=["Editor"]),
)

# Add a member with Viewer role (read-only)
client.workspaces.create_workspace_member(
    workspace="ml-team",
    body=CreateWorkspaceMemberRequest(principal="bob@example.com", roles=["Viewer"]),
)

# Add a member with Admin role (full control)
client.workspaces.create_workspace_member(
    workspace="ml-team",
    body=CreateWorkspaceMemberRequest(principal="charlie@example.com", roles=["Admin"]),
)
```

### Add a Service Account

Service-account Scoped Access Keys authenticate as `service-account:<id>`.
Create the role binding for that full principal value, not for the unprefixed
service account ID:

#### CLI

```bash
nemo workspaces members create \
  --principal service-account:intake-reader \
  --roles Viewer \
  --workspace ml-team
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient
from nemo_helix_plugin.workspaces.types import CreateWorkspaceMemberRequest

client = NemoClient.from_config()

client.workspaces.create_workspace_member(
    workspace="ml-team",
    body=CreateWorkspaceMemberRequest(principal="service-account:intake-reader", roles=["Viewer"]),
)
```

A human HelixAdmin must create the key. Service-account callers are
rejected, and any other caller receives `403 Forbidden`. Use the unprefixed ID
only in that command:

`nemo auth access-keys create --service-account intake-reader`. NeMo stamps the
token subject as `service-account:intake-reader`.

> **Warning**
>
> Do not grant customer automation access with the `service:<name>` principal
> form. The `service:` prefix is reserved for internal platform service
> principals.

### List Members

View all members of a workspace to audit access or verify permissions. The response includes each member's principal, roles, and when access was granted.

#### CLI

```bash
nemo workspaces members list --workspace ml-team
```

```json
[
  {
    "principal": "alice@example.com",
    "roles": [
      "Editor"
    ],
    "granted_at": "2026-01-20T10:00:00Z",
    "granted_by": "admin@example.com"
  },
  {
    "principal": "bob@example.com",
    "roles": [
      "Viewer"
    ],
    "granted_at": "2026-01-20T10:01:00Z",
    "granted_by": "admin@example.com"
  },
  {
    "principal": "charlie@example.com",
    "roles": [
      "Admin"
    ],
    "granted_at": "2026-01-20T10:02:00Z",
    "granted_by": "admin@example.com"
  }
]
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient

client = NemoClient.from_config()

members = client.workspaces.list_workspace_members(workspace="ml-team").data()

for member in members.data:
    print(f"{member.principal}: {member.roles}")
```

### Update Member Roles

Change a member role to adjust their permissions, for example, promoting a Viewer to Editor when they need to create resources.

#### CLI

```bash
nemo workspaces members update bob@example.com --roles Editor --workspace ml-team
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient
from nemo_helix_plugin.workspaces.types import UpdateWorkspaceMemberRequest

client = NemoClient.from_config()

# Promote a Viewer to Editor
client.workspaces.update_workspace_member(
    workspace="ml-team",
    principal_id="bob@example.com",
    body=UpdateWorkspaceMemberRequest(roles=["Editor"]),
)
```

### Remove a Member

Revoke a member's access by removing them from the workspace. This removes all their role bindings in the workspace — they will no longer be able to access any resources unless re-added.

#### CLI

```bash
nemo workspaces members delete alice@example.com --workspace ml-team
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient

client = NemoClient.from_config()

client.workspaces.delete_workspace_member(workspace="ml-team", principal_id="alice@example.com")
```

## Granting Access to All Users

Use the wildcard principal `*` to grant a role to all authenticated users. This is useful for shared workspaces where you want broad access without adding each user individually.

Common use cases:

* **Shared datasets** — Grant Viewer to `*` so everyone can use common training data
* **Team shared space** — Grant Editor to `*` for a workspace where anyone can experiment
* **Published models** — Grant Viewer to `*` for production models that everyone should access

### Make a Workspace Readable by Everyone

Grant the Viewer role to `*` so all authenticated users can view resources.

#### CLI

```bash
nemo workspaces members create --principal "*" --roles Viewer --workspace shared-models
```

```json
{
  "principal": "*",
  "roles": [
    "Viewer"
  ],
  "granted_at": "2026-01-20T10:05:00Z",
  "granted_by": "admin@example.com"
}
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient
from nemo_helix_plugin.workspaces.types import CreateWorkspaceMemberRequest

client = NemoClient.from_config()

client.workspaces.create_workspace_member(
    workspace="shared-models", body=CreateWorkspaceMemberRequest(principal="*", roles=["Viewer"])
)
```

### Make a Workspace Editable by Everyone

Grant the Editor role to `*` so all authenticated users can create and modify resources.

#### CLI

```bash
nemo workspaces members create --principal "*" --roles Editor --workspace shared-datasets
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient
from nemo_helix_plugin.workspaces.types import CreateWorkspaceMemberRequest

client = NemoClient.from_config()

client.workspaces.create_workspace_member(
    workspace="shared-datasets", body=CreateWorkspaceMemberRequest(principal="*", roles=["Editor"])
)
```

### Remove Public Access

Remove the wildcard binding to restrict the workspace to explicit members only.

#### CLI

```bash
nemo workspaces members delete "*" --workspace ml-team
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient

client = NemoClient.from_config()

client.workspaces.delete_workspace_member(workspace="ml-team", principal_id="*")
```

> **Note**
>
> **Default Workspace Access**
>
> The platform automatically grants wildcard access to built-in workspaces:
>
> * `default` workspace: All users have **Editor** access
> * `system` workspace: All users have **Viewer** access (read-only)
>
> This allows users to start working immediately without explicit role assignment.

## Admin Protection

Every workspace must have at least one Admin to prevent orphaned workspaces. The platform enforces this rule:

* You cannot remove the last Admin from a workspace
* You cannot change the last Admin's role to Viewer or Editor

If you need to leave a workspace where you are the only Admin, add another Admin first:

#### CLI

```bash
# Add another admin first
nemo workspaces members create --principal charlie@example.com --roles Admin --workspace ml-team

# Now you can remove yourself
nemo workspaces members delete alice@example.com --workspace ml-team
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient
from nemo_helix_plugin.workspaces.types import CreateWorkspaceMemberRequest

client = NemoClient.from_config()

# Add another admin first
client.workspaces.create_workspace_member(
    workspace="ml-team", body=CreateWorkspaceMemberRequest(principal="charlie@example.com", roles=["Admin"])
)

# Now you can remove yourself
client.workspaces.delete_workspace_member(workspace="ml-team", principal_id="alice@example.com")
```

## Platform Admin Access

The **HelixAdmin** role (set using `admin_email` in config) has full access to all workspaces and bypasses authorization checks. HelixAdmin is typically used for initial platform setup, creating the first workspaces and granting Admin roles to team leads. After bootstrap, day-to-day access management should use workspace-level members (above).

For details on configuring the platform admin, refer to [Auth Configuration](/nemo-helix/v0.9/documentation/access-control/deployment). For the full security implications, refer to [Security Model](/nemo-helix/v0.9/documentation/access-control/security-model).

## Deleting Workspaces

Admins can delete workspaces they manage. Deletion marks the workspace for asynchronous cleanup and returns immediately. The workspace becomes inaccessible through the API, and its role bindings are removed immediately to revoke access. The workspace cleanup controller then deletes its entities and external resources; you do not need to delete projects or dataset FileSets individually first.

> **Warning**
>
> Deleting a workspace is destructive. Ensure that any data you need to retain has been copied elsewhere before requesting deletion. A successful response confirms that cleanup was requested, not that cleanup has finished.

#### CLI

```bash
nemo workspaces delete ml-team
```

#### Python SDK

```python
from nemo_helix_plugin.client.client import NemoClient

client = NemoClient.from_config()

client.workspaces.delete_workspace(name="ml-team").data()
```