Skip to content

Deployment ​

Axiom is one Hono application over platform ports (apps/api/src/deps.ts). It runs on Cloudflare Workers today; a Node entry point and Google Cloud adapters exist for the GCP target. Business logic never imports platform types, so both runtimes enforce the same contract.

Hostnames ​

HostServesDeployed from
sectigoaxiom.com, app.sectigoaxiom.comLanding page, free public services, console, Control, approval pagesapps/web (static-assets Worker, SPA fallback)
api.sectigoaxiom.comREST API /v1/*, OAuth 2.1 server, JWKS, well-known metadataapps/api
gw.sectigoaxiom.comHosted Gateway proxy: /p/{project_id}/http/* and /p/{project_id}/mcpapps/api (same Worker)
mcp.sectigoaxiom.comAxiom MCP server at /mcpapps/api (same Worker)
docs.sectigoaxiom.comThis siteapps/docs (static-assets Worker)
sample.sectigoaxiom.comAcme Billing sample providerapps/sample-billing

api, gw and mcp are one Worker routed by hostname, so they share bindings and the single execution claim. In local development everything runs on localhost: the API on :8787 with the gateway under /gw and the MCP server at /mcp, the sample provider on :8788, the console on :5173 and the docs on :5174.

Runtime ports ​

ConcernCloudflare (now)GCP (target)
HTTP runtimeWorkersCloud Run (apps/api/src/platform/node/server.ts)
Relational storeD1 via kysely-d1Cloud SQL Postgres via Kysely PostgresDialect
Atomic execution claimConditional UPDATE … WHERE state = 'approved'Same statement
Queue (approval delivery, readback, webhooks, reconciliation, SIEM, monitors)Cloudflare Queues axiom-work with dead-letter queue axiom-work-dlqPub/Sub push subscription
Cache (rate limits, simulated connector records, MCP upstream era)KVA cache_entries table in Cloud SQL
Blobs (evidence exports, incident bundles)R2 bucket axiom-evidenceCloud Storage
Signing keysWorker secrets holding private JWKs (env:AXIOM_KEY_<ROLE>)Cloud KMS asymmetric keys (kms: references)
Scheduled maintenanceCron Trigger every 5 minutesCloud Scheduler → POST /internal/maintenance
EmailCloudflare Email Service bindingSendGrid
CASectigo SCM adapter (mock mode by default), dev CASame

Cloudflare ​

Local development ​

sh
git clone --recurse-submodules https://github.com/hassard0/sectigo-axiom.git
cd sectigo-axiom
npm install
npm run dev-keys -w @axiom/api          # local signing keys → apps/api/.dev.vars, apps/sample-billing/.dev.vars
npm run db:migrate:local -w @axiom/api
npm run db:migrate:local -w @axiom/sample-billing
npm run dev:api                          # http://localhost:8787
npm run dev:sample                       # http://localhost:8788
npm run dev:web                          # http://localhost:5173
npm run dev:docs                         # http://localhost:5174

dev-keys writes one ES256 key per signing role (identity, grant, observation, policy, event) and the sample provider's outcome key. These files are never committed.

Provision and deploy ​

  1. Create resources. node scripts/provision-cloudflare.mjs creates (or finds) the API's D1 database axiom, KV namespace axiom-cache, R2 bucket axiom-evidence and queues axiom-work and axiom-work-dlq, plus the sample provider's D1 database axiom-sample-billing, and writes their IDs into apps/api/wrangler.jsonc and apps/sample-billing/wrangler.jsonc. It is idempotent: only the all-zero placeholder IDs are replaced. The web app and docs need no resources.

  2. Set secrets for the API Worker, one private JWK per signing role:

    sh
    cd apps/api
    for role in IDENTITY GRANT OBSERVATION POLICY EVENT; do
      npx wrangler secret put AXIOM_KEY_$role --env production
    done

    Optional: AXIOM_SAMPLE_OUTCOME_JWK (the sample provider's public outcome key), AXIOM_CA_KEK (wraps the dev CA keys, required in production for the CA in mock mode), and the SCM settings below.

  3. Migrate and deploy the API: npm run db:migrate:remote -w @axiom/api, then npx wrangler deploy --env production in apps/api. The production environment binds api.sectigoaxiom.com, gw.sectigoaxiom.com and mcp.sectigoaxiom.com as custom domains and runs the maintenance cron every 5 minutes.

  4. Deploy the web app: npm run build -w @axiom/web, then npx wrangler deploy --env production in apps/web (custom domains sectigoaxiom.com and app.sectigoaxiom.com).

  5. Deploy the sample provider: apply its migrations (npx wrangler d1 migrations apply axiom-sample-billing --remote --env production in apps/sample-billing), set wrangler secret put SAMPLE_OUTCOME_PRIVATE_JWK --env production, and deploy.

  6. Deploy the docs: npm run deploy -w @axiom/docs -- --env production builds this site and deploys apps/docs/wrangler.jsonc to docs.sectigoaxiom.com.

Configuration ​

API variables (apps/api/wrangler.jsonc, apps/api/src/config.ts):

VariableMeaningProduction value
AXIOM_ENVdevelopment enables dev conveniences (logged magic links, dev_link on invitations, HTTP webhooks)production
AXIOM_ISSUERIssuer in tokens, receipts and dispatch authorisationshttps://api.sectigoaxiom.com
AXIOM_API_ORIGIN, AXIOM_GATEWAY_ORIGIN, AXIOM_MCP_ORIGINPublic originshttps://api.…, https://gw.…, https://mcp.…
AXIOM_WEB_ORIGIN, AXIOM_DOCS_ORIGINAllowed CORS origins; links in emailshttps://app.sectigoaxiom.com, https://docs.sectigoaxiom.com
AXIOM_SAMPLE_ORIGINUpstream of seeded sample projectshttps://sample.sectigoaxiom.com
AXIOM_COOKIE_DOMAIN, AXIOM_RP_IDSession cookie domain and WebAuthn relying party.sectigoaxiom.com, sectigoaxiom.com
AXIOM_MAIL_FROMSender for magic links and approval noticesSectigo Axiom <no-reply@sectigoaxiom.com>
AXIOM_DEV_AUTO_VERIFY_ORGSDevelopment only (AXIOM_ENV=development): true marks organisations verified without a CA validation, so Control can be tried locally. The evidence records "NOT validated by Sectigo"; ignored in staging and productionunset

CA variables (apps/api/src/ca/index.ts): AXIOM_CA (sectigo-scm, the default, or dev), AXIOM_SCM_MODE (mock, the default, or live), AXIOM_SCM_BASE_URL, AXIOM_SCM_AUTH (password or oauth), AXIOM_SCM_LOGIN, AXIOM_SCM_PASSWORD, AXIOM_SCM_CUSTOMER_URI, AXIOM_SCM_CLIENT_ID, AXIOM_SCM_CLIENT_SECRET, AXIOM_SCM_TOKEN_URL, AXIOM_SCM_ORG_ID, AXIOM_SCM_CERT_TYPE, AXIOM_SCM_TRUST_ANCHORS_PEM.

Mock mode

Until SCM credentials are configured and AXIOM_SCM_MODE=live is set, the SCM adapter runs in mock mode backed by a local development CA that issues real X.509 certificates. Organisation verification and agent certificates issued in mock mode are not Sectigo-validated. See Sectigo's CA role.

Google Cloud ​

The GCP target runs the same app on Cloud Run with Cloud SQL Postgres, Pub/Sub, Cloud Storage, Cloud KMS (one key per signing role), Secret Manager and Cloud Scheduler. The runbook is docs/deploy-gcp.md in the repository and is still being completed. It covers: project, APIs and service accounts; Cloud SQL (collation C, because timestamps are compared as RFC 3339 text); Pub/Sub; Cloud Storage; Cloud KMS keys per role; Secret Manager; build and deploy; the Pub/Sub push subscription and Cloud Scheduler calling /internal/* with OIDC tokens; custom domains; cutover from the hosted Cloudflare deployment; the environment reference; and cost notes.

Status

The Node entry point (apps/api/src/platform/node) and the GCP adapters (apps/api/src/platform/gcp) are in active development. Treat GCP as a target, not a supported production deployment, until that runbook is complete.

Customer-hosted gateways ​

Control already registers customer-hosted gateways and adapters, signs their policy bundles, collects heartbeats and acknowledgements, and moves the single executor between gateways (see Fleet, gateways and cutover). The deployable customer-hosted gateway container and the Kong, Apigee and AWS API Gateway adapters are not part of this repository yet.

Developer preview. Contract version 2026-11-14.