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

# Authentication

> Authenticate to Sakshi with a Bearer token: an ingest API key for register and witness, or an OIDC JWT for governance and admin actions.

Every request to Sakshi carries a Bearer token in the `Authorization` header.
There are two kinds of token, and which one you need depends on what you are
doing:

* An **ingest API key** for the write path an agent uses at runtime: register
  itself and witness its decisions.
* An **OIDC JWT** from your identity provider for governance and admin actions:
  activating an agent, publishing an autonomy envelope, minting keys, editing
  access mappings.

Sakshi is single-tenant and runs in your environment, so the base URL in every
example is your own deployment. The public demo at `https://demo.rotavision.com`
is read-only and exposes a single `auditor` persona.

<Tip>
  **Evaluating Sakshi and don't have an instance yet?** [Request a sandbox](https://rotavision.com/sandbox)
  for a private, synthetic-data Sakshi you can sign into, mint an ingest key in,
  and point the SDK at. It is writable, unlike the read-only demo, so you can
  register an agent and witness real decisions. No install required.
</Tip>

## The Authorization header

Send the token as a Bearer credential on every call:

```
Authorization: Bearer <token>
```

Sakshi routes the token by shape: a value with dots is treated as a JWT and
verified against your IdP; anything else is looked up as an ingest key by its
SHA-256 hash. You do not choose a header or a scheme per token type. Send the
one you hold.

## Ingest API keys

Ingest keys are the credential your agents carry in production. They are
**ingest-scoped**: they can register an agent and witness decisions, and nothing
more. An ingest key cannot activate an agent, publish an envelope, or mint
another key. Attempting a governance action with an ingest key returns `403`.

### Minting a key

Keys are minted in the console under **Admin → API keys**. Minting is an admin
action, so it requires an OIDC session, not another key.

<Steps>
  <Step title="Open the console as an admin">
    Sign in through SSO and open **Admin → API keys**.
  </Step>

  <Step title="Mint a key scoped to an org unit">
    Give the key a name and the org unit it may write for. Scope is enforced at
    agent creation, capture, and evaluation, so a key can only ever act within
    its unit.
  </Step>

  <Step title="Copy the raw key once">
    The raw key is shown **exactly once**, at mint time. Sakshi stores only its
    SHA-256 hash, so it cannot show the value again. Copy it into your secrets
    manager now.
  </Step>
</Steps>

<Warning>
  The raw key is displayed once and never again. If you lose it, revoke it and
  mint a new one. Never commit a key to source control, paste it into logs, or
  ship it in client-side code.
</Warning>

### Using a key with the SDK

Pass the key to the client. The base URL is your deployment.

<CodeGroup>
  ```python Python theme={null}
  from sakshi import SakshiClient

  client = SakshiClient(
      base_url="https://sakshi.your-company.internal",
      api_key="sks_...",
  )

  agent_id = client.register(
      "loan-decision-agent",
      owner_name="Priya Sharma",
      owner_email="priya@your-company.com",
  )
  ```

  ```bash cURL theme={null}
  curl https://sakshi.your-company.internal/api/v1/chain/verify \
    -H "Authorization: Bearer sks_..."
  ```
</CodeGroup>

<Tip>
  Read the key from the environment rather than hard-coding it. In CI or a
  secrets manager, expose it as `SAKSHI_API_KEY` and pass
  `api_key=os.environ["SAKSHI_API_KEY"]`.
</Tip>

### Rotating and revoking

Rotate on your own schedule, and immediately if a key may have leaked:

<Steps>
  <Step title="Mint a replacement">
    Create a new key with the same org-unit scope.
  </Step>

  <Step title="Roll it out">
    Update your secrets manager and restart the agents that read the key.
    `register` is idempotent by name, so restarts do not create duplicate
    agents.
  </Step>

  <Step title="Revoke the old key">
    Revoke it in the console. Revocation takes effect on the next request, so
    verify the new key is live before you revoke.
  </Step>
</Steps>

## OIDC JWTs for governance

Registering and witnessing is deliberately the only thing an ingest key can do.
The decisions that shape governance, who owns an agent, what its autonomy
envelope permits, who may approve a parked action, are gated behind a person
authenticated by your identity provider.

For those actions, obtain a JWT from your IdP through the console SSO flow and
send it as the Bearer token. The token carries the caller's identity, roles, and
team claims, which Sakshi resolves into a Sakshi role and org unit through the
access mapping (see the `access` and `me` endpoints in the
[API reference](/api-reference/introduction)). Governance and admin endpoints
require a valid JWT; an ingest key on the same route returns `403`.

Actions that need a JWT include:

* Activating, suspending, or transferring ownership of an agent
* Publishing or linting an autonomy envelope, setting a response policy, arming
  circuit breakers
* Activating or releasing the kill switch, attesting a drill
* Claiming and resolving review-queue items
* Minting or revoking ingest keys and webhooks
* Editing the access mapping under Admin

## The public demo

The hosted demo at `https://demo.rotavision.com` is read-only and synthetic. It
exposes a single `auditor` persona, which can read the registry, recompute the
chain, and pull evidence, but cannot write. Use it to explore the API surface
and the evidence model. Point the SDK at your own deployment when you are ready
to write records.

## What to read next

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Install the SDK, register an agent, and witness a decision with a key.
  </Card>

  <Card title="Errors" icon="triangle-exclamation" href="/errors">
    The exception model, fail-open capture versus fail-closed enforcement, and
    the HTTP status codes.
  </Card>

  <Card title="Python SDK" icon="code" href="/sdk/python">
    Every client method, the witness session, and the exception types.
  </Card>

  <Card title="API reference" icon="terminal" href="/api-reference/introduction">
    Every endpoint, generated from the live OpenAPI spec.
  </Card>
</CardGroup>
