Skip to content

fix(web): harden observability env handling and Sentry log redaction#917

Merged
gildesmarais merged 9 commits intomainfrom
port/observability-sentry
Mar 28, 2026
Merged

fix(web): harden observability env handling and Sentry log redaction#917
gildesmarais merged 9 commits intomainfrom
port/observability-sentry

Conversation

@gildesmarais
Copy link
Copy Markdown
Member

Summary

  • add runtime env parsing and validation for web boot
  • initialize Sentry in web boot with explicit enablement controls
  • redact sensitive log payloads before Sentry forwarding
  • add focused specs for app logger and sentry log forwarding

Validation

  • make ready
  • attempted make dev smoke (blocked by existing port 4000 usage in local env)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens html2rss-web boot-time environment handling by capturing required runtime configuration once, scrubbing sensitive env vars from the process environment, and integrating Sentry initialization plus a log-forwarding bridge with redaction.

Changes:

  • Introduces RuntimeEnv capture + sensitive env scrubbing, and updates auth/health codepaths to read secrets from RuntimeEnv.
  • Adds boot-time Sentry configuration (with explicit log enablement) and forwards structured logs into Sentry with PII filtering.
  • Expands specs to cover env validation, boot setup behavior, Sentry log forwarding/redaction, and post-scrub request flows.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
spec/support/runtime_env_helpers.rb Test helper to capture/scrub runtime env for production-style scenarios.
spec/spec_helper.rb Ensures runtime env + secret key are reset/stable between tests.
spec/html2rss/web/sentry_logs_spec.rb Verifies Sentry log forwarding and redaction behavior.
spec/html2rss/web/environment_validator_spec.rb Adds coverage for production build metadata validation.
spec/html2rss/web/boot/setup_spec.rb Validates boot sequencing, env scrubbing, and Sentry configuration behaviors.
spec/html2rss/web/app_logger_spec.rb Covers Sentry forwarding and resilience when Sentry forwarding fails.
spec/html2rss/web/app_integration_spec.rb Ensures feed token auth still works after env scrubbing.
spec/html2rss/web/api/v1_spec.rb Ensures health endpoint works after env scrubbing.
public/openapi.yaml Updates /health response description.
frontend/src/api/generated/types.gen.ts Regenerated API types/comments from OpenAPI changes.
docs/README.md Documents new managed env keys including build metadata + Sentry log enablement.
docker-compose.yml Requires BUILD_TAG/GIT_SHA; adds Sentry env wiring.
config.ru Switches Sentry rack middleware enablement to boot setup flag.
app/web/telemetry/sentry_logs.rb New Sentry log bridge with payload sanitization.
app/web/telemetry/app_logger.rb Emits structured log payloads to Sentry bridge during formatting.
app/web/security/auth.rb Uses RuntimeEnv.secret_key instead of ENV.
app/web/config/runtime_env.rb New runtime env capture/scrub module + boolean parsing.
app/web/config/environment_validator.rb Enforces production build metadata presence; rubocop length disables.
app/web/boot/setup.rb Captures runtime env, configures Sentry, sets Rack::Timeout, logs startup metadata.
app/web/boot/sentry.rb New boot-time Sentry initializer reading from RuntimeEnv.
app/web/api/v1/health.rb Uses RuntimeEnv.health_check_token instead of ENV.
README.md Mentions optional Sentry env vars in docker-compose quickstart.

Comment thread public/openapi.yaml Outdated
Comment thread README.md Outdated
Comment thread app/web/telemetry/sentry_logs.rb
Comment thread app/web/telemetry/app_logger.rb
@gildesmarais gildesmarais enabled auto-merge (squash) March 28, 2026 02:03
@gildesmarais gildesmarais merged commit ed2b3e9 into main Mar 28, 2026
12 checks passed
@gildesmarais gildesmarais deleted the port/observability-sentry branch March 28, 2026 02:03
gildesmarais added a commit that referenced this pull request May 1, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.1.0](html2rss-web-v1.0.0...html2rss-web/v1.1.0)
(2026-05-01)


### Features

* add help text on error page
([eeee345](eeee345)),
closes [#338](#338)
* add routed frontend feed creation workflow
([#963](#963))
([2d1b71a](2d1b71a))
* **auto_source:** add support for `auto_source` feature
([#676](#676))
([531dced](531dced))
* default browserless onboarding and request strategies
([#895](#895))
([377cff0](377cff0))
* **deps:** use html2rss in latest development status
([#728](#728))
([5885d1d](5885d1d))
* **docker:** switch to alpine 21
([7adcc89](7adcc89))
* **docker:** upgrade to use ruby 3.3 image
([ceafe24](ceafe24))
* **docker:** use multilayer build to cut image size in half
([2f6e322](2f6e322))
* **docker:** use Ruby 3.4
([4f7d795](4f7d795))
* **frontend:** polish result experience and validation tooling
([#964](#964))
([b11665e](b11665e))
* **frontend:** relaunch the app with a focused v1 flow
([e0692d7](e0692d7))
* **frontend:** unify feed/result state flow
([#943](#943))
([6dfa1a9](6dfa1a9))
* **health_check:** add HTTP Basic authentication to `GET
/health_check.txt`
([#559](#559))
([d0ccd83](d0ccd83))
* improve example feed config in feed.yml and link to it
([#552](#552))
([de08695](de08695))
* install Gemfile.lock specified bundler version
([4190160](4190160))
* integrate request_service and use ssrf_filter strategy by default
([#707](#707))
([b7516fd](b7516fd))
* link included feeds to the instance feed directory
([#901](#901))
([51ce79a](51ce79a))
* optionally allow APM using Sentry via env variable
([#696](#696))
([94477d5](94477d5))
* redact sensitive feed data in structured logs
([#903](#903))
([ee7df73](ee7df73))
* remove dependency on activesupport
([048cb73](048cb73))
* **runtime:** rebuild feed and api behavior around typed v1 services
([b61602d](b61602d))
* simplify feed creation contract & backend error handling
([#962](#962))
([dfca027](dfca027))
* stabilize public http interface & slimmer docker
([#882](#882))
([fe3f4be](fe3f4be))
* unify web and feed result surfaces
([#896](#896))
([e747b23](e747b23))
* use parallel processing for feed retrieval in health_check.rb
([#665](#665))
([4a24997](4a24997))


### Bug Fixes

* ArgumentError when RACK_TIMEOUT_SERVICE_TIMEOUT env var is set
([96acbab](96acbab)),
closes [#527](#527)
* **auto_source:** respect headers from global config
([#691](#691))
([3e9ba91](3e9ba91))
* **build:** only cleanup when there is a test container
([f7bafa6](f7bafa6))
* caching with dynamic parameters yields incorrect rss
([#589](#589))
([bb945c2](bb945c2)),
closes [#587](#587)
* **ci:** repair Ruby, OpenAPI, and frontend checks
([#880](#880))
([ec6673b](ec6673b))
* defects for token/retry/loading UX
([#924](#924))
([2d38633](2d38633))
* **docker:** missing curl installation for health check
([0bd9157](0bd9157))
* example feed in config/feeds.yml broken
([#664](#664))
([b961897](b961897))
* **frontend:** preserve created feeds when preview loading fails
([#915](#915))
([383ecc3](383ecc3))
* **frontend:** streamline web ux
([#916](#916))
([85e79bf](85e79bf))
* harden container config defaults
([392997c](392997c))
* healthcheck broken due to missing curl
([c97e746](c97e746))
* keep unknown api v1 paths inside the api contract
([a820478](a820478))
* responds with http status 422
([#738](#738))
([ad9394c](ad9394c))
* **runtime:** polish relaunch smoke behavior and health checks
([65e1644](65e1644))
* stylesheets not included in feed
([#779](#779))
([9116d9d](9116d9d))
* tzdata package not installed but required for tz conversion
([#663](#663))
([55814d2](55814d2))
* **web:** harden feed reader fallback and rss rendering
([#944](#944))
([438d9f6](438d9f6))
* **web:** harden observability env handling and Sentry log redaction
([#917](#917))
([ed2b3e9](ed2b3e9))


### Performance Improvements

* enable YJIT
([729f31f](729f31f))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
gildesmarais added a commit that referenced this pull request May 1, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.2.0](v1.1.0...v1.2.0)
(2026-05-01)


### Features

* add help text on error page
([eeee345](eeee345)),
closes [#338](#338)
* add routed frontend feed creation workflow
([#963](#963))
([2d1b71a](2d1b71a))
* **auto_source:** add support for `auto_source` feature
([#676](#676))
([531dced](531dced))
* default browserless onboarding and request strategies
([#895](#895))
([377cff0](377cff0))
* **deps:** use html2rss in latest development status
([#728](#728))
([5885d1d](5885d1d))
* **docker:** switch to alpine 21
([7adcc89](7adcc89))
* **docker:** upgrade to use ruby 3.3 image
([ceafe24](ceafe24))
* **docker:** use multilayer build to cut image size in half
([2f6e322](2f6e322))
* **docker:** use Ruby 3.4
([4f7d795](4f7d795))
* **frontend:** polish result experience and validation tooling
([#964](#964))
([b11665e](b11665e))
* **frontend:** relaunch the app with a focused v1 flow
([e0692d7](e0692d7))
* **frontend:** unify feed/result state flow
([#943](#943))
([6dfa1a9](6dfa1a9))
* **health_check:** add HTTP Basic authentication to `GET
/health_check.txt`
([#559](#559))
([d0ccd83](d0ccd83))
* improve example feed config in feed.yml and link to it
([#552](#552))
([de08695](de08695))
* install Gemfile.lock specified bundler version
([4190160](4190160))
* integrate request_service and use ssrf_filter strategy by default
([#707](#707))
([b7516fd](b7516fd))
* link included feeds to the instance feed directory
([#901](#901))
([51ce79a](51ce79a))
* optionally allow APM using Sentry via env variable
([#696](#696))
([94477d5](94477d5))
* redact sensitive feed data in structured logs
([#903](#903))
([ee7df73](ee7df73))
* remove dependency on activesupport
([048cb73](048cb73))
* **runtime:** rebuild feed and api behavior around typed v1 services
([b61602d](b61602d))
* simplify feed creation contract & backend error handling
([#962](#962))
([dfca027](dfca027))
* stabilize public http interface & slimmer docker
([#882](#882))
([fe3f4be](fe3f4be))
* unify web and feed result surfaces
([#896](#896))
([e747b23](e747b23))
* use parallel processing for feed retrieval in health_check.rb
([#665](#665))
([4a24997](4a24997))


### Bug Fixes

* ArgumentError when RACK_TIMEOUT_SERVICE_TIMEOUT env var is set
([96acbab](96acbab)),
closes [#527](#527)
* **auto_source:** respect headers from global config
([#691](#691))
([3e9ba91](3e9ba91))
* **build:** only cleanup when there is a test container
([f7bafa6](f7bafa6))
* caching with dynamic parameters yields incorrect rss
([#589](#589))
([bb945c2](bb945c2)),
closes [#587](#587)
* **ci:** repair Ruby, OpenAPI, and frontend checks
([#880](#880))
([ec6673b](ec6673b))
* **ci:** robustly parse release tags and align config
([#972](#972))
([2efd6ef](2efd6ef))
* defects for token/retry/loading UX
([#924](#924))
([2d38633](2d38633))
* **docker:** missing curl installation for health check
([0bd9157](0bd9157))
* example feed in config/feeds.yml broken
([#664](#664))
([b961897](b961897))
* **frontend:** preserve created feeds when preview loading fails
([#915](#915))
([383ecc3](383ecc3))
* **frontend:** streamline web ux
([#916](#916))
([85e79bf](85e79bf))
* harden container config defaults
([392997c](392997c))
* healthcheck broken due to missing curl
([c97e746](c97e746))
* keep unknown api v1 paths inside the api contract
([a820478](a820478))
* responds with http status 422
([#738](#738))
([ad9394c](ad9394c))
* **runtime:** polish relaunch smoke behavior and health checks
([65e1644](65e1644))
* stylesheets not included in feed
([#779](#779))
([9116d9d](9116d9d))
* tzdata package not installed but required for tz conversion
([#663](#663))
([55814d2](55814d2))
* **web:** harden feed reader fallback and rss rendering
([#944](#944))
([438d9f6](438d9f6))
* **web:** harden observability env handling and Sentry log redaction
([#917](#917))
([ed2b3e9](ed2b3e9))


### Performance Improvements

* enable YJIT
([729f31f](729f31f))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants