Identity Service
@nx/identity is the JWKS issuer for the BANA platform — it signs JWTs (ES256) and exposes public keys at /jw-certs. All other services act as VerifierApplication and trust tokens issued here. The package owns user identity, credentials, employees, customers, roles, permissions, and policy definitions.
1. Quick Reference
| Property | Value |
|---|---|
| Package | @nx/identity |
| Code | SVC-00010-IDENTITY |
| Type | Microservice (JWKS issuer) |
| Runtime | Bun |
| Base Class | IssuerApplication |
| Location | packages/identity |
| Base Path | /v1/api/identity |
| Dev Port | 31010 |
| Container Port | 3000 (external 31010) |
| Snowflake ID | 1 |
| DB Schema | identity (User, UserCredential, UserIdentifier, UserProfile, Role, Permission, PolicyDefinition, Customer, Employee + Configuration) |
| JWKS endpoint | GET /jw-certs |
| JWT algorithm | ES256 |
| Binding Namespace | @nx/identity |
2. Purpose & Scope
| Included | Excluded |
|---|---|
| User CRUD + identifier (email/phone/username) + credential (BASIC/OAuth) | OAuth2 federation (declared scheme; no provider yet) |
| JWT issuance (ES256) — sign-in / sign-up / change-password / refresh | Per-resource ABAC (only Casbin RBAC) |
| Email OTP + SMS OTP (verify email, verify phone, forgot password, link account) | Multi-tenant key isolation (single signing key) |
| Casbin-based RBAC (Role × Permission × PolicyDefinition) | Revocation list / token blocklist |
| Fixed system roles + custom roles per merchant | Session storage (stateless JWT only) |
| Customer + Employee specialized profiles | Identity provider chaining |
| Mail templates + SMS templates (EN/VI) |
3. Tech Stack
External:
| Library | Purpose |
|---|---|
@venizia/ignis | IoC + DI + base classes |
@venizia/ignis-helpers | Logger, Redis helper, password hashing |
hono + @hono/zod-openapi | HTTP + OpenAPI generation |
@scalar/hono-api-reference | Scalar viewer at /doc |
drizzle-orm + pg | DB |
casbin | RBAC engine |
nodemailer | Email transport |
bullmq + ioredis | Mail/OTP queue (when Redis configured) |
Internal:
| Package | Purpose |
|---|---|
@nx/core | Schemas, repositories, IssuerApplication, JWKSIssuerTokenService, MQSMSComponent, MailComponent |
4. Project Structure
packages/identity/
├── src/
│ ├── application.ts # IssuerApplication subclass
│ ├── index.ts # bootstrapApplication()
│ ├── migrate.ts # bootstrapMigration()
│ ├── common/
│ │ ├── constants.ts # 15+ enums (UserIdentifierSchemes, OTPDefaults, MailValidationFields, …)
│ │ ├── keys.ts # BindingKeys (Redis/BullMQ, OTP_SENDER, SMS_TEMPLATE_ENGINE)
│ │ ├── rest-paths.ts # 12 REST paths
│ │ └── … # mail/sms/otp helpers
│ ├── components/
│ │ ├── mail/ # NodemailerComponent (SMTP)
│ │ ├── sms/ # ApplicationSMSComponent (VN Pay SMS)
│ │ └── websocket/ # ApplicationWebSocketComponent (Redis-backed)
│ ├── controllers/ # 8 folders → 12 controllers
│ ├── datasources/ # PostgresCoreDataSource
│ ├── migrations/processes/ # 7 seed processes
│ ├── models/ # zod request/response schemas
│ ├── repositories/ # re-exports + identity-local repos
│ └── services/ # 15 services (top-level + otp/ + policy-definition/)
├── package.json
└── tsconfig.json5. Architecture
Detail: see Architecture.
6. Domain Snapshot
Full ERD + per-entity tables: see Domain Model.
7. Surface Summary
REST controllers — full reference rendered live from /v1/api/identity/doc/openapi.json (live spec — Scalar viewer at /doc, gateway portal):
| Controller | Base path | Notes |
|---|---|---|
IdentityAuthController | /auth | sign-in/up, change-password, refresh, OTP flows (verify email/phone, forgot password, link account) |
UserController | /users | merchant-scoped CRUD |
RoleController | /roles | priority-aware CRUD; system roles immutable |
PermissionController | /permissions | catalogue read; writes via migration seed |
PolicyDefinitionController | /policy-definitions | low-level RBAC edges |
OrganizerPolicyDefinitionController | /policy-definitions/... | organizer-scoped policy targeting |
RolePolicyDefinitionController | /policy-definitions/... | role-scoped policy targeting |
UserPolicyDefinitionController | /policy-definitions/... | user-scoped policy targeting |
CustomerController | /customers | customer profile |
EmployeeController | /employees | employee profile + organizational mapping |
UserIdentifierController | /user-identifiers | email/phone/username CRUD |
UserConfigurationController | /user-configurations | per-user settings |
Async surface — full reference in API Events:
| Direction | Channel | Notes |
|---|---|---|
| Outbound | WebSocket | identity events broadcast (auth state, role/policy changes) |
| Outbound | Mail (Nodemailer) | verification, forgot-password, welcome, password-changed |
| Outbound | SMS (MQ-SMS) | phone-auth, add-phone OTP |
Identity is not a Kafka producer or consumer — it is the auth boundary; sister services pull JWKS over HTTP.
8. Components
| Component | File | Purpose |
|---|---|---|
NodemailerComponent | src/components/mail/component.ts | SMTP transport + template registry |
ApplicationSMSComponent | src/components/sms/sms.component.ts | VN Pay SMS via MQSMSComponent; loads config from DB at startup |
ApplicationWebSocketComponent | src/components/websocket/component.ts | Redis-backed emitter (single/cluster) |
9. Services (15 total)
Top-level (8) + OTP sub-services (3 + base) + policy-definition sub-services (4 + base).
| Service | File | One-liner |
|---|---|---|
AuthenticationService | authentication.service.ts (369 lines) | Sign-in, sign-up, change-password, refresh, generate-token (JWT ES256) |
UserService | user.service.ts (535 lines) | User aggregate CRUD: identifier + credential + profile + role assignment |
RoleService | role.service.ts (409 lines) | Role CRUD with priority validation + scope resolution |
PermissionService | permission.service.ts | Permission catalogue management |
ConfigurationService | configuration.service.ts | System config (mail, SMS, OTP) read/write |
CustomerService | customer.service.ts | Customer profile CRUD |
EmployeeService | employee.service.ts | Employee profile + org mapping |
UserConfigurationService | user-configuration.service.ts | Per-user setting defaults |
| OTP | services/otp/ | |
BaseOTPBasedMFAService | base | Abstract: hash + TTL + attempt limit + cooldown + daily quota |
EmailOtpService | email-otp.service.ts | Email OTP delivery + verification |
PhoneOtpService | phone-otp.service.ts | SMS OTP delivery + verification |
VerifyEmailService | verify-email.service.ts | Email verification flow (code → token) |
VerifyPhoneService | verify-phone.service.ts | Phone verification flow |
ForgotPasswordService | forgot-password.service.ts | OTP → reset-token → new password |
LinkAccountService | link-account.service.ts | Add phone/email to authenticated account |
| Policy | services/policy-definition/ | |
BasePolicyDefinitionService | base | Abstract policy CRUD by subject type |
UserPolicyDefinitionService | concrete | User → Role/Permission/Organizer/Merchant edges |
RolePolicyDefinitionService | concrete | Role → Permission/User edges |
OrganizerPolicyDefinitionService | concrete | Organizer-scoped edges |
PermissionPolicyDefinitionService | concrete | Permission-scoped edges |
10. Repositories (12)
| Repository | Source | Notes |
|---|---|---|
UserRepository | identity-local | Aggregate-aware (identifier + credential atomic create) |
UserIdentifierRepository | identity-local | Lookup by (scheme, value) — sign-in entry point |
UserCredentialRepository | @nx/core | Hashed credential persistence (Bun.password) |
UserProfileRepository | @nx/core | 1:1 with User |
UserConfigurationRepository | @nx/core | Per-user settings |
RoleRepository | @nx/core | Priority + scope semantics |
PermissionRepository | @nx/core | Catalogue |
PolicyDefinitionRepository | @nx/core | RBAC edges (variant: GROUP/PERMISSION) |
CustomerRepository | @nx/core | — |
MerchantRepository | @nx/core | Cross-package read |
OrganizerRepository | @nx/core | Cross-package read |
ConfigurationRepository | @nx/core | Mail/SMS/OTP system configuration |
11. Entry Points
| File | Purpose |
|---|---|
src/index.ts | Service entry → bootstrapApplication() |
src/migrate.ts | Migration entry → bootstrapMigration() |
src/application.ts | Application extends IssuerApplication |
12. Configuration
Env vars + seeded data: see Configuration.
13. Operations
Deployment + observability + security + runbook: see Operations.
14. Related Pages
Concepts — why/how:
- Architecture
- Domain Model
- Integration — sister services pull JWKS, request permissions
Reference — lookup:
- API Events — mail/SMS/WS surfaces
- Configuration
- Operations
- REST endpoints — live OpenAPI at
/v1/api/identity/doc/openapi.json(live spec — Scalar viewer at/doc, gateway portal)
Features — deep dives:
- Authentication — sign-in / sign-up / change-password / refresh
- User Management — User aggregate + Employee
- Customer Management
- RBAC — Role + Permission + PolicyDefinition + Casbin
- MFA & OTP — Email/SMS OTP flows
Decisions: