Skip to main content

iam-service

Catalog entry · Enterprise Architecture §6 · Security & Tenancy · Deep bundle: services/iam-service/

1. Purpose

Authoritative source of "who a principal is" for the entire Melmastoon platform. Owns credentials, sessions, devices, MFA factors, API keys, and federated identity links. Issues short-lived JWTs consumed by every other service. Does not own profile data, role assignments, organizational membership, or property scoping — those belong to tenant-service.

2. Bounded Context

FieldValue
ContextIdentity & Access
TypeGeneric subdomain
Strategic patternOpen Host Service (OHS) for JWT validation
Upstream ofevery other service (JWT consumer)
Downstream oftenant-service (consumes membership lifecycle), KMS, OIDC/SAML IdPs

3. Aggregates

AggregateRootNotes
UserUserIdentity-side projection only (no profile, no roles).
CredentialUser (child)Password hash, breach-list state, rotation history.
SessionSessionRefresh-token family, device binding, AMR.
DeviceDeviceHardware fingerprint + Ed25519 public key; offline binding cert.
MFAFactorUser (child)TOTP / WebAuthn / recovery codes.
APIKeyAPIKeyHashed key, scopes, tenant binding.
ExternalIdentityUser (child)OIDC / SAML link records.

4. Top Responsibilities

#ResponsibilityDetail
1RegistrationEmail + password, magic link, social SSO, JIT from SAML.
2LoginPassword / SSO (OIDC, SAML) / WebAuthn / magic link.
3Token issuanceAccess JWT (EdDSA Ed25519, 15 min) + rotating refresh (30 d online / 7 d offline).
4MFATOTP, WebAuthn, recovery codes; adaptive challenge via ai-orchestrator-service.
5Device bindingLong-lived Ed25519 device cert for Electron desktop offline.
6API key lifecycleHashed at rest (argon2id), prefix-only logging, scope-bound.
7JWKS publication/.well-known/jwks.json via CDN, 5-min TTL, rotation overlap ≥ 2 days.
8GDPR erasureParticipates in saga; purges credentials/sessions/devices/MFA on guest request.

5. REST Excerpt (top 5 endpoints)

MethodPathPurpose
POST/api/v1/auth/registerCreate User + Credential; emit melmastoon.iam.user.registered.v1.
POST/api/v1/auth/loginVerify credential; issue access + refresh; may return mfa_required.
POST/api/v1/auth/refreshRotate refresh token; detect reuse → revoke entire family.
POST/api/v1/auth/devices/{id}/bind-offlineIssue Ed25519 device certificate (≤ 7 d) for Electron desktop.
GET/.well-known/jwks.jsonPublic signing keys (CDN-cached).

Full surface in API_CONTRACTS.md.

6. Top Events

Published

SubjectRetentionTrigger
melmastoon.iam.user.registered.v1regulatedSuccessful registration.
melmastoon.iam.user.login_succeeded.v1operationalLogin (any factor) success.
melmastoon.iam.user.login_failed.v1securityLogin failure (any reason).
melmastoon.iam.user.mfa_enrolled.v1regulatedMFA factor added.
melmastoon.iam.session.refreshed.v1operationalRefresh-token rotation.
melmastoon.iam.session.revoked.v1securityLogout, lockout, reuse, admin revoke.
melmastoon.iam.device.registered.v1operationalNew device record.
melmastoon.iam.device.bound_for_offline.v1regulatedOffline cert issued (Electron).
melmastoon.iam.apikey.issued.v1regulatedAPI key created.
melmastoon.iam.apikey.revoked.v1securityAPI key revoked.
melmastoon.iam.password.reset_requested.v1securityPassword reset initiated.
melmastoon.iam.password.reset_completed.v1securityPassword successfully reset.
melmastoon.iam.user.locked.v1securityAccount locked (lockout / admin).

Consumed

SubjectEffect
melmastoon.tenant.created.v1Provision super-tenant-admin user.
melmastoon.tenant.deleted.v1Revoke all sessions / API keys for that tenant.
melmastoon.tenant.guest.erasure_requested.v1Purge identity rows; emit melmastoon.iam.user.erased.v1.

7. Storage

StoreUse
Cloud SQL (PostgreSQL 16 HA)All aggregates; RLS by tenant_id for tenant-scoped users; platform.* rows are tenant-less.
Memorystore (Redis)Session cache, refresh-token reuse window, rate limits, magic-link nonces.
Cloud KMSJWT signing key (EdDSA Ed25519), tenant device-CA root, breach-list HMAC secret.
Secret ManagerOIDC/SAML client secrets, breach-list API key, SMTP credentials.
FirestoreSync cursors for Device deltas (consumed by sync-service).

8. Multi-Tenancy

LayerEnforcement
DomainUser.tenantId? — nullable for platform.super_admin; required otherwise. JWT tid claim required for tenant-scoped endpoints.
ApplicationUse cases reject mismatched tid ↔ requested-tenant.
StoragePostgres RLS: USING (tenant_id = current_setting('app.tenant_id')::uuid OR tenant_id IS NULL) on tenant-aware tables.
EdgeAPI gateway sets app.tenant_id GUC on connection checkout via pgbouncer hook.

See Security & Compliance & Tenancy §3.

9. Hotel-Specific Concerns

  • Personas: front-desk staff, housekeeping, maintenance, GM, tenant owner, chain operator, platform admin, guest (email + magic link or social SSO for direct-bookings).
  • Electron desktop offline: A bound desktop install holds an Ed25519 device certificate signed by the tenant CA. Allows refresh-token rotation entirely offline for up to 7 days (configurable per tenant). See ADR-0003.
  • Property scope: iam-service issues a tenant-scoped JWT; per-property authorization is decided downstream by tenant-service against propertyId claims it injects on token mint.
  • Guest account vs staff account: distinct userType projection (staff | guest | platform_admin). Guests cannot acquire API keys or device-bind for offline.

10. Edge Cases

  • Brute-force lockout: 5 failures / 15 min → 15-min lockout; exponential to 120 min on repeated lockouts.
  • Refresh-token reuse → entire session family revoked; melmastoon.iam.session.revoked.v1 with reason='rotation_reuse'.
  • Device offline > grace period → certificate expires; next online contact forces re-bind.
  • SSO IdP downtime → circuit breaker; fallback to local password if tenant policy permits.
  • Magic-link replay → server-side single-use nonce; second use returns MELMASTOON.IAM.MAGIC_LINK_USED.
  • Concurrent MFA enrollment → optimistic lock on users.version; second writer retries.
  • Password breach-list match (HIBP) → reject at registration / reset; force change on existing user via melmastoon.iam.user.locked.v1 (reason='breached_credential').

11. Deep Bundle Index

FilePurpose
SERVICE_OVERVIEW.mdPurpose, dependencies, decisions, hotel concerns.
DOMAIN_MODEL.mdAggregates, invariants, domain events.
APPLICATION_LOGIC.mdUse cases, ports, orchestration.
API_CONTRACTS.mdREST surface, error codes.
EVENT_SCHEMAS.mdEvent JSON Schemas.
DATA_MODEL.mdPostgres DDL, RLS, indexes.
SYNC_CONTRACT.mdDesktop sync surface.
AI_INTEGRATION.mdAdaptive MFA + login anomaly.
SECURITY_MODEL.mdCrypto, RBAC/ABAC, audit, GDPR.
OBSERVABILITY.mdSLIs/SLOs, alerts, dashboards.
TESTING_STRATEGY.mdTest pyramid, scenarios.
DEPLOYMENT_TOPOLOGY.mdCloud Run, KMS, HA.
FAILURE_MODES.mdFailure catalog.
LOCAL_DEV_SETUP.mdCompose recipe, seed data.
SERVICE_READINESS.mdProduction gate checklist.
SERVICE_RISK_REGISTER.mdKnown risks.
MIGRATION_PLAN.mdMigration policy + tenant onboarding.