Access Control And 2FA¶
This document describes the authorization path implemented in code.
Source of truth:
pytmbot/middleware/access_control.pypytmbot/middleware/session_manager.pypytmbot/middleware/session_wrapper.pypytmbot/utils/totp.py
Request Pipeline¶
For class middlewares, the runtime order is:
UpdateDedupAccessControlRateLimit
The middleware chain is assembled in pytmbot/pytmbot_instance.py.
AccessControl Middleware¶
AccessControl protects all message and callback-query updates.
Current rules:
- Allowed users are read from
access_control.allowed_user_ids. - Unauthorized users accumulate attempts.
- After
3failed attempts, a user is blocked for3600seconds. - Cleanup of expired block state runs in a background thread every
3600seconds. - Admin notifications for repeated unauthorized access are suppressed for
300seconds per user.
Bootstrap exception:
/getmyidis intentionally allowed for unauthorized users.- This supports initial setup and ID discovery before the allowlist is complete.
Session Management¶
SessionManager stores per-user authentication state for privileged flows.
States:
unauthenticatedprocessingauthenticatedblocked
Default timing:
- session timeout:
10minutes - cleanup interval:
600seconds - user-facing invalid TOTP attempts before a block:
3 - short-window TOTP burst limit: at least
5attempts per60seconds - temporary TOTP block duration:
10minutes
Implementation notes:
SessionManageris a named singleton with weak-reference instance storage.- Expired sessions are removed by a background cleanup thread.
- Session statistics are exposed to the health subsystem.
Two-Factor Authentication¶
2FA is built in. It is not implemented as a plugin.
Current behavior:
- Sensitive handlers use
two_factor_auth_requiredfrompytmbot/middleware/session_wrapper.py. - TOTP codes are 6-digit codes with a 30-second interval.
- QR codes are generated from the per-user TOTP secret.
- Successful verification transitions the user session to
authenticated. - Replayed or invalid codes are rejected by
pytmbot/utils/totp.py. - Replay state is persisted in the runtime state directory when it is writable.
What Is Protected¶
The bot uses allowlists for all access and applies 2FA only to selected sensitive operations.
Examples of 2FA-protected flows in the current codebase:
- Docker container management actions
- runtime container details
- log access
The exact protected handlers are the ones decorated with two_factor_auth_required.
Observability¶
Access and authentication subsystems emit structured logs for:
- unauthorized access attempts
- blocks and block expiry
- session lifecycle
- TOTP failures
- privileged action denial
See also: