Skip to main content

Test mode

identsphere-server can run in a sandbox / test mode that mirrors how Stripe's test environment behaves: the same binary, the same Postgres schema, the same license — but no real email is delivered, and responses are tagged so callers can tell at a glance which environment they're hitting.

This is intended for two use cases:

  1. CI and integration tests — your test suite needs registration, password reset, and email-OTP flows to work end-to-end without ever sending a real email.
  2. Customer-facing sandboxes — give customers a sandbox URL where they can poke around their integration with their real license and real data shape, without risk of leaking notification mail.

Enabling test mode​

Set the env var when you start the server:

IDENTSPHERE_TEST_MODE=true \
DATABASE_URL=postgres://... \
IDENTSPHERE_JWT_SECRET=$(openssl rand -base64 48) \
identsphere-server

Accepted truthy values: 1, true, TRUE, yes. Anything else (including unset) keeps test mode off — production deployments need no action.

On start-up the server logs a WARN-level line:

IDENTSPHERE_TEST_MODE=true — outbound email is suppressed and responses are tagged test_mode.
Do not use this configuration in production.

What changes when test mode is on​

Outbound email is silently swallowed​

Every email the SDK would have sent — registration verification, password reset, magic-link, MFA recovery — is short-circuited at the EmailSender layer. The configured transport is wrapped in TestModeSender, which logs a "test mode: would have sent ..." line and returns success without invoking the wrapped transport.

This holds even if you have SMTP credentials configured. The intent is that a misconfigured sandbox can never accidentally leak mail to real customer addresses.

Webhooks fall back to test endpoints​

If IDENTSPHERE_TEST_MODE=true and a webhook target is not in your sandbox configuration, the delivery is logged but not dispatched. Configure test-only webhook targets per-webhook if you need to exercise that flow in CI.

Audit logs are tagged​

Audit entries written while test mode is on carry mode = "test" in the JSONB metadata column. This lets you keep test traffic in the same audit table as production traffic if you choose, and filter by mode at query time:

select * from identsphere_audit_log
where metadata ->> 'mode' = 'test'
order by created_at desc;

Response envelopes include meta.test_mode​

A handful of high-signal endpoints (the session response, the user profile response, and the audit log read endpoint) include a meta.test_mode = true field in the JSON envelope. Client SDKs can surface a "Sandbox" banner in the UI based on that flag without having to track which environment they pointed at separately.

License verification still runs​

The license check happens exactly as it does in production. Test mode is not a way to bypass license verification — customers are expected to validate that their license works in test mode the same way it would in production. A given license key behaves identically in either mode.

The test+*@example.com short-circuit​

Independent of the IDENTSPHERE_TEST_MODE toggle, any recipient address matching the pattern test+*@example.com (e.g. [email protected], [email protected]) is always routed to fake delivery. The match is case-insensitive.

This is the seam test suites hook into: a test that needs to drive the "forgot password" flow can pass [email protected] as the recipient and assert against the "test mode: would have sent ..." log line without having to flip a global flag on the sender.

Verifying test mode​

After starting the server with IDENTSPHERE_TEST_MODE=true, register a user and hit GET /v1/auth/session. The response envelope should include:

{
"user": { "...": "..." },
"meta": {
"test_mode": true
}
}

If meta.test_mode is missing or false, the env var didn't take — check capitalization and the server start-up log line.

Going back to production​

Unset the env var (or set it to anything that isn't a truthy value) and restart the server. There is no on-disk state associated with test mode; the toggle is purely a run-time flag. Audit rows previously tagged mode = "test" remain in the database — they're a permanent record of what ran in which mode and are not retroactively cleared.

  • Environment variables — full list, including IDENTSPHERE_TEST_MODE.
  • License keys — how to install and verify a license key.
  • Email senders — how to wire SMTP or a custom transport. Both are wrapped in TestModeSender when IDENTSPHERE_TEST_MODE is on.