Sandbox and production
Sandbox and production use different issuers, credentials and sign-in requirements, and are labelled in text everywhere. Nothing issued in one is trusted in the other.
Side by side
| Sandbox | Production | |
|---|---|---|
| Sign-in | Passkey, enterprise SSO (OIDC), or the labelled sandbox guest. | Passkey or enterprise SSO (OIDC). Sandbox guests get 403 on any production action. |
| Workload attestation | sandbox_token (browser-approved, single use, 30 minutes) or oidc_jwt. | oidc_jwt only. A database constraint forbids sandbox attestation in production. |
| Signing keys | Software-backed keys under dedicated sandbox test roots. | Hardware-protected keys provisioned with Sectigo PKI Operations. Production deployments refuse software signing keys. |
| Root provisioning | Automatic when you create a space. | Through a separate PKI operator principal under ceremony control; the online service cannot sign roots. |
| CA validity | Root 90 days, issuing CA 60 days. | Root 10 years, issuing CA 2 years. |
| Subject label | Mutual Trust SANDBOX TEST Root · … | Mutual Trust Production Root · … |
| Workload URI | urn:mutualtrust:workload:sandbox:… | urn:mutualtrust:workload:production:… |
| Billing | Free; consumes zero connections. | Each (production service, consuming organization) pair with an active or suspended grant consumes one connection. |
| Stripe | Test mode. | Live mode, only in the production deployment. |
Sandbox guest sign-in
POST https://app.mutualtrust.io/auth/sandbox creates a labelled guest user (“Sandbox guest”) and a 12-hour session. It is rate-limited to 20 sign-ins per hour per client IP. GET /v1/me returns an environment_notice for guests: “Sandbox guest: production actions are unavailable.” Check availability with GET /auth/config:
{
"oidc_configured": true,
"sandbox_guest": true
}How environments are kept apart
- Every space, service, workload, gateway, grant and certificate records its environment; issuance refuses a workload/issuer environment mismatch, and the signer re-checks it.
- Gateways reject manifests whose environment differs from the one pinned at pairing, and deny certificates whose workload URI names another environment (
malformed_san). - Sandbox and production use separate signer keys; production deployments reject software signing keys and sandbox chains.
- Stripe live keys are refused outside the production deployment (
billing_misconfigured).
Production onboarding
An organization creates production spaces and services once three things are true. The portal shows them as a checklist under Organization → Production readiness, and GET /v1/organizations/{id}/production-readiness returns the same checklist. Until then, creating a production space or service returns 403 production_onboarding_incomplete with a missing list.
- A verified domain. An organization owner proves control of a domain the organization owns (below). The portal labels it Domain control verified.
- Approved production access. Request it from the portal and choose the assurance policy:
domain_control(default): a verified domain is enough.legal_entity: Mutual Trust staff also verify your legal entity (legal name, registration number and jurisdiction). The portal labels it Legal entity verified, separately from domain control.
- An active entitlement. Either an active production subscription through billing, or approved invoice terms set by Mutual Trust finance for customers billed by invoice. Invoice terms are effective-dated; the larger of the two sets your production connection capacity.
Production trust spaces are provisioned by Sectigo PKI Operations on hardware-protected keys once your organization is ready. Root provisioning runs under ceremony control through a separate PKI operator principal, so the online service never signs roots. If the space is not provisioned yet, the portal says so and nothing else is needed from you.
Creating a production space or service is a high-risk change: it needs a sign-in or passkey re-authentication from the last 15 minutes (step-up).
Sandbox work does not carry over: production uses new issuers, new gateway pairings and new workload credentials, so nothing from a sandbox can reach a production API.
Domain control verification
Add a domain under Organization → Verification (or POST /v1/organizations/{id}/domains). Mutual Trust gives you a random token; publish it as a DNS TXT record:
_mutualtrust-challenge.example.com. 300 IN TXT "mutualtrust-domain-verification=<token>"- Mutual Trust looks the record up over DNS-over-HTTPS through two independent public resolvers (Cloudflare and Google). Both must return the token before the domain is verified; when they disagree or one is unreachable, the check is retried. Only these two fixed resolver endpoints are ever contacted.
- Checks run automatically with backoff (1, 5, 15 and 30 minutes, then hourly up to every 6 hours). Check now in the portal (
POST /v1/organizations/{id}/domains/{domain_id}/check) runs one immediately. - States:
pending(waiting for the record),verified,failed(the record did not appear within 7 days, or another organization already verified the domain) andexpired. Check now retries a failed or expired domain. - Verification lasts 90 days. Mutual Trust re-checks the record 7 days before expiry; keep the TXT record in place so the domain stays verified without any action from you.
- A domain can be verified by one organization at a time. Public names only: IP addresses and internal suffixes such as
.localor.internalare refused.
Production service readiness
Each production service shows a readiness checklist on its page and in GET /v1/services/{id} (readiness, first_failing_step). A production connection is verified only when every step passes; the portal names the exact step that fails and what to do next.
- Organization verified for production: the onboarding checks above.
- Private trust anchor provisioned by Sectigo PKI Operations.
- Service owner assigned: a member who is a service owner, trust administrator or owner.
- Gateway paired with a scoped production connector credential.
- Policy applied: the gateway acknowledged the current policy revision.
- Server TLS configured: the gateway reports its TLS mode and server certificate expiry in its signed acknowledgments, or a service owner records an attestation in the portal (audited).
- Direct access to the origin is closed: a passing origin check from the last 90 days.
- Partner accepted through its own identity provider or passkey account, never a sandbox guest session.
- Partner bound an OIDC workload identity from an approved workload issuer.
- Real allowed call verified: a receipt for an allowed request over mutual TLS under an active grant.
- Denied control request observed: a receipt for a request the policy denied, with a verified client certificate.
Checking that the origin is closed
The gateway only protects an API that cannot be reached around it. Start a check on the service page (POST /v1/services/{id}/origin-checks); the portal shows a one-time command. Run it from a machine outside your private network:
mt gateway check-origin --url https://orders.internal.example.com:8443 --check och_... --token mtoc_...- The CLI connects straight to the origin, without the gateway or a client certificate. The check passes when the connection is refused, times out, the name does not resolve, the TLS handshake is rejected, or the origin answers HTTP
401,403,407,421,495or496. Any other answer means the origin is reachable directly and the step fails. - The CLI signs its result with HMAC-SHA256 keyed by the one-time check token and posts it to Mutual Trust. The token is valid for one hour and one result; only its hash is stored.
- Without
--checkand--tokenthe command runs the same probe and prints the result without recording it.