# `Urchin.Auth.Plug`
[🔗](https://github.com/urth-inc/urchin/blob/v0.4.0/lib/urchin/auth/plug.ex#L1)

A `Plug` that enforces a valid OAuth 2.1 bearer token on every request.

Mount it ahead of the MCP transport in a Plug/Phoenix pipeline:

    plug Urchin.Auth.Metadata, auth: auth
    plug Urchin.Auth.Plug, auth: auth
    forward "/mcp", to: Urchin.Transport.StreamableHTTP, init_opts: [server: MyServer]

Most servers instead pass `:auth` directly to `Urchin.Transport.StreamableHTTP` (or
`Urchin.start_link/2`), which runs the very same check internally. This standalone plug
is for custom pipelines that want authorization as an explicit pipeline stage.

On success the validated `Urchin.Auth.Claims` are stored under `conn.private[:urchin_auth]`;
the transport reads that key and surfaces it to handlers as `ctx.auth`, regardless of
whether this plug or the transport performed the check. On failure the plug sends the
appropriate `401`/`403`/`400`/`500` OAuth error with a `WWW-Authenticate` challenge and
halts the pipeline.

## Options

  * `:auth` (required) - an `Urchin.Auth` struct or a keyword list of `Urchin.Auth.new!/1`
    options.

# `authenticate`

```elixir
@spec authenticate(Plug.Conn.t(), Urchin.Auth.t() | nil) ::
  {:ok, Plug.Conn.t()} | {:sent, Plug.Conn.t()}
```

The shared authentication seam used by this plug and `Urchin.Transport.StreamableHTTP`.

Returns `{:ok, conn}` with the validated claims stored in `conn.private[:urchin_auth]`,
or `{:sent, conn}` after sending the OAuth error challenge. When `auth` is `nil`
(authorization disabled) the connection passes through untouched.

# `fetch_claims`

```elixir
@spec fetch_claims(Plug.Conn.t()) :: Urchin.Auth.Claims.t() | nil
```

Returns the validated claims stored on the connection, or `nil`.

---

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