FAQs

Q: What GDPR actions does eq-user-service support?

The service supports: (1) GDPR Export — export all user PII as an Excel file stored in S3, triggered via Step Functions; (2) GDPR Delete — anonymize all personal data after a configurable retention period, also via Step Functions. Soft-delete (status=DELETED) happens immediately; physical anonymization runs when the retention period expires and the delete Step Function is triggered.

Q: What happens to a user’s data when their account is deleted?

The user record is immediately soft-deleted (status=DELETED). A retention period (default 30 days, configurable) must expire before physical deletion. When the gdpr.delete Step Function runs, it anonymizes all PII across users, addresses, payment profiles, and consents, then hard-deletes all lists. Other services (orders, etc.) that reference the userId receive anonymized identifiers.

Q: How does guest-to-registered user merge work?

If isUserMergeEnabled=true on the instance, calling POST /v1/lists/migrate with the guest identifier and the registered user identifier migrates all guest lists to the registered account. The guestListsMerged EventBridge event is published. The guest user record itself is then marked inactive/deleted.

Q: Can multiple SSO providers be configured for a single instance?

Yes. pluginConfig supports cognito, oidc, and saml simultaneously. The provider to use is selected at login via the provider query param (GET /v1/auth/sso/login?provider=cognito|oidc|saml). The IamInvoker routes the operation to the correct connector.

Q: What happens when the Typesense circuit breaker opens?

The circuit breaker (@equinox/circuit-breaker-redis) monitors Typesense call failures. After CB_FAILURE_THRESHOLD consecutive failures (default: 5 in dev, 10 in prod), the circuit transitions to OPEN state. In OPEN state, all Typesense calls fail immediately (fast-fail) without hitting the Typesense host — MongoDB is used as fallback for reads. After CB_TIMEOUT_SECONDS (default: 60/120 sec), the circuit moves to HALF-OPEN and allows up to CB_HALF_OPEN_MAX_REQUESTS probe requests. If those succeed, the circuit closes. Circuit state is persisted in Redis so it survives service restarts.

Q: How are plugins loaded at runtime?

The service uses @equinox/plugin-registry to load validator and lifecycle extensions. Plugins can come from three sources: (1) Lambda Layer / npm package — package name must be in ALLOWED_PLUGIN_PACKAGES; (2) Local/EFS JS file — path prefix must be in ALLOWED_PLUGIN_FILE_PREFIXES; (3) S3 JS file — bucket must be in ALLOWED_PLUGIN_S3_BUCKETS. Plugins are loaded on first request for the extensionType key and cached in memory. The pluginConfig on the instance document specifies which plugin packages/paths are active for each extension point. Use USER_VALIDATOR_LAYER_ARN for Lambda layer delivery.

Q: What does USER_USE_INMEMORY=true mode do and when should it be used?

When USER_USE_INMEMORY=true, the service starts without connecting to MongoDB, Redis, EventBridge, or Typesense. All repositories are replaced with in-memory stub implementations. This mode is intended for local development and CI pipelines where external services are unavailable. It should never be enabled in staging or production — data is not persisted between restarts and events are not published.

Q: How is the GDPR retention period configured?

The retention period before physical anonymization is not an instance property — it is a Step Function input parameter passed when the gdpr.delete Step Function is triggered. The gdpr.delete.initialize action receives a retentionDays parameter (default varies by deployment) and calculates the expiryDate as now - retentionDays. Only users with status=DELETED and deletedAt < expiryDate are included in the anonymization batch.


Revision History
2026-08-04 | JP – Created the page and added the content.