Third-party integrations — one vendor account per environment

Neon Law Navigator talks to a handful of external services. They fall into two kinds:

The full catalog below lists every external service the application code itself dials. Purely operational layers that sit above the env-var interface — Doppler (secret values), DNSimple (DNS) — are deliberately out of scope here: they are not code dependencies, and a fork can swap them freely.

Why two accounts

Deployment selector and credential separation

The narrow deployment selector is exact: NAVIGATOR_ENVIRONMENT=staging selects staging, while empty or unset selects production. Mixed case, whitespace, and every other nonempty value fail configuration parsing. It controls infrastructure safety checks only.

Both sources use the same application variable names (DOCUSIGN_*, XERO_*, …). The operator also sets NAVIGATOR_CREDENTIAL_ENVIRONMENT to staging or production; startup rejects a mismatch. Cloud staging receives the non-production set from a staging-labeled Kubernetes Secret, while production receives a distinct production Secret.

Normal staging requires real non-production SendGrid and DocuSign demo configuration. Only the explicit NAVIGATOR_CI_HARNESS=1 staging test surface may use in-process fakes; production rejects that flag.

Current integrations

ServicePurposeKindEnv prefix
DocuSignE-signaturebindingDOCUSIGN_*
XeroAccounting / billing (ACCREC invoices)bindingXERO_*
Restate CloudDurable workflow execution (workflows-service)platformRESTATE_*
Google CloudStorage, Cloud SQL, OIDC, archiveplatformNAVIGATOR_*, GOOGLE_OAUTH_*, DATABASE_URL
Vertex AIA2A agent-router LLM (Gemini Flash in prod)platformNAVIGATOR_GCP_*
SendGridOutbound + inbound emailplatformSENDGRID_*

Notes:

When you add a binding vendor, follow the two-account shape: create the sandbox + production accounts, add a <VENDOR>_* block to .env.example that references this convention, put sandbox credentials in .env and production credentials in .env.production, and fall back to a stub when the vendor is unconfigured. A platform service needs only its own <VENDOR>_* block and a stub/local equivalent (Garage, in-cluster Postgres, the NullRouter) so a fresh checkout boots and self-tests without any cloud account.

Not in this catalog — and why

A few external-looking things are deliberately absent. They are not third-party SaaS vendors, so the per-environment account convention does not apply to them: