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

# JWTIdentityProvider

> Verify a bearer JWT and map its verified claims onto a `Principal` (SPEC-v0.3 §3.4).

`ctrlrun.jwt_identity.JWTIdentityProvider` — class, defined at `src/ctrlrun/jwt_identity.py:87`

```python theme={null}
class JWTIdentityProvider()
    def __init__(jwks_url: str | None, public_key: str | None, secret: str | None, algorithms: Sequence[str], issuer: str, audience: str, token_type: str | None, header: str, agent_claim: str, user_claim: str | None, claim_names: Sequence[str], leeway: timedelta, jwks_min_refresh_interval: timedelta, http_timeout: timedelta, clock: Callable[[], datetime])
```

Verify a bearer JWT and map its verified claims onto a `Principal` (SPEC-v0.3 §3.4).

Absent header → `None`, a **decline** (§3.2): in-process there are no headers at all, and
a provider with nothing to say must not break code that already uses `context()`. Present
and invalid → `IdentityError`, a **refusal**, which `Control` never backfills from.

Every configuration mistake that can be caught before a token is seen is caught at
construction, because that is the end that can be refused: the token end is already
covered by the `algorithms` allow-list, and a check that only existed there would be a
negative test against behaviour the library refuses anyway.

## Next

* [Python API index](/reference/api/index).
* [Get started](/get-started/quickstart) · [Why](/why).


## Related topics

- [Authority and delegation](/concepts/authority-and-delegation.md)
- [Install](/get-started/install.md)
- [Roadmap](/ROADMAP.md)
- [Threat model](/THREAT_MODEL.md)
- [Python API](/reference/api/index.md)
