> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blindsight.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Team & access

> Invite teammates, assign roles, define custom permissions, and mint API keys for programmatic access.

Access in Blindsight has three layers that combine: **workspace roles**,
**per‑project membership**, and **API keys** for programmatic
access. This page covers all three.

## Roles

### Built‑in workspace roles

| Role         | What they can do                                                          |
| ------------ | ------------------------------------------------------------------------- |
| **Owner**    | Full control, including billing and license. There is always exactly one. |
| **Admin**    | Manage users, settings, integrations. Cannot transfer ownership.          |
| **Member**   | Create projects, datasets, scans. Cannot manage settings or users.        |
| **Reviewer** | Read and triage findings. Cannot delete or change settings.               |
| **Viewer**   | Read‑only.                                                                |

### Custom roles

Admins can define custom roles from a granular permission catalog. A
custom role is just a named bundle of permissions.

| Permission                   | Lets the user                                 |
| ---------------------------- | --------------------------------------------- |
| `scans.create`               | Launch new scans.                             |
| `datasets.delete`            | Delete datasets.                              |
| `compliance.generate_report` | Run compliance report generation.             |
| `playground.access`          | Open the Data Playground.                     |
| `custom_rules.manage`        | Create and edit detection rules.              |
| `support.manage`             | Triage support submissions.                   |
| `runtime_security.scan`      | Call the Runtime Security scan endpoints.     |
| `runtime_security.manage`    | Edit Runtime Security configuration and Apps. |

### Per‑project access

In addition to the workspace role, projects can have their own member
lists. A workspace `Member` can be a project `Admin` inside one
specific project. Workspace roles are the floor; project roles are
the ceiling.

<Tip>
  Use this pattern to give a contractor `Viewer` access at the workspace level
  and `Reviewer` access inside one project, without exposing them to the rest of
  your data.
</Tip>

## Invitations

<Steps>
  <Step title="Invite a user">
    From **Settings → Users → Invite**, enter the email and pick a role.
  </Step>

  <Step title="They accept">
    The invitee gets an email with a one‑click acceptance link, sets a password,
    picks a display name, and lands in the workspace with the role you assigned.
  </Step>

  <Step title="Manage pending invites">
    Pending invitations show on the Users page. **Resend** or **Revoke** at any
    time. Invitations expire after a configurable window (set under **Settings →
    Security**).
  </Step>
</Steps>

## Reviewers

Reviewers are a specialised subset used by the triage workflows. They
can be:

* Mentioned in result comments (`@reviewer-name`).
* Assigned specific findings for review.
* Listed as approvers on a healing run (where required by policy).

You don't have to use Reviewers, workspace Admins and Members can do
the same things, but they're a useful designation when triage is
someone's main job.

## User profile (`/profile`)

Every user has their own profile page with:

* Display name and avatar.
* Email and password reset.
* Notification preferences (per event type, per channel).
* Active sessions and a "sign out everywhere" button.

## API keys

Everything in the UI is also available via the REST API. To use it
programmatically, mint a key.

### Creating a key

<Steps>
  <Step title="Open Settings → API Keys">
    Click **New key**.
  </Step>

  <Step title="Name and scope">
    Give it a descriptive name (`CI pipeline`, `Lab upload script`).
    Pick scopes:

    * **Read‑only**, can list and read but not mutate.
    * **Upload dataset**, can ingest data.
    * **Full**, mirrors your workspace permissions.

    Or compose a custom scope from the permission catalog.
  </Step>

  <Step title="Set an expiration">
    Never, 30 days, 90 days, 1 year. Short‑lived keys are safer; mint
    a new one when this one expires.
  </Step>

  <Step title="Copy the token">
    **Now.** The token is displayed exactly once. If you miss it,
    revoke and mint a new one.
  </Step>
</Steps>

### Using the key

Pass it as `Authorization: Bearer <token>` on every API call.

```bash theme={null}
curl -H "Authorization: Bearer $BLINDSIGHT_TOKEN" \
     $API_BASE/api/datasets
```

You can do everything via the API:

* Upload datasets (`POST /api/uploads/*`).
* Launch scans (`POST /api/datasets/{id}/scan`).
* Poll progress (`GET /api/scans/{id}`).
* Stream live progress (`WS /ws/api/scans/{id}`).
* Trigger healing (`POST /api/datasets/{id}/cure`).
* Generate compliance reports (`POST /api/compliance/reports/*`).
* Manage Playground sessions, custom rules, schedules, projects,
  webhooks.

See the [API reference](/api-reference/introduction) for the full
schema.

### Revoking a key

From **Settings → API Keys**, click **Revoke** on any row. Revocation
is instant and audit‑logged. Subsequent calls using the revoked key
return `401`.

### Rotation best practices

<AccordionGroup>
  <Accordion title="CI / CD pipelines">
    Mint one key per pipeline. Rotate every 90 days. Store the new
    value in your CI's secret manager, run jobs against both old and
    new for one rotation window, then revoke the old one.
  </Accordion>

  <Accordion title="Long‑running services">
    Mint with **Never** expiry and rotate manually on a cadence. Tag the key with
    the service name so it's obvious in the audit trail.
  </Accordion>

  <Accordion title="Ad‑hoc scripts">
    Mint a short‑lived key (30 days), use it, revoke when done.
    Treat ad‑hoc keys like one‑use tokens.
  </Accordion>
</AccordionGroup>
