Sign in with Telegram
XLADA can let an administrator into the panel through a Telegram account. Then no password is needed: the panel sends you to the Telegram page and, after confirmation, issues a regular JWT token. This is convenient for daily work and protects against password guessing.
Telegram sign-in is administrator-only sign-in for the panel. It has nothing to do with subscription users and is configured separately from the notifications bot.
What you needâ
Setup lives in the panel, under Settings â Authentication â Telegram OAuth2. You will need four values:
| Field | What it is |
|---|---|
| Enabled | the provider switch |
Client ID | Telegram application identifier |
Client Secret | Telegram application secret |
Frontend Domain | panel domain without https://, for example panel.example.com |
Allowed IDs | list of numeric Telegram IDs of administrators |
Client ID and Client Secret are issued by Telegram for your bot â they are
separate data, not the TELEGRAM_BOT_TOKEN. The panel domain must be a real
FQDN: the panel builds the callback address from it, and it must match what is
registered for the bot.
The callback address you need to allow for the bot:
https://panel.example.com/api/auth/oauth2/callback/telegram
Copy the callback address in full, together with /api/auth/oauth2/callback/telegram.
If you specify only the domain, Telegram cannot return you to the panel.
In Allowed IDs, add the numeric IDs of administrators. The list is required:
while it is empty, the provider cannot be enabled, and sign-in will not work for
anyone. An ID is a number, not a username.
If at least one of the fields is not filled in â Client ID, Client Secret, or
Frontend Domain â the panel will not enable Telegram OAuth2. Save the settings
and test sign-in right away so you do not lock yourself out.
How sign-in worksâ
- You click sign in with Telegram, and the panel opens the Telegram authorization page.
- The panel sends
stateand a PKCE check (code_verifier, method S256); the request uses theopenid,profile, andtelegram:bot_accessscopes. - Telegram returns a code to the callback address â the very
/api/auth/oauth2/callback/telegram. - The panel verifies
stateand the provider, exchanges the code for a token, and reads the numeric user ID from the ID token. - If the ID is in
Allowed IDs, the panel issues a super-administrator token and records the successful sign-in in the log.
After confirmation, the first administrator (super admin) signs in to the panel. Other administrators do not sign in through Telegram â this is intentional.
Limitationsâ
- The provider works over HTTPS only: the panel does not start without a reverse proxy with TLS anyway.
Frontend Domainis set without a scheme and without a path. For local debugging,localhostand127.0.0.1are allowed.Allowed IDsis the only access filter. If the list is empty or contains an extra ID, the wrong person can sign in.- The provider can be enabled together with the password and other sign-in methods â they do not conflict.
Securityâ
The panel protects sign-in with several mechanisms:
stateis stored in Valkey and lives for a limited time â a Telegram response cannot be forged without it;- PKCE is used, so an intercepted code cannot be turned into a token;
- access is decided by the ID list, not by an email address or a name;
- failed sign-in attempts are recorded with the
service.login_attempt_failedevent and go to Telegram and webhooks; - the password is never included in such notifications.
Client Secret is a full-fledged secret. It is stored in the panel settings and
is never exposed in plain text. Do not publish it, do not forward it in
messengers, and do not keep it in a repository. If it leaks, change the secret in
Telegram and in the settings.
If you disabled password sign-in and lost access to Telegram, the rescue CLI will help you get back in: it can enable password sign-in again.
What's nextâ
- Rescue CLI â how to restore access to the panel.
- Panel Security â passwords, 2FA, and brute-force protection.
- Panel Installation â domains and reverse proxy.
- Common Errors â if sign-in does not work.