Skip to main content
Version: v5.7.0

Support bundle

Included from Basic tier

The support bundle is the redacted diagnostics tar.gz for a support case (G21). One package — internal/support — defines what a bundle holds, and both collectors consume it, so the two bundles can never drift:

  • CLI-side: opschain support bundle collects locally (the home's config and key presence) and, with --server, fetches the live diagnostics over HTTP. See opschain docs cli/support-bundle.
  • Server-side: GET /api/admin/support_bundle assembles the same bundle in-process and streams it — the GUI's download. The diagnostics items are fetched through the composed handler itself (the same routes, gates and payloads an external fetch would see), under the requesting caller's own bearer.

What the bundle collects​

Always:

  • bundle.json — the manifest (format opschain-support-bundle/v1): creation time, the collector's identity (CLI: cli_version, cli_commit, cli_built_at, server; server: server_version, server_commit, server_built_at, source: "server") and the file listing.
  • config.yaml — the server configuration, redacted (below). When no config file exists, config.yaml.txt records that instead.
  • keys-presence.txt — WHICH keys server/keys.env holds (present/absent per key name), never their values.

The live server diagnostics (the shared ServerItems list — bundle file name → path):

FileFetched from
healthz.json/healthz
readyz.json/readyz
admin-status.json/admin/status
admin-queue.json/admin/queue
licence.json/admin/licence
runners.json/api/runners
runner-groups.json/api/runner_groups
events.json/api/events
metrics.txt/metrics

Every body is stored verbatim; a failed fetch is recorded as <name>.error.txt (containing GET <path>: HTTP <status>: <body>) rather than failing the bundle. licence.json names the server's store_kind (postgres or sqlite) beside the resolved licence status, so support sees at once which store the server runs on (opschain docs storage). The CLI without --server produces an offline config-only bundle.

Redaction​

The bundle shares serverconfig.Redacted with the admin config catalog — one rule, not two: every secret-bearing config value is replaced with [REDACTED]. That covers the store DSN password (stripped from URL-shaped DSNs; SQLite paths pass through), the LDAP bind password (ldap.password), and the vault block's secret keys (token, password, secret_id, client_options, transportable_key). Non-secret operational values (addresses, bases, paths) stay readable. Key material is excluded outright — the keys file contributes only a presence report. No customer secrets, no tokens, no key material; TestSupportBundleContainsZeroSecrets enforces it.

Who may fetch it​

GET /api/admin/support_bundle is an admin-gated route, like the rest of the admin-ops surface (/api/admin/overview, /api/admin/config). The server-side collector forwards the caller's own Authorization bearer to the admin-gated items, so the bundle contains exactly what that admin may see. The CLI uses --auth-token (default $OPSCHAIN_ADMIN_TOKEN) for the same items; items the token cannot read arrive as their .error.txt.

Output format and naming​

A gzip-compressed tar stream. The server sets Content-Type: application/gzip and a Content-Disposition: attachment; filename="opschain-support-bundle-<UTC timestamp>.tar.gz"; the CLI writes opschain-support-bundle-<UTC timestamp>.tar.gz in the current directory unless --out names a path. Members are flat files, mode 0600.

Failure modes​

  • A failing or unreachable diagnostic never fails the bundle — it is recorded in place as <name>.error.txt, so a bundle collected from a degraded server still documents how it is degraded.
  • An unreadable config file does fail the collection (the bundle's core item cannot be rendered); an absent one does not.
  • An unreadable keys.env is reported inside keys-presence.txt (keys.env unreadable: <error>), not fatal.
  • The CLI refuses to overwrite an existing output file (the bundle is opened with O_EXCL).
  • opschain docs cli/support-bundle — the CLI collector and its flags.
  • opschain docs config — the catalog that shares the redaction rules.
  • opschain docs storage — keys.env and what those keys protect.