# How Authentication, Rate-Limiting, and Security Middleware Layers Work Together in Claude-Code-Telegram

> Discover how Claude-Code-Telegram middleware layers ensure security. Learn how authentication, rate limiting, and security work together to protect your Claude API from unauthorized access and abuse.

- Repository: [Richard A/claude-code-telegram](https://github.com/richardatct/claude-code-telegram)
- Tags: internals
- Published: 2026-02-20

---

**The Claude-Code-Telegram bot processes every incoming update through a strict pipeline of authentication, rate-limiting, and security middleware layers that short-circuit on failure to protect the underlying Claude API from unauthorized access, abuse, and malicious payloads.**

The `RichardAtCT/claude-code-telegram` repository implements a defense-in-depth architecture where three specialized middleware components intercept Telegram updates before they reach the business logic. Understanding how these middleware layers interact is essential for customizing security policies, debugging access issues, or extending the bot's protective capabilities.

## Middleware Architecture Overview

The bot employs a layered middleware pattern managed by the `MessageOrchestrator` class in [`src/bot/orchestrator.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/orchestrator.py). Rather than handling authentication, rate limiting, and security as separate concerns, the orchestrator chains them into a unified processing stack.

### The Processing Pipeline

Each incoming Telegram update traverses the following sequence:

1. **Authentication Middleware** (`auth_middleware` in [`src/bot/middleware/auth.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/auth.py)) – Verifies user identity and session validity
2. **Rate-Limiting Middleware** (`rate_limit_middleware` in [`src/bot/middleware/rate_limit.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/rate_limit.py)) – Enforces usage quotas and cost controls
3. **Security Middleware** (`security_middleware` in [`src/bot/middleware/security.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/security.py)) – Sanitizes inputs and validates file uploads

The orchestrator constructs this chain by wrapping handlers in reverse order, ensuring that the outermost layer (authentication) executes first.

## Authentication Middleware

The authentication layer guarantees that only recognized and authorized users can invoke bot commands. Located in [`src/bot/middleware/auth.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/auth.py), the `auth_middleware` function implements session management and whitelist enforcement.

### Key Implementation Steps

The middleware performs the following operations for every update:

- Extracts the Telegram `user_id` and optional `username` from the incoming update
- Retrieves the `auth_manager` and `audit_logger` from the handler context
- Checks existing session validity via `auth_manager.is_authenticated(user_id)`
- Refreshes active sessions using `auth_manager.refresh_session(user_id)` to prevent timeout
- Authenticates new users through `auth_manager.authenticate_user(user_id)`, which validates against configured whitelists or external providers
- Logs all attempts via `audit_logger.log_auth_attempt` for security auditing
- Short-circuits with an "Authentication Required" message if any check fails

```python

# Simplified flow from src/bot/middleware/auth.py

async def auth_middleware(handler, event, data):
    user_id = event.from_user.id
    auth_manager = data["auth_manager"]
    audit_logger = data["audit_logger"]
    
    if not auth_manager.is_authenticated(user_id):
        result = await auth_manager.authenticate_user(user_id)
        audit_logger.log_auth_attempt(user_id, result)
        if not result.success:
            await event.answer("Authentication Required")
            return  # Stop processing

    
    auth_manager.refresh_session(user_id)
    return await handler(event, data)

```

## Rate-Limiting Middleware

Once authenticated, requests pass to the rate-limiting layer in [`src/bot/middleware/rate_limit.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/rate_limit.py). This middleware prevents resource exhaustion and Claude API cost overruns by enforcing usage quotas per user.

### Cost-Aware Rate Limiting

The `rate_limit_middleware` implements sophisticated cost estimation:

- Calculates message cost via `estimate_message_cost(event)`, considering message length, file attachments, and command complexity
- Invokes `rate_limiter.check_rate_limit(user_id, cost, tokens=1)` to validate against configured quotas
- Records violations through `audit_logger.log_rate_limit_exceeded`
- Returns a friendly "⏱️ Rate limit exceeded" message and aborts processing if limits are breached

The middleware also supports **burst protection** and **post-processing cost tracking** when registered with the `MessageOrchestrator`.

```python

# Excerpt from src/bot/middleware/rate_limit.py

async def rate_limit_middleware(handler, event, data):
    user_id = event.from_user.id
    rate_limiter = data["rate_limiter"]
    audit_logger = data["audit_logger"]
    
    cost = estimate_message_cost(event)
    allowed = await rate_limiter.check_rate_limit(user_id, cost, tokens=1)
    
    if not allowed:
        audit_logger.log_rate_limit_exceeded(user_id, cost)
        await event.reply("⏱️ Rate limit exceeded. Please try again later.")
        return  # Short-circuit

    
    return await handler(event, data)

```

## Security Middleware

The final protective layer, located in [`src/bot/middleware/security.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/security.py), sanitizes inputs and validates file uploads to prevent command injection, path traversal, and other attacks.

### Context-Aware Validation

The `security_middleware` adapts its behavior based on the bot's operational mode:

- Retrieves the `security_validator` and `audit_logger` from context
- Checks `settings.agentic_mode` to determine validation strictness
- In standard mode, calls `validate_message_content` to scan for dangerous patterns using regex-based checks
- For document uploads, invokes `validate_file_upload` to verify filename safety, size limits, and MIME type against a blacklist
- Logs security events via the audit logger and short-circuits with a security alert if threats are detected

When `agentic_mode` is enabled, the middleware treats incoming text as free-form prompts, skipping restrictive validation to allow natural language interaction while still enforcing file upload checks.

```python

# Simplified logic from src/bot/middleware/security.py

async def security_middleware(handler, event, data):
    security_validator = data["security_validator"]
    audit_logger = data["audit_logger"]
    
    if not settings.agentic_mode:
        is_safe = await security_validator.validate_message_content(event.text)
        if not is_safe:
            audit_logger.log_security_event(event.from_user.id, "dangerous_content")
            await event.reply("🛡️ Security alert: Potentially dangerous content detected.")
            return
    
    if event.document:
        file_safe = await security_validator.validate_file_upload(event.document)
        if not file_safe:
            await event.reply("🛡️ File validation failed.")
            return
    
    return await handler(event, data)

```

## How the Layers Interact

The `MessageOrchestrator` in [`src/bot/orchestrator.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/orchestrator.py) constructs the middleware chain by wrapping handlers in reverse order. This creates a nested execution flow where authentication executes first, followed by rate limiting, then security validation, and finally the business logic.

### Execution Flow

```python

# Conceptual chain construction from src/bot/orchestrator.py

handler = self._handle_agentic_message
handler = security_middleware(handler, event, data)
handler = rate_limit_middleware(handler, event, data)
handler = auth_middleware(handler, event, data)

await handler(event, data)  # Execution begins here

```

### Short-Circuit Behavior

Each middleware layer implements **fail-fast** semantics. If any layer detects a violation, it immediately returns without calling the next handler, preventing unauthorized or dangerous requests from consuming Claude API resources.

| Layer | Success Action | Failure Action |
|-------|---------------|----------------|
| **Authentication** | Refreshes session, proceeds to next layer | Returns "Authentication Required", stops |
| **Rate-Limiting** | Consumes quota, proceeds to next layer | Returns "⏱️ Rate limit exceeded", stops |
| **Security** | Validates content, proceeds to handler | Returns "🛡️ Security alert", stops |

This layered approach ensures that expensive AI processing only occurs for authenticated, compliant, and safe requests.

## Summary

- **Authentication Middleware** ([`src/bot/middleware/auth.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/auth.py)) validates user identity against whitelists and manages session refresh, short-circuiting unauthenticated requests before they consume resources.
- **Rate-Limiting Middleware** ([`src/bot/middleware/rate_limit.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/rate_limit.py)) enforces cost-aware usage quotas using `estimate_message_cost` and `check_rate_limit`, protecting against API cost overruns and resource exhaustion.
- **Security Middleware** ([`src/bot/middleware/security.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/security.py)) sanitizes inputs and validates file uploads, adapting validation strictness based on `settings.agentic_mode` to block command injection and path traversal attacks.
- **MessageOrchestrator** ([`src/bot/orchestrator.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/orchestrator.py)) chains these layers in reverse order (auth → rate-limit → security → handler), creating a fail-fast pipeline where each layer can abort processing to protect the Claude API backend.

## Frequently Asked Questions

### What happens if a user fails authentication but tries to send many requests?

The **authentication middleware** short-circuits every request immediately upon failure, returning an "Authentication Required" message without invoking the rate limiter or security validator. Because the request never reaches the Claude API, failed authentication attempts consume minimal server resources and do not count against rate limits.

### How does the bot prevent API cost overruns from expensive file uploads?

The **rate-limiting middleware** calculates message costs using `estimate_message_cost(event)`, which factors in file attachments, message length, and command complexity. Before processing uploads, `rate_limiter.check_rate_limit(user_id, cost, tokens=1)` verifies the user has sufficient quota. If an upload would exceed the budget, the middleware aborts with a "⏱️ Rate limit exceeded" message, preventing the expensive API call.

### Why does the security middleware behave differently in agentic mode?

When `settings.agentic_mode` is enabled, the **security middleware** treats incoming text as free-form natural language prompts rather than structured commands. In this mode, `validate_message_content` skips restrictive regex checks that would otherwise block legitimate AI prompts, while still enforcing `validate_file_upload` for document attachments. This balance allows flexible conversational interaction while maintaining protection against malicious file uploads.

### Can I add custom middleware without breaking the existing security chain?

Yes, the **MessageOrchestrator** in [`src/bot/orchestrator.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/orchestrator.py) supports custom middleware insertion by wrapping the existing handler stack. New middleware should follow the pattern `def custom_middleware(handler, event, data)` and call `await handler(event, data)` to proceed. Insert custom layers between the existing auth, rate-limit, and security middleware, or wrap the entire chain, depending on whether your logic requires pre-authentication or post-security processing.