Skip to main content

Identity Service

Vecton's identity backend is the OAuth issuer and authentication source of truth for the entire platform. Every login, refresh, password reset, two-factor verification, tenant membership change, and service-account API key flows through this service.

Service surface

RepositoryTechRole
main/main-identity-backendLaravel 12 + Passport 13 + PHP 8.2OAuth issuer, user CRUD, tenant memberships, 2FA, sessions
main/main-identity-frontendVue 3 + Vuetify + PiniaLogin UI, account settings, admin pages, tenant switcher

Identity does NOT own per-tenant business data (CRM, warehouse, webshop) — those live behind the dedicated tenant services. It owns the questions "who is this user", "what tenants do they belong to", and "what may they do here".

Refactor state (2026-05-08)

The service was hardened across F0 through F9 in a focused identity refactor sprint. The scope and final state of each phase:

PhaseThemeDeliverable
F0Security criticalPKCE, hashed client_secret, hashed system-token cache, refresh rotation + reuse detection, removed EnsureSessionFromToken and SkipTrustedClientAuthorization, OAUTH_CLIENT_SECRET env-required, frontend localStorage→cookie, nginx security headers, open-redirect guard, OTel propagation tightened
F1Frontend cleanup~60 dead Vuexy components and ~30 deps removed, vuexy-vuejs-admin-templatevecton-identity-frontend, MSW infra eliminated
F2Mocks outMath.random() fake progress → indeterminate state, Cypress localStorage keys aligned, localhost hardcodes env-driven
F3Controller splitUserController (985 LoC) → User + Role + Permission, Admin\TenantController (906 LoC) → Tenant + Member + Credentials, ProfileController (747 LoC) → Profile + Permissions + Authorizations, plus PermissionResolver and UserAccessPolicy services
F4Menu structurei18n nav keys (en/hu/de), backend-driven useAuthStore.isSystemAdmin getter
F5OpenAPI + SDKScramble (dedoc/scramble), @hey-api/openapi-ts + @hey-api/client-axios, hand-curated src/types/api.ts, : any count 95 → 19, extractApiError/getErrorStatus/getErrorFieldErrors/isAxiosError
F6Backend hardeningPer-action Gate::define + IdentityPolicy base + 5 child policies, mass-assignment guard on is_system_admin, atomic incrementFailedAttempts, hashed 2FA email codes + recovery codes, /api/health real probe, last-owner check, impersonation TTL + audit marker, tenant-destroy cascade revocation, cross-tenant role-injection guard, DB indexes, audit:prune + sessions:prune cleanup commands
F7Missing featuresPOST /auth/logout-all, 30-day GDPR account deletion, email-change session revocation, POST /auth/switch-tenant, service-account TTL + scopes, RabbitMQ EventPublisher + PublishUserLifecycleToBroker, frontend idle-timeout composable
F8Tests8 new test files (27 tests) covering Application secret, UserSecurity atomicity, refresh rotation, identity Gates, cross-tenant role injection, logout-all, tenant switch, account deletion
F9DocumentationThis rewrite

The full audit list lives at main/IDENTITY_AUDIT_FINDINGS.md (316 findings: 51 critical / 106 high / 134 medium / 25 low).

  • OAuth flows — the issuer surface (PKCE, auth-code, refresh rotation, system tokens, introspection).
  • Security — authentication chain, authorisation (Gate::define + Policies), audit log, exception render.
  • Multi-tenant — memberships, role assignment guards, tenant switch.
  • Service accounts — non-human principals, API keys, scopes, TTL defaults.
  • Events — the RabbitMQ envelope identity publishes for tenant-services to subscribe to.
  • Controller split — the F3 controller-bontás story: what moved where and why.