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

# Backends

> Understanding authentication backends and how they integrate with Tasteful flavors

# Backends

Backends in Tasteful are pluggable components that handle specific concerns like authentication, data storage, caching, and external service integrations. They provide a standardized interface that flavors can use without being tightly coupled to specific implementations.

## Authentication Backends

Authentication backends handle user verification and session management. Tasteful provides a flexible authentication system based on OpenID Connect (OIDC) with support for both synchronous and asynchronous authentication patterns.

<CardGroup cols={2}>
  <Card title="OIDC Backend" icon="shield">
    OpenID Connect integration with OAuth providers and custom OIDC servers
  </Card>

  <Card title="Async Authentication" icon="bolt">
    High-performance async authentication for modern applications
  </Card>

  <Card title="Custom User Models" icon="user">
    Extensible user models with BaseUser foundation
  </Card>

  <Card title="Token Introspection" icon="magnifying-glass">
    Automatic token validation with OIDC introspection endpoints
  </Card>
</CardGroup>

### OIDC Authentication Backend

The `OIDCAuthenticationBackend` provides comprehensive OpenID Connect authentication with automatic token validation and user creation:

```python theme={null}
from tasteful.authn.oidc import OIDCAuthenticationBackend

# Basic OIDC configuration
oidc_backend = OIDCAuthenticationBackend(
    name="my_oidc_app",
    metadata_url="https://your-provider.com/.well-known/openid_configuration",
    client_id="your-client-id",
    client_secret="your-client-secret",
    scopes="openid profile email"
)
```

**Key Features:**

* **Automatic Discovery**: Uses OIDC metadata URLs for automatic endpoint discovery
* **Token Introspection**: Validates tokens using the provider's introspection endpoint
* **Async Support**: Built on `AsyncAuthenticationBackend` for high performance
* **Custom Scopes**: Configurable OAuth scopes for fine-grained permissions
* **User Creation**: Automatic user object creation from token claims

**Configuration Parameters:**

* `name`: Unique identifier for the OIDC client
* `metadata_url`: OIDC discovery endpoint URL
* `client_id`: OAuth client identifier
* `client_secret`: OAuth client secret
* `scopes`: Space-separated OAuth scopes
* `introspection_endpoint`: Optional custom introspection endpoint

### Base Authentication Classes

Tasteful provides base classes for building custom authentication backends:

#### AsyncAuthenticationBackend

For high-performance async authentication:

```python theme={null}
from tasteful.authn.base import AsyncAuthenticationBackend, BaseUser
from fastapi import Request

class CustomAsyncBackend(AsyncAuthenticationBackend):
    async def authenticate(self, request: Request) -> BaseUser | None:
        # Custom async authentication logic
        token = request.headers.get("Authorization")
        if token and await self.validate_token(token):
            return BaseUser(name="authenticated_user")
        return None
```

#### AuthenticationBackend

For synchronous authentication scenarios:

```python theme={null}
from tasteful.authn.base import AuthenticationBackend, BaseUser
from fastapi import Request

class CustomSyncBackend(AuthenticationBackend):
    def authenticate(self, request: Request) -> BaseUser | None:
        # Custom sync authentication logic
        api_key = request.headers.get("X-API-Key")
        if api_key and self.validate_api_key(api_key):
            return BaseUser(name="api_user")
        return None
```

### User Models

#### BaseUser

The foundation for all user models in Tasteful:

```python theme={null}
from tasteful.authn.base import BaseUser

class BaseUser(BaseModel):
    name: str
```

#### OIDCUser

Extended user model for OIDC authentication with token claims:

```python theme={null}
from tasteful.authn.oidc import OIDCUser

class OIDCUser(BaseUser):
    user_info: dict  # Contains all OIDC token claims
```

#### Custom User Models

Create custom user models by extending BaseUser:

```python theme={null}
from tasteful.authn.base import BaseUser
from typing import Optional

class CustomUser(BaseUser):
    email: str
    roles: list[str] = []
    department: Optional[str] = None
    is_active: bool = True
```

## Storage Backends

<Warning>
  Storage backends implementation and documentation coming soon.
</Warning>

## Message Backends

<Warning>
  Message backends implementation and documentation coming soon.
</Warning>

## Custom Backends

<Warning>
  Custom backend documentation coming soon.
</Warning>

## Backend Configuration

Authentication backends are configured when creating your Tasteful application. The backends are passed as FastAPI dependencies to secure your entire application:

```python theme={null}
from tasteful import TastefulApp
from tasteful.authn.oidc import OIDCAuthenticationBackend

# Configure OIDC backend
oidc_backend = OIDCAuthenticationBackend(
    name="company_sso",
    metadata_url="https://auth.company.com/.well-known/openid_configuration",
    client_id="tasteful-app-client",
    client_secret="your-client-secret",
    scopes="openid profile email groups"
)

# Create application with authentication
app = TastefulApp(
    title="My Secure Application",
    version="1.0.0",
    authentication_backends=[oidc_backend],
    flavors=[YourFlavor]
)
```

### Multiple Authentication Backends

You can configure multiple authentication backends for different use cases:

```python theme={null}
from tasteful.authn.oidc import OIDCAuthenticationBackend
from tasteful.authn.base import AuthenticationBackend

# OIDC for user authentication
user_auth = OIDCAuthenticationBackend(
    name="user_sso",
    metadata_url="https://auth.company.com/.well-known/openid_configuration",
    client_id="user-client",
    client_secret="user-secret",
    scopes="openid profile email"
)

# Custom backend for API keys
class APIKeyBackend(AuthenticationBackend):
    def authenticate(self, request):
        # API key validation logic
        pass

api_auth = APIKeyBackend()

# Use both backends
app = TastefulApp(
    title="Multi-Auth Application",
    authentication_backends=[user_auth, api_auth],
    flavors=[YourFlavor]
)
```

### Environment-Based Configuration

Use environment variables for secure configuration:

```python theme={null}
import os
from tasteful.authn.oidc import OIDCAuthenticationBackend

oidc_backend = OIDCAuthenticationBackend(
    name=os.getenv("OIDC_CLIENT_NAME", "default_app"),
    metadata_url=os.getenv("OIDC_METADATA_URL"),
    client_id=os.getenv("OIDC_CLIENT_ID"),
    client_secret=os.getenv("OIDC_CLIENT_SECRET"),
    scopes=os.getenv("OIDC_SCOPES", "openid profile email")
)
```

## Authentication Middleware

Authentication backends in Tasteful work as FastAPI dependencies, automatically handling:

* **Token Extraction**: Automatically extracts tokens from Authorization headers
* **Token Validation**: Validates tokens using OIDC introspection or custom logic
* **User Creation**: Creates user objects from validated tokens
* **Request State**: Adds authenticated user to `request.state.user`
* **Error Handling**: Returns appropriate HTTP status codes for authentication failures

### Middleware Flow

1. **Request Received**: Incoming request with Authorization header
2. **Token Extraction**: Backend extracts Bearer token from header
3. **Token Validation**: Backend validates token (OIDC introspection, etc.)
4. **User Creation**: Backend creates user object from token claims
5. **State Injection**: User object added to `request.state.user`
6. **Route Execution**: Your flavor controller receives authenticated request

### Error Responses

Authentication backends automatically handle error responses:

* **401 Unauthorized**: Missing or invalid token
* **500 Internal Server Error**: Authentication backend errors

```python theme={null}
# Automatic error handling - no additional code needed
{
    "detail": "Unauthorized"  # 401 response for invalid tokens
}
```
