Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

img

Telekot

Telekot is a minimal Telegram-based OpenID Connect provider. Lets your OIDC-compatible apps and websites accept "Sign in with Telegram", restricted to members of a specific Telegram chat/group/channel.

⚠️ What? TL;DR: Only your telegram friends (members of a group) can access your apps and websites.

Built on zitadel/oidc — a certified Go OpenID Provider library.

How it works

  1. Your app redirects the user to /authorize (standard OIDC authorization code flow, PKCE supported).
  2. Telekot redirects to a Telegram Login Widget page.
  3. The user approves via Telegram; Telegram redirects back to Telekot with signed user data (verified via HMAC-SHA256, per the Login Widget spec).
  4. If the OAuth client's mode is group_membership, Telekot checks (via the Bot API getChatMember) that the user is a member of the configured access_chat_id. Non-members are rejected. Clients in public mode skip this check and let any Telegram user through.
  5. Telekot completes the OIDC authorization request and redirects back to your app with a code (or errors out).
  6. Your app exchanges the code for tokens at /oauth/token as usual. The ID token and userinfo include sub, name, given_name, family_name, picture, preferred_username, a synthesized stable email (telegram.<id>@$EMAIL_DOMAIN), and a custom group claim.

Note

The synthesized user email address is just for protocol compliance. It is not functional.

Configuration

example .env file:

TELEGRAM_TOKEN=123456:your-bot-token
TELEGRAM_BOT=your_bot_username
URL=https://telekot.example.com
EMAIL_DOMAIN=tg.example.com
DATA_PATH=./data
LISTEN_ADDR=:8075
ENABLE_LOGIN_LOGGING=true
LOG_RETENTION_DAYS=90
LOG_IP_ADDRESSES=true

DATA_PATH holds the SQLite database and the persisted RSA signing key (generated on first run).

Bot setup

In @BotFather, create your bot and set your domain for the login widget.

Running

go build -o telekot ./cmd/telekot
./telekot serve

Or with Docker:

docker compose up -d --build

Admin CLI

Manage OAuth clients and inspect login logs:

# Register a client restricted to members of a Telegram chat/group/channel
./telekot client add my-app \
  --redirect-uris=https://my-app.example.com/callback \
  --secret=some-strong-secret \
  --mode=group_membership \
  --access-chat-id=@my_group_or_chat_id

# Register a client open to any Telegram user
./telekot client add my-public-app \
  --redirect-uris=https://my-public-app.example.com/callback \
  --mode=public

# Update existing clients
./telekot client update my-app --access-chat-id=-100123456789
./telekot client update my-public-app --mode=group_membership --access-chat-id=-100123456789

# List, inspect, or remove clients
./telekot client list
./telekot client show my-app
./telekot client rm my-app

# Login audit log
./telekot logs list --limit=50 --client=my-app
./telekot logs prune   # deletes logs older than LOG_RETENTION_DAYS

Endpoints

Standard OIDC discovery is served at /.well-known/openid-configuration, exposing /authorize, /oauth/token, /userinfo, /keys (JWKS), etc. — all implemented by zitadel/oidc. Telekot adds the Telegram-specific login UI at /telegram/initiate and /telegram/callback.

Reverse Proxy

Auth plugins for reverse proxies allow you to protect to create a login page for any website. Below are instructions for Caddy but others (Nginx, Traefik, etc.) have similar plugins too.

Caddy

Example Caddyfile for server:

telekot.example.com {
        reverse_proxy localhost:8075
}

Example Caddyfile for your protected apps (uses caddy security plugin):

{
        order authenticate before respond
        order authorize before basicauth

        security {
                oauth identity provider generic {
                        realm generic
                        driver generic
                        client_id my-app
                        client_secret your-client-secret
                        scopes openid email profile
                        base_auth_url https://telekot.example.com/
                        metadata_url https://telekot.example.com/.well-known/openid-configuration
                }

                authentication portal my-portal {
                        # 3600 = 1 hour
                        crypto default token lifetime 10800
                        enable identity provider generic
                        cookie domain example.com
                        transform user {
                                match realm generic
                                action add role authp/user
                        }
                }

                authorization-code-callback
                authorization policy plausiblepolicy {
                        bypass uri prefix /api/
                        bypass uri prefix /js/
                        set auth url https://auth.example.com/oauth2/generic
                        allow roles authp/admin authp/user
                        validate bearer header
                        inject headers with claims
                }
        }
}

auth.example.com {
        authenticate with my-portal
}

homepage.example.com {
        authorize with plausiblepolicy
        reverse_proxy localhost:3311
}

immich.example.com {
        authorize with plausiblepolicy
        reverse_proxy localhost:2283
}

plausible.example.com {
        authorize with plausiblepolicy
        reverse_proxy localhost:8181
}

Add the callback url https://auth.example.com/oauth2/generic/ to redirect-uris in your client settings.

Optional bypass uri prefix /api/ and bypass uri prefix /js/ will allow you to use use your apps' API etc. without auth. Just be careful about what prefixes you allow. You can also have multiple authorization policies for different apps.

You can use a different domain for server and apps.

Tip: You can download caddy binary with security plugin at caddyserver.com/download

OIDC-compatible apps

Some apps natively support OpenID/OAuth login: Outline, Gitea, and many more.

Tip: Immich does have OAuth support, but I still use Caddy-security for it to protect the "public" links for sharing albums.

About

OIDC/OAuth2 server for Telegram-based communities

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages