# Authentication

Bearer sk_live\_ tokens, how to mint them, and how to keep them safe.

Every call to `api.salfio.com/v1` must carry a Bearer token.

    GET /v1/health HTTP/1.1
    Host: api.salfio.com
    Authorization: Bearer sk_live_<your-token>

Missing, malformed, revoked, or expired tokens yield `401 Unauthorized` with the standard [error envelope](/docs/api/conventions#errors). No rate-limit counters are exposed on `401` responses.

## Key types

Salfio issues two parallel kinds of keys:

| Type | Scope | Who sees what |
|----|----|----|
| **User key** | Inherits the creator's permissions | Same as the human in the app |
| **Service key** | Full organization scope | All org data, independent of any user |

Both are minted from the dashboard. Programmatic key management is explicitly out of scope — the API does not let you create or revoke keys over HTTP.

## Mint a key

1.  In the app, open **Settings → API Keys**.
2.  Click **Create key**. Pick:
    - **Name** — a human-friendly label (`"ingest-worker"`, `"partner-xyz"`).
    - **Type** — User or Service (see table above).
3.  Save. The full `sk_live_…` token is displayed **once**, immediately.
4.  Copy it to your secret manager of choice. Salfio does not keep the plain-text token — it is stored as a hash. You cannot retrieve it again.

## Rotate and revoke

- **Rotate:** mint a new key, ship it to your consumers, revoke the old one. There is no in-place rotation; this is intentional.
- **Revoke:** in **Settings → API Keys**, click **Revoke**. The key stops working within the auth cache TTL (≤10 seconds) — the app-side LRU cache invalidates the revoked entry on the next authentication attempt.

Every Service Key creation emits an audit log entry and an email to every organization admin. Treat Service Keys as you would any production secret.

## Security notes

- Keys are ~190 bits of entropy (`sk_live_` + 32 random bytes base62).
- Tokens are hashed at rest (argon2id); server-side compromise does not leak the plain-text.
- Organization limits: **10 User keys per user**, **5 Service keys per organization**. Exceeding returns `409 Conflict`.

### The "try it" panel on these docs

The interactive request panel on reference pages runs in your browser and sends your pasted token over the public internet. **Use a test/revocable key for the in-browser panel. Never paste production keys.** Revoke any key you test with in the dashboard when you're done.

## Related pages

- [Administrator Tools](./administrator-tools.md)
- [Agent Tools](./mcp-external-servers.md)
- [Assign a Slack channel to a client over the API](./guides-assign-slack-channel.md)
- [Authenticated health check](./api-reference-gethealth.md)
- [Cards](./cards.md)
- [Changelog](./changelog.md)
- [Changelog](../changelog.md)
- [Connect a workspace](./getting-started-connect-workspace.md)
- [Connect an integration](./getting-started-connect-integration.md)
- [Connect from Claude Desktop](./mcp-connect-claude-desktop.md)

# Agent Instructions

This portal answers questions programmatically. To receive a synthesized,
source-cited answer instead of crawling page by page, append the `?ask=`
query parameter to any page URL on this site:

    /guides/quickstart?ask=how+do+I+authenticate

Optional parameters:

- `&goal=<what-you-are-trying-to-do>` steers the answer toward your
  objective (e.g. `&goal=write+a+python+client`).
- `&version=<label>` scopes the answer to a mounted version when the
  portal publishes more than one.

The response is `text/markdown`: the answer followed by a `# Sources` list
of the portal pages it was grounded in. Status codes are the contract:

- `200` — the answer; `402` — the portal owner’s plan or answer credits are
  exhausted (surface this to your operator; do NOT retry); `429` — you are
  rate-limited; back off for the `Retry-After` seconds; `503` — the answer
  lane is temporarily unavailable; fall back to crawling the `.md` pages.

For the full corpus map read `llms.txt` at the site root; for the tool
surface (search + page fetch as MCP tools) see `/mcp`.
