Sign inSign up

ankouros/samakia-auth

By ankouros

•Updated 10 months ago

NestJS identity + OIDC provider with dynamic client registration, optional refresh tokens, and auto-

Image
0

2.8K

ankouros/samakia-auth repository overview

Category: Backend Service

⁠samakia-auth

⁠Overview

Samakia Auth is a NestJS 11 microservice exposing identity APIs (user CRUD), an OAuth2/OIDC provider (with dynamic client registration), and notification hooks. It persists users to MariaDB, caches sessions in Redis, and publishes email events to RabbitMQ. Object-storage responsibilities are handled by the separate samakia-minio service.

⁠Technology & Stack

  • Language/Runtime: Node.js 20 (Alpine base)
  • Framework: NestJS 11 (HTTP), TypeORM 0.3 (MariaDB)
  • Messaging: RabbitMQ (amqplib)
  • Cache: Redis (ioredis)
  • Logging: Pino
  • Build: webpack-cli
  • Dockerfile: ops/docker/samakia-auth.Dockerfile

⁠Purpose

  • Provide OIDC endpoints for the Samakia web app and other clients.
  • Manage user lifecycle (register, activate, update, delete).
  • Emit email notifications via RabbitMQ for the mail worker to deliver.

⁠Architecture

flowchart TD
  subgraph Ingress
    I[NGINX Ingress\n auth.samakia.net]
  end
  I --> A[Auth Service\n(NestJS)]
  A -->|JWT/RS256| J[JWKS /.well-known]
  A -->|CRUD| DB[(MariaDB\nDB_DATABASE_AUTH)]
  A -->|Sessions, rate limit| R[(Redis)]
  A -->|mail.send| Q[(RabbitMQ)]
  A -.->|OIDC clients| C[Dynamic Registration]
  A -.X M[(MinIO App)]:::note

  classDef note fill:#f5f5f5,stroke:#bbb,color:#333
  class M note

⁠Configuration

Environment is loaded via @samakia-platform/config. In prod, make docker-publish sources values from Vault export (vault.prod.json). Dynamic client registration endpoint is /auth/clients (advertised in discovery as registration_endpoint).

Config highlights:

  • AUTH_REFRESH_TOKENS_ENABLED enables refresh tokens in prod; TTLs controlled by AUTH_ACCESS_TOKEN_TTL_SECONDS and AUTH_REFRESH_TOKEN_TTL_SECONDS.
  • AUTH_AUTO_ACTIVATE_ON_LOGIN (boolean) optionally activates a user after successful password verification (migration aid).
  • Database name is service-scoped: DB_DATABASE_AUTH (legacy DB_DATABASE is ignored).
  • Standard deps: AUTH_PORT, AUTH_JWT_*, REDIS_*, RABBITMQ_*, SSO keys like GOOGLE_*.

⁠HTTP Endpoints

Base path: /auth (Ingress host auth.samakia.net). Selected routes:

  • OIDC Well-known
    • GET /.well-known/openid-configuration (authorization_endpoint = https://auth.samakia.net/auth/authorize)
    • GET /.well-known/jwks.json
  • Auth flows
    • POST /auth/register
    • POST /auth/clients (OIDC dynamic client registration)
    • POST /auth/activate
    • GET /auth/authorize
    • POST /auth/authorize
    • POST /auth/token
    • GET /auth/google/start
    • GET /auth/google/callback
    • POST /auth/password/reset/start
    • POST /auth/password/reset/complete
  • Users
    • POST /users
    • GET /users
    • GET /users/:id
    • PATCH /users/:id
    • DELETE /users/:id
⁠OIDC Dynamic Registration
  • Register: POST /auth/clients with metadata (redirect_uris, token_endpoint_auth_method, grant_types, ...).
  • Read: GET /auth/clients/:clientId with registration access token.
  • Update/Delete supported per spec. Client secrets stored hashed; public clients supported (none).

⁠Interworking

  • MariaDB: primary user storage
  • Redis: caching tokens/user lookups
  • RabbitMQ: publishes to queue ${RABBITMQ_MAIL_QUEUE} (default mail.send)
  • Object storage: handled by samakia-minio service

⁠Sequence (Registration → Activation)

sequenceDiagram
  participant U as User
  participant W as Web (Next.js)
  participant A as Auth (OIDC)
  participant Q as RabbitMQ
  participant M as Mail Worker

  U->>W: Submit registration
  W->>A: POST /auth/register
  A->>Q: Publish mail.send { activationToken }
  M->>Q: Consume mail.send
  M->>U: Send activation email (SMTP)
  U->>A: POST /auth/activate { token }
  A-->>U: 200 Activated
⁠Login With Optional Auto-Activation
sequenceDiagram
  participant B as Browser
  participant A as Auth
  Note over A: AUTH_AUTO_ACTIVATE_ON_LOGIN=true
  B->>A: POST /auth/authorize (username/password)
  A->>A: Verify credentials
  A->>A: If not active → activate
  A-->>B: 302 to redirect_uri with code
  B->>A: POST /auth/token (code)
  A-->>B: { access_token, refresh_token? }

⁠Deployment

  • Kubernetes: ops/k8s/base/deployments/samakia-auth.yaml, Service + Ingress auth.samakia.net.
  • Image: docker.io/<namespace>/samakia-auth:<tag>
  • Ports: 3100/tcp

⁠Tests

  • Unit: Jest specs under apps/samakia-auth/src/app/**.spec.ts
  • Load: make k6-auth (k6 flow via Docker)

⁠Runbook

  • Restart: kubectl rollout restart deploy/samakia-auth -n samakia-platform
  • Logs: kubectl logs deploy/samakia-auth -n samakia-platform -f

Tag summary

Content type

Image

Digest

sha256:862440f23…

Size

59.5 MB

Last updated

about 1 year ago

docker pull ankouros/samakia-auth