mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-16 18:49:14 +02:00
Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com>
195 lines
6 KiB
Text
195 lines
6 KiB
Text
---
|
|
title: jwt_issuer
|
|
sidebarTitle: jwt_issuer
|
|
---
|
|
|
|
# `fastmcp.server.auth.jwt_issuer`
|
|
|
|
|
|
JWT token issuance and verification for FastMCP OAuth Proxy.
|
|
|
|
This module implements the token factory pattern for OAuth proxies, where the proxy
|
|
issues its own JWT tokens to clients instead of forwarding upstream provider tokens.
|
|
This maintains proper OAuth 2.0 token audience boundaries.
|
|
|
|
|
|
## Functions
|
|
|
|
### `derive_jwt_key` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/jwt_issuer.py#L25" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
derive_jwt_key(upstream_secret: str, server_salt: str) -> bytes
|
|
```
|
|
|
|
|
|
Derive JWT signing key from upstream client secret and server salt.
|
|
|
|
Uses HKDF (RFC 5869) to derive a cryptographically secure signing key from
|
|
the upstream OAuth client secret combined with a server-specific salt.
|
|
|
|
**Args:**
|
|
- `upstream_secret`: The OAuth client secret from upstream provider
|
|
- `server_salt`: Random salt unique to this server instance
|
|
|
|
**Returns:**
|
|
- 32-byte key suitable for HS256 JWT signing
|
|
|
|
|
|
### `derive_encryption_key` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/jwt_issuer.py#L46" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
derive_encryption_key(upstream_secret: str) -> bytes
|
|
```
|
|
|
|
|
|
Derive Fernet encryption key from upstream client secret.
|
|
|
|
Uses HKDF to derive a cryptographically secure encryption key for
|
|
encrypting upstream tokens at rest.
|
|
|
|
**Args:**
|
|
- `upstream_secret`: The OAuth client secret from upstream provider
|
|
|
|
**Returns:**
|
|
- 32-byte Fernet key (base64url-encoded)
|
|
|
|
|
|
### `derive_key_from_secret` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/jwt_issuer.py#L67" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
derive_key_from_secret(secret: str | bytes, salt: str, info: bytes) -> bytes
|
|
```
|
|
|
|
|
|
Derive 32-byte key from user-provided secret (string or bytes).
|
|
|
|
Accepts any length input and derives a proper cryptographic key.
|
|
Uses HKDF to stretch weak inputs into strong keys.
|
|
|
|
**Args:**
|
|
- `secret`: User-provided secret (any string or bytes)
|
|
- `salt`: Application-specific salt string
|
|
- `info`: Key purpose identifier
|
|
|
|
**Returns:**
|
|
- 32-byte key suitable for HS256 JWT signing or Fernet encryption
|
|
|
|
|
|
## Classes
|
|
|
|
### `JWTIssuer` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/jwt_issuer.py#L90" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
|
|
Issues and validates FastMCP-signed JWT tokens using HS256.
|
|
|
|
This issuer creates JWT tokens for MCP clients with proper audience claims,
|
|
maintaining OAuth 2.0 token boundaries. Tokens are signed with HS256 using
|
|
a key derived from the upstream client secret.
|
|
|
|
|
|
**Methods:**
|
|
|
|
#### `issue_access_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/jwt_issuer.py#L116" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
issue_access_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int = 3600) -> str
|
|
```
|
|
|
|
Issue a minimal FastMCP access token.
|
|
|
|
FastMCP tokens are reference tokens containing only the minimal claims
|
|
needed for validation and lookup. The JTI maps to the upstream token
|
|
which contains actual user identity and authorization data.
|
|
|
|
**Args:**
|
|
- `client_id`: MCP client ID
|
|
- `scopes`: Token scopes
|
|
- `jti`: Unique token identifier (maps to upstream token)
|
|
- `expires_in`: Token lifetime in seconds
|
|
|
|
**Returns:**
|
|
- Signed JWT token
|
|
|
|
|
|
#### `issue_refresh_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/jwt_issuer.py#L163" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
issue_refresh_token(self, client_id: str, scopes: list[str], jti: str, expires_in: int) -> str
|
|
```
|
|
|
|
Issue a minimal FastMCP refresh token.
|
|
|
|
FastMCP refresh tokens are reference tokens containing only the minimal
|
|
claims needed for validation and lookup. The JTI maps to the upstream
|
|
token which contains actual user identity and authorization data.
|
|
|
|
**Args:**
|
|
- `client_id`: MCP client ID
|
|
- `scopes`: Token scopes
|
|
- `jti`: Unique token identifier (maps to upstream token)
|
|
- `expires_in`: Token lifetime in seconds (should match upstream refresh expiry)
|
|
|
|
**Returns:**
|
|
- Signed JWT token
|
|
|
|
|
|
#### `verify_token` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/jwt_issuer.py#L211" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
verify_token(self, token: str) -> dict[str, Any]
|
|
```
|
|
|
|
Verify and decode a FastMCP token.
|
|
|
|
Validates JWT signature, expiration, issuer, and audience.
|
|
|
|
**Args:**
|
|
- `token`: JWT token to verify
|
|
|
|
**Returns:**
|
|
- Decoded token payload
|
|
|
|
**Raises:**
|
|
- `JoseError`: If token is invalid, expired, or has wrong claims
|
|
|
|
|
|
### `TokenEncryption` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/jwt_issuer.py#L255" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
|
|
Handles encryption/decryption of upstream OAuth tokens at rest.
|
|
|
|
|
|
**Methods:**
|
|
|
|
#### `encrypt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/jwt_issuer.py#L266" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
encrypt(self, token: str) -> bytes
|
|
```
|
|
|
|
Encrypt a token for storage.
|
|
|
|
**Args:**
|
|
- `token`: Plain text token
|
|
|
|
**Returns:**
|
|
- Encrypted token bytes
|
|
|
|
|
|
#### `decrypt` <sup><a href="https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/auth/jwt_issuer.py#L277" target="_blank"><Icon icon="github" style="width: 14px; height: 14px;" /></a></sup>
|
|
|
|
```python
|
|
decrypt(self, encrypted_token: bytes) -> str
|
|
```
|
|
|
|
Decrypt a token from storage.
|
|
|
|
**Args:**
|
|
- `encrypted_token`: Encrypted token bytes
|
|
|
|
**Returns:**
|
|
- Plain text token
|
|
|
|
**Raises:**
|
|
- `cryptography.fernet.InvalidToken`: If token is corrupted or key is wrong
|
|
|