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

233 lines
5.3 KiB
Markdown

# 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.
## Recommended Model
### 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:
```http
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:
```json
{
"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.
### Option B. Telegram bot deep-link or custom auth
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
## Recommended Rollout For This Repo
### 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.