cab-backend/AUTH_ARCHITECTURE.md
2026-03-30 21:00:35 +03:00

5.3 KiB

Auth Architecture

Goal

One user should authenticate once in master and then access other game services without re-login.

For this project, the recommended approach is:

  • master is the single authentication provider
  • user authentication uses JWT access tokens
  • game services validate the same user JWT
  • internal service-to-service calls use a separate auth mechanism

Do not use one shared secret or one "same key for everything" approach for both users and services.

1. User authentication

The user authenticates in master:

  • via Telegram initData for TG game/webapp
  • or via regular login if needed for admin panel

master verifies the user and issues:

  • short-lived access token JWT
  • optionally a refresh token

This access token is then sent to all game services in:

Authorization: Bearer <access_token>

2. Validation in other services

Each game service:

  • does not log the user in again
  • does not store the user's password or Telegram auth secret
  • only validates the JWT from master

This gives SSO behavior across all games and services.

3. Service-to-service authentication

Calls between backend services should use a separate mechanism:

  • service JWT
  • or HMAC
  • or mTLS

Do not rely on a user JWT as the only trust mechanism between services.

Why This Is Better

  • the user logs in once
  • all services trust one source of identity
  • auth logic stays in one place
  • compromised game service should not be able to mint user tokens
  • easier role and permission management

Token Strategy

Access token

Use a short lifetime:

  • 15m to 30m for user access token

Include claims like:

  • sub: user ID
  • role: user, admin, moderator
  • iss: issuer, for example master-auth
  • aud: target audience, for example game-services
  • exp
  • iat

Example payload:

{
  "sub": "123",
  "role": "user",
  "iss": "master-auth",
  "aud": ["game-services"],
  "iat": 1735689600,
  "exp": 1735690500
}

Refresh token

Use if you want silent re-login:

  • lifetime 7d to 30d
  • store server-side or make it revocable

Refresh token should be handled only by master.

Signing Algorithm

Recommended:

  • RS256 or EdDSA

Why:

  • master signs with a private key
  • other services verify with a public key
  • game services cannot issue tokens even if compromised

Avoid using one shared HS256 secret across many services if you plan to scale.

Telegram Login Flow

Option A. Telegram WebApp / Mini App

Flow:

  1. Client gets initData from Telegram.
  2. Client sends initData to master.
  3. master verifies Telegram signature.
  4. master finds or creates the user.
  5. master issues JWT access token.
  6. Client uses that JWT in all other services.

Same principle:

  1. Telegram proves identity to master.
  2. master converts that identity into your internal user.
  3. master issues your platform JWT.

Telegram should only be the initial identity proof. After that, your platform should use its own JWT.

Authorization Model

Authentication and authorization should be separated:

  • authentication: who the user is
  • authorization: what the user can do

Minimum authorization data in JWT:

  • user ID
  • role

If needed later, add:

  • game access list
  • scopes
  • tenant/project ID

Do not put large mutable permission lists into JWT if they change often.

How This Fits Current Project

Current state in this repo:

  • HTTP API already uses JWT
  • gRPC wallet currently uses HMAC metadata

Recommended target state:

  • keep JWT for user-facing HTTP and user-facing gRPC
  • keep HMAC or service JWT for trusted backend-to-backend calls

That means:

  • admin panel and game client use user JWT
  • wallet or internal processors may still use HMAC/service auth for internal calls

Practical Architecture

Public auth endpoints in master

Suggested endpoints:

  • POST /api/auth/telegram
  • POST /api/auth/refresh
  • POST /api/auth/logout
  • GET /api/auth/me

Shared verification in services

Every service should have middleware/interceptor that:

  • reads Authorization: Bearer <token>
  • verifies signature
  • checks iss, aud, exp
  • extracts sub and role
  • places user context into request context

Stage 1

  • keep existing HTTP JWT auth
  • add Telegram login endpoint in master
  • issue JWT after Telegram verification

Stage 2

  • add JWT verification middleware for any external game-facing services
  • keep current gRPC HMAC only for internal trusted integrations

Stage 3

  • if wallet becomes user-facing over gRPC, add JWT gRPC interceptor
  • optionally keep HMAC/service JWT for internal callers only

What Not To Do

  • do not make each game service perform Telegram login separately
  • do not duplicate user auth logic in every service
  • do not use one shared secret for both user tokens and service authentication
  • do not issue long-lived access tokens without refresh/revocation strategy

Final Recommendation

Best approach for your case:

  • authenticate the player once in master
  • issue a platform JWT there
  • reuse that JWT across all game services
  • use separate service authentication for internal backend calls

This is the cleanest and safest SSO model for a TG game ecosystem.