Skip to main content
Version: next

Deployment and observability audit rules

Auditable rules for deploying and operating Front-Commerce projects, covering health checks, metrics, logs, environment configuration, and version hygiene.

These rules verify that a Front-Commerce project is operable in production: that failures are detected before customers report them, that configuration is environment-driven, and that the deployed versions are supportable. Rules marked static can be verified from the repository alone, runtime rules require a running application (local or a deployed URL), and manual rules require human judgment. Use the rule codes (AUDIT-INFRA-NN) to reference findings in audit reports.

AUDIT-INFRA-01 — Expose and supervise the health and metrics endpoints

Severity: important — Detection: runtime

Rule: The /__front-commerce/health endpoint returns 200 on every production instance, the /__front-commerce/metrics endpoint is enabled and protected, and both are consumed by a supervision tool (orchestrator probe, uptime monitor, Prometheus).

Why: Without a wired health probe, an instance that fails to boot keeps receiving traffic and serves errors until a human notices. Without metrics, memory leaks and backend slowdowns are invisible until they become outages.

How to check:

  1. Health endpoint:
    curl -s -o /dev/null -w "%{http_code}" https://<site>/__front-commerce/health
    Expect 200. A 503 means the application is not ready; a 404 means the deployment strips the path — both are findings.
  2. Metrics endpoint: confirm FRONT_COMMERCE_CLOUD_METRICS_KEY is defined in the production environment, then:
    curl -s -H "Authorization: Basic $FRONT_COMMERCE_CLOUD_METRICS_KEY" https://<site>/__front-commerce/metrics | head
    Expect Prometheus-format output including outbound_requests_duration histograms for backend services. An unauthenticated 200 on this endpoint is a security finding; a 404 means metrics are disabled.
  3. Ask the team which system polls each endpoint and what alert fires on failure. Endpoints that respond but that nothing watches do not satisfy this rule.

AUDIT-INFRA-02 — Configure health checks for critical backend services

Severity: important — Detection: static + runtime

Rule: Every backend service the storefront cannot run without (commerce platform, search engine, payment provider) has a registered health check (services.MaintenanceMode.addHealthCheckService) so the store switches to maintenance mode automatically when the service is down.

Why: Without automatic detection, a backend outage surfaces as broken pages, failed checkouts, and error noise instead of a clean maintenance page — and recovery requires a human to notice and intervene twice (once to enable maintenance mode, once to disable it).

How to check:

  1. Find the registered checks:
    grep -rn "addHealthCheckService" app extensions
    Compare the list against the backends configured in front-commerce.config.ts (commerce extension, search, payments). A critical backend without a health check is a finding.
  2. Verify the schedule: look for maintenance.healthChecks.schedule in front-commerce.config.ts. The default is every 10 seconds; confirm the configured value is a deliberate choice compatible with the backend's own rate limits.
  3. Confirm FRONT_COMMERCE_MAINTENANCE_MODE_AUTHORIZATION_TOKEN is set, so operators can also toggle maintenance mode and health checks manually.
  4. Runtime (staging): make one monitored service unreachable and confirm the store serves the maintenance page (503) within the configured interval, then recovers on its own when the service returns.

AUDIT-INFRA-03 — Monitor critical application logs

Severity: important — Detection: runtime + manual

Rule: Production logs are aggregated and reviewed: GraphQL errors, SSR errors, and abnormal 404 volume each have a defined owner and an alerting or review routine.

Why: These three log families are the earliest signal of real problems — broken resolvers after a backend deployment, SSR regressions that degrade SEO and first paint, and 404 storms that reveal broken links, misconfigured redirects, or bot probing. Unread logs detect nothing.

How to check:

  1. Ask where production logs go (aggregator, files, stdout collector) and who looks at them. "Nobody, unless something breaks" is a finding.
  2. Inspect a recent window (24–48 h) of application logs for recurring GraphQL resolver errors and SSR errors. Recurring errors that no ticket tracks are findings.
  3. Analyze HTTP status distribution in the access logs, for example with goaccess:
    goaccess access.log --log-format=COMBINED
    Look at the 404 panel: a high or growing 404 rate on product/category URLs points at missing redirects (see the SEO rules).
  4. Cross-check with the codebase: silent catch blocks that return empty values without logging defeat this rule at the source —
    grep -rn -A2 "catch" app extensions | grep -B1 "return \[\]\|return null"
    flags candidates worth reviewing.

AUDIT-INFRA-04 — Drive configuration from environment variables, and expose only FRONT_COMMERCE_WEB_* to the client

Severity: important — Detection: static

Rule: Environment-dependent values (backend URLs, keys, feature toggles) come from environment variables — never hardcoded — and client-side code reads only variables prefixed with FRONT_COMMERCE_WEB_.

Why: Hardcoded values make the same build behave differently than intended across environments (staging pointing at production backends is a classic incident). And any non-WEB_ variable referenced in client code is either bundled into public JavaScript (leaking it) or undefined at runtime (breaking the feature).

How to check:

  1. Client-side process.env usage — list every reference outside .server. files and loaders:
    grep -rn "process.env" app extensions --include="*.tsx" --include="*.ts" | grep -v ".server."
    For each hit in code that ships to the browser (components, hooks, client utilities), the variable must start with FRONT_COMMERCE_WEB_. Anything else is a violation.
  2. Hardcoded environment-specific values:
    grep -rnE "https?://[a-z0-9.-]*(staging|preprod|prod|magento|localhost)" app extensions front-commerce.config.ts
    URLs and keys embedded in source instead of read from configuration are violations (test fixtures excepted).
  3. Confirm .env.dist (or equivalent template) documents every variable the code reads, so environments can be reproduced.

AUDIT-INFRA-05 — Remove the example-extensions directory

Severity: minor — Detection: static

Rule: The project does not contain the skeleton's example-extensions directory, and front-commerce.config.ts references none of its extensions.

Why: The examples ship as learning material, not production code. Keeping them adds dead routes and demo endpoints to the deployed application, enlarges the attack surface, and confuses future maintainers about what is real project code.

How to check:

  1. test -d example-extensions && echo "VIOLATION: directory present"
  2. grep -rn "example-extensions" front-commerce.config.ts app
    Any import from the directory is a violation. If one example was genuinely adopted, its code must be moved into extensions/ under a project-owned name.

AUDIT-INFRA-06 — Customize the maintenance and offline pages

Severity: minor — Detection: static + runtime

Rule: The maintenance page (shown during backend maintenance mode) and the offline page (shown by the PWA without network) are overridden to match the project's brand.

Why: These pages appear exactly when users are already experiencing a degraded moment. A default, unbranded framework page at that moment reads as a broken site and erodes trust, where a branded page reads as a handled situation.

How to check:

  1. Static: look for the theme overrides —
    find app/theme -path "*pages/Offline*" -o -path "*pages/Error/Maintenance*" -o -path "*pages/Maintenance*"
    No matching override means the default framework pages ship as-is.
  2. Runtime: on an environment where FRONT_COMMERCE_ENV is not production, open /__front-commerce/maintenance and /__front-commerce/offline and confirm both render project branding (logo, colors, wording, translated copy).
  3. For the offline page, also verify the PWA setup is complete (service worker registered, manifest.json branded) so the page can actually be served offline.

AUDIT-INFRA-07 — Serve the correct robots.txt per environment

Severity: important — Detection: runtime

Rule: Production serves a robots.txt that allows crawling and declares the sitemap; staging and preview environments serve Disallow: / (or are otherwise blocked from indexing).

Why: The two failure modes are both costly: a production store that disallows crawling disappears from search results, and an indexable staging environment creates duplicate content that competes with production and leaks unreleased catalog data.

How to check:

  1. Production:
    curl -s https://<production-site>/robots.txt
    Expect Allow: / (or no global Disallow) and a Sitemap: line pointing at the production sitemap URL. A global Disallow: / here is a critical SEO finding.
  2. Staging/preprod:
    curl -s https://<staging-site>/robots.txt
    Expect Disallow: /. Front-Commerce generates this automatically outside production mode; if the environment runs in production mode, indexing must be blocked another way (HTTP auth, x-robots-tag).
  3. If the project overrides app/routes/robots[.txt].tsx, read the override: allowCrawling (or the equivalent logic) must depend on the environment, not be hardcoded to true.

AUDIT-INFRA-08 — Run supported, up-to-date Front-Commerce and Node.js versions

Severity: important — Detection: static

Rule: The project uses a currently supported Front-Commerce release line, lags no more than a few minor versions behind the latest release, and runs a Node.js version supported by that release.

Why: Version lag is the most recurrent audit finding, and it compounds: each skipped minor makes the next upgrade larger and riskier, while security fixes and performance improvements ship only in recent releases. An end-of-life Node.js version stops receiving security patches entirely.

How to check:

  1. Read the deployed versions:
    grep -E "\"@front-commerce/(core|remix)\"" package.json
    grep -E "\"node\"" package.json
    cat .nvmrc 2>/dev/null
  2. Compare the @front-commerce/* version against the latest release listed on the changelog. Record the gap in minor versions; more than two or three minors behind, or a major line that no longer receives fixes, is a finding with the upgrade path as remediation.
  3. Verify the Node.js version (engines field, .nvmrc, or the deployment image) is an active or maintenance LTS line and matches the requirement of the Front-Commerce release in use.
  4. Check the lockfile is committed and consistent (pnpm-lock.yaml or equivalent), so the audited versions are the deployed ones.