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

# Auth

> Issue a PAT and trigger secret, and select only the scopes you need

The SDK carries two credentials, both server-side:

| Credential                        | What it opens                                                                  | Scope                                        |
| --------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------------- |
| **Trigger secret** (one per Flow) | `flows.run` · `signals.report` on that Flow's own traces                       | That Flow only. Not retrievable after issue. |
| **PAT** `nora_pat_…` + scopes     | Management — `resolve`, improvements, versions, simulations, memory, knowledge | Workspace                                    |

You typically need both. `flows.run` and `feedback` are authenticated by the trigger secret; everything else keys off the PAT.

## Initialise the client

```ts theme={null}
import { createClient } from "@conscience-technology/nora-sdk";

const nora = createClient({
  tenant: "t_...",
  token: process.env.NORA_PAT,                    // management calls
  triggerSecret: process.env.NORA_TRIGGER_SECRET, // execution calls
});
```

Full `ClientOptions` reference (base URL, retries, logging, custom fetch, custom trigger header) lives on the next page: [Client options](/sdk/client-options).

## Where credentials come from

### Trigger secret

Minted on the Flow's trigger block. Generate it in the app (**Trigger → Generate secret**) or via CLI:

```bash theme={null}
nora triggers secret rotate <trigger-id>
```

The plaintext is printed to stdout **once** — copy it into your secret manager immediately. There is no "print again" path; if you lose it, rotate again.

Each Flow has its own secret. A leaked secret compromises only that one Flow.

### Personal access token (PAT)

Mint under **Settings → Personal Access Tokens** in the app. When you create it, select the exact scopes you need — the token is granted the union of what you tick.

The token is shown once; store it in your secret manager and reference via env var:

```bash theme={null}
export NORA_PAT="nora_pat_…"
export NORA_TRIGGER_SECRET="…"
```

## PAT scopes (enforced)

Scopes are strictly enforced server-side. A `read` token can't approve; a `simulate` token can't write memory.

| Scope      | Opens                                                                                                                                                      |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `read`     | [`resolve`](/sdk/transparency) · trace lookups · [`improvements.list`](/sdk/improvements) / `get` (may surface prompts and end-user data — treat as admin) |
| `content`  | [`memory`](/sdk/resources) / [`knowledge`](/sdk/resources) writes (scoped resources require `onBehalfOf`)                                                  |
| `simulate` | [`simulations.*`](/sdk/simulations) — **paid**, billed against your workspace LLM keys                                                                     |
| `approve`  | [`improvements.approve`](/sdk/improvements) · `revert` · [`versions.rollback`](/sdk/improvements#versions) — production changes                            |

`approve` and `simulate` are separate from `read` so a leaked read token can't ship changes or spend money.

## Least-privilege recipes

**Read-only integration** (dashboards, "why did this answer" panels):

```bash theme={null}
scopes: read
```

**Improvement-queue embed** (surface fixes to your admins):

```bash theme={null}
scopes: read, approve
```

**Full loop, including on-demand simulation**:

```bash theme={null}
scopes: read, approve, simulate
```

**Content writes** (uploads, memory writes from app code):

```bash theme={null}
scopes: content
```

Mint separate tokens per role rather than one broad token. Rotating a compromised token then costs one path, not everything.

## Environment overrides

Standard env vars the SDK reads with no code change:

* `NORA_PAT` — read into `token` if you leave it off the `createClient` call.
* `NORA_TRIGGER_SECRET` — same for `triggerSecret`.
* `NORA_BASE_URL` — overrides `baseUrl` (default: `https://platform.nora.my/api/v1`).
* `NORA_TENANT` — overrides `tenant` if you leave it off.

Local `.env` files aren't loaded automatically — use `dotenv` or your framework's env loader.

## Next

* [Client options](/sdk/client-options) — the full options surface (timeouts, retries, logger, custom fetch, trigger header override).
* [Execution](/sdk/execution) — start calling Flows.
* [Errors](/sdk/errors) — how auth failures surface and what to catch.
