# `SuperPi.Auth`
[🔗](https://github.com/oleksandr/super-pi-beam/blob/v0.1.0/lib/super_pi/auth.ex#L1)

Bearer-token authentication and conversation ownership for the Gateway and RPC server.

## Tokens

Configure tokens with `config :super_pi, gateway_tokens: [...]` or the
`SUPER_PI_GATEWAY_TOKEN` environment variable (comma separated). An entry is either a
token string or a `{name, token}` pair. A named entry makes the principal readable in
logs and ownership records. An unnamed token gets the principal `token:<hash prefix>`.
The older single `:gateway_token` key still works.

With no tokens configured the endpoints are open, which is safe only on a loopback
address. `SuperPi.Gateway.Server` refuses to start on another address without a token.
Open endpoints use the principal `"anonymous"`.

## Ownership

The first principal to create a conversation owns it (`pi.owner` document). Another
principal gets `:not_found` for it, the same answer as for a conversation that does not
exist, so an id does not reveal that a conversation exists. A conversation with no
owner (created by the CLI, or before this check existed) belongs to `"anonymous"`, so
it is reachable only when authentication is off.

# `anonymous`

Principal used when authentication is off.

# `authenticate`

```elixir
@spec authenticate(String.t() | nil) :: {:ok, String.t()} | :error
```

Checks a presented token. Returns `{:ok, principal}` or `:error`.
With no tokens configured, any call (including a missing token) is `{:ok, "anonymous"}`.

# `authorized?`

True when `principal` may use the conversation.

# `bearer_token`

Extracts the token from an `Authorization: Bearer ...` header value.

# `claim!`

Records `principal` as the owner of `conversation_id`.

# `owner`

Owner of a conversation (`"anonymous"` when none is recorded).

# `required?`

True when at least one token is configured.

# `tokens`

```elixir
@spec tokens() :: %{required(String.t()) =&gt; String.t()}
```

Returns `%{token => principal}` from config and environment.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
