Skip to content

API and authentication

Use a personal API key for a script, Python SDK integration, or CI job. Use browser sign-in for account administration, and use Connected apps for a chat app that supports HLA-Compass OAuth. These credentials have different permissions; an API key is not your browser session.

Choose the environment

Create the key in the same environment where the integration will run.

Environment Web application API base URL CLI environment
Development https://hub.dev.alithea.bio https://api.dev.alithea.bio dev
Staging https://hub.staging.alithea.bio https://api.staging.alithea.bio staging
Production https://hub.alithea.bio https://api.alithea.bio prod

The examples below use dev. Change the API hostname and SDK/CLI environment together when using another environment. Changing an environment or organization setting does not move an existing key.

These instructions describe the repository's API contract. They do not prove that an unreleased change is deployed. Read GET /version (also available as GET /v1/system/version) and the target environment's GET /v1/openapi.json before relying on a new operation. Release metadata includes the API contract version, Git commit, and commit build date; unknown means that metadata was not packaged. Use an SDK version compatible with the deployed contract.

Create a personal key

  1. Sign in to the web application and select the organization the integration should use. Open your profile, then API keys → Create API Key.
  2. Give the key a name that identifies one integration, such as “Daily analysis”. Choose an expiration. The form defaults to 90 days and offers 30, 90, 180, or 365 days. Keys cannot be extended or recovered after creation.
  3. Start with Read. Add Write or Delete only if the integration needs those actions, then select the corresponding product-area scopes. A typical module integration needs read and write, with modules:write, so it can start a run and retrieve its status/results.
  4. For module publishing from CI, select Module publishing instead. This requires the developer role or above and creates a publish-only key; it cannot also read scientific data, run modules, or call MCP tools.
  5. Click Create API Key. Copy the secret once and save it in a password manager or deployment secret store before closing the dialog. The key list shows only a masked prefix; it cannot reveal the secret again.

The limit is 10 active, unexpired personal keys per user in each organization. If the limit is reached, revoke an unused key. If creation is refused because your role cannot grant a scope, remove that scope or ask an organization administrator about the access you need. Creating or revoking a key from a privileged account can require MFA; complete the supported sign-in/challenge flow when prompted. The API key itself does not perform MFA.

For bearer-authenticated automation of key management, the contract is POST /v1/api-keys, GET /v1/api-keys, and DELETE /v1/api-keys/{id}. Creation accepts name, expires_in_days (1–365), permissions, and scopes. Specify the expiry explicitly: the raw API default is 365 days, unlike the profile form. An API key cannot create or revoke other keys.

Store the key and check it

Install the SDK and CLI using the getting started guide. For a local Bash or Zsh terminal, these commands accept the key without putting its literal value into shell history:

unset HLA_COMPASS_API_KEY
read -r -s HLA_API_KEY
export HLA_API_KEY

After the read command, paste the key and press Enter; input is hidden. For CI, set HLA_API_KEY from your CI secret store instead. Do not paste a key into a chat, notebook, repository, command example, or log. Environment variables provide the credential to a process; they are not a persistent secret store.

The SDK accepts both HLA_COMPASS_API_KEY and HLA_API_KEY. HLA_API_KEY wins if both are set, and either variable takes precedence over a saved browser login. Use one variable deliberately to avoid testing the wrong credential.

Check the key through HTTP:

curl --fail-with-body --silent --show-error \
  --header "X-API-Key: $HLA_API_KEY" \
  "https://api.dev.alithea.bio/v1/api/auth/me"

Or through the CLI:

hla-compass auth status --check --env dev

Or from Python in the same environment:

from hla_compass import APIClient

client = APIClient(environment="dev")
identity = client.whoami()
print(identity)

HTTP and Python return the credential identity: its key ID, organization, credential type, permissions, and scopes. Check the returned organization and grants before using the integration. The CLI check confirms authentication and prints the credential type; use HTTP or Python to inspect the server's grants. The identity endpoint also works for publish-only keys.

A successful check proves authentication, not permission to run a particular module or access a particular dataset. Plain hla-compass auth status shows local configuration; use --check to make a request and get a failing exit status when authentication does not work.

Direct HTTP requests using a key must use an operation with an API-key route, commonly /v1/api/..., and the X-API-Key header. Do not add /api to an arbitrary path: some operations are available only to bearer sessions. The SDK selects the supported credential plane and reports a session-only operation when there is no key route. Consult the SDK guide and the target environment's OpenAPI document for the operation you need.

What permissions and scopes mean

read, write, and delete are independent: write does not include read or delete. publish is a separate publish-only permission. New keys use scope policy version 1; every write/delete action also requires its exact scope.

Intended operation Key grant Additional boundary
Discover governed data and retrieve permitted results read Current resource access policies still apply.
Start a module run and then read its results read, write; modules:write The module and inputs must be accessible; compute/cost admission still applies.
Start a pipeline run and read its status (via MCP) read, write; pipelines:write Pipeline, inputs, and compute must be permitted.
Cancel a pipeline run (via MCP) delete; pipelines:delete The run's authorization rules still apply.
Publish a module from CI publish alone Developer role and the publishing endpoint are required.

The pipeline rows refer to MCP tools: run_pipeline needs write with pipelines:write, status/log tools need read without a pipelines:read scope, and cancel_pipeline_run needs delete with pipelines:delete. Starting or cancelling also requires the tool's confirmation. Native pipeline HTTP routes (/v1/pipelines/... and /v1/pipeline-runs/...) and their SDK/CLI operations require an interactive bearer session; do not substitute /v1/api paths.

A scope is a product area, not a grant to one named catalog or module. Selecting modules:write does not authorize pipelines or storage changes. Wildcards such as *, *:write, and modules:* are not supported. Read-only and publish-only keys do not need mutation scopes.

The caller can create only scopes their role permits. During use, the platform rechecks the owner's active membership and current role, and caps a machine credential at the developer role. Even an administrator's key cannot manage users, organizations, credentials, or the platform administrator control plane. A listed scope does not bypass a route's role requirement or make a bearer-only operation available. Use your interactive account for catalog administration and other administrator operations.

Replace legacy keys. Keys without scopePolicyVersion do not have the new scope contract. REST write/delete requests require exact scopes. MCP still accepts the legacy empty-scope policy for otherwise permitted actions. Do not interpret an empty legacy scope list as a restriction to read-only access: create a replacement with exact scopes and revoke the old key.

Rotate, revoke, and recover

There is no renewal or secret-recovery operation. To rotate a key without interrupting an integration:

  1. Create a replacement with the permissions and expiry you need.
  2. Update the integration's secret store and restart/reload it if required.
  3. Check the replacement and verify the intended operation.
  4. In Profile → API keys, revoke the old key and confirm that it is rejected.

If a key is exposed, revoke it immediately and replace it. Revocation is irreversible. After successful revocation, an already cached API authorization may remain valid for up to 60 seconds. Wait for that window, then verify that an authenticated request is rejected. Uncached lookups use a consistent read.

A previously issued storage signed URL has its own expiry; revoking the API key does not retract that URL. Multipart part URLs expire after 15 minutes; retained run-file and report download URLs expire after five minutes. Other operations return their own expiresIn value. Cancellation stops new part signing and completion while the server verifies cleanup; it is not retroactive URL revocation. Revoking a key does not erase downloaded data or undo completed runs.

hla-compass auth logout removes stored interactive credentials; it does not revoke an API key or remove a variable from the parent shell. After local key use, remove shell variables when no longer needed:

unset HLA_COMPASS_API_KEY HLA_API_KEY

Browser and CLI sessions

For interactive CLI work, first unset API-key variables so they do not shadow your login, then use:

unset HLA_COMPASS_API_KEY HLA_API_KEY
hla-compass auth login --env dev
hla-compass auth status --check --env dev

Finish sign-in and MFA in the browser when prompted. The CLI exchanges a short-lived, single-use authorization code using PKCE and a local loopback callback. No bearer or refresh token is placed in that callback URL. Use the released CLI instead of reproducing the flow in a script. Stored sessions can refresh while their refresh credentials remain valid; if refresh fails or a privileged operation needs MFA, sign in again. A browser session does not extend an API key's expiry.

For chat apps, follow MCP and connected apps. Approve the organization and access in the HLA-Compass consent flow; do not paste an API key into the conversation. Provider API keys in Profile → LLM keys pay for model access inside HLA-Compass; they are different credentials from personal HLA-Compass API keys and connected-app authorization.

Organization selection

API keys stay in their issuing organization and cannot switch organizations. For an ordinary bearer session, X-Organization-Id: <uuid> selects an active, unsuspended membership; that membership's role applies to the request. The X-HLA-Org-Context alias takes precedence if both headers are set. Authorized platform administrators have a separate organization-selection capability; a connected chat app remains limited to its consented organization.

The CLI command hla-compass auth use-org <organization-uuid> --env dev records a default selection. It does not grant membership or change an API key's organization. The server must authorize the organization on each request.

Diagnose an authentication failure

Check the HTTP status and any typed error.code; do not depend on message text. Gateway rejections can have only a message and no application error object.

Response What to check
401 Missing/invalid/expired bearer token or another authentication rejection. Sign in again if needed.
403 without a typed code An API key may be invalid, expired, revoked, or used on the wrong environment/route. Check the identity endpoint and effective credential.
403 FORBIDDEN Check the required permission, exact scope, current role, membership, and resource access.
403 MACHINE_CREDENTIAL_NOT_PERMITTED Use an interactive session; an API key cannot perform this operation.
403 MFA_REQUIRED Complete supported browser/MFA authentication for the privileged action.
400 during key creation Check expiry, permission/scope combinations, and the active-key limit.
409 Check state/version, replay, or lifecycle conflict details.
429 Respect the rate/quota response and retry guidance.
503 A dependency or rollout gate may be unavailable; retain the request ID for support.

For support, include the environment, operation, status, error code, and request ID. Remove credential values and signed URLs. Do not blindly retry a mutation: an idempotency header makes a retry safe only where the specific operation documents a persisted replay contract.

Recover a password

On the sign-in page, choose Forgot your password?, enter your email, and request a recovery code. Enter the code and your new password to complete recovery. If you already received a code, choose I already have a reset code.

Organization administrators can request a code from Org admin → People → Send password reset code. Confirm the recipient before sending. The user completes the reset; requesting a code does not change their password or MFA.

Request an account

If you have no invitation, submit an access request for administrator review. This does not create an account or organization membership:

from hla_compass.auth import Auth

request = Auth().request_access(
    "scientist@example.org",
    "Ada",
    "Lovelace",
    "Example Bio",
    environment="dev",
    position="Scientist",
    field_of_interest="TCR",
)
print(request["message"])