Getting started /Authentication

Authentication

You only need an API key to talk to the HESO cloud. Signing and verification run locally and need no key at all.

Most of what HESO does happens in your own process. Gating an action against policy, signing it into a receipt, and verifying a receipt later all run locally. None of that touches a server, so none of it needs an API key. You authenticate only when you reach the cloud: mirroring receipts, pulling your org’s policy, or opening and polling approvals.

What needs the cloud, and what does not

Local, no API key: policy evaluation (gating), signing receipts, and offline verification. These are pure crypto and policy logic running in-process or in a reviewer’s browser.

Cloud, API key required: POST /v1/receipts (mirror receipts), GET /v1/policy/pull (pull policy), the /v1/approvals endpoints (open and poll approvals), and GET /v1/audit/chain.

Get an API key

Create and manage API keys in the dashboard. Each key is scoped to one org and carries scopes that limit what it can do, for example receipts:write, policy:read, and approvals:write. Copy the key when it is created. It is shown once. Store it in an environment variable, not in source.

Authenticate a request

Send the key on every cloud request. Use either header. They are equivalent:

  • x-api-key: <key>
  • Authorization: Bearer <key>

The cloud base URL is https://api.heso.ca. It is configurable per deployment, so a self-hosted org points at its own host. Here is a receipt mirrored to the cloud, with the key read from the environment:

push-receipt.shbash
curl https://api.heso.ca/v1/receipts \
  -H "x-api-key: $HESO_API_KEY" \
  -H "Content-Type: application/json" \
  -d @receipt.json

The bearer form is identical. Use whichever your HTTP client makes easier:

pull-policy.shbash
curl https://api.heso.ca/v1/policy/pull \
  -H "Authorization: Bearer $HESO_API_KEY"

The org is resolved from the key, so no team or org id appears in any path. See the Cloud API reference for the full endpoint list and request shapes.

Configure the SDK client

Both SDKs read the same key. In Python, heso.init picks it up from HESO_API_KEY along with the rest of your config. In TypeScript you call configure once at startup with the key and the endpoint.

import heso

# Reads config from env, then heso.toml, then defaults.
# The API key is read from HESO_API_KEY.
heso.init()

# gate / sign / verify run in-process. No key, no network.
@heso.tool
def lookup(member_id: str) -> dict:
    ...

The verifying and signing side of each SDK — gate, assertGate, and the receipt signing — runs in-process and never reads the API key. Only the cloud helpers (pushReceipt, pullPolicy, the approval helpers) do.

Configure before the first cloud call

In TypeScript, call configure before any cloud helper runs. In Python, init resolves config from explicit arguments first, then environment variables, then heso.toml, then defaults. Calling init again replaces the active config.

Environment variables

The Python SDK reads these when you do not pass explicit arguments to init. Only HESO_API_KEY is a cloud credential. The rest describe your local project and run.

VariableWhat it sets
HESO_API_KEYThe cloud API key. The only secret used to authenticate to the HESO cloud.
HESO_ENDPOINTCloud base URL. Defaults to https://api.heso.ca. Set it to point at a self-hosted deployment.
HESO_KEY_PASSPHRASEUnlocks the encrypted operator signing key on disk. Local only, never sent to the cloud.
HESO_PROJECT_ROOTProject root used to discover the config and the local data directory.
HESO_WORKFLOWDefault workflow label stamped onto captured actions.
HESO_ACCOUNTDefault account stamped onto captured actions.
HESO_ENVSet to production for strict key custody. Refuses weak or default key handling.
The operator signing key is not an API key

The key that signs your receipts is a local Ed25519 key in heso-local-data/, unlocked by HESO_KEY_PASSPHRASE. It never leaves your machine and is never sent to the cloud. The API key only authenticates a network request. It cannot produce a valid operator or approver signature, so the cloud can never forge a receipt. Trust comes from the signatures, not from being authenticated.

Two auth planes

HESO authenticates two separate surfaces. As a developer you use the first.

  • API keys— the programmatic plane. Your SDK and scripts use these to call the cloud.
  • Dashboard session— the console plane. The dashboard signs you in with a Supabase session JWT. It is for the web console, not for SDK use.

Do not put a dashboard JWT in your SDK config, and do not use an API key to sign into the console. They are different credentials for different jobs.

Next steps

With a key in place, push receipts and pull your policy.