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 trial license issued by scripts/issue-trial-license.sh works 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. test+alice@example.com, test+anything+else@example.com) 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 test+suite+pwreset@example.com 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.
  • Trial license — how to issue a Scale-tier trial license for sandbox evaluation.
  • Email senders — how to wire SMTP or a custom transport. Both are wrapped in TestModeSender when IDENTSPHERE_TEST_MODE is on.