# Organizations and keys

An organization owns folders, experiments and API keys, and every request to
Metrics acts in exactly one organization. People join as members with a role, by
invitation; jobs and agents act through organization API keys (`ak_...`); a run
writes its data with a short-lived experiment token (`ik_...`). Manage all of it
in the app's settings or with the [command line](https://metrics.041.io/docs/cli.md) after a browser
sign-in.

## Organizations

Anyone signed in can create an organization and becomes its admin. A person can
belong to several and switches between them; the data of one is never visible
from another. Folders, experiments and keys cannot move between organizations.

In the app, the organization switcher changes the active organization, and it
and the account menu lead to three settings pages:

| page         | path                         | what it holds                                              |
| ------------ | ---------------------------- | ---------------------------------------------------------- |
| Organization | `/app/settings/organization` | the organization's profile, members, roles and invitations |
| Account      | `/app/settings/account`      | your profile, email addresses and sign-in security         |
| API keys     | `/app/settings/api-keys`     | create and revoke API keys of the active organization      |

From the command line:

```bash
syvain-metrics org list          # your organizations; current marks the active one
syvain-metrics org switch my-lab # id, slug or name
syvain-metrics org create "My Lab"
```

## Members and roles

Two roles exist by default: `admin` (`org:admin`) and `member` (`org:member`).
Four permissions gate the management routes:

| permission                   | allows                                                   |
| ---------------------------- | -------------------------------------------------------- |
| `org:sys_memberships:read`   | list members and pending invitations                     |
| `org:sys_memberships:manage` | change roles, remove members, invite, revoke invitations |
| `org:sys_api_keys:read`      | list API keys                                            |
| `org:sys_api_keys:manage`    | create and revoke API keys                               |

Admins hold all four. Changing members, invitations and keys therefore needs the
admin role. Reading and writing experiment data needs only membership.

```bash
syvain-metrics member list
syvain-metrics member role ada@example.com admin
syvain-metrics member remove ada@example.com
```

## Invitations

An invitation emails a link. Following it signs the person in, or creates their
account, and joins them to the organization with the invited role.

```bash
syvain-metrics invitation create ada@example.com --role member
syvain-metrics invitation list                 # pending only
syvain-metrics invitation revoke orginv_...
```

## Credentials

| credential           | looks like                    | acts as                                  | where it comes from                                | lifetime                             |
| -------------------- | ----------------------------- | ---------------------------------------- | -------------------------------------------------- | ------------------------------------ |
| organization API key | `ak_...`                      | the organization                         | API keys page, `syvain-metrics api-key create`     | until revoked or its optional expiry |
| personal CLI key     | `ak_...`                      | the organization, while you are a member | minted by `syvain-metrics auth login` in a browser | until `auth logout` or revocation    |
| browser sign-in      | OAuth tokens in the CLI login | you, in the organization you picked      | `syvain-metrics auth login --device`               | refreshed by the CLI                 |
| experiment token     | `ik_...`                      | one experiment, for writes               | `syvain.v2.experiment.open`                        | 24 hours, refreshable                |
| app session          | cookie                        | you, in the active organization          | signing in to the app                              | the session                          |

## API keys

An organization API key is what a training job, CI or an agent uses:
`SYVAIN_METRICS_API_KEY` for the [collector](https://metrics.041.io/docs/collector.md), the
[Python API client](https://metrics.041.io/docs/python-client.md), [DuckDB](https://metrics.041.io/docs/duckdb.md) and the
[command line](https://metrics.041.io/docs/cli.md), and `Authorization: Bearer ak_...` for the
[HTTP API](https://metrics.041.io/docs/api.md). It reads and writes everything in its organization and
belongs to no person, so it keeps working when its creator leaves.

```bash
syvain-metrics api-key create ci --description "GitHub Actions" --expires-in-days 90
syvain-metrics api-key list
syvain-metrics api-key revoke ak_...
```

The secret is shown once, at creation. Servers remember a verified key for up to
60 seconds, so a revoked key can still be accepted for up to a minute. A key
cannot manage members, invitations or other keys.

## Personal CLI keys

DuckDB and the Python API client read only an API key from the CLI login. So a
browser sign-in also mints an organization API key for you on this machine,
named `syvain-metrics CLI: <your email> on <hostname>`, and saves it in the
login. Any member may mint one. It acts as the organization, like any key, but
the API accepts it only while you are still a member. `org switch` and
`org create` replace it with a key of the new organization, and `auth logout`
revokes it with the key itself, so logout works without a live sign-in. It
appears in `api-key list` and on the API keys page like any other key; an admin
can revoke it there.

## Experiment tokens

`syvain.v2.experiment.open`, sent with an organization key, returns the
experiment's id and an experiment token. The token authorizes only
`/api/v2/experiments/{experimentId}/events` of that experiment: lifecycle,
metrics, annotations and its own revocation. It expires after 24 hours.
`syvain.v2.experiment.tokenRefresh`, sent with the organization key and the
current unexpired token, issues a new one; the old one keeps working for at most
30 seconds. `syvain.v2.experiment.tokenRevoke` ends it. Each open issues another
token without revoking earlier ones. The collector and the Python client's write
session do all of this for you; see the [HTTP API](https://metrics.041.io/docs/api.md#recording-a-run) to do
it by hand.

Per-experiment ingestion keys created through the older
`/api/v1/experiments/{experimentId}/ingestion-keys` route are the same kind of
credential and still work on the experiment endpoint. New code opens the
experiment instead.

## Management over HTTP

The CLI's management commands call these routes. They accept only a browser
sign-in's bearer token, with the organization in the `syvain-org-id` header; an
API key or an app session cannot manage an organization.

| method and path                                          | does                                                      |
| -------------------------------------------------------- | --------------------------------------------------------- |
| `GET`, `POST /api/v2/user/organizations`                 | list your organizations; create one                       |
| `GET /api/v2/organization/members`                       | list members                                              |
| `PATCH`, `DELETE /api/v2/organization/members/{userId}`  | change a role; remove a member                            |
| `GET`, `POST /api/v2/organization/invitations`           | list pending invitations; invite                          |
| `DELETE /api/v2/organization/invitations/{invitationId}` | revoke an invitation                                      |
| `GET`, `POST /api/v2/organization/api-keys`              | list keys; create one                                     |
| `DELETE /api/v2/organization/api-keys/{apiKeyId}`        | revoke a key                                              |
| `POST /api/v2/user/cli-api-keys`                         | mint a personal CLI key                                   |
| `DELETE /api/v2/auth/cli-api-key`                        | revoke the personal CLI key sent as the bearer credential |

Related: [command line](https://metrics.041.io/docs/cli.md), [concepts](https://metrics.041.io/docs/concepts.md),
[limits and fair use](https://metrics.041.io/docs/limits.md), [HTTP API](https://metrics.041.io/docs/api.md).

---

Metrics by 041 documentation. Every page: https://metrics.041.io/llms.txt
