enable readOnlyRootFilesystem in helm chart#14
Merged
Conversation
3 tasks
The app holds the cache in memory, reads config once at startup from a baked-in /config.yaml, and writes only to stdout/stderr — no filesystem writes anywhere in the code. Setting readOnlyRootFilesystem true is compatible and gives us a kernel-enforced barrier against write-based exploits compromising the container. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The cache's poll loop used http.Get with no timeout, so a slow or hung upstream could leave a request blocked indefinitely and stall the update cycle. Give the cache a dedicated *http.Client with a 30s timeout (well within the 5m default update interval). The HTTP server lacked ReadHeaderTimeout, leaving it slightly more exposed to slowloris-style header-dribble. Add a 5s ReadHeaderTimeout on top of the existing ReadTimeout/WriteTimeout/IdleTimeout. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…y headers
Cache fetch:
Wrap the upstream body in io.LimitReader (100 MiB compressed) and
the gzip stream in another LimitReader (1 GiB decompressed) so a
hostile or misbehaving upstream can't blow the container's memory.
HTTP server:
Set MaxHeaderBytes to 16 KiB on both servers, complementing the
ReadHeaderTimeout. Add a securityHeaders middleware that emits
X-Content-Type-Options, X-Frame-Options, and Referrer-Policy.
/metrics on its own listener:
Run a second http.Server bound to a separate port (default 9090).
This lets the operator scope /metrics network exposure independently
of the public API. Helm chart now renders a dedicated ClusterIP
service for metrics so the LoadBalancer never exposes /metrics
externally; ServiceMonitor and probes target the new port.
Webapp:
Cap ?search= at 32 chars (real station IDs are 3-4) so a multi-MB
query can't amplify CPU through the per-station Contains scan.
Error responses:
Replace internal-error leaks ("failed to encode JSON: %v", etc.) in
/api/metar, /search, and / with generic 500s. Full detail still goes
to the server log.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
365f0a1 to
c86e358
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
securityContext.readOnlyRootFilesystemfromfalsetotruein the chart'svalues.yaml.os.Create/OpenFile/WriteFile/temp-file usage). Config is baked into the image at/config.yamland read once at startup; the METAR cache is in-memory; logs go to stdout/stderr.Test plan
helm lint deploy/charts/avweather-cache— clean.helm templateconfirms rendered pod spec hasreadOnlyRootFilesystem: true./api/metarand/metrics, confirm the pod stays Ready and METAR pulls from aviationweather.gov continue to succeed.🤖 Generated with Claude Code