9
2
Fork
You've already forked platform
2

Add opt-in Sentry error reporting for platform services and dashboard #377

Open
opened 2026年07月10日 22:16:48 +02:00 by caution-bot · 1 comment

Summary

Add opt-in Sentry error reporting for the operator-facing Caution platform services and dashboard, with separate development and production Sentry environments. The integration should improve crash/error visibility without weakening Caution's confidentiality, attestation, reproducibility, or secret-handling guarantees.

Proposed implementation

Backend Rust services

Add a small shared workspace crate, for example src/observability / caution-observability, that centralizes Sentry and tracing setup for:

  • src/api
  • src/gateway
  • src/metering
  • src/email-service

The crate should:

  • initialize Sentry only when SENTRY_DSN is set and non-empty;
  • keep existing stdout tracing behavior intact;
  • integrate with the existing tracing usage via sentry + sentry-tracing;
  • capture panics and tracing::error! events;
  • treat tracing::warn! events as breadcrumbs unless there is a specific reason to promote one to an event;
  • attach service name, environment, release, and request ID/correlation ID where safe;
  • scrub sensitive headers and values before anything can leave the process;
  • never capture request or response bodies by default.

Recommended Rust crates, subject to compatibility with the repository's pinned toolchain/container builds:

sentry = { version = "0.48.4", default-features = false, features = [
 "backtrace",
 "contexts",
 "panic",
 "tracing",
 "tower",
 "tower-http",
 "tower-axum-matched-path",
 "reqwest",
 "rustls",
] }
sentry-tracing = "0.48.4"

Use the rustls path rather than native TLS where feasible because these services are built for static/musl StageX-style runtime images.

Axum request context

Layer Sentry into the Axum routers where appropriate, but prefer route templates/matched paths over raw user-controlled URLs. Include safe context such as:

  • service name (api, gateway, metering, email-service);
  • release/git SHA;
  • environment (development, production, etc.);
  • HTTP method and matched route;
  • status code;
  • sanitized request ID.

Do not capture request/response bodies.

The gateway already has X-Request-Id middleware. Before using this value as a Sentry tag/context, validate it strictly, e.g. accept UUIDs only and generate a new UUID otherwise, to avoid log/header/tag injection from user-supplied request IDs.

Frontend Vue dashboard

Add an opt-in Vue integration in frontend/src/main.js using @sentry/vue:

  • initialize only when VITE_SENTRY_DSN is set;
  • set sendDefaultPii: false;
  • keep tracing sample rate at 0 initially;
  • do not enable Session Replay in the first pass because the dashboard handles WebAuthn, SSH keys, billing, attestation, and deployment state.

Add build-time variables to the frontend build path used by containerfiles/Containerfile.gateway and containerfiles/Containerfile.frontend.

Source map upload, if desired, should be a follow-up in CI/release automation using a CI-only SENTRY_AUTH_TOKEN. Do not pass SENTRY_AUTH_TOKEN through Docker build args, final images, env.example, systemd units, or runtime .env files.

Sentry setup instructions

1. Create Sentry organization/projects

In Sentry, create separate projects for backend and frontend so SDK settings and alert rules can differ:

  • Backend project: caution-platform-backend, platform Rust
  • Frontend project: caution-platform-frontend, platform JavaScript/Vue

Use separate Sentry environments instead of separate projects for dev vs prod unless there is a compliance or access-control reason to fully isolate them:

  • development
  • production

If staging is used, also add:

  • staging

2. Development environment

Development should be opt-in and low/no-noise by default.

Recommended local .env additions:

# Observability / Sentry (optional)
SENTRY_DSN=https://<backend-public-key>@<sentry-host>/<backend-project-id>
SENTRY_ENVIRONMENT=development
SENTRY_RELEASE=dev-local
SENTRY_TRACES_SAMPLE_RATE=0
SENTRY_PROFILES_SAMPLE_RATE=0
SENTRY_SEND_DEFAULT_PII=false
# Frontend Sentry (optional; public DSN is safe to expose, auth tokens are not)
VITE_SENTRY_DSN=https://<frontend-public-key>@<sentry-host>/<frontend-project-id>
VITE_SENTRY_ENVIRONMENT=development
VITE_SENTRY_RELEASE=dev-local
VITE_SENTRY_TRACES_SAMPLE_RATE=0

For ordinary local development, leave both DSNs empty to disable Sentry entirely. Developers can set them only when intentionally testing observability.

Development verification steps:

  1. Run the affected service with SENTRY_DSN set.
  2. Trigger a controlled non-secret test error or panic in a development-only path or test harness.
  3. Verify the event appears in Sentry with environment development.
  4. Confirm no cookies, authorization headers, internal service secrets, request bodies, encrypted secret material, raw attestation documents, cloud credentials, SMTP credentials, or Paddle secrets appear in the event.
  5. Clear the test hook before merging unless it is test-only and guarded.

3. Production environment

Production should use real release identifiers and conservative sampling.

Recommended production runtime .env additions:

SENTRY_DSN=https://<backend-public-key>@<sentry-host>/<backend-project-id>
SENTRY_ENVIRONMENT=production
SENTRY_RELEASE=<git-sha-or-release-version>
SENTRY_TRACES_SAMPLE_RATE=0
SENTRY_PROFILES_SAMPLE_RATE=0
SENTRY_SEND_DEFAULT_PII=false
VITE_SENTRY_DSN=https://<frontend-public-key>@<sentry-host>/<frontend-project-id>
VITE_SENTRY_ENVIRONMENT=production
VITE_SENTRY_RELEASE=<git-sha-or-release-version>
VITE_SENTRY_TRACES_SAMPLE_RATE=0

Production rollout guidance:

  1. Deploy backend Sentry first with SENTRY_TRACES_SAMPLE_RATE=0 and frontend tracing disabled.
  2. Verify events are grouped by service and release.
  3. Verify sensitive data scrubbing against real-shaped but fake test requests.
  4. Only after error capture is stable, consider enabling a very low traces sample rate such as 0.01, and only for routes where privacy and volume are understood.
  5. Keep Session Replay disabled unless a separate privacy/security review approves it.
  6. Set Sentry alert routing for production only; keep development alerts muted or routed to a low-priority channel.

4. Source maps and releases

Frontend source maps should be uploaded from CI/release automation, not from runtime containers.

If source map upload is added later:

  • use @sentry/vite-plugin or sentry-cli in CI;
  • store SENTRY_AUTH_TOKEN only as a CI secret;
  • associate source maps with VITE_SENTRY_RELEASE;
  • delete or avoid publishing source maps in served static assets if that is the desired production policy;
  • do not commit, print, or bake SENTRY_AUTH_TOKEN into images.

Security and privacy requirements

Sentry must not send or store:

  • request bodies or response bodies;
  • cookies;
  • Authorization headers;
  • INTERNAL_SERVICE_SECRET;
  • Paddle API keys, webhook secrets, checkout payload secrets, or billing provider secrets;
  • SMTP credentials;
  • cloud credentials;
  • plaintext .env values;
  • encrypted secret material from .caution/secrets/*.asc;
  • Locksmith shard contents or private keys;
  • raw attestation documents, nonce material, PCR blobs, or certificate chains unless explicitly reviewed and redacted;
  • customer workload secrets or deployment-time secrets;
  • private SSH keys, WebAuthn challenge responses, or passkey credential material.

Do not initialize Sentry inside enclave/customer workload code or deterministic/reproducible build paths. Sentry should be limited to operator-facing platform services and the dashboard.

Acceptance criteria

  • SENTRY_DSN unset or empty means backend Sentry is fully disabled and services behave as they do today.
  • VITE_SENTRY_DSN unset or empty means frontend Sentry is fully disabled.
  • Backend services emit Sentry events for panics and error-level tracing events when enabled.
  • Events include service, environment, and release context.
  • Request context uses matched routes/sanitized IDs rather than raw attacker-controlled values where possible.
  • Sensitive headers and known secret-bearing fields are scrubbed before events are sent.
  • Request/response bodies are not captured by default.
  • Frontend captures uncaught Vue/browser errors when enabled, with sendDefaultPii: false and replay disabled.
  • env.example, deployment docs, or relevant README sections document dev and prod Sentry setup.
  • Tests cover configuration parsing/defaults and scrubbing behavior.
  • Existing regular checks continue to pass.

Suggested test plan

Backend:

cargo check -p api -p gateway -p metering -p email-service
cargo test -p caution-observability
cargo test --workspace

Frontend:

cd frontend
npm install
npm run build

Container/build smoke tests where feasible:

make build-api
make build-gateway
make build-metering
make build-email
## Summary Add opt-in Sentry error reporting for the operator-facing Caution platform services and dashboard, with separate development and production Sentry environments. The integration should improve crash/error visibility without weakening Caution's confidentiality, attestation, reproducibility, or secret-handling guarantees. ## Proposed implementation ### Backend Rust services Add a small shared workspace crate, for example `src/observability` / `caution-observability`, that centralizes Sentry and tracing setup for: - `src/api` - `src/gateway` - `src/metering` - `src/email-service` The crate should: - initialize Sentry only when `SENTRY_DSN` is set and non-empty; - keep existing stdout tracing behavior intact; - integrate with the existing `tracing` usage via `sentry` + `sentry-tracing`; - capture panics and `tracing::error!` events; - treat `tracing::warn!` events as breadcrumbs unless there is a specific reason to promote one to an event; - attach service name, environment, release, and request ID/correlation ID where safe; - scrub sensitive headers and values before anything can leave the process; - never capture request or response bodies by default. Recommended Rust crates, subject to compatibility with the repository's pinned toolchain/container builds: ```toml sentry = { version = "0.48.4", default-features = false, features = [ "backtrace", "contexts", "panic", "tracing", "tower", "tower-http", "tower-axum-matched-path", "reqwest", "rustls", ] } sentry-tracing = "0.48.4" ``` Use the rustls path rather than native TLS where feasible because these services are built for static/musl StageX-style runtime images. ### Axum request context Layer Sentry into the Axum routers where appropriate, but prefer route templates/matched paths over raw user-controlled URLs. Include safe context such as: - service name (`api`, `gateway`, `metering`, `email-service`); - release/git SHA; - environment (`development`, `production`, etc.); - HTTP method and matched route; - status code; - sanitized request ID. Do not capture request/response bodies. The gateway already has `X-Request-Id` middleware. Before using this value as a Sentry tag/context, validate it strictly, e.g. accept UUIDs only and generate a new UUID otherwise, to avoid log/header/tag injection from user-supplied request IDs. ### Frontend Vue dashboard Add an opt-in Vue integration in `frontend/src/main.js` using `@sentry/vue`: - initialize only when `VITE_SENTRY_DSN` is set; - set `sendDefaultPii: false`; - keep tracing sample rate at `0` initially; - do not enable Session Replay in the first pass because the dashboard handles WebAuthn, SSH keys, billing, attestation, and deployment state. Add build-time variables to the frontend build path used by `containerfiles/Containerfile.gateway` and `containerfiles/Containerfile.frontend`. Source map upload, if desired, should be a follow-up in CI/release automation using a CI-only `SENTRY_AUTH_TOKEN`. Do not pass `SENTRY_AUTH_TOKEN` through Docker build args, final images, `env.example`, systemd units, or runtime `.env` files. ## Sentry setup instructions ### 1. Create Sentry organization/projects In Sentry, create separate projects for backend and frontend so SDK settings and alert rules can differ: - Backend project: `caution-platform-backend`, platform Rust - Frontend project: `caution-platform-frontend`, platform JavaScript/Vue Use separate Sentry environments instead of separate projects for dev vs prod unless there is a compliance or access-control reason to fully isolate them: - `development` - `production` If staging is used, also add: - `staging` ### 2. Development environment Development should be opt-in and low/no-noise by default. Recommended local `.env` additions: ```dotenv # Observability / Sentry (optional) SENTRY_DSN=https://<backend-public-key>@<sentry-host>/<backend-project-id> SENTRY_ENVIRONMENT=development SENTRY_RELEASE=dev-local SENTRY_TRACES_SAMPLE_RATE=0 SENTRY_PROFILES_SAMPLE_RATE=0 SENTRY_SEND_DEFAULT_PII=false # Frontend Sentry (optional; public DSN is safe to expose, auth tokens are not) VITE_SENTRY_DSN=https://<frontend-public-key>@<sentry-host>/<frontend-project-id> VITE_SENTRY_ENVIRONMENT=development VITE_SENTRY_RELEASE=dev-local VITE_SENTRY_TRACES_SAMPLE_RATE=0 ``` For ordinary local development, leave both DSNs empty to disable Sentry entirely. Developers can set them only when intentionally testing observability. Development verification steps: 1. Run the affected service with `SENTRY_DSN` set. 2. Trigger a controlled non-secret test error or panic in a development-only path or test harness. 3. Verify the event appears in Sentry with environment `development`. 4. Confirm no cookies, authorization headers, internal service secrets, request bodies, encrypted secret material, raw attestation documents, cloud credentials, SMTP credentials, or Paddle secrets appear in the event. 5. Clear the test hook before merging unless it is test-only and guarded. ### 3. Production environment Production should use real release identifiers and conservative sampling. Recommended production runtime `.env` additions: ```dotenv SENTRY_DSN=https://<backend-public-key>@<sentry-host>/<backend-project-id> SENTRY_ENVIRONMENT=production SENTRY_RELEASE=<git-sha-or-release-version> SENTRY_TRACES_SAMPLE_RATE=0 SENTRY_PROFILES_SAMPLE_RATE=0 SENTRY_SEND_DEFAULT_PII=false VITE_SENTRY_DSN=https://<frontend-public-key>@<sentry-host>/<frontend-project-id> VITE_SENTRY_ENVIRONMENT=production VITE_SENTRY_RELEASE=<git-sha-or-release-version> VITE_SENTRY_TRACES_SAMPLE_RATE=0 ``` Production rollout guidance: 1. Deploy backend Sentry first with `SENTRY_TRACES_SAMPLE_RATE=0` and frontend tracing disabled. 2. Verify events are grouped by service and release. 3. Verify sensitive data scrubbing against real-shaped but fake test requests. 4. Only after error capture is stable, consider enabling a very low traces sample rate such as `0.01`, and only for routes where privacy and volume are understood. 5. Keep Session Replay disabled unless a separate privacy/security review approves it. 6. Set Sentry alert routing for production only; keep development alerts muted or routed to a low-priority channel. ### 4. Source maps and releases Frontend source maps should be uploaded from CI/release automation, not from runtime containers. If source map upload is added later: - use `@sentry/vite-plugin` or `sentry-cli` in CI; - store `SENTRY_AUTH_TOKEN` only as a CI secret; - associate source maps with `VITE_SENTRY_RELEASE`; - delete or avoid publishing source maps in served static assets if that is the desired production policy; - do not commit, print, or bake `SENTRY_AUTH_TOKEN` into images. ## Security and privacy requirements Sentry must not send or store: - request bodies or response bodies; - cookies; - `Authorization` headers; - `INTERNAL_SERVICE_SECRET`; - Paddle API keys, webhook secrets, checkout payload secrets, or billing provider secrets; - SMTP credentials; - cloud credentials; - plaintext `.env` values; - encrypted secret material from `.caution/secrets/*.asc`; - Locksmith shard contents or private keys; - raw attestation documents, nonce material, PCR blobs, or certificate chains unless explicitly reviewed and redacted; - customer workload secrets or deployment-time secrets; - private SSH keys, WebAuthn challenge responses, or passkey credential material. Do not initialize Sentry inside enclave/customer workload code or deterministic/reproducible build paths. Sentry should be limited to operator-facing platform services and the dashboard. ## Acceptance criteria - `SENTRY_DSN` unset or empty means backend Sentry is fully disabled and services behave as they do today. - `VITE_SENTRY_DSN` unset or empty means frontend Sentry is fully disabled. - Backend services emit Sentry events for panics and error-level tracing events when enabled. - Events include service, environment, and release context. - Request context uses matched routes/sanitized IDs rather than raw attacker-controlled values where possible. - Sensitive headers and known secret-bearing fields are scrubbed before events are sent. - Request/response bodies are not captured by default. - Frontend captures uncaught Vue/browser errors when enabled, with `sendDefaultPii: false` and replay disabled. - `env.example`, deployment docs, or relevant README sections document dev and prod Sentry setup. - Tests cover configuration parsing/defaults and scrubbing behavior. - Existing regular checks continue to pass. ## Suggested test plan Backend: ```bash cargo check -p api -p gateway -p metering -p email-service cargo test -p caution-observability cargo test --workspace ``` Frontend: ```bash cd frontend npm install npm run build ``` Container/build smoke tests where feasible: ```bash make build-api make build-gateway make build-metering make build-email ```
Author
Member
Copy link

Duplicate/related issue audit while moving this into General Availability:

  • Supersedes #132 (Error tracking and logging). That issue asked for durable error tracking/logging, and the later discussion specifically called out Sentry as the likely error-tracking solution. Closing #132 in favor of this more detailed GA-scoped issue.
  • Includes the already-closed duplicate lineage from #247 (Add instrumentation for error notifications), which had previously been closed in favor of #132.

I also checked #233 (Observability Into Builders). That one is related but not a duplicate: it focuses on builder logs/metrics and encrypted log streaming, while this issue intentionally limits Sentry to operator-facing platform services/dashboard and says not to initialize Sentry inside builder/enclave/reproducible paths.

Duplicate/related issue audit while moving this into General Availability: - Supersedes #132 (`Error tracking and logging`). That issue asked for durable error tracking/logging, and the later discussion specifically called out Sentry as the likely error-tracking solution. Closing #132 in favor of this more detailed GA-scoped issue. - Includes the already-closed duplicate lineage from #247 (`Add instrumentation for error notifications`), which had previously been closed in favor of #132. I also checked #233 (`Observability Into Builders`). That one is related but not a duplicate: it focuses on builder logs/metrics and encrypted log streaming, while this issue intentionally limits Sentry to operator-facing platform services/dashboard and says not to initialize Sentry inside builder/enclave/reproducible paths.
Sign in to join this conversation.
No Branch/Tag specified
main
feat/paddle-byoc-subscriptions
feat/legal-publish-doc
fix/issue-116-duplicate-ssh-key
fix/issue-307-remove-apps
fix/issue-265-http-port-private
fix/issue-330-remove-build-binary
feat/issue-164-account-id
fix/issue-119-logout-confirmation
feat/add-tofu-lockfile-cache
feat/webauthn-discoverable-login
docs/issue-339-install-instructions
fix/issue-336-split-qr-login-tokens
fix/verify-app-source-preflight
fix/many-git-push-deploy
fix/issue-334-email-verification-throttle
fix/issue-273-billing-url
fix/issue-333-final-usage-collection
fix/issue-270-low-credit-email
fix/issue-301-remove-auto-topup
fix/issue-320-byoc-auth-first
fix/issue-348-git-progress-checklist
fix/issue-321-byoc-caution-hcl
fix/issue-332-resource-id-suspension
fix/eif-app-mode-normalization
feat/cli-stagex-container
fix/eif-s3-layer-cache
fix/authz-role-checks
fix/paddle-customdata-credit-mint
fix/cli-hangs-unsupported-ssh-url
feat/print-platform-commit-dashboard
anton/feat/multi-user
fix/config-domain-validation
anton/support-ssh-destroy-get
fix/cli-config-dir
feat/publish-build-inputs
feat/locksmith-polishing
fix/procfile-run-command-no-split
anton/byoc-require-login
fix/hcl-init-template
feat/egress-default-deny
ryansquared/hcl
quotas
anton/feat/region-routing-resource-unavailable-alert
fix/attestation-502-dashboard
ryansquared/systemdize
fix/verify-git-credential-hang
anton/fix-low-credits-alert
xenushka/rename-byoc
ryansquared/add-download-eif
add-debug-flag
test/pr1-integration-harness
anton/fix/only-pass-required-env-vars
ryansquared/add-database-bucket
No results found.
Labels
Clear labels
Compat/Breaking
Breaking change that won't be backward compatible
Component/Enclave-Builder
This issue affects Enclave Builder (git-push and CLI)
Component/Infrastructure
This issue affects generic Caution hosted infra components
Deploy/BYOC
Relates to Caution Bring-your-own-compute
Deploy/Full-managed
Relates to Caution fully managed cloud
Deploy/Self-hosted
Relates to Caution deployed on self-hosted infra
Interface/API
This issue affects the API
Interface/CLI
This issue affects the command line interface
Interface/Git
This issue affects the Git `push` interface
Interface/Web
This issue affects the web dashboard
Kind/Bug
Something is not working
Kind/Documentation
Documentation changes
Kind/Enhancement
Improve existing functionality
Kind/Feature
New functionality
Kind/Security
This is security issue
Kind/Testing
Issue or pull request related to testing
Priority
Critical
The priority is critical
Priority
High
The priority is high
Priority
Low
The priority is low
Priority
Medium
The priority is medium
Reviewed
Confirmed
Issue has been confirmed
Reviewed
Duplicate
This issue or pull request already exists
Reviewed
Invalid
Invalid issue
Reviewed
Won't Fix
This issue won't be fixed
Status
Abandoned
Somebody has started to work on this but abandoned work
Status
Blocked
Something is blocking this issue or pull request
Status
Need More Info
Feedback is required to reproduce issue or to continue work
Milestone
Clear milestone
No items
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
caution/platform#377
Reference in a new issue
caution/platform
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?