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

# Authentication and scopes

> Authorize applications with OAuth 2.0, PKCE, refresh tokens, and tenant-scoped permissions.

Silo uses OAuth 2.0 Authorization Code with PKCE `S256` for both the REST API
and MCP. Applications act as the signed-in user. Do not use an admin session
cookie, a shared organization token, or an organization ID supplied by the
client.

## Discover the authorization server

Start with the protected resource metadata:

```text theme={"system"}
$SILO_API_URL/.well-known/oauth-protected-resource
```

Its `authorization_servers` value identifies the authorization server. The
authorization-server metadata is available at:

```text theme={"system"}
$SILO_ADMIN_URL/.well-known/oauth-authorization-server/api/auth
```

Use the endpoints in that document instead of constructing OAuth paths. It
advertises the authorization, token, registration, and JSON Web Key Set
endpoints, along with supported scopes and grant types.

## Authorization flow

1. Register the client through the advertised Dynamic Client Registration
   endpoint.
2. Generate a PKCE verifier and its `S256` challenge.
3. Send the user to the advertised authorization endpoint with
   `response_type=code`, the registered redirect URI, the requested scopes,
   the PKCE challenge, and `resource=$SILO_API_URL`.
4. The user signs in, selects an active organization if needed, reviews the
   requested scopes, and grants access.
5. Exchange the returned code at the advertised token endpoint using the
   original PKCE verifier.
6. Send the access token as `Authorization: Bearer <token>` to REST or MCP.
7. Request `offline_access` and store the returned refresh token securely when
   the connection must survive access-token expiry.

The access token is bound to the authorizing user, OAuth client, selected
organization, and API resource. A user must authorize each organization
separately. Switching the user's active organization later does not widen an
existing token.

## Scopes

Request only the scopes the integration needs.

| Scope                | Access                                                   |
| -------------------- | -------------------------------------------------------- |
| `articles:read`      | List, search, and read articles in accessible sites      |
| `articles:write`     | Create, update, and delete draft articles                |
| `publications:read`  | List, search, and read books and publication records     |
| `publications:write` | Create, update, and delete books and publication records |
| `magazines:read`     | List, search, and read magazines and issues              |
| `magazines:write`    | Create, update, and delete magazines and issues          |
| `knowledge:read`     | List, search, and read visible AI knowledge files        |
| `knowledge:write`    | Create, update, and delete AI knowledge files            |
| `crm:read`           | List, search, and read CRM contacts and companies        |
| `crm:write`          | Create, update, and delete CRM contacts and companies    |

Identity scopes `openid`, `profile`, and `email` are supported.
`offline_access` enables refresh-token access.

OAuth scopes are an upper bound, not a replacement for Silo permissions. For
example, a token with `crm:write` still cannot update a company when the user no
longer has the corresponding CRM permission.

## Verify a connection

After obtaining an access token, call the principal endpoint:

```bash theme={"system"}
curl "$SILO_API_URL/v1/me" \
  --header "Authorization: Bearer $SILO_ACCESS_TOKEN"
```

The response identifies the token's user, organization, client, source, and
granted tenant scopes. It does not return broader access than the token has.

<Warning>
  Keep access tokens, refresh tokens, PKCE verifiers, and client secrets out of
  browser bundles, logs, analytics payloads, and source control.
</Warning>
