feat: Removed SQL Lite for Valkey storage for server scalability. Perfomed full UI security review and addressed findings#69
Merged
Conversation
- Replace custom splitN/indexOf helpers with strings.SplitN - Restore nil guard for mostDownloaded in ui_stats.go after error - Add readinessProbe (valkey-cli ping) to valkey-deployment.yaml - Remove out-of-scope pkg/registry line from services/version/go.mod - Add stats smoke e2e test: Module CR + Version CR download + totalDownloads/mostDownloaded assertions
- Run go mod tidy to move go-redis/v9 and miniredis/v2 to direct require block - Add browse resources assertion to smoke test: assert totalDownloads >= 1 via /opendepot/ui/v1/resources after download
…L auth
- Replace 4 hand-rolled Valkey templates (deployment, service, serviceaccount,
PVC) with the official valkey-io/valkey-helm v0.9.4 subchart committed as
chart/opendepot/charts/valkey-0.9.4.tgz
- Add fullnameOverride: valkey so the generated Service name stays 'valkey',
preserving the existing --stats-valkey-addr flag in server-deployment.yaml
- Replace valkey.persistence.* values with subchart-native valkey.dataStorage.*
keys in values.yaml; update all 3 e2e --set flags accordingly
- Add opt-in ACL password authentication:
- values.yaml: valkey.auth.{enabled,usersExistingSecret,aclUsers} + server.stats.valkeyPasswordSecretName
- server-deployment.yaml: conditional env block injecting OPENDEPOT_VALKEY_PASSWORD from secretKeyRef
- services/server/main.go: redis.Options.Password from os.Getenv("OPENDEPOT_VALKEY_PASSWORD")
- Add e2e test Context 'with Valkey ACL auth enabled' in Server Authentication
Describe: creates BYO Secret, deploys with auth flags, asserts /opendepot/ui/v1/stats returns 200
- Makefile: add chart-deps target (helm dependency update); wire into ui-setup
and ui-setup-oidc prerequisites; remove stale server.stats.emptyDir flags
- CONTRIBUTING.md: add Chart Dependencies callout explaining make chart-deps
All 63 e2e specs pass.
- Replace valkey.persistence.* with valkey.dataStorage.* in all docs
- Add valkey.auth.{enabled,usersExistingSecret,aclUsers} and
server.stats.valkeyPasswordSecretName rows to helm-chart.md and installation.md
- Add production security callout recommending ACL auth and ESO/Vault
- Fix registry-explorer.md YAML snippet
- Fix migration.md persistence key reference
…it, pin image tag, add .trivyignore
…6-4878 with tracking note
… NGINX configmap ## Changes ### Dockerfile (services/ui/Dockerfile) - Add `apk upgrade --no-cache` in runner stage to resolve 32 Alpine CVEs (2 CRITICAL, 30 HIGH) in libcrypto3/libssl3, musl, zlib, libpng, libxml2, libexpat, and nghttp2-libs ### Entrypoint (services/ui/entrypoint.sh) - Bind Next.js standalone server to 127.0.0.1 instead of 0.0.0.0 to prevent in-cluster workloads from bypassing NGINX security headers ### NGINX (services/ui/nginx.conf + chart/opendepot/templates/ui-configmap.yaml) - Add `client_max_body_size 10m` to prevent large-upload DoS - Replace `$http_host` with `$host` by default to prevent Host header injection; new `ui.nginx.preserveHostPort` flag (default: false) opts in to `$http_host` for local dev at non-standard ports - Add HSTS header (`Strict-Transport-Security`) when server.tls.enabled - Add justification comment above `proxy_ssl_verify off` ### Helm chart (chart/opendepot/templates/ui-deployment.yaml) - Enforce `ui.sessionPasswordSecretName` at install time via Helm `required` — prevents silently broken deployments with no session key ### Helm values (chart/opendepot/values.yaml) - Add `ui.nginx.preserveHostPort: false` (secure default) ### Makefile - Set `ui.nginx.preserveHostPort=true` in `ui-deploy-anon` and full e2e targets where localtest.me:port requires the port in the Host header ### Sidebar component (services/ui/src/components/Sidebar.tsx) - Remove undocumented `NEXT_PUBLIC_API_BASE_URL` variable; use hardcoded relative URL to prevent accidental internal hostname exposure ### Security agent (\.github/agents/security-review.agent.md) - Expand coverage to include TypeScript/React, NGINX, Valkey, iron-session, GPG signing, and cloud storage credentials
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.
Overview
This PR replaces the SQLite-backed statistics store with Valkey (Redis-compatible) for horizontal scalability, migrates the Valkey deployment to the official
valkey-io/valkey-helmsubchart, and performs a complete first-ever security review of the UI service.Changes
Stats store: SQLite → Valkey
services/server/stats_db.goandstats_db_test.go(316 + 126 lines of SQLite implementation)services/server/stats_valkey.goandstats_valkey_test.go— full Valkey-backed stats implementation with connection pooling, pipeline support, and test coverageservices/server/main.go,ui_browse.go,ui_stats.go,storage.go,types.goto wire the new stats backendchart/opendepot/templates/server-stats-pvc.yaml— PVC no longer needed without SQLiteservices/server/test/e2e/e2e_test.goto cover the Valkey stats pathHelm chart: Valkey subchart migration
charts/dex-0.24.0.tgz→dex-0.24.1.tgz(patch update)charts/valkey-0.9.4.tgz— officialvalkey-io/valkey-helmsubchart (replaces inline deployment)chart/opendepot/Chart.yamlandChart.lockfor new dependencieschart/opendepot/values.yamlwith Valkey subchart configuration including opt-in ACL auth and image tag pinned to"8"(LTS)chart/opendepot/templates/server-deployment.yamlfor new Valkey connection env varsUI security review (first-ever)
All findings from the full review of
services/ui/are resolved in this PR.Image CVEs (32 fixed — 2 CRITICAL, 30 HIGH):
apk upgrade --no-cachein Dockerfile runner stage — resolves CVEs in libcrypto3/libssl3, musl, zlib, libpng, libxml2, libexpat, nghttp2-libsNGINX hardening (
services/ui/nginx.conf+chart/opendepot/templates/ui-configmap.yaml):client_max_body_size 10mto prevent large-upload DoS$http_hostwith$hostby default to prevent Host header injectionui.nginx.preserveHostPortflag (default:false) — set totruein local dev/e2e targets whereopendepot.localtest.me:PORTrequires the port in the Host headerStrict-Transport-Security) whenserver.tls.enabled=trueproxy_ssl_verify off(self-signed cert path)Session hardening (
chart/opendepot/templates/ui-deployment.yaml):ui.sessionPasswordSecretNamenow enforced athelm installtime viarequired— prevents silently broken deployments with no encryption keyNext.js binding (
services/ui/entrypoint.sh):127.0.0.1instead of0.0.0.0— prevents in-cluster workloads from bypassing NGINX security headers by hitting port 3000 directlySidebar component (
services/ui/src/components/Sidebar.tsx):NEXT_PUBLIC_API_BASE_URL— hardcoded relative URL prevents accidental internal hostname exposure in the browser bundleTrivy suppressions (
.trivyignore)Security agent (
.github/agents/security-review.agent.md)Documentation
docs/getting-started/installation.md,docs/guides/migration.md,docs/guides/registry-explorer.md,docs/helm-chart.md,docs/reference/api.mdto reflect Valkey subchart, new values, and UI changesoverrides/main.htmlto reflect current chart versionScan Results
trivy image ghcr.io/tonedefdev/opendepot/ui:devyarn npm audit --severity hightrivy config chart/opendepot/trivy fs --scanners secret,misconfig services/ui/