Skip to content
Open
13 changes: 7 additions & 6 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
## Commands

```bash
uv sync # setup (dependencies live in pyproject.toml)
uv pip install "hopsworks[python] @ git+https://github.com/logicalclocks/hopsworks-api.git@main#subdirectory=python" # install Python API (needed for API docs section)
touch docs/javadoc; uv run mkdocs build -s; rm docs/javadoc # build (strict)
touch docs/javadoc; uv run mkdocs serve; rm docs/javadoc # preview with live reload
npx markdownlint-cli2 "**/*.md" # lint Markdown (requires Node.js)
uv tool install md-snakeoil && snakeoil --line-length 88 --rules "E,F,B,C4,ISC,PIE,PYI,Q,RSE,RET,SIM,TC,I,W,D2,D3,D4,INP,UP,FA" docs # lint Python code blocks
uv sync --extra cli # setup: mkdocs plus the hopsworks-docs CLI in .venv
uv pip install ../hopsworks-api/python # Python API for the API docs section; CI clones hopsworks-api next to this repo
uv run hopsworks-docs check # build in strict mode (creates the docs/javadoc stub itself)
uv run hopsworks-docs serve # preview with live reload
uv run hopsworks-docs markdownlint # lint Markdown
uv run hopsworks-docs snakeoil # lint Python code blocks (ruff at line length 88)
uv run hopsworks-docs linkchecker # check for broken links
```

## Rules
Expand Down
13 changes: 7 additions & 6 deletions .claude/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ There is no application code — all work is writing Markdown under `docs/` and
## Commands

```bash
uv sync # setup (dependencies live in pyproject.toml)
uv pip install "hopsworks[python] @ git+https://github.com/logicalclocks/hopsworks-api.git@main#subdirectory=python" # needed for Python API section
touch docs/javadoc; uv run mkdocs serve; rm docs/javadoc # preview with live reload
touch docs/javadoc; uv run mkdocs build -s; rm docs/javadoc # build in strict mode
npx markdownlint-cli2 "**/*.md" # lint Markdown (requires Node.js)
uv tool install md-snakeoil && snakeoil --line-length 88 --rules "E,F,B,C4,ISC,PIE,PYI,Q,RSE,RET,SIM,TC,I,W,D2,D3,D4,INP,UP,FA" docs # lint Python code blocks
uv sync --extra cli # setup: mkdocs plus the hopsworks-docs CLI in .venv
uv pip install ../hopsworks-api/python # Python API for the API docs section; CI clones hopsworks-api next to this repo
uv run hopsworks-docs check # build in strict mode (creates the docs/javadoc stub itself)
uv run hopsworks-docs serve # preview with live reload
uv run hopsworks-docs markdownlint # lint Markdown
uv run hopsworks-docs snakeoil # lint Python code blocks (ruff at line length 88)
uv run hopsworks-docs linkchecker # check for broken links
```

`docs/javadoc` is a directory generated by CI from the `hopsworks-api` Java source.
Expand Down
74 changes: 74 additions & 0 deletions docs/user_guides/projects/api_key/api_key_scopes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# API Key Scopes

Every API key carries a set of scopes.
A scope unlocks a group of REST endpoints; a request made with a key that lacks the scope an endpoint requires is rejected before it reaches the endpoint.
Scopes are chosen when a key is created and can be changed later from the key's edit page, without regenerating the secret.
See [How To Create An API Key][how-to-create-an-api-key] for the UI walkthrough.

A scope never grants more than the account itself may do.
Endpoints still check the caller's role in the project, so a Data Scientist's key with the `FEATURESTORE` scope cannot do what a Data Owner's key with the same scope can.

## Scope reference

| Scope | Grants access to |
| --- | --- |
| `FEATURESTORE` | Feature stores and everything inside them: feature groups, feature views, training datasets, data sources and storage connectors, transformation functions, statistics, data validation, feature monitoring, tags, keywords, provenance and feature store search. Also Hopsworks actions and the tag schema catalogue; creating or deleting a tag schema additionally requires the `HOPS_ADMIN` role. |
| `PROJECT` | Project management: list, create, update and delete projects; read project information and client credentials; manage members; project alerts, receivers, routes and silences; cloud role mappings; the operation log; tutorials and product news. |
| `JOB` | Jobs and executions: create, update, schedule, start, stop and delete jobs; read execution logs; default job configurations; job alerts and tags; Python apps; expectation suites and validation reports. |
| `DATASET_VIEW` | Read access to project datasets: list datasets, browse and download files, and use global, project and dataset search. |
| `DATASET_CREATE` | Create datasets and directories, upload files, and copy, move, zip or unzip them. |
| `DATASET_DELETE` | Delete datasets, directories and files. |
| `MODELREGISTRY` | Model registries and models: register, update and delete models; model tags and provenance; Hugging Face imports; generated deployment configurations. |
| `SERVING` | Model deployments: create, start, stop and delete deployments; read deployment logs; send inference requests; deployment tags; OpenTelemetry traces and metrics. |
| `KAFKA` | The project's Kafka topics and schema registry: topics, subjects, schema versions and compatibility settings. Also accepted, as an alternative to `FEATURESTORE` or `PROJECT`, by the few read endpoints a Kafka or OnlineFS client needs, such as listing projects and feature stores. |
| `PYTHON_LIBRARIES` | Python environments: list, create and delete environments; install and uninstall pip, conda and npm packages; search package indexes; environment build commands, history and conflicts. |
| `GIT` | Git repositories in the project: clone, branches, commits, remotes, repository actions and their executions, and the account's Git provider credentials. |
| `TRINO` | The Trino query engine: submit and cancel SQL statements, read query, worker and cluster status, and manage Trino catalogs. |
| `SUPERSET` | Superset dashboards: log in to Superset, list dashboards, create permalinks, make a dashboard public or share it with another project, and delete dashboards. |
| `TERMINAL` | The web terminal: start, extend, stop and inspect terminal sessions, and mint the proxy tokens used to attach to them. |
| `MOUNTABLE_SECRET` | The project's mountable secrets: named bundles of credential files (Oracle wallets, JKS keystores, service account JSON) that a service mounts read-only. Create, list and delete bundles. Contents are never returned. Requires the Data Owner role. |
| `USER` | The account itself: profile, secrets, account environment variables, AI provider settings, and API keys. A key with this scope can create, edit and delete API keys, including keys carrying any other scope the account is allowed to hold, so treat it as equivalent to all of them. |
| `ADMIN` | Cluster administration: the admin API (configuration variables, backups, projects, users, Trino, TTL purge, coding agent configuration, cloud role mappings, search reindexing, the operation log), compute resources and the UI theme. Privileged. |
| `ADMINISTER_USERS` | User administration in the admin API: list, accept, reject, block, modify and delete users, change roles, reset passwords and sync remote groups. Privileged. |
| `ADMINISTER_USERS_REGISTER` | Only the user registration endpoint of the admin API. Privileged. |
| `AUTH` | The JWT service: issue, renew and invalidate tokens and remove signing keys. Privileged, and also available to accounts in the `AGENT` group. |

## Privileged scopes

`ADMIN`, `ADMINISTER_USERS`, `ADMINISTER_USERS_REGISTER` and `AUTH` are privileged.
Only accounts with the `HOPS_ADMIN` role can create keys carrying them, because the endpoints they unlock act on the whole cluster rather than on a project the caller is a member of.

## Scopes an account can select

The set of scopes offered when creating or editing a key depends on the account's role.

| Account role | Selectable scopes |
| --- | --- |
| `HOPS_ADMIN` | All scopes. |
| `HOPS_USER` | All unprivileged scopes. |
| `AGENT` | All unprivileged scopes plus `AUTH`. |
| `HOPS_SERVICE_USER` | All unprivileged scopes except `GIT`. |

The API key form preselects `FEATURESTORE`, `PROJECT`, `JOB`, `DATASET_VIEW`, `DATASET_CREATE`, `DATASET_DELETE`, `KAFKA`, `SERVING`, `MODELREGISTRY`, `USER` and `PYTHON_LIBRARIES`.
Deselect what the key's consumer does not need.

## Scopes of a key created by hops setup

`hops setup` creates its key through the browser token flow rather than the API key form, so the scopes are not chosen interactively.
The key carries every scope a `hops` subcommand needs: `FEATURESTORE`, `PROJECT`, `JOB`, `DATASET_VIEW`, `DATASET_CREATE`, `DATASET_DELETE`, `MODELREGISTRY`, `SERVING`, `USER`, `KAFKA`, `TERMINAL`, `PYTHON_LIBRARIES`, `GIT`, `TRINO` and `SUPERSET`.
A key created by an older release lacks the last six; edit it in the UI to add them, or run `hops setup --force` to mint a new one.

## Scope errors

A request made with a key that lacks the required scope fails with HTTP 403 and error code 320004.
The message names the scope the endpoint accepts.

```json
{
"errorCode": 320004,
"usrMsg": "No valid scope found for this invocation. Valid scope for this invocation is: [PYTHON_LIBRARIES]",
"errorMsg": "No valid scope found for this invocation"
}
```

Add the named scope to the key from the _API_ section of _Account Settings_, or create a new key that has it.
1 change: 1 addition & 0 deletions docs/user_guides/projects/api_key/create_api_key.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Keys with no expiration show _Never_ in the expiration column.
### Step 2: Create an API Key

Click `New API key`, enter a name, optionally set an expiration, select the required scopes, and click `Create API key`.
Each scope unlocks a group of REST endpoints; see [API Key Scopes][api-key-scopes] for what every scope grants.

**Expiration options:**

Expand Down
1 change: 1 addition & 0 deletions docs/user_guides/projects/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This section serves to provide guides and examples for the common usage of servi
- [Projects](project/create_project.md)
- [Authentication](auth/login.md)
- [API Keys](api_key/create_api_key.md)
- [API Key Scopes](api_key/api_key_scopes.md)
- [Jupyter](jupyter/python_notebook.md)
- [Apps](apps/index.md)
- [Jobs](jobs/pyspark_job.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/user_guides/projects/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Without any of them it is rejected with a `422`, because there is no "match ever

The response carries one bucket per class, each with its own total, for example `featuregroups` with `featuregroupsTotal` and `apps` with `appsTotal`.

### API key scopes
### API key scopes { #search-api-key-scopes }

Search results are filtered to the scopes of the API key you use, so a key cannot discover a class it was not minted for.
A `FEATURESTORE` key sees feature groups, feature views, training datasets and features, `JOB` sees jobs and apps, `MODELREGISTRY` sees models, and `SERVING` sees deployments and agents.
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ nav:
- Account-level Environment Variables: user_guides/projects/env_vars/create.md
- Api Keys:
- Create API Key: user_guides/projects/api_key/create_api_key.md
- API Key Scopes: user_guides/projects/api_key/api_key_scopes.md
- AWS IAM Roles: user_guides/projects/iam_role/iam_role_chaining.md
- Query Engine (Trino):
- Query Engine: user_guides/projects/trino/query_engine.md
Expand Down
Loading