# How Audit Logging Tracks User Actions in Claude-Code-Telegram: Implementation Guide

> Implement robust audit logging in Claude-Code-Telegram. Learn how the three-layer system tracks user actions, security events, and violations using an AuditEvent dataclass, Storage backends, and AuditLogger API.

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

---

**The bot implements a three-layer audit logging system using an `AuditEvent` dataclass, pluggable `AuditStorage` backends, and a high-level `AuditLogger` API to persist authentication attempts, commands, file accesses, and security violations to SQLite.**

The `RichardAtCT/claude-code-telegram` repository captures every security-relevant activity through a comprehensive audit logging subsystem designed for forensics and real-time monitoring. This implementation provides structured event tracking with queryable storage, separating event definition, storage abstraction, and business logic into distinct maintainable layers. The audit logging architecture ensures that both successful operations and security violations leave a permanent, searchable trail.

## Audit Logging Architecture Overview

The system organizes audit logging into five interconnected layers that handle everything from event definition to dashboard reporting:

| Layer | Responsibility | Key Implementation |
|-------|----------------|---------------------|
| **Event model** | Defines structured records for auditable actions. | `AuditEvent` dataclass in [`src/security/audit.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/security/audit.py) (lines 22-34). |
| **Storage abstraction** | Provides pluggable backends for testing and production. | `AuditStorage` ABC and `InMemoryAuditStorage` in [`src/security/audit.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/security/audit.py) (lines 46-88). |
| **Repository** | Persists events to SQLite and offers query helpers. | `AuditLogRepository.log_event` in [`src/storage/repositories.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/storage/repositories.py) (lines 55-68). |
| **High-level logger** | Business-logic API used throughout the bot. | `AuditLogger` methods in [`src/security/audit.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/security/audit.py) (lines 89-212). |
| **Integration points** | Middleware and handlers trigger logging. | Authentication middleware in [`src/bot/middleware/auth.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/auth.py) (lines 66-74). |

## Defining Audit Events with AuditEvent

At the core of the system lies the `AuditEvent` dataclass, which serves as the canonical format for every log entry stored in [`src/security/audit.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/security/audit.py).

```python
@dataclass
class AuditEvent:
    timestamp: datetime                # UTC time of the event

    user_id: int                       # Telegram user ID

    event_type: str                    # e.g., "auth_attempt", "command", "file_access"

    success: bool                      # Pass/fail flag

    details: Dict[str, Any]            # Arbitrary payload (method, command, path, etc.)

    ip_address: Optional[str] = None
    session_id: Optional[str] = None
    risk_level: str = "low"            # "low", "medium", "high", "critical"

```

This definition enforces type safety while allowing flexible metadata storage through the `details` dictionary, ensuring every auditable action conforms to a consistent schema.

## Pluggable Storage Backends

The audit logging system supports multiple storage implementations via the `AuditStorage` abstract base class defined in [`src/security/audit.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/security/audit.py).

**In-Memory Storage for Testing**

The `InMemoryAuditStorage` class stores events in a Python list and automatically trims old entries. It also logs high-risk events via `structlog` for immediate visibility during test execution (lines 71-88).

**SQLite Repository for Production**

The `AuditLogRepository` in [`src/storage/repositories.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/storage/repositories.py) handles database persistence. It writes JSON-encoded event data to the `audit_log` table and provides filtered queries such as `get_user_audit_log` (lines 80-95) and `get_recent_audit_log` for administrative review.

## High-Level AuditLogger API

The `AuditLogger` class wraps concrete storage implementations and exposes convenience methods for specific event types. This facade pattern simplifies audit logging calls throughout the bot's business logic.

### Logging Authentication Attempts

The authentication middleware in [`src/bot/middleware/auth.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/bot/middleware/auth.py) records every verification attempt by calling `log_auth_attempt`:

```python
if audit_logger:
    await audit_logger.log_auth_attempt(
        user_id=user_id,
        success=authentication_successful,
        method="automatic",
        reason="message_received",
    )

```

This captures the authentication method, success status, and contextual reason for security analysis.

### Recording Command Execution

When users execute system commands, the logger captures execution metadata and assesses risk based on command arguments:

```python
await audit_logger.log_command(
    user_id=user_id,
    command="git",
    args=["clone", "repo.git"],
    success=True,
    working_directory="/tmp",
    execution_time=1.23,
    exit_code=0,
)

```

The method automatically evaluates risk levels based on command names and argument patterns, storing the result in the `risk_level` field.

### Tracking File Access and Security Violations

Additional methods handle file system interactions and security policy breaches:

- **`log_file_access()`** records path, action (read/write/delete), file size, and risk level.
- **`log_security_violation()`** captures violation type, severity, and maps events to elevated risk levels.
- **`log_rate_limit_breach()`** tracks limit types and usage ratios for abuse detection.

All methods route through `self.storage.store_event(event)`, ensuring consistent persistence regardless of backend implementation.

## SQLite Persistence Implementation

The `AuditLogRepository.log_event` method in [`src/storage/repositories.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/storage/repositories.py) handles database insertion using parameterized queries to prevent SQL injection:

```python
async def log_event(self, audit_log: AuditLogModel) -> int:
    async with self.db.get_connection() as conn:
        event_data_json = json.dumps(audit_log.event_data) if audit_log.event_data else None
        cursor = await conn.execute(
            """
            INSERT INTO audit_log
            (user_id, event_type, event_data, success, timestamp, ip_address)
            VALUES (?, ?, ?, ?, ?, ?)
            """,
            (
                audit_log.user_id,
                audit_log.event_type,
                event_data_json,
                audit_log.success,
                audit_log.timestamp,
                audit_log.ip_address,
            ),
        )
        await conn.commit()
        return cursor.lastrowid

```

This implementation stores flexible JSON payloads in the `event_data` column while maintaining relational constraints on user IDs and timestamps.

## Querying Audit Logs and Security Dashboards

The repository layer provides aggregation helpers for administrative interfaces. The `AuditLogger` exposes `get_user_activity_summary()` (lines 93-111) to retrieve total events, per-type counts, risk distribution, and success rates for specific users.

For system-wide monitoring, `get_security_dashboard()` (lines 43-81) aggregates recent events, violation counts, active user statistics, and top violation types. These endpoints power the bot's `/status` command and administrative dashboards:

```python
recent = await storage.audit.get_recent_audit_log(hours=24)
dashboard = await audit_logger.get_security_dashboard()

```

## Integration Points

The storage facade in [`src/storage/facade.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/storage/facade.py) exposes the audit logger to the application via `self.audit = AuditLogRepository(db)`, making it accessible to handlers and middleware throughout the bot. Unit tests in [`tests/unit/test_security/test_audit.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/tests/unit/test_security/test_audit.py) verify that each logging method correctly persists events to the configured storage backend.

## Summary

- **Structured Events**: The `AuditEvent` dataclass in [`src/security/audit.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/security/audit.py) provides a type-safe, extensible schema for all security-relevant activities.
- **Pluggable Storage**: The `AuditStorage` abstraction supports both `InMemoryAuditStorage` for unit tests and `AuditLogRepository` for production SQLite persistence.
- **Comprehensive Coverage**: The `AuditLogger` API captures authentication attempts, command executions, file accesses, rate-limit breaches, and security violations.
- **Database Persistence**: Events serialize to JSON and store in the `audit_log` table via parameterized SQLite queries in [`src/storage/repositories.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/storage/repositories.py).
- **Administrative Visibility**: Built-in aggregation methods enable user activity summaries and security dashboards for real-time monitoring.

## Frequently Asked Questions

### Where are audit logs stored in the Claude-Code-Telegram bot?

Audit logs persist to a SQLite database table named `audit_log` via the `AuditLogRepository` class in [`src/storage/repositories.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/storage/repositories.py). For testing scenarios, the system uses `InMemoryAuditStorage` to avoid database dependencies while still validating logging logic.

### What event types does the audit logging system capture?

The system captures authentication attempts, command executions, file system accesses, security policy violations, and rate-limit breaches. Each event includes metadata such as user ID, timestamp, success status, risk level, and contextual details in a JSON payload.

### How does the bot determine risk levels for audit events?

The `AuditLogger` class assesses risk based on event context. For commands, it evaluates the executable name and arguments; for file access, it considers the operation type and path sensitivity. Risk levels map to "low", "medium", "high", or "critical" classifications stored in the `risk_level` field of every `AuditEvent`.

### Can administrators query audit logs for specific users?

Yes. The `AuditLogRepository.get_user_audit_log` method in [`src/storage/repositories.py`](https://github.com/RichardAtCT/claude-code-telegram/blob/main/src/storage/repositories.py) provides filtered queries by user ID, and the `AuditLogger.get_user_activity_summary` method aggregates statistics including event counts, risk distribution, and success rates for individual users. These methods support compliance auditing and security investigations.