# auth.md

Sveda is a self-hosted embeddable agent. **https://sveda.dev is the product site and documentation.** It does not create operator accounts. Optional Sveda Cloud cells are provisioned privately and are not this origin. A docs copilot widget on this origin mints short-lived embed tokens only for that widget; it is not a public credential API.

## Audience

Host backends, install agents (Cursor, Claude Code, and similar), and operators running `sveda-server` beside their app.

## Provisioning

Credentials live on the operator's runtime, default bind `0.0.0.0:8787`. Enable minting with `SVEDA_EMBED_ENABLED=true`.

1. Set `SVEDA_EMBED_HOST_API_KEY` on the runtime.
2. From the host server, `POST /sveda/embed/token` with that host key.
3. Return `{ origin, token, expires_in }` to the browser. The browser never holds the host key.

Registration URI (documentation, not an account-create POST): https://sveda.dev/docs/embed

## Methods

| Method | Where | How |
| --- | --- | --- |
| Host API key | Operator runtime | Header `x-sveda-host-key` (or Bearer) on `POST /sveda/embed/token` |
| Embed token | Browser / JS client | Header `x-sveda-embed-token` or `Authorization: Bearer sveda_embed_…` on stream and JSON turns |
| Admin key | Operator runtime | Header `x-sveda-admin-key` for admin settings |

Tokens are HMAC, prefixed `sveda_embed_`, scoped to `visitor_id`. Default TTL is 3600 seconds.

## Credential use

```
POST {runtime}/sveda/embed/token
Content-Type: application/json
x-sveda-host-key: $SVEDA_EMBED_HOST_API_KEY

{"visitor_id":"visitor-123","policy":"reader"}
```

Sveda does not store application users or roles. Three layers: role (host app), policy (named document in `sveda.yaml`), capability (enforced every chat turn from the token's policy plus optional `grants`). Body fields: `visitor_id`, `host_mcp_url`, `host_mcp_token`, optional `policy` (string name), optional `grants` (object that can only tighten the named policy). Unknown policy name → 422. Tokens without policy/grants keep unrestricted behavior. When a policy is set, omitted web/code default to denied; empty mcp.allow / client.allow means no tools of that class. Globs: `*`, `prefix*`, `*suffix` only. `max_mode` order: read < write < delete. Map the signed-in user to a policy name on the host (`policyUsing` / `resolveToolsUsing`); substituting an email in the browser does not change policy. Mobile and web clients only hold the embed token; never ship `SVEDA_EMBED_HOST_API_KEY` to end users. Row-level data rules stay in the host tool handler.

The JS client then calls `session.send` against `{runtime}/sveda/stream` with `x-sveda-embed-token`. `GET /sveda/embed/config` returns `capabilities` for UI hints; enforcement is the token, not the UI.

This origin does not speak OAuth authorization-code login. Discovery documents at `/.well-known/oauth-authorization-server` and `/.well-known/oauth-protected-resource` exist so agents can find this page and the OpenAPI spec. Operator token minting stays on the self-hosted runtime (`POST /sveda/embed/token`). The marketing copilot uses `POST https://sveda.dev/sveda/session` on this host and never exposes `SVEDA_EMBED_HOST_API_KEY`.

## Agent discovery

Public documentation tools (no credential):

- MCP server card: https://sveda.dev/.well-known/mcp/server-card.json
- MCP Streamable HTTP: POST https://sveda.dev/agent/mcp
- A2A agent card: https://sveda.dev/.well-known/agent-card.json
- A2A JSON-RPC: POST https://sveda.dev/agent/a2a
- WebMCP tools register in the browser via `navigator.modelContext.registerTool`
- Web Bot Auth directory: https://sveda.dev/.well-known/http-message-signatures-directory

The docs copilot widget uses a separate Bearer-gated `POST https://sveda.dev/mcp`. That token is minted by `POST https://sveda.dev/sveda/session` and is not a public API key. Outbound HTTP from this origin is signed with Web Bot Auth (`Signature-Agent`, `Signature-Input`, `Signature`).

## agent_auth

```json
{
  "skill": "https://sveda.dev/.well-known/agent-skills/sveda-install/SKILL.md",
  "register_uri": "https://sveda.dev/docs/embed",
  "identity_types_supported": [
    "anonymous"
  ],
  "anonymous": {
    "credential_types_supported": [
      "api_key"
    ],
    "claim_uri": "https://sveda.dev/docs/embed"
  }
}
```

## Install with an agent

Read https://sveda.dev/llms.txt and https://sveda.dev/docs/start. Skill: https://sveda.dev/.well-known/agent-skills/sveda-install/SKILL.md
