From 0f0fcb8e19dd9629db4eef53218eff3965dd8f9d Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Fri, 23 Oct 2026 23:51:51 +0500 Subject: [PATCH 01/42] helm: default secrets.create to false in every chart Eleven charts rendered an in-chart Secret by default from committed dev placeholders (a DSN with password 'dev-****' and sslmode=disable). An install that forgot secrets.existingSecret silently shipped that known credential. - secrets.create now defaults to false. The Deployment envFroms a Secret named secrets.existingSecret, falling back to the chart fullname, which is the name the ExternalSecret for fp-auth already targets. A missing Secret now stops the pod from starting instead of running with placeholders. - The secretName helper used `required` on existingSecret, which contradicted the values comment ("defaults to the chart's fullname when empty"). The helper now does what the comment says. - The migrate initContainer gate no longer requires existingSecret to be set explicitly when create=false. - make helm-install / helm-upgrade pass --set secrets.create=true, so the local Kind flow is unchanged. Side effect worth knowing: with the old default, 11 of 12 charts failed to render without a jwtSecret, so Trivy's Helm scanner could not render them and skipped them. They now render with default values. Co-Authored-By: Claude Opus 5.5 --- Makefile | 5 +++++ deploy/argocd/README.md | 4 ++-- deploy/helm/fp-ai-gateway/templates/_helpers.tpl | 2 +- deploy/helm/fp-ai-gateway/templates/deployment.yaml | 4 ++-- deploy/helm/fp-ai-gateway/values.yaml | 13 +++++++++---- deploy/helm/fp-auth/templates/_helpers.tpl | 2 +- deploy/helm/fp-auth/templates/deployment.yaml | 4 ++-- deploy/helm/fp-auth/values.yaml | 13 +++++++++---- deploy/helm/fp-billing/templates/_helpers.tpl | 2 +- deploy/helm/fp-billing/templates/deployment.yaml | 4 ++-- deploy/helm/fp-billing/values.yaml | 13 +++++++++---- .../fp-experiment-tracker/templates/_helpers.tpl | 2 +- .../fp-experiment-tracker/templates/deployment.yaml | 4 ++-- deploy/helm/fp-experiment-tracker/values.yaml | 13 +++++++++---- deploy/helm/fp-feature-store/templates/_helpers.tpl | 2 +- .../helm/fp-feature-store/templates/deployment.yaml | 4 ++-- deploy/helm/fp-feature-store/values.yaml | 13 +++++++++---- .../fp-inference-gateway/templates/_helpers.tpl | 2 +- deploy/helm/fp-inference-gateway/values.yaml | 13 +++++++++---- deploy/helm/fp-model-monitor/templates/_helpers.tpl | 2 +- .../helm/fp-model-monitor/templates/deployment.yaml | 4 ++-- deploy/helm/fp-model-monitor/values.yaml | 13 +++++++++---- deploy/helm/fp-model-serving/templates/_helpers.tpl | 2 +- deploy/helm/fp-model-serving/values.yaml | 13 +++++++++---- deploy/helm/fp-notification/templates/_helpers.tpl | 2 +- .../helm/fp-notification/templates/deployment.yaml | 4 ++-- deploy/helm/fp-notification/values.yaml | 13 +++++++++---- .../fp-pipeline-orchestrator/templates/_helpers.tpl | 2 +- .../templates/deployment.yaml | 4 ++-- deploy/helm/fp-pipeline-orchestrator/values.yaml | 13 +++++++++---- deploy/helm/fp-registry/templates/_helpers.tpl | 2 +- deploy/helm/fp-registry/templates/deployment.yaml | 4 ++-- deploy/helm/fp-registry/values.yaml | 13 +++++++++---- 33 files changed, 135 insertions(+), 75 deletions(-) diff --git a/Makefile b/Makefile index 0ea51c3..8af9c17 100644 --- a/Makefile +++ b/Makefile @@ -346,6 +346,9 @@ kind-load: ## Load Docker image into Kind: make kind-load SVC=auth # Helm # ============================================================================ +# Local Kind installs render the chart's own dev Secret (secrets.create=true). +# The chart default is false so that a real install fails closed on a missing +# Secret instead of shipping the committed dev placeholders. .PHONY: helm-install helm-install: ## Install service via Helm: make helm-install SVC=auth @if [ -z "$(SVC)" ]; then echo "ERROR: specify SVC="; exit 1; fi @@ -353,6 +356,7 @@ helm-install: ## Install service via Helm: make helm-install SVC=auth helm install fp-$(SVC) deploy/helm/fp-$(SVC)/ \ --namespace $(NAMESPACE) \ --create-namespace \ + --set secrets.create=true \ --set image.repository=$(REGISTRY)-$(SVC) \ --set image.tag=$(IMAGE_TAG) @@ -362,6 +366,7 @@ helm-upgrade: ## Upgrade service via Helm: make helm-upgrade SVC=auth @echo "==> Upgrading $(SVC) via Helm in namespace $(NAMESPACE)..." helm upgrade fp-$(SVC) deploy/helm/fp-$(SVC)/ \ --namespace $(NAMESPACE) \ + --set secrets.create=true \ --set image.repository=$(REGISTRY)-$(SVC) \ --set image.tag=$(IMAGE_TAG) diff --git a/deploy/argocd/README.md b/deploy/argocd/README.md index e12d652..882efa9 100644 --- a/deploy/argocd/README.md +++ b/deploy/argocd/README.md @@ -201,8 +201,8 @@ The AppProject is least privilege for the delivery layer itself: ## Secrets note GitOps means manifests live in Git — so plaintext secrets must NOT. The fp-auth -chart's in-chart Secret holds **dev-only placeholders** (see its values.yaml -SECURITY CONTRACT). In prod, `secrets.create: false` and the real Secret comes +chart's optional in-chart Secret holds **dev-only placeholders** (see its values.yaml +SECURITY CONTRACT), so `secrets.create` defaults to `false` and the real Secret comes from **External Secrets Operator** or **Sealed Secrets** (ADR-0002 follow-up, Phase 17) — the encrypted/sealed material is safe to commit, the plaintext never is. ``` diff --git a/deploy/helm/fp-ai-gateway/templates/_helpers.tpl b/deploy/helm/fp-ai-gateway/templates/_helpers.tpl index 7998c9f..1b13acd 100644 --- a/deploy/helm/fp-ai-gateway/templates/_helpers.tpl +++ b/deploy/helm/fp-ai-gateway/templates/_helpers.tpl @@ -109,7 +109,7 @@ secrets.existingSecret. Either way the Deployment references ONE stable name. {{- if .Values.secrets.create -}} {{- include "fp-ai-gateway.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-ai-gateway.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-ai-gateway/templates/deployment.yaml b/deploy/helm/fp-ai-gateway/templates/deployment.yaml index 6f22081..2f21914 100644 --- a/deploy/helm/fp-ai-gateway/templates/deployment.yaml +++ b/deploy/helm/fp-ai-gateway/templates/deployment.yaml @@ -110,7 +110,7 @@ spec: IDEMPOTENCY: golang-migrate tracks the applied version in schema_migrations. A re-deploy with no new files prints "no change" and exits 0. */}} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} initContainers: - name: migrate image: "{{ .Values.migrations.image.repository }}:{{ .Values.migrations.image.tag }}" @@ -226,7 +226,7 @@ spec: volumes: - name: tmp emptyDir: {} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} # The migrations ConfigMap (the chart's migrations/*.sql) mounted into the # migrate initContainer at /migrations. defaultMode 0444 = world-readable, # read-only -- the nonroot migrate process can read it without owning it. diff --git a/deploy/helm/fp-ai-gateway/values.yaml b/deploy/helm/fp-ai-gateway/values.yaml index b0e4d9d..3b2711a 100644 --- a/deploy/helm/fp-ai-gateway/values.yaml +++ b/deploy/helm/fp-ai-gateway/values.yaml @@ -163,9 +163,9 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # # The gateway has TWO sensitive values: # - redisUrl (FP_REDIS_URL): the DSN may embed a password / TLS auth. @@ -178,7 +178,12 @@ config: # a signing key is access-controlled, not plaintext config. # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" diff --git a/deploy/helm/fp-auth/templates/_helpers.tpl b/deploy/helm/fp-auth/templates/_helpers.tpl index 69abff6..1948178 100644 --- a/deploy/helm/fp-auth/templates/_helpers.tpl +++ b/deploy/helm/fp-auth/templates/_helpers.tpl @@ -104,7 +104,7 @@ secrets.existingSecret. Either way the Deployment references ONE stable name. {{- if .Values.secrets.create -}} {{- include "fp-auth.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-auth.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-auth/templates/deployment.yaml b/deploy/helm/fp-auth/templates/deployment.yaml index 9979a93..db987f5 100644 --- a/deploy/helm/fp-auth/templates/deployment.yaml +++ b/deploy/helm/fp-auth/templates/deployment.yaml @@ -104,7 +104,7 @@ spec: A re-deploy with no new files prints "no change" and exits 0 — safe to run on every rollout and every replica (it serializes on the DB). */}} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} initContainers: - name: migrate image: "{{ .Values.migrations.image.repository }}:{{ .Values.migrations.image.tag }}" @@ -218,7 +218,7 @@ spec: volumes: - name: tmp emptyDir: {} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} # The migrations ConfigMap (the chart's migrations/*.sql) mounted into the # migrate initContainer at /migrations. defaultMode 0444 = world-readable, # read-only — the nonroot migrate process can read it without owning it. diff --git a/deploy/helm/fp-auth/values.yaml b/deploy/helm/fp-auth/values.yaml index 46c888e..9101ddd 100644 --- a/deploy/helm/fp-auth/values.yaml +++ b/deploy/helm/fp-auth/values.yaml @@ -92,12 +92,17 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" diff --git a/deploy/helm/fp-billing/templates/_helpers.tpl b/deploy/helm/fp-billing/templates/_helpers.tpl index 7a8416e..57d34ba 100644 --- a/deploy/helm/fp-billing/templates/_helpers.tpl +++ b/deploy/helm/fp-billing/templates/_helpers.tpl @@ -104,7 +104,7 @@ secrets.existingSecret. Either way the Deployment references ONE stable name. {{- if .Values.secrets.create -}} {{- include "fp-billing.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-billing.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-billing/templates/deployment.yaml b/deploy/helm/fp-billing/templates/deployment.yaml index 33ff410..4f63420 100644 --- a/deploy/helm/fp-billing/templates/deployment.yaml +++ b/deploy/helm/fp-billing/templates/deployment.yaml @@ -105,7 +105,7 @@ spec: A re-deploy with no new files prints "no change" and exits 0 -- safe to run on every rollout and every replica (it serializes on the DB). */}} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} initContainers: - name: migrate image: "{{ .Values.migrations.image.repository }}:{{ .Values.migrations.image.tag }}" @@ -220,7 +220,7 @@ spec: volumes: - name: tmp emptyDir: {} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} # The migrations ConfigMap (the chart's migrations/*.sql) mounted into the # migrate initContainer at /migrations. defaultMode 0444 = world-readable, # read-only -- the nonroot migrate process can read it without owning it. diff --git a/deploy/helm/fp-billing/values.yaml b/deploy/helm/fp-billing/values.yaml index a5dfe73..cd03500 100644 --- a/deploy/helm/fp-billing/values.yaml +++ b/deploy/helm/fp-billing/values.yaml @@ -112,16 +112,21 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # # Billing has TWO secrets: the Postgres DSN and the JWT VERIFY key (FP_JWT_SECRET, # the shared HMAC key the auth interceptor uses to verify token signatures — see # the header). Neither is a JWT SIGNING key; billing never mints tokens. # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" diff --git a/deploy/helm/fp-experiment-tracker/templates/_helpers.tpl b/deploy/helm/fp-experiment-tracker/templates/_helpers.tpl index 5475f49..70c6578 100644 --- a/deploy/helm/fp-experiment-tracker/templates/_helpers.tpl +++ b/deploy/helm/fp-experiment-tracker/templates/_helpers.tpl @@ -106,7 +106,7 @@ secrets.existingSecret. Either way the Deployment references ONE stable name. {{- if .Values.secrets.create -}} {{- include "fp-experiment-tracker.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-experiment-tracker.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-experiment-tracker/templates/deployment.yaml b/deploy/helm/fp-experiment-tracker/templates/deployment.yaml index 0633412..93c0469 100644 --- a/deploy/helm/fp-experiment-tracker/templates/deployment.yaml +++ b/deploy/helm/fp-experiment-tracker/templates/deployment.yaml @@ -106,7 +106,7 @@ spec: A re-deploy with no new files prints "no change" and exits 0 -- safe to run on every rollout and every replica (it serializes on the DB). */}} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} initContainers: - name: migrate image: "{{ .Values.migrations.image.repository }}:{{ .Values.migrations.image.tag }}" @@ -220,7 +220,7 @@ spec: volumes: - name: tmp emptyDir: {} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} # The migrations ConfigMap (the chart's migrations/*.sql) mounted into the # migrate initContainer at /migrations. defaultMode 0444 = world-readable, # read-only -- the nonroot migrate process can read it without owning it. diff --git a/deploy/helm/fp-experiment-tracker/values.yaml b/deploy/helm/fp-experiment-tracker/values.yaml index 824edd9..fcfc0e9 100644 --- a/deploy/helm/fp-experiment-tracker/values.yaml +++ b/deploy/helm/fp-experiment-tracker/values.yaml @@ -104,9 +104,9 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # # This service does NOT MINT JWTs (auth is the sole minter), but it MUST VERIFY # caller JWTs in-process for its auth interceptor (design D2 — local HMAC verify, @@ -116,7 +116,12 @@ config: # JWT signing key and its own Postgres DSN. # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" diff --git a/deploy/helm/fp-feature-store/templates/_helpers.tpl b/deploy/helm/fp-feature-store/templates/_helpers.tpl index 2b9029d..161026f 100644 --- a/deploy/helm/fp-feature-store/templates/_helpers.tpl +++ b/deploy/helm/fp-feature-store/templates/_helpers.tpl @@ -107,7 +107,7 @@ secrets.existingSecret. Either way the Deployment references ONE stable name. {{- if .Values.secrets.create -}} {{- include "fp-feature-store.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-feature-store.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-feature-store/templates/deployment.yaml b/deploy/helm/fp-feature-store/templates/deployment.yaml index 03a3359..b17320c 100644 --- a/deploy/helm/fp-feature-store/templates/deployment.yaml +++ b/deploy/helm/fp-feature-store/templates/deployment.yaml @@ -104,7 +104,7 @@ spec: A re-deploy with no new files prints "no change" and exits 0 -- safe to run on every rollout and every replica (it serializes on the DB). */}} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} initContainers: - name: migrate image: "{{ .Values.migrations.image.repository }}:{{ .Values.migrations.image.tag }}" @@ -218,7 +218,7 @@ spec: volumes: - name: tmp emptyDir: {} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} # The migrations ConfigMap (the chart's migrations/*.sql) mounted into the # migrate initContainer at /migrations. defaultMode 0444 = world-readable, # read-only -- the nonroot migrate process can read it without owning it. diff --git a/deploy/helm/fp-feature-store/values.yaml b/deploy/helm/fp-feature-store/values.yaml index 65193da..35ee372 100644 --- a/deploy/helm/fp-feature-store/values.yaml +++ b/deploy/helm/fp-feature-store/values.yaml @@ -94,9 +94,9 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # # NOTE vs fp-auth: feature-store does NOT MINT tokens (auth does) — but it must # VERIFY them. The shared authentication interceptor verifies each caller's JWT @@ -109,7 +109,12 @@ config: # FP_JWT_SECRET from a managed store exactly like FP_DATABASE_URL. # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" diff --git a/deploy/helm/fp-inference-gateway/templates/_helpers.tpl b/deploy/helm/fp-inference-gateway/templates/_helpers.tpl index 5cf73bf..6cdeb54 100644 --- a/deploy/helm/fp-inference-gateway/templates/_helpers.tpl +++ b/deploy/helm/fp-inference-gateway/templates/_helpers.tpl @@ -109,7 +109,7 @@ secrets.existingSecret. Either way the Deployment references ONE stable name. {{- if .Values.secrets.create -}} {{- include "fp-inference-gateway.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-inference-gateway.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-inference-gateway/values.yaml b/deploy/helm/fp-inference-gateway/values.yaml index df50b5f..6d765c1 100644 --- a/deploy/helm/fp-inference-gateway/values.yaml +++ b/deploy/helm/fp-inference-gateway/values.yaml @@ -125,9 +125,9 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # # The gateway has TWO sensitive values: # - redisUrl (FP_REDIS_URL): the DSN may embed a password / TLS auth. @@ -140,7 +140,12 @@ config: # a signing key is access-controlled, not plaintext config. # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" diff --git a/deploy/helm/fp-model-monitor/templates/_helpers.tpl b/deploy/helm/fp-model-monitor/templates/_helpers.tpl index 2cb754b..a6aef4c 100644 --- a/deploy/helm/fp-model-monitor/templates/_helpers.tpl +++ b/deploy/helm/fp-model-monitor/templates/_helpers.tpl @@ -106,7 +106,7 @@ secrets.existingSecret. Either way the Deployment references ONE stable name. {{- if .Values.secrets.create -}} {{- include "fp-model-monitor.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-model-monitor.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-model-monitor/templates/deployment.yaml b/deploy/helm/fp-model-monitor/templates/deployment.yaml index 4cf48e9..168b0e2 100644 --- a/deploy/helm/fp-model-monitor/templates/deployment.yaml +++ b/deploy/helm/fp-model-monitor/templates/deployment.yaml @@ -104,7 +104,7 @@ spec: A re-deploy with no new files prints "no change" and exits 0 -- safe to run on every rollout and every replica (it serializes on the DB). */}} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} initContainers: - name: migrate image: "{{ .Values.migrations.image.repository }}:{{ .Values.migrations.image.tag }}" @@ -219,7 +219,7 @@ spec: volumes: - name: tmp emptyDir: {} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} # The migrations ConfigMap (the chart's migrations/*.sql) mounted into the # migrate initContainer at /migrations. defaultMode 0444 = world-readable, # read-only -- the nonroot migrate process can read it without owning it. diff --git a/deploy/helm/fp-model-monitor/values.yaml b/deploy/helm/fp-model-monitor/values.yaml index 259ad39..13ee253 100644 --- a/deploy/helm/fp-model-monitor/values.yaml +++ b/deploy/helm/fp-model-monitor/values.yaml @@ -154,9 +154,9 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # # NOTE vs fp-auth: model-monitor does NOT mint tokens, but it MUST verify them — so # it DOES carry a jwtSecret (the shared auth interceptor's HS256 verify key, design @@ -164,7 +164,12 @@ config: # the Postgres DSN and the Redis URL (both may embed creds). # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" diff --git a/deploy/helm/fp-model-serving/templates/_helpers.tpl b/deploy/helm/fp-model-serving/templates/_helpers.tpl index e9c3f80..cc74e8c 100644 --- a/deploy/helm/fp-model-serving/templates/_helpers.tpl +++ b/deploy/helm/fp-model-serving/templates/_helpers.tpl @@ -109,7 +109,7 @@ DSN or JWT key (this service has neither). {{- if .Values.secrets.create -}} {{- include "fp-model-serving.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-model-serving.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-model-serving/values.yaml b/deploy/helm/fp-model-serving/values.yaml index 17ae9f3..7af2e5a 100644 --- a/deploy/helm/fp-model-serving/values.yaml +++ b/deploy/helm/fp-model-serving/values.yaml @@ -141,9 +141,9 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # # Unlike fp-auth (which also has a DB DSN), model-serving has no database. It # DOES share fp-auth's JWT signing key (the gRPC auth interceptor verifies every @@ -152,7 +152,12 @@ config: # pull the artifact. # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" diff --git a/deploy/helm/fp-notification/templates/_helpers.tpl b/deploy/helm/fp-notification/templates/_helpers.tpl index bcbfdb7..6f372b1 100644 --- a/deploy/helm/fp-notification/templates/_helpers.tpl +++ b/deploy/helm/fp-notification/templates/_helpers.tpl @@ -105,7 +105,7 @@ secrets.existingSecret. Either way the Deployment references ONE stable name. {{- if .Values.secrets.create -}} {{- include "fp-notification.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-notification.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-notification/templates/deployment.yaml b/deploy/helm/fp-notification/templates/deployment.yaml index 49d7ea7..81bf4c0 100644 --- a/deploy/helm/fp-notification/templates/deployment.yaml +++ b/deploy/helm/fp-notification/templates/deployment.yaml @@ -104,7 +104,7 @@ spec: A re-deploy with no new files prints "no change" and exits 0 -- safe to run on every rollout and every replica (it serializes on the DB). */}} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} initContainers: - name: migrate image: "{{ .Values.migrations.image.repository }}:{{ .Values.migrations.image.tag }}" @@ -218,7 +218,7 @@ spec: volumes: - name: tmp emptyDir: {} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} # The migrations ConfigMap (the chart's migrations/*.sql) mounted into the # migrate initContainer at /migrations. defaultMode 0444 = world-readable, # read-only -- the nonroot migrate process can read it without owning it. diff --git a/deploy/helm/fp-notification/values.yaml b/deploy/helm/fp-notification/values.yaml index 03a548a..33eb7cc 100644 --- a/deploy/helm/fp-notification/values.yaml +++ b/deploy/helm/fp-notification/values.yaml @@ -111,9 +111,9 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # # WHY a jwtSecret here even though notification does NOT mint tokens: the gRPC auth # interceptor VERIFIES every caller's JWT locally (design D2 — no per-request hop to @@ -124,7 +124,12 @@ config: # (NOT the ConfigMap) because it is sensitive symmetric key material. # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" diff --git a/deploy/helm/fp-pipeline-orchestrator/templates/_helpers.tpl b/deploy/helm/fp-pipeline-orchestrator/templates/_helpers.tpl index 6055c70..0560355 100644 --- a/deploy/helm/fp-pipeline-orchestrator/templates/_helpers.tpl +++ b/deploy/helm/fp-pipeline-orchestrator/templates/_helpers.tpl @@ -105,7 +105,7 @@ secrets.existingSecret. Either way the Deployment references ONE stable name. {{- if .Values.secrets.create -}} {{- include "fp-pipeline-orchestrator.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-pipeline-orchestrator.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-pipeline-orchestrator/templates/deployment.yaml b/deploy/helm/fp-pipeline-orchestrator/templates/deployment.yaml index 91c7bb7..e008cae 100644 --- a/deploy/helm/fp-pipeline-orchestrator/templates/deployment.yaml +++ b/deploy/helm/fp-pipeline-orchestrator/templates/deployment.yaml @@ -106,7 +106,7 @@ spec: A re-deploy with no new files prints "no change" and exits 0 -- safe to run on every rollout and every replica (it serializes on the DB). */}} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} initContainers: - name: migrate image: "{{ .Values.migrations.image.repository }}:{{ .Values.migrations.image.tag }}" @@ -220,7 +220,7 @@ spec: volumes: - name: tmp emptyDir: {} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} # The migrations ConfigMap (the chart's migrations/*.sql) mounted into the # migrate initContainer at /migrations. defaultMode 0444 = world-readable, # read-only -- the nonroot migrate process can read it without owning it. diff --git a/deploy/helm/fp-pipeline-orchestrator/values.yaml b/deploy/helm/fp-pipeline-orchestrator/values.yaml index 845e7ea..9fe6987 100644 --- a/deploy/helm/fp-pipeline-orchestrator/values.yaml +++ b/deploy/helm/fp-pipeline-orchestrator/values.yaml @@ -95,9 +95,9 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # # NOTE vs fp-auth: the orchestrator does not MINT tokens (only fp-auth holds the # authority to issue them), but it DOES need the shared HMAC key to VERIFY inbound @@ -105,7 +105,12 @@ config: # the SAME jwtSecret as fp-auth, plus its own Postgres DSN. # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" diff --git a/deploy/helm/fp-registry/templates/_helpers.tpl b/deploy/helm/fp-registry/templates/_helpers.tpl index c78aa95..06eb2f2 100644 --- a/deploy/helm/fp-registry/templates/_helpers.tpl +++ b/deploy/helm/fp-registry/templates/_helpers.tpl @@ -105,7 +105,7 @@ secrets.existingSecret. Either way the Deployment references ONE stable name. {{- if .Values.secrets.create -}} {{- include "fp-registry.fullname" . -}} {{- else -}} -{{- required "secrets.create=false requires secrets.existingSecret to name the externally-managed Secret" .Values.secrets.existingSecret -}} +{{- default (include "fp-registry.fullname" .) .Values.secrets.existingSecret -}} {{- end -}} {{- end -}} diff --git a/deploy/helm/fp-registry/templates/deployment.yaml b/deploy/helm/fp-registry/templates/deployment.yaml index 359514b..5467b53 100644 --- a/deploy/helm/fp-registry/templates/deployment.yaml +++ b/deploy/helm/fp-registry/templates/deployment.yaml @@ -104,7 +104,7 @@ spec: A re-deploy with no new files prints "no change" and exits 0 -- safe to run on every rollout and every replica (it serializes on the DB). */}} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} initContainers: - name: migrate image: "{{ .Values.migrations.image.repository }}:{{ .Values.migrations.image.tag }}" @@ -219,7 +219,7 @@ spec: volumes: - name: tmp emptyDir: {} - {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (and (not .Values.secrets.create) .Values.secrets.existingSecret)) }} + {{- if and .Values.migrations.enabled (or (and .Values.secrets.create .Values.secrets.databaseUrl) (not .Values.secrets.create)) }} # The migrations ConfigMap (the chart's migrations/*.sql) mounted into the # migrate initContainer at /migrations. defaultMode 0444 = world-readable, # read-only -- the nonroot migrate process can read it without owning it. diff --git a/deploy/helm/fp-registry/values.yaml b/deploy/helm/fp-registry/values.yaml index 440e67e..ea53fb9 100644 --- a/deploy/helm/fp-registry/values.yaml +++ b/deploy/helm/fp-registry/values.yaml @@ -111,16 +111,21 @@ config: # below. Convenient for local Kind; NEVER commit real # values here. # secrets.create: false → chart renders NO Secret. You must provide a Secret -# named `secrets.existingSecret` out-of-band (External -# Secrets / Sealed Secrets / kubectl). The Deployment -# still envFrom's it. +# named `secrets.existingSecret` (default: the chart +# fullname) out-of-band (External Secrets / Sealed +# Secrets / kubectl). The Deployment still envFrom's it. # Registry carries TWO secrets: the Postgres DSN (password is the sensitive part) # and the shared jwtSecret it uses to VERIFY inbound JWTs (design D2 local verify — # it does NOT sign tokens; that's auth's job). The jwtSecret MUST equal auth's # FP_JWT_SECRET byte-for-byte, or tokens auth mints fail verification here. # ---------------------------------------------------------------------------- secrets: - create: true + # DEFAULT false (fail-closed). The chart renders NO Secret and the Deployment + # envFrom's an externally-managed one (External Secrets Operator / Sealed + # Secrets). If that Secret is missing the pod fails to start, instead of + # silently running with the committed dev placeholders below. Local Kind: + # `make helm-install` passes --set secrets.create=true. + create: false # When create=false, the Deployment envFrom's this externally-managed Secret. # Defaults to the chart's fullname when empty (see _helpers "secretName"). existingSecret: "" From cb19e95a71017f57c56c43c1151e77291eb3007d Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Fri, 23 Oct 2026 23:52:31 +0500 Subject: [PATCH 02/42] helm: pin the migrate initContainer image by digest Nine charts pulled migrate/migrate:v4.18.3 from Docker Hub by tag, under a comment calling it "an immutable tag". Docker Hub tags are mutable: whoever controls the repo can re-push v4.18.3, and the next pod start would run different bytes with database credentials in its environment. The tag value is now v4.18.3@sha256:39b5... (the current index digest for that tag), so the kubelet pulls by digest and the tag stays readable for humans. The comments now say why the digest is there. No version change. Co-Authored-By: Claude Opus 5.5 --- deploy/helm/fp-ai-gateway/values.yaml | 6 ++++-- deploy/helm/fp-auth/values.yaml | 8 +++++--- deploy/helm/fp-billing/values.yaml | 8 +++++--- deploy/helm/fp-experiment-tracker/values.yaml | 8 +++++--- deploy/helm/fp-feature-store/values.yaml | 8 +++++--- deploy/helm/fp-model-monitor/values.yaml | 8 +++++--- deploy/helm/fp-notification/values.yaml | 8 +++++--- deploy/helm/fp-pipeline-orchestrator/values.yaml | 8 +++++--- deploy/helm/fp-registry/values.yaml | 8 +++++--- 9 files changed, 44 insertions(+), 26 deletions(-) diff --git a/deploy/helm/fp-ai-gateway/values.yaml b/deploy/helm/fp-ai-gateway/values.yaml index 3b2711a..c45b312 100644 --- a/deploy/helm/fp-ai-gateway/values.yaml +++ b/deploy/helm/fp-ai-gateway/values.yaml @@ -241,9 +241,11 @@ migrations: image: # golang-migrate official image. Alpine-based, so it has /bin/sh (needed to # expand the DSN from env without baking it into the pod spec) and the `migrate` - # binary on PATH. Pinned to an immutable tag for reproducible rollouts. + # binary on PATH. Pinned BY DIGEST: Docker Hub tags are mutable (a re-pushed + # v4.18.3 would change what the kubelet pulls), so the tag is for humans and + # the digest is what actually gets pulled. Bump both together, deliberately. repository: migrate/migrate - tag: v4.18.3 + tag: v4.18.3@sha256:39b59b389634e43bb3f2d4e94bc1edef0775ec2a9a3540ce6a2cf330e5daae55 pullPolicy: IfNotPresent # Modest resources: the migrate step is short-lived and IO-light. resources: diff --git a/deploy/helm/fp-auth/values.yaml b/deploy/helm/fp-auth/values.yaml index 9101ddd..166cfe1 100644 --- a/deploy/helm/fp-auth/values.yaml +++ b/deploy/helm/fp-auth/values.yaml @@ -149,10 +149,12 @@ migrations: image: # golang-migrate official image. Alpine-based, so it has /bin/sh (needed to # expand the DSN from env without baking it into the pod spec) and the - # `migrate` binary on PATH. Pinned to an immutable tag for reproducible - # rollouts — bump deliberately, never track a moving tag. + # `migrate` binary on PATH. Pinned BY DIGEST: Docker Hub tags are + # mutable (a re-pushed v4.18.3 would change what the kubelet pulls), so the + # tag is for humans and the digest is what actually gets pulled. Bump both + # together, deliberately. repository: migrate/migrate - tag: v4.18.3 + tag: v4.18.3@sha256:39b59b389634e43bb3f2d4e94bc1edef0775ec2a9a3540ce6a2cf330e5daae55 pullPolicy: IfNotPresent # Modest resources: the migrate step is short-lived and IO-light. Requests are # tiny so it never blocks scheduling; limits cap a pathological migration. diff --git a/deploy/helm/fp-billing/values.yaml b/deploy/helm/fp-billing/values.yaml index cd03500..6052e08 100644 --- a/deploy/helm/fp-billing/values.yaml +++ b/deploy/helm/fp-billing/values.yaml @@ -175,10 +175,12 @@ migrations: image: # golang-migrate official image. Alpine-based, so it has /bin/sh (needed to # expand the DSN from env without baking it into the pod spec) and the - # `migrate` binary on PATH. Pinned to an immutable tag for reproducible - # rollouts — bump deliberately, never track a moving tag. + # `migrate` binary on PATH. Pinned BY DIGEST: Docker Hub tags are + # mutable (a re-pushed v4.18.3 would change what the kubelet pulls), so the + # tag is for humans and the digest is what actually gets pulled. Bump both + # together, deliberately. repository: migrate/migrate - tag: v4.18.3 + tag: v4.18.3@sha256:39b59b389634e43bb3f2d4e94bc1edef0775ec2a9a3540ce6a2cf330e5daae55 pullPolicy: IfNotPresent # Modest resources: the migrate step is short-lived and IO-light. Requests are # tiny so it never blocks scheduling; limits cap a pathological migration. diff --git a/deploy/helm/fp-experiment-tracker/values.yaml b/deploy/helm/fp-experiment-tracker/values.yaml index fcfc0e9..54673c7 100644 --- a/deploy/helm/fp-experiment-tracker/values.yaml +++ b/deploy/helm/fp-experiment-tracker/values.yaml @@ -169,10 +169,12 @@ migrations: image: # golang-migrate official image. Alpine-based, so it has /bin/sh (needed to # expand the DSN from env without baking it into the pod spec) and the - # `migrate` binary on PATH. Pinned to an immutable tag for reproducible - # rollouts — bump deliberately, never track a moving tag. + # `migrate` binary on PATH. Pinned BY DIGEST: Docker Hub tags are + # mutable (a re-pushed v4.18.3 would change what the kubelet pulls), so the + # tag is for humans and the digest is what actually gets pulled. Bump both + # together, deliberately. repository: migrate/migrate - tag: v4.18.3 + tag: v4.18.3@sha256:39b59b389634e43bb3f2d4e94bc1edef0775ec2a9a3540ce6a2cf330e5daae55 pullPolicy: IfNotPresent # Modest resources: the migrate step is short-lived and IO-light. Requests are # tiny so it never blocks scheduling; limits cap a pathological migration. diff --git a/deploy/helm/fp-feature-store/values.yaml b/deploy/helm/fp-feature-store/values.yaml index 35ee372..16fbbde 100644 --- a/deploy/helm/fp-feature-store/values.yaml +++ b/deploy/helm/fp-feature-store/values.yaml @@ -166,10 +166,12 @@ migrations: image: # golang-migrate official image. Alpine-based, so it has /bin/sh (needed to # expand the DSN from env without baking it into the pod spec) and the - # `migrate` binary on PATH. Pinned to an immutable tag for reproducible - # rollouts — bump deliberately, never track a moving tag. + # `migrate` binary on PATH. Pinned BY DIGEST: Docker Hub tags are + # mutable (a re-pushed v4.18.3 would change what the kubelet pulls), so the + # tag is for humans and the digest is what actually gets pulled. Bump both + # together, deliberately. repository: migrate/migrate - tag: v4.18.3 + tag: v4.18.3@sha256:39b59b389634e43bb3f2d4e94bc1edef0775ec2a9a3540ce6a2cf330e5daae55 pullPolicy: IfNotPresent # Modest resources: the migrate step is short-lived and IO-light. Requests are # tiny so it never blocks scheduling; limits cap a pathological migration. diff --git a/deploy/helm/fp-model-monitor/values.yaml b/deploy/helm/fp-model-monitor/values.yaml index 13ee253..249ec82 100644 --- a/deploy/helm/fp-model-monitor/values.yaml +++ b/deploy/helm/fp-model-monitor/values.yaml @@ -220,10 +220,12 @@ migrations: image: # golang-migrate official image. Alpine-based, so it has /bin/sh (needed to # expand the DSN from env without baking it into the pod spec) and the - # `migrate` binary on PATH. Pinned to an immutable tag for reproducible - # rollouts — bump deliberately, never track a moving tag. + # `migrate` binary on PATH. Pinned BY DIGEST: Docker Hub tags are + # mutable (a re-pushed v4.18.3 would change what the kubelet pulls), so the + # tag is for humans and the digest is what actually gets pulled. Bump both + # together, deliberately. repository: migrate/migrate - tag: v4.18.3 + tag: v4.18.3@sha256:39b59b389634e43bb3f2d4e94bc1edef0775ec2a9a3540ce6a2cf330e5daae55 pullPolicy: IfNotPresent # Modest resources: the migrate step is short-lived and IO-light. Requests are # tiny so it never blocks scheduling; limits cap a pathological migration. diff --git a/deploy/helm/fp-notification/values.yaml b/deploy/helm/fp-notification/values.yaml index 33eb7cc..0a1091d 100644 --- a/deploy/helm/fp-notification/values.yaml +++ b/deploy/helm/fp-notification/values.yaml @@ -175,10 +175,12 @@ migrations: image: # golang-migrate official image. Alpine-based, so it has /bin/sh (needed to # expand the DSN from env without baking it into the pod spec) and the - # `migrate` binary on PATH. Pinned to an immutable tag for reproducible - # rollouts — bump deliberately, never track a moving tag. + # `migrate` binary on PATH. Pinned BY DIGEST: Docker Hub tags are + # mutable (a re-pushed v4.18.3 would change what the kubelet pulls), so the + # tag is for humans and the digest is what actually gets pulled. Bump both + # together, deliberately. repository: migrate/migrate - tag: v4.18.3 + tag: v4.18.3@sha256:39b59b389634e43bb3f2d4e94bc1edef0775ec2a9a3540ce6a2cf330e5daae55 pullPolicy: IfNotPresent # Modest resources: the migrate step is short-lived and IO-light. Requests are # tiny so it never blocks scheduling; limits cap a pathological migration. diff --git a/deploy/helm/fp-pipeline-orchestrator/values.yaml b/deploy/helm/fp-pipeline-orchestrator/values.yaml index 9fe6987..f6f90db 100644 --- a/deploy/helm/fp-pipeline-orchestrator/values.yaml +++ b/deploy/helm/fp-pipeline-orchestrator/values.yaml @@ -156,10 +156,12 @@ migrations: image: # golang-migrate official image. Alpine-based, so it has /bin/sh (needed to # expand the DSN from env without baking it into the pod spec) and the - # `migrate` binary on PATH. Pinned to an immutable tag for reproducible - # rollouts — bump deliberately, never track a moving tag. + # `migrate` binary on PATH. Pinned BY DIGEST: Docker Hub tags are + # mutable (a re-pushed v4.18.3 would change what the kubelet pulls), so the + # tag is for humans and the digest is what actually gets pulled. Bump both + # together, deliberately. repository: migrate/migrate - tag: v4.18.3 + tag: v4.18.3@sha256:39b59b389634e43bb3f2d4e94bc1edef0775ec2a9a3540ce6a2cf330e5daae55 pullPolicy: IfNotPresent # Modest resources: the migrate step is short-lived and IO-light. Requests are # tiny so it never blocks scheduling; limits cap a pathological migration. diff --git a/deploy/helm/fp-registry/values.yaml b/deploy/helm/fp-registry/values.yaml index ea53fb9..fcdbcfd 100644 --- a/deploy/helm/fp-registry/values.yaml +++ b/deploy/helm/fp-registry/values.yaml @@ -171,10 +171,12 @@ migrations: image: # golang-migrate official image. Alpine-based, so it has /bin/sh (needed to # expand the DSN from env without baking it into the pod spec) and the - # `migrate` binary on PATH. Pinned to an immutable tag for reproducible - # rollouts — bump deliberately, never track a moving tag. + # `migrate` binary on PATH. Pinned BY DIGEST: Docker Hub tags are + # mutable (a re-pushed v4.18.3 would change what the kubelet pulls), so the + # tag is for humans and the digest is what actually gets pulled. Bump both + # together, deliberately. repository: migrate/migrate - tag: v4.18.3 + tag: v4.18.3@sha256:39b59b389634e43bb3f2d4e94bc1edef0775ec2a9a3540ce6a2cf330e5daae55 pullPolicy: IfNotPresent # Modest resources: the migrate step is short-lived and IO-light. Requests are # tiny so it never blocks scheduling; limits cap a pathological migration. From d636d127ca48ce0e4d8294e885b8bdca5e24eb24 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:00:02 +0500 Subject: [PATCH 03/42] deploy: run postgres, grafana and ollama with read-only root filesystems Fixes six of the HIGH Trivy findings that keep the Security gate red: KSV-0014 on postgres, grafana and ollama, and KSV-0118 (x2) on ollama. - postgres: readOnlyRootFilesystem: true plus an emptyDir at /tmp. As uid 999 the entrypoint skips its root-only chown step, and PGDATA (PVC) and the socket dir (emptyDir) were already writable. The in-file comment claiming the image could not run read-only was wrong, so the Kyverno require-readonly-rootfs exception for postgres is removed with it. - grafana: readOnlyRootFilesystem: true, an emptyDir at /tmp, and GF_LOG_MODE=console so Grafana stops trying to write /var/log/grafana/grafana.log. - ollama: the pod had a completely default security context. It now has seccomp RuntimeDefault, all capabilities dropped, no privilege escalation, a read-only root (writes go to the model PVC and a /tmp emptyDir) and no SA token. It still runs as uid 0, because the existing PVC (including the 0600 id_ed25519 key) is root-owned and local-path ignores fsGroup. The migration steps are in deploy/llm/README.md. None of this was tested against a cluster. postgres is synced by the fp-infra Argo CD app, so check `kubectl -n fp-infra logs postgres-0` after merge. Co-Authored-By: Claude Opus 5.5 --- deploy/k8s/infra/postgres/postgres.yaml | 19 ++++++++--- deploy/k8s/observability/grafana/grafana.yaml | 22 ++++++++++--- deploy/llm/README.md | 23 +++++++++++++ deploy/llm/ollama.yaml | 29 +++++++++++++++++ deploy/policies/README.md | 22 ++++++------- deploy/policies/base/00-pod-security.yaml | 32 ++++++------------- 6 files changed, 104 insertions(+), 43 deletions(-) diff --git a/deploy/k8s/infra/postgres/postgres.yaml b/deploy/k8s/infra/postgres/postgres.yaml index 7f2bf43..01e657a 100644 --- a/deploy/k8s/infra/postgres/postgres.yaml +++ b/deploy/k8s/infra/postgres/postgres.yaml @@ -143,10 +143,16 @@ spec: containerPort: 5432 securityContext: allowPrivilegeEscalation: false - # readOnlyRootFilesystem is NOT set: the postgres entrypoint writes to - # /var/run/postgresql (socket) and a few transient paths. We give it a - # writable emptyDir for the socket dir instead of a fully-read-only FS, - # which the image doesn't cleanly support. Data still lives on the PVC. + # Read-only root FS (Trivy KSV-0014). Running as uid 999 the entrypoint + # skips its root-only chown/gosu step, and everything it and the server + # write lands on one of three mounts: PGDATA on the PVC, the unix socket + # in /var/run/postgresql, and /tmp (bash heredoc spill files, nss_wrapper + # if the uid were ever not in /etc/passwd). Both of the latter are + # emptyDirs below. Earlier revisions left this unset on the belief the + # image could not run read-only; it can, as long as those paths are + # writable. VERIFY on the cluster after rollout: `kubectl -n fp-infra + # logs postgres-0` should show "database system is ready". + readOnlyRootFilesystem: true capabilities: drop: ["ALL"] resources: @@ -184,6 +190,8 @@ spec: readOnly: true - name: run mountPath: /var/run/postgresql + - name: tmp + mountPath: /tmp volumes: - name: init configMap: @@ -195,6 +203,9 @@ spec: # triggers parse errors in strict YAML-1.1 tooling (e.g. some linters). - name: run emptyDir: {} + - name: tmp + emptyDir: + sizeLimit: 256Mi volumeClaimTemplates: - metadata: name: data diff --git a/deploy/k8s/observability/grafana/grafana.yaml b/deploy/k8s/observability/grafana/grafana.yaml index efe8653..6378999 100644 --- a/deploy/k8s/observability/grafana/grafana.yaml +++ b/deploy/k8s/observability/grafana/grafana.yaml @@ -289,15 +289,23 @@ spec: # Provisioned dashboards live under this path (matches the provider). - name: GF_PATHS_PROVISIONING value: /etc/grafana/provisioning + # Log to stdout only. The image default also writes + # /var/log/grafana/grafana.log, which a read-only root FS forbids, and + # the kubelet already captures stdout. + - name: GF_LOG_MODE + value: console ports: - name: http containerPort: 3000 securityContext: allowPrivilegeEscalation: false - # NOT read-only: Grafana writes its internal SQLite + plugin cache to - # /var/lib/grafana even in provisioned mode. We give it a writable - # emptyDir there (below) rather than a fully read-only root FS, which - # the image does not cleanly support. + # Read-only root FS (Trivy KSV-0014). Grafana's writes all have a + # writable mount: SQLite + plugins in /var/lib/grafana (emptyDir), + # scratch in /tmp (emptyDir), and logs go to stdout (GF_LOG_MODE + # above). The earlier note said the image does not cleanly support + # this; with those three paths covered it should. VERIFY after apply: + # /api/health returns 200 and the provisioned dashboards load. + readOnlyRootFilesystem: true capabilities: drop: ["ALL"] resources: @@ -340,6 +348,9 @@ spec: # Writable scratch for Grafana's runtime state (SQLite, plugins). - name: grafana-data mountPath: /var/lib/grafana + # Writable scratch (session/render temp files) for the read-only root. + - name: tmp + mountPath: /tmp volumes: - name: datasources configMap: @@ -352,3 +363,6 @@ spec: name: grafana-dashboards - name: grafana-data emptyDir: {} + - name: tmp + emptyDir: + sizeLimit: 128Mi diff --git a/deploy/llm/README.md b/deploy/llm/README.md index 66b2846..32113e2 100644 --- a/deploy/llm/README.md +++ b/deploy/llm/README.md @@ -56,3 +56,26 @@ kubectl --kubeconfig $KC -n fp-ml exec deploy/ollama -- \ TTS + cluster unharmed). - Scale-to-zero `ScaledObject`: **authored**, applied together with the L1 AI Gateway (which creates the `AI_REQUESTS` stream + publishes the warm signal). + +## Security context, and the move off root + +The pod runs with seccomp `RuntimeDefault`, every Linux capability dropped, no +privilege escalation and a read-only root filesystem (writes go to the model PVC +at `/root/.ollama` and an emptyDir at `/tmp`). It still runs as **uid 0**: the +`ollama-models` PVC was populated by a root process, including the `0600` +`id_ed25519` key Ollama reads at startup, and the k3s `local-path` provisioner +ignores `fsGroup`, so changing the uid in the manifest alone would crash the pod +on its own data. + +To finish the job (one-time, on the cluster): + +1. Scale to zero: `kubectl -n fp-ml scale deploy/ollama --replicas=0`. +2. Chown the volume to the target uid, e.g. with a throwaway pod that mounts + `ollama-models` and runs `chown -R 65532:65532 /data`. +3. In `ollama.yaml` set `runAsUser`/`runAsGroup: 65532`, `runAsNonRoot: true`, + `HOME=/home/ollama` and `OLLAMA_MODELS=/home/ollama/.ollama/models`, and move + the PVC mount to `/home/ollama/.ollama`. +4. Scale back up and confirm `ollama list` still shows the pulled model. + +`fp-ml` is also outside the namespaces the Kyverno policies match +(`deploy/policies`), so none of this is checked at admission yet. diff --git a/deploy/llm/ollama.yaml b/deploy/llm/ollama.yaml index dff2e3e..6b49126 100644 --- a/deploy/llm/ollama.yaml +++ b/deploy/llm/ollama.yaml @@ -58,6 +58,15 @@ spec: spec: # Terminate fast on scale-down so the node reclaims RAM quickly. terminationGracePeriodSeconds: 20 + # Ollama never calls the Kubernetes API. + automountServiceAccountToken: false + # Pod-level hardening (Trivy KSV-0118: the pod previously ran with an + # entirely default security context). seccomp RuntimeDefault filters the + # syscall surface. The process still runs as uid 0 - see the container + # securityContext for why and for what it no longer has. + securityContext: + seccompProfile: + type: RuntimeDefault containers: - name: ollama image: ollama/ollama:0.30.10 @@ -65,6 +74,21 @@ spec: ports: - name: http containerPort: 11434 + # STILL ROOT (uid 0), deliberately, for now: the existing ollama-models + # PVC was populated by a root process (including the 0600 id_ed25519 + # key Ollama reads at startup), and local-path volumes ignore fsGroup, + # so switching uid here would crash the pod on its own data. Moving to + # a non-root uid needs a one-time chown of the PVC; tracked in + # deploy/llm/README.md. Meanwhile root is defanged: ALL capabilities + # dropped (no CAP_DAC_OVERRIDE, CAP_CHOWN, CAP_NET_RAW, ...), no + # privilege escalation, and a read-only root FS (Trivy KSV-0014) so a + # compromised runner cannot modify the image's binaries. Writes go to + # the model PVC (/root/.ollama) and /tmp only. + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] env: # Keep a model warm for 2m between requests so rapid embed/judge/chat # calls don't each cold-load from disk (which timed out the cache embed @@ -95,6 +119,8 @@ spec: volumeMounts: - name: models mountPath: /root/.ollama + - name: tmp + mountPath: /tmp # The model loads lazily on the first request (keep_alive=0), so readiness # is just the HTTP server being up, not a model being resident. readinessProbe: @@ -113,6 +139,9 @@ spec: - name: models persistentVolumeClaim: claimName: ollama-models + - name: tmp + emptyDir: + sizeLimit: 512Mi --- apiVersion: v1 kind: Service diff --git a/deploy/policies/README.md b/deploy/policies/README.md index 151a75c..2f9967b 100644 --- a/deploy/policies/README.md +++ b/deploy/policies/README.md @@ -21,7 +21,7 @@ This is part of milestone **M6 — Platform security, GitOps & autoscaling** | `require-run-as-nonroot` | `runAsNonRoot=true` (pod or every container) | fp-auth podSecurityContext; infra `runAsUser` 999/1000 | | `disallow-privilege-escalation` | `allowPrivilegeEscalation=false` on all containers | every container securityContext | | `drop-all-capabilities` | `capabilities.drop` contains `ALL` | every container securityContext | -| `require-readonly-rootfs` | `readOnlyRootFilesystem=true` (**exception:** `app.kubernetes.io/name=postgres`) | fp-auth, redis, nats, minio | +| `require-readonly-rootfs` | `readOnlyRootFilesystem=true` (no exceptions) | fp-auth, redis, nats, minio, postgres | | `require-seccomp-runtimedefault` | `seccompProfile.type` is `RuntimeDefault`/`Localhost` | all pods' podSecurityContext | | `require-resource-requests-and-limits` | cpu+memory **requests AND limits** on every container | fp-auth `resources`; all infra pods | | `disallow-latest-tag` | image is tagged and not `:latest` | pinned infra tags; appVersion tag | @@ -51,16 +51,14 @@ audit** trail): it's disallowed in non-dev. `fp-dev` is excluded so the permissive dev default stays frictionless locally. -### The documented `readOnlyRootFilesystem` exception +### No `readOnlyRootFilesystem` exception -`require-readonly-rootfs` **excludes** pods labeled -`app.kubernetes.io/name=postgres`. The official `postgres` image's entrypoint -writes to transient paths and does not cleanly support a fully read-only root FS -(see the comments in `deploy/k8s/infra/postgres/postgres.yaml`), so postgres -confines writes to its PVC + an emptyDir socket dir instead. The carve-out is a -**narrow, named, label-selected** exclusion — not a blanket hole. Adding another -genuinely-incompatible image means extending that exclusion explicitly and -documenting why. +`require-readonly-rootfs` used to exclude pods labeled +`app.kubernetes.io/name=postgres`, on the belief that the official image could not +run with a read-only root FS. It can: PGDATA lives on the PVC and the socket dir +and `/tmp` are emptyDirs (see `deploy/k8s/infra/postgres/postgres.yaml`), so the +exception was removed. If an image genuinely cannot run read-only, add a +**narrow, named, label-selected** exclusion and document why next to it. ### The parameterized registry allowlist @@ -162,7 +160,7 @@ These Kyverno policies **complement** — they don't replace — PodSecurity: | | Pod Security admission | Kyverno (these policies) | |---|---|---| | Granularity | 3 fixed profiles, all-or-nothing per namespace | per-rule, fine-grained, individually toggled | -| Exceptions | none built in (exempt = whole namespace) | **narrow, labeled** (e.g. postgres readonly-rootfs) | +| Exceptions | none built in (exempt = whole namespace) | **narrow, labeled** (selector-based `exclude`) | | Coverage | pod securityContext only | + **registries, image tags, resource limits, labels, hostPort** | | Reporting | deny only (no "audit-but-allow" inventory of *all* violations) | rich PolicyReports, background scan of existing objects | | Custom rules | not possible | yes (any field, JMESPath conditions) | @@ -189,7 +187,7 @@ deploy/policies/ ├── base/ ← all policies, validationFailureAction: Audit │ ├── kustomization.yaml │ ├── 00-pod-security.yaml ← nonroot, no-priv-esc, drop-all-caps, -│ │ readonly-rootfs (+postgres exception), +│ │ readonly-rootfs, │ │ seccomp RuntimeDefault │ ├── 10-require-resources.yaml ← requests + limits (cpu & memory) │ ├── 20-image-policies.yaml ← disallow-latest-tag, restrict-registries diff --git a/deploy/policies/base/00-pod-security.yaml b/deploy/policies/base/00-pod-security.yaml index c948161..7d2d9a1 100644 --- a/deploy/policies/base/00-pod-security.yaml +++ b/deploy/policies/base/00-pod-security.yaml @@ -371,21 +371,18 @@ spec: --- # ----------------------------------------------------------------------------- -# require-readonly-rootfs (WITH a documented exception for stateful infra) +# require-readonly-rootfs (no exceptions) # ----------------------------------------------------------------------------- # readOnlyRootFilesystem=true means the container can't write to its own image # layers — it must mount an emptyDir/PVC for any writable path. This neuters a # whole class of attacks (dropping a binary, tampering with config) and is set -# on fp-auth, redis, nats, and minio. +# on fp-auth, redis, nats, minio and postgres. # -# THE EXCEPTION (read the postgres manifest): the official postgres image's -# entrypoint writes to a few transient paths and does not cleanly support a -# fully read-only root FS, so postgres deliberately omits readOnlyRootFilesystem -# and instead confines writes to a PVC + an emptyDir socket dir. We encode that -# as a precondition-based exclusion keyed on the well-known label -# app.kubernetes.io/name=postgres, so the exception is NARROW, named, and -# auditable — not a blanket hole. If we add another image that genuinely can't -# run read-only, we extend this allowlist explicitly (and document why). +# There used to be a label-selected exception for postgres, on the belief that +# the official image could not run read-only. It can (PGDATA on the PVC, the +# socket dir and /tmp on emptyDirs; see deploy/k8s/infra/postgres/postgres.yaml), +# so the exception is gone. If an image genuinely cannot run read-only, add a +# NARROW, label-selected exclusion here and document why next to it. apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: @@ -396,10 +393,7 @@ metadata: policies.kyverno.io/severity: medium policies.kyverno.io/subject: Pod policies.kyverno.io/description: >- - Containers must set securityContext.readOnlyRootFilesystem=true. A narrow, - documented exception applies to stateful infra whose image cannot run with - a read-only root FS (currently: postgres), selected by the - app.kubernetes.io/name label. + Containers must set securityContext.readOnlyRootFilesystem=true. spec: validationFailureAction: Audit background: true @@ -422,18 +416,10 @@ spec: - kube-system - kube-node-lease - kube-public - # DOCUMENTED EXCEPTION: postgres cannot run read-only (see - # deploy/k8s/infra/postgres/postgres.yaml comments). Exclude by its - # platform label so the carve-out is explicit and greppable. - - resources: - selector: - matchLabels: - app.kubernetes.io/name: postgres validate: message: >- readOnlyRootFilesystem must be true on every container. Mount an - emptyDir/PVC for any writable path (e.g. /tmp). Documented exception: - stateful infra labeled app.kubernetes.io/name=postgres. + emptyDir/PVC for any writable path (e.g. /tmp). pattern: spec: =(ephemeralContainers): From d3da9186847ede55ceb7296502ae8ef94ea0a328 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:01:07 +0500 Subject: [PATCH 04/42] deploy: pin third-party images by tag and digest The infra manifests ran floating tags (postgres:17, redis:7, nats:2.11, postgres:17-alpine) that a Kyverno comment described as "pinned". Every new node or pod restart could pull different bytes. Each image now names the exact version it resolves to today plus that tag's index digest: postgres:17 -> 17.11@sha256:b8fa... redis:7 -> 7.4.11@sha256:4496... nats:2.11 -> 2.11.17@sha256:c991... postgres:17-alpine -> 17.11-alpine@sha256:eee6... (backup CronJob) ollama/ollama:0.30.10, grafana 11.5.1, tempo 2.7.1, loki 3.4.2, prometheus v3.1.0, otel-collector-contrib 0.119.0 -> same tags + digest None of these is a version change: each digest is what the old tag resolves to on Docker Hub today. Digests were read from the registry API, not from a pull. Not changed: minio/minio and minio/mc. Both Docker Hub repositories now return 404, so their RELEASE tags can no longer be pulled or resolved to a digest. The MinIO deployment needs a replacement image or a different object store, which is a separate decision. Co-Authored-By: Claude Opus 5.5 --- deploy/backup/postgres-backup-cronjob.yaml | 5 +++-- deploy/k8s/infra/nats/nats.yaml | 4 +++- deploy/k8s/infra/postgres/postgres.yaml | 4 +++- deploy/k8s/infra/redis/redis.yaml | 4 +++- deploy/k8s/observability/grafana/grafana.yaml | 2 +- deploy/k8s/observability/loki/loki.yaml | 2 +- .../k8s/observability/otel-collector/otel-collector.yaml | 2 +- deploy/k8s/observability/prometheus/prometheus.yaml | 2 +- deploy/k8s/observability/tempo/tempo.yaml | 2 +- deploy/llm/ollama.yaml | 4 +++- deploy/policies/base/20-image-policies.yaml | 7 +++++-- 11 files changed, 25 insertions(+), 13 deletions(-) diff --git a/deploy/backup/postgres-backup-cronjob.yaml b/deploy/backup/postgres-backup-cronjob.yaml index 98ad2d5..c4a6c5b 100644 --- a/deploy/backup/postgres-backup-cronjob.yaml +++ b/deploy/backup/postgres-backup-cronjob.yaml @@ -135,8 +135,9 @@ spec: containers: - name: pg-dump # Use the same Postgres version as the server to avoid pg_dump - # client/server version skew warnings. Pin the tag. - image: postgres:17-alpine + # client/server version skew warnings. Pinned by tag AND digest (Docker + # Hub tags can be re-pushed; the digest is what pins the bytes). + image: postgres:17.11-alpine@sha256:eee6c6e1b0894fa4fe0075eb054af9fd1cf39a35321c2d4110626cfe506411fb imagePullPolicy: IfNotPresent securityContext: diff --git a/deploy/k8s/infra/nats/nats.yaml b/deploy/k8s/infra/nats/nats.yaml index 97f82f2..ea16df8 100644 --- a/deploy/k8s/infra/nats/nats.yaml +++ b/deploy/k8s/infra/nats/nats.yaml @@ -109,7 +109,9 @@ spec: type: RuntimeDefault # use the kernel's default seccomp filter containers: - name: nats - image: nats:2.11 + # Tag for humans, digest for the kubelet: Docker Hub tags (even version tags) + # can be re-pushed, so the digest is what pins the bytes. Bump both together. + image: nats:2.11.17@sha256:c991221cdddd53a24893cd18a90faf7a42396108496aed076bb982a349e76484 args: ["-c", "/etc/nats/nats.conf"] ports: - name: client diff --git a/deploy/k8s/infra/postgres/postgres.yaml b/deploy/k8s/infra/postgres/postgres.yaml index 01e657a..4827ef2 100644 --- a/deploy/k8s/infra/postgres/postgres.yaml +++ b/deploy/k8s/infra/postgres/postgres.yaml @@ -127,7 +127,9 @@ spec: type: RuntimeDefault containers: - name: postgres - image: postgres:17 + # Tag for humans, digest for the kubelet: Docker Hub tags (even version tags) + # can be re-pushed, so the digest is what pins the bytes. Bump both together. + image: postgres:17.11@sha256:b8faeff7712663c2773a190181e1246e37e364b887611c04658c28b44e2408fe envFrom: - secretRef: name: postgres-credentials diff --git a/deploy/k8s/infra/redis/redis.yaml b/deploy/k8s/infra/redis/redis.yaml index ae98a3b..9c90be4 100644 --- a/deploy/k8s/infra/redis/redis.yaml +++ b/deploy/k8s/infra/redis/redis.yaml @@ -101,7 +101,9 @@ spec: type: RuntimeDefault containers: - name: redis - image: redis:7 + # Tag for humans, digest for the kubelet: Docker Hub tags (even version tags) + # can be re-pushed, so the digest is what pins the bytes. Bump both together. + image: redis:7.4.11@sha256:44960b3100c48159a66d28c18b0588c193492e25f7551d60e51dd464fc3eca5b args: ["redis-server", "/etc/redis/redis.conf"] ports: - name: redis diff --git a/deploy/k8s/observability/grafana/grafana.yaml b/deploy/k8s/observability/grafana/grafana.yaml index 6378999..59d74fb 100644 --- a/deploy/k8s/observability/grafana/grafana.yaml +++ b/deploy/k8s/observability/grafana/grafana.yaml @@ -260,7 +260,7 @@ spec: # VERIFY before first deploy: confirm this tag on Docker Hub # (hub.docker.com/r/grafana/grafana/tags) and check the release notes # for provisioning-format or datasource-API breaking changes. - image: grafana/grafana:11.5.1 + image: grafana/grafana:11.5.1@sha256:5781759b3d27734d4d548fcbaf60b1180dbf4290e708f01f292faa6ae764c5e6 env: # ---- SECURITY HARDENING (same as docker-compose) ---------------- # Admin password injected from the Secret — NOT hardcoded, NOT the diff --git a/deploy/k8s/observability/loki/loki.yaml b/deploy/k8s/observability/loki/loki.yaml index 5ca66a3..30f5922 100644 --- a/deploy/k8s/observability/loki/loki.yaml +++ b/deploy/k8s/observability/loki/loki.yaml @@ -151,7 +151,7 @@ spec: # (hub.docker.com/r/grafana/loki/tags) and check the changelog for # schema or config breaking changes before bumping (schema migrations # are one-way — see schema_config above). - image: grafana/loki:3.4.2 + image: grafana/loki:3.4.2@sha256:58a6c186ce78ba04d58bfe2a927eff296ba733a430df09645d56cdc158f3ba08 args: ["-config.file=/etc/loki/loki.yaml"] ports: - name: http diff --git a/deploy/k8s/observability/otel-collector/otel-collector.yaml b/deploy/k8s/observability/otel-collector/otel-collector.yaml index 3a22f29..e085629 100644 --- a/deploy/k8s/observability/otel-collector/otel-collector.yaml +++ b/deploy/k8s/observability/otel-collector/otel-collector.yaml @@ -237,7 +237,7 @@ spec: # VERIFY before first deploy: confirm this tag exists on Docker Hub # (hub.docker.com/r/otel/opentelemetry-collector-contrib/tags) and # check the release notes for breaking pipeline config changes. - image: otel/opentelemetry-collector-contrib:0.119.0 + image: otel/opentelemetry-collector-contrib:0.119.0@sha256:36c35cc213c0f3b64d6e8a3e844dc90822f00725e0e518eaed5b08bcc2231e72 args: ["--config=/etc/otel/config.yaml"] ports: - name: otlp-grpc diff --git a/deploy/k8s/observability/prometheus/prometheus.yaml b/deploy/k8s/observability/prometheus/prometheus.yaml index 00f6c63..ce22451 100644 --- a/deploy/k8s/observability/prometheus/prometheus.yaml +++ b/deploy/k8s/observability/prometheus/prometheus.yaml @@ -225,7 +225,7 @@ spec: # VERIFY before first deploy: confirm this tag on Docker Hub # (hub.docker.com/r/prom/prometheus/tags) and review the CHANGELOG for # scrape config or TSDB breaking changes before bumping. - image: prom/prometheus:v3.1.0 + image: prom/prometheus:v3.1.0@sha256:6559acbd5d770b15bb3c954629ce190ac3cbbdb2b7f1c30f0385c4e05104e218 args: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.path=/prometheus" diff --git a/deploy/k8s/observability/tempo/tempo.yaml b/deploy/k8s/observability/tempo/tempo.yaml index 90d8e05..2936e3b 100644 --- a/deploy/k8s/observability/tempo/tempo.yaml +++ b/deploy/k8s/observability/tempo/tempo.yaml @@ -137,7 +137,7 @@ spec: # VERIFY before first deploy: confirm this tag exists on Docker Hub # (hub.docker.com/r/grafana/tempo/tags) and check the changelog for # storage-format or config breaking changes before bumping. - image: grafana/tempo:2.7.1 + image: grafana/tempo:2.7.1@sha256:4443be217c396b065ee34845534199c36fdba4dc619cb96550e228d73fba6e69 args: ["-config.file=/etc/tempo/tempo.yaml"] ports: - name: http-query diff --git a/deploy/llm/ollama.yaml b/deploy/llm/ollama.yaml index 6b49126..d6177a1 100644 --- a/deploy/llm/ollama.yaml +++ b/deploy/llm/ollama.yaml @@ -69,7 +69,9 @@ spec: type: RuntimeDefault containers: - name: ollama - image: ollama/ollama:0.30.10 + # Tag for humans, digest for the kubelet: Docker Hub tags (even version tags) + # can be re-pushed, so the digest is what pins the bytes. Bump both together. + image: ollama/ollama:0.30.10@sha256:bfc9c6d53cc6989aa5131a6fde6b162b2802d4d337657f3253b5f69579bddeee imagePullPolicy: IfNotPresent ports: - name: http diff --git a/deploy/policies/base/20-image-policies.yaml b/deploy/policies/base/20-image-policies.yaml index 51b7548..546a73e 100644 --- a/deploy/policies/base/20-image-policies.yaml +++ b/deploy/policies/base/20-image-policies.yaml @@ -17,8 +17,11 @@ # impossible, and a poisoned upstream tag silently lands in prod. Pinned tags # (and ideally digests) make deployments reproducible and auditable — this is a # 12-Factor "build, release, run" separation and a "hermetic builds" -# requirement. Our infra images are already pinned (postgres:17, redis:7, -# nats:2.11, minio/...:RELEASE.); fp-auth uses appVersion as the tag. +# requirement. The infra images are pinned by tag AND digest (e.g. +# postgres:17.11@sha256:...), because a Docker Hub tag, even a version tag, can be +# re-pushed. (An earlier revision of this comment called postgres:17, redis:7 and +# nats:2.11 "pinned"; those are floating tags.) The fp-* charts use +# Chart.appVersion as the tag. # # We assert TWO things: (1) a tag is present at all, and (2) it isn't `latest`. apiVersion: kyverno.io/v1 From db2f8d1dd8f8e3d0c514ad529e7398459447beb7 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:15:21 +0500 Subject: [PATCH 05/42] terraform: commit the provider lock file .terraform.lock.hcl was in the root .gitignore, while versions.tf and environments/dev/versions.tf both said "the committed .terraform.lock.hcl freezes the exact version + checksums". It was never committed, so every `terraform init` could resolve a different provider build inside the ~> constraints, with no hash to check it against. - Drop .terraform.lock.hcl from the root .gitignore and rewrite the note in deploy/terraform/.gitignore to say it is committed and how to regenerate it. - Add environments/dev/.terraform.lock.hcl, generated by `terraform providers lock -platform=linux_amd64 -platform=darwin_arm64`: aws 5.100.0, kubernetes 2.38.0, random 3.9.1, tls 4.4.2. The two versions.tf comments are now true, so they are unchanged. Co-Authored-By: Claude Opus 5.5 --- .gitignore | 3 +- deploy/terraform/.gitignore | 19 ++-- .../environments/dev/.terraform.lock.hcl | 91 +++++++++++++++++++ 3 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 deploy/terraform/environments/dev/.terraform.lock.hcl diff --git a/.gitignore b/.gitignore index 9a8ce2b..2acca4b 100644 --- a/.gitignore +++ b/.gitignore @@ -39,7 +39,8 @@ Thumbs.db *.tfstate *.tfstate.backup .terraform/ -.terraform.lock.hcl +# NOTE: .terraform.lock.hcl is deliberately NOT ignored. It pins the exact +# provider versions and their checksums; see deploy/terraform/.gitignore. # Helm packaging artifacts deploy/helm/*/charts/ diff --git a/deploy/terraform/.gitignore b/deploy/terraform/.gitignore index 694198f..3b98a5c 100644 --- a/deploy/terraform/.gitignore +++ b/deploy/terraform/.gitignore @@ -1,9 +1,9 @@ # ============================================================================ # Terraform-specific ignores (scoped to deploy/terraform) # ============================================================================ -# The repo root .gitignore already excludes *.tfstate, *.tfstate.backup, -# .terraform/, and .terraform.lock.hcl. This file adds the bits specific to this -# tree and documents WHY each is ignored. +# The repo root .gitignore already excludes *.tfstate, *.tfstate.backup and +# .terraform/. This file adds the bits specific to this tree and documents WHY +# each is ignored. # Real per-env variable files. terraform.tfvars.example IS committed (the # template); the filled-in terraform.tfvars may contain environment-specific @@ -18,7 +18,12 @@ terraform.tfvars crash.log *.tfplan -# NOTE on lock files: .terraform.lock.hcl is ignored by the ROOT .gitignore in -# this repo. In a production setup you would normally COMMIT the lock file so -# every machine/CI run resolves identical provider checksums. If you adopt that, -# add `!**/.terraform.lock.hcl` here to un-ignore it. +# NOTE on lock files: .terraform.lock.hcl IS committed, one per root module +# (environments//, bootstrap/). It records the exact provider version +# `terraform init` selected inside the ~> constraints AND the checksums of that +# build for every platform we run on, so a provider binary that does not match +# the recorded hash fails `init` instead of running. After changing a +# constraint, regenerate it with: +# terraform providers lock -platform=linux_amd64 -platform=darwin_arm64 +# (linux_amd64 = CI runners, darwin_arm64 = maintainer laptops.) Dependabot's +# terraform ecosystem updates the lock file together with the constraint. diff --git a/deploy/terraform/environments/dev/.terraform.lock.hcl b/deploy/terraform/environments/dev/.terraform.lock.hcl new file mode 100644 index 0000000..50e3b26 --- /dev/null +++ b/deploy/terraform/environments/dev/.terraform.lock.hcl @@ -0,0 +1,91 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.100.0" + constraints = "~> 5.60" + hashes = [ + "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "h1:edXOJWE4ORX8Fm+dpVpICzMZJat4AX0VRCAy/xkcOc0=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.38.0" + constraints = "~> 2.31" + hashes = [ + "h1:5CkveFo5ynsLdzKk+Kv+r7+U9rMrNjfZPT3a0N/fhgE=", + "h1:soK8Lt0SZ6dB+HsypFRDzuX/npqlMU6M0fvyaR1yW0k=", + "zh:0af928d776eb269b192dc0ea0f8a3f0f5ec117224cd644bdacdc682300f84ba0", + "zh:1be998e67206f7cfc4ffe77c01a09ac91ce725de0abaec9030b22c0a832af44f", + "zh:326803fe5946023687d603f6f1bab24de7af3d426b01d20e51d4e6fbe4e7ec1b", + "zh:4a99ec8d91193af961de1abb1f824be73df07489301d62e6141a656b3ebfff12", + "zh:5136e51765d6a0b9e4dbcc3b38821e9736bd2136cf15e9aac11668f22db117d2", + "zh:63fab47349852d7802fb032e4f2b6a101ee1ce34b62557a9ad0f0f0f5b6ecfdc", + "zh:924fb0257e2d03e03e2bfe9c7b99aa73c195b1f19412ca09960001bee3c50d15", + "zh:b63a0be5e233f8f6727c56bed3b61eb9456ca7a8bb29539fba0837f1badf1396", + "zh:d39861aa21077f1bc899bc53e7233262e530ba8a3a2d737449b100daeb303e4d", + "zh:de0805e10ebe4c83ce3b728a67f6b0f9d18be32b25146aa89116634df5145ad4", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:faf23e45f0090eef8ba28a8aac7ec5d4fdf11a36c40a8d286304567d71c1e7db", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.9.1" + constraints = "~> 3.6" + hashes = [ + "h1:PlW+UZ4EElQF3NQwf41KQwavFujab3Czc51zu9dyVM8=", + "h1:g40qr7yDmIpaur4SsK5BcOda3HSo1RJ6zHVMqN4EJ+0=", + "zh:05f4734c1f0be840b711b3eff259ebc5fca436784c728955b1678078466f48d7", + "zh:0b91bf19371d012434eba1deeb6aab77158def9b39601dcbd94450b3974a2a26", + "zh:0ee6eacd47ec00183d55d726a4b6c4ce951a199f944bf22f1aa58392ebdfa7a2", + "zh:19388a4074b76a89a43a6c8328d7ae8ee2e7de3d346af51e80d3e6d3d12925f1", + "zh:23e74d48c5e2ac2e823fd527f49fee9db37d32a1990c9e3bf126ead697b843eb", + "zh:3cabf7fbd096c520064aae3aba61aba670af83ab91291a71fa1b1332929c2b7f", + "zh:5c0a3b8af0be60be4eca12ddee385cfa8babc1ec8e98cdf9de2f2274c73eabfa", + "zh:60b4f8a8ef18f52bf8e19215229dae408bee732825964092db7c989fd2de4097", + "zh:7359015acfedcbd6366f2329c854cf8d3c8ca5cd0faa89d2d37db358d6eba6c5", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7b38758402f0e13a1071162da28994023cd2ac676e54af350c9ffd8dfa73fa7b", + "zh:7c7fbb8895eb75bb4de1f933e98553bd99c8d048c89a925ddba490aa5a67f7dc", + "zh:8c2b8c6a7ccdec16b73e2fb9f3700ea097f58c592571e4c5de60c93d2301732c", + ] +} + +provider "registry.terraform.io/hashicorp/tls" { + version = "4.4.2" + constraints = "~> 4.0" + hashes = [ + "h1:/RQKd6LussdsR99zSuIYdV4e3JrV4l0stQ5Vb1qnbWo=", + "h1:cMw+jmw1zbZ2Tgl2zwm1pU3S5jySk9i2W3ZRzu7YaVI=", + "zh:034fdb3f45f0fe3e6fc905bfe451eab8f7055c253f27c787470f550621993c4b", + "zh:16a5d4055a8e2f6d35e139d6c4c23fb8c53d9f6105b8d509030bb9720b301e02", + "zh:2d4009339fcbb2c9c2fe0eeb1cd9154d8bc06794c1c34265a32f97a5a56001f7", + "zh:3ee85048c51bbc06c7327c5aadf621e360d87fa39fbf7910eabb2a4e9edd98d4", + "zh:4d5ba1e4e9c5054ff123286a53d8d3e082818f20162f5cbdd3b0c634fab0b3f6", + "zh:4e55f5c32d9e2e87eec31a874535a4916ba5add06c1123dd4ae5d5c0909f785d", + "zh:8cd5cd017c2e8c93f9beb7f54776480210f22b2498a8fdf90dc01dfdf0930ba2", + "zh:a3996a6ffa641d1670cebde54421441f858104702a3c512c85b832eab3eaf564", + "zh:ab88ea84cef01a0cbdc8f65fb67fc6e840ad1475844a0f4995a7559816bc592e", + "zh:aef59a5322085ec071013fa79621ec75716846ce25f98fb181233df657e60d03", + "zh:dfb0f5cfe5b139cdddb941baae0d40f793c7080546f7a46988c5df2644c010bb", + "zh:e5b9b260e468fed152a31a7a815eaf4cb048e579857d7da883cdf6fa012415f9", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} From 005498bf6a8331013a3e6ec56a85ebbaafac7c51 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:16:27 +0500 Subject: [PATCH 06/42] log connection URLs with the password redacted Eight services logged their NATS and Redis URLs verbatim at startup ("redis connected" url=..., "nats connected" url=...), and pkg/natsutil logged nc.ConnectedUrl() on every reconnect. In AWS, FP_REDIS_URL comes from Secrets Manager through External Secrets and embeds the ElastiCache auth token (rediss://:@host), so each pod start copied that token into the log pipeline. - pkg/config.RedactURL replaces the userinfo password with "xxxxx" (net/url's URL.Redacted), passes a bare host:port through unchanged, and returns a placeholder rather than echoing a value it cannot parse. - Startup log lines in ai-gateway, billing, experiment-tracker, inference-gateway, model-serving, notification, pipeline-orchestrator and registry use it. ConnectedUrl() becomes nats.go's ConnectedUrlRedacted(). Tests: pkg/config unit tests pass. The pkg/natsutil tests need Docker (testcontainers) and were not run here. All eight services build and vet. Co-Authored-By: Claude Opus 5.5 --- pkg/config/redact.go | 30 +++++++++++++++++++ pkg/config/redact_test.go | 26 ++++++++++++++++ pkg/natsutil/connection.go | 2 +- services/ai-gateway/cmd/server/main.go | 4 +-- services/billing/cmd/server/main.go | 4 +-- .../experiment-tracker/cmd/server/main.go | 2 +- services/inference-gateway/cmd/server/main.go | 4 +-- services/model-serving/cmd/server/main.go | 4 +-- services/notification/cmd/server/main.go | 2 +- .../pipeline-orchestrator/cmd/server/main.go | 4 +-- services/registry/cmd/server/main.go | 4 +-- 11 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 pkg/config/redact.go create mode 100644 pkg/config/redact_test.go diff --git a/pkg/config/redact.go b/pkg/config/redact.go new file mode 100644 index 0000000..1a608f0 --- /dev/null +++ b/pkg/config/redact.go @@ -0,0 +1,30 @@ +package config + +import ( + "net/url" + "strings" +) + +// RedactURL returns a connection URL that is safe to log: any password in the +// userinfo is replaced by "xxxxx" (net/url's own convention), so +// "redis://:s3cret@host:6379" logs as "redis://:xxxxx@host:6379". +// +// WHY this exists: the services log their NATS and Redis URLs at startup. In +// AWS those URLs come from Secrets Manager via External Secrets Operator and +// embed the ElastiCache auth token (rediss://:@host), so logging them +// verbatim copies a credential into every log sink. +// +// Values without a scheme (a bare "host:port", as the registry and billing +// Redis config allow) carry no userinfo and are returned unchanged. A value +// that does not parse as a URL is NOT echoed back, because it may still +// contain a secret; a fixed placeholder is returned instead. +func RedactURL(raw string) string { + if !strings.Contains(raw, "://") { + return raw + } + u, err := url.Parse(raw) + if err != nil { + return "" + } + return u.Redacted() +} diff --git a/pkg/config/redact_test.go b/pkg/config/redact_test.go new file mode 100644 index 0000000..f0a5d60 --- /dev/null +++ b/pkg/config/redact_test.go @@ -0,0 +1,26 @@ +package config + +import "testing" + +func TestRedactURL(t *testing.T) { + tests := []struct { + name string + in string + want string + }{ + {"redis password only", "redis://:s3cret@localhost:6379", "redis://:xxxxx@localhost:6379"}, + {"rediss with token", "rediss://:tok3n@master.example.cache.amazonaws.com:6379", "rediss://:xxxxx@master.example.cache.amazonaws.com:6379"}, + {"nats user and password", "nats://fp:s3cret@localhost:4222", "nats://fp:xxxxx@localhost:4222"}, + {"no credentials", "nats://nats.fp-infra.svc.cluster.local:4222", "nats://nats.fp-infra.svc.cluster.local:4222"}, + {"bare host:port", "localhost:6379", "localhost:6379"}, + {"empty", "", ""}, + {"unparseable is not echoed", "redis://:pa ss@%zz", ""}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := RedactURL(tt.in); got != tt.want { + t.Errorf("RedactURL(%q) = %q, want %q", tt.in, got, tt.want) + } + }) + } +} diff --git a/pkg/natsutil/connection.go b/pkg/natsutil/connection.go index 4c88d57..e52fa54 100644 --- a/pkg/natsutil/connection.go +++ b/pkg/natsutil/connection.go @@ -78,7 +78,7 @@ func Connect(url string, opts ...nats.Option) (*nats.Conn, jetstream.JetStream, } }), nats.ReconnectHandler(func(nc *nats.Conn) { - slog.Info("NATS reconnected", slog.String("url", nc.ConnectedUrl())) + slog.Info("NATS reconnected", slog.String("url", nc.ConnectedUrlRedacted())) }), } diff --git a/services/ai-gateway/cmd/server/main.go b/services/ai-gateway/cmd/server/main.go index c24c1cf..0f7cee7 100644 --- a/services/ai-gateway/cmd/server/main.go +++ b/services/ai-gateway/cmd/server/main.go @@ -238,7 +238,7 @@ func main() { os.Exit(1) } pingCancel() - logger.Info("redis connected", slog.String("url", cfg.RedisURL)) + logger.Info("redis connected", slog.String("url", config.RedactURL(cfg.RedisURL))) // 4b. NATS JetStream — events + warm signal. natsConn, js, err := natsutil.Connect(cfg.NATSUrl) @@ -251,7 +251,7 @@ func main() { logger.Error("nats drain error", slog.String("error", drainErr.Error())) } }() - logger.Info("NATS connected", slog.String("url", cfg.NATSUrl)) + logger.Info("NATS connected", slog.String("url", config.RedactURL(cfg.NATSUrl))) // 5. ENSURE STREAMS (idempotent; fail fast — a gateway that can't guarantee its // streams would silently drop cost events and never wake Ollama). diff --git a/services/billing/cmd/server/main.go b/services/billing/cmd/server/main.go index ad4f0de..a9d62ba 100644 --- a/services/billing/cmd/server/main.go +++ b/services/billing/cmd/server/main.go @@ -209,7 +209,7 @@ func main() { slog.Int("grpc_port", cfg.GRPCPort), slog.Int("health_port", cfg.Port), slog.String("log_level", cfg.LogLevel), - slog.String("nats_url", cfg.NATSUrl), + slog.String("nats_url", config.RedactURL(cfg.NATSUrl)), slog.String("default_currency", cfg.DefaultCurrency), slog.Bool("otel_insecure", cfg.OTelInsecure), ) @@ -287,7 +287,7 @@ func main() { logger.Error("failed to connect NATS", slog.String("error", err.Error())) os.Exit(1) } - logger.Info("nats connected", slog.String("url", natsConn.ConnectedUrl())) + logger.Info("nats connected", slog.String("url", natsConn.ConnectedUrlRedacted())) // ENSURE THE STREAMS BILLING USES EXIST. JetStream silently DROPS a published // message whose subject no stream captures, and a consumer cannot attach to a diff --git a/services/experiment-tracker/cmd/server/main.go b/services/experiment-tracker/cmd/server/main.go index d41ca89..ce8b432 100644 --- a/services/experiment-tracker/cmd/server/main.go +++ b/services/experiment-tracker/cmd/server/main.go @@ -249,7 +249,7 @@ func main() { logger.Error("nats drain error", slog.String("error", drainErr.Error())) } }() - logger.Info("NATS connected", slog.String("url", cfg.NATSUrl)) + logger.Info("NATS connected", slog.String("url", config.RedactURL(cfg.NATSUrl))) // --- ENSURE THE EXPERIMENTS STREAM EXISTS (producer owns its stream) --- // experiment-tracker is the OWNER and sole producer of the fp.experiments.* tree diff --git a/services/inference-gateway/cmd/server/main.go b/services/inference-gateway/cmd/server/main.go index bf6162a..35470c5 100644 --- a/services/inference-gateway/cmd/server/main.go +++ b/services/inference-gateway/cmd/server/main.go @@ -219,7 +219,7 @@ func main() { os.Exit(1) } pingCancel() - logger.Info("redis connected", slog.String("url", cfg.RedisURL)) + logger.Info("redis connected", slog.String("url", config.RedactURL(cfg.RedisURL))) // ================================================================ // 4b. NATS JetStream — the async event bus (publish + subscribe) @@ -241,7 +241,7 @@ func main() { logger.Error("nats drain error", slog.String("error", drainErr.Error())) } }() - logger.Info("NATS connected", slog.String("url", cfg.NATSUrl)) + logger.Info("NATS connected", slog.String("url", config.RedactURL(cfg.NATSUrl))) // ================================================================ // 5. CONSTRUCT ADAPTERS → PUBLISHER → DOMAIN SERVICE → HANDLER diff --git a/services/model-serving/cmd/server/main.go b/services/model-serving/cmd/server/main.go index 0030be1..43aebb7 100644 --- a/services/model-serving/cmd/server/main.go +++ b/services/model-serving/cmd/server/main.go @@ -237,10 +237,10 @@ func main() { // async-bus equivalent of the gRPC graceful drain. natsConn, js, err := natsutil.Connect(cfg.NATSUrl) if err != nil { - logger.Error("failed to connect to NATS", slog.String("url", cfg.NATSUrl), slog.String("error", err.Error())) + logger.Error("failed to connect to NATS", slog.String("url", config.RedactURL(cfg.NATSUrl)), slog.String("error", err.Error())) os.Exit(1) } - logger.Info("connected to NATS JetStream", slog.String("url", cfg.NATSUrl)) + logger.Info("connected to NATS JetStream", slog.String("url", config.RedactURL(cfg.NATSUrl))) // Deferred SECOND-from-last (runs after subscribers are stopped below, before // OTel flush). Drain is graceful; if it errors we still proceed to exit. defer func() { diff --git a/services/notification/cmd/server/main.go b/services/notification/cmd/server/main.go index 4e6037c..8308c22 100644 --- a/services/notification/cmd/server/main.go +++ b/services/notification/cmd/server/main.go @@ -183,7 +183,7 @@ func main() { slog.Int("grpc_port", cfg.GRPCPort), slog.Int("health_port", cfg.Port), slog.String("log_level", cfg.LogLevel), - slog.String("nats_url", cfg.NATSUrl), + slog.String("nats_url", config.RedactURL(cfg.NATSUrl)), slog.String("environment", cfg.Environment), ) diff --git a/services/pipeline-orchestrator/cmd/server/main.go b/services/pipeline-orchestrator/cmd/server/main.go index 22b7376..f2ec628 100644 --- a/services/pipeline-orchestrator/cmd/server/main.go +++ b/services/pipeline-orchestrator/cmd/server/main.go @@ -246,7 +246,7 @@ func main() { slog.Int("grpc_port", cfg.GRPCPort), slog.Int("health_port", cfg.Port), slog.String("log_level", cfg.LogLevel), - slog.String("nats_url", cfg.NATSUrl), + slog.String("nats_url", config.RedactURL(cfg.NATSUrl)), slog.Bool("otel_insecure", cfg.OTelInsecure), slog.Duration("compensation_timeout", cfg.CompensationTimeout), ) @@ -307,7 +307,7 @@ func main() { logger.Error("failed to connect to nats", slog.String("error", err.Error())) os.Exit(1) } - logger.Info("nats connected", slog.String("url", natsConn.ConnectedUrl())) + logger.Info("nats connected", slog.String("url", natsConn.ConnectedUrlRedacted())) // Provision the JetStream streams this service depends on, idempotently. // WHY here (and why CreateOrUpdateStream): a PUBLISH only persists if some stream diff --git a/services/registry/cmd/server/main.go b/services/registry/cmd/server/main.go index d49cfab..606aef5 100644 --- a/services/registry/cmd/server/main.go +++ b/services/registry/cmd/server/main.go @@ -174,7 +174,7 @@ func main() { slog.Int("grpc_port", cfg.GRPCPort), slog.Int("health_port", cfg.Port), slog.String("log_level", cfg.LogLevel), - slog.String("nats_url", cfg.NATSUrl), + slog.String("nats_url", config.RedactURL(cfg.NATSUrl)), slog.Bool("otel_insecure", cfg.OTelInsecure), ) @@ -259,7 +259,7 @@ func main() { logger.Error("failed to connect NATS", slog.String("error", err.Error())) os.Exit(1) } - logger.Info("nats connected", slog.String("url", natsConn.ConnectedUrl())) + logger.Info("nats connected", slog.String("url", natsConn.ConnectedUrlRedacted())) // --- ENSURE THE MODELS STREAM EXISTS (producer owns its stream) --- // The registry is the OWNER and sole producer of the fp.models.* lifecycle tree. From 1899dc1a4527ebe6eaebcbaac5813919f09c59a5 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:26:26 +0500 Subject: [PATCH 07/42] compose: bind the local stack to 127.0.0.1 and require Redis/NATS auth docker-compose published Postgres, Redis, NATS, MinIO, Prometheus, Tempo and Loki as "port:port", which Docker binds on 0.0.0.0. With a remote engine (this repo is developed against a docker context over ssh), 0.0.0.0 is the engine host's LAN and VPN interfaces, and Redis and NATS had no auth at all. - Every published port binds to ${FP_BIND_ADDR:-127.0.0.1}. Monitoring and UI ports (8222, 9001, 9090, 3000, 3200, 3100) are always loopback-only. To reach the stack from another machine, use an ssh tunnel. - Redis runs with --requirepass and NATS with --user/--pass, from REDIS_PASSWORD and NATS_PASSWORD (dev default "fp", the same as POSTGRES_PASSWORD). The defaults are published, so the control is the loopback bind. The .env passwords exist so that real values take effect end to end. - Go local defaults carry the same dev credentials (redis://:fp@localhost:6379, nats://fp:fp@localhost:4222), so `go run` against compose works as before. Every Helm ConfigMap sets these URLs explicitly, so no deployed default changes. - registry and billing passed FP_REDIS_URL straight to Options.Addr, so they could not take a password or TLS at all, including rediss:// from ElastiCache. They now use redis.ParseURL when the value has a scheme and still accept a bare host:port (the Helm default). Unit tests cover both. - :latest images pinned (prometheus v3.1.0, grafana 11.5.1, tempo 2.7.1, loki 3.4.2, mc RELEASE.2025-04-16T18-13-26Z, matching deploy/k8s), and postgres/redis/nats pinned by digest. The MinIO images can no longer be pulled from Docker Hub (404). See the compose comment. Tests: new unit tests pass. Packages whose tests need Docker (testcontainers) were not run. All touched modules build and vet. Co-Authored-By: Claude Opus 5.5 --- .env.example | 24 +++++++- docker-compose.yaml | 60 ++++++++++++------- pkg/config/config.go | 6 +- services/ai-gateway/cmd/server/main.go | 2 +- services/billing/cmd/server/main.go | 36 ++++++++--- .../billing/cmd/server/redis_options_test.go | 38 ++++++++++++ services/feature-store/cmd/server/main.go | 2 +- services/inference-gateway/cmd/server/main.go | 2 +- .../model-monitor/internal/config/config.go | 2 +- services/notification/cmd/server/main.go | 2 +- services/registry/cmd/server/main.go | 31 ++++++++-- .../registry/cmd/server/redis_options_test.go | 38 ++++++++++++ 12 files changed, 200 insertions(+), 43 deletions(-) create mode 100644 services/billing/cmd/server/redis_options_test.go create mode 100644 services/registry/cmd/server/redis_options_test.go diff --git a/.env.example b/.env.example index 528c4aa..1205dd4 100644 --- a/.env.example +++ b/.env.example @@ -11,11 +11,21 @@ # make up # # If .env is absent, docker-compose uses the defaults shown here (via ${VAR:-default}). -# The defaults are safe for a local-only stack; change them if you expose -# the stack on a shared network. +# The defaults are PUBLISHED dev values. They are acceptable only because every +# port binds to 127.0.0.1 (see FP_BIND_ADDR below). Replace every *_PASSWORD +# before binding to anything else. # # ============================================================================ +# ---------------------------------------------------------------------------- +# NETWORK EXPOSURE +# ---------------------------------------------------------------------------- +# Address every published port binds to. With a REMOTE docker engine (docker +# context over ssh) this address is on the engine host, not your laptop, and +# 0.0.0.0 there means its LAN and VPN interfaces. Prefer an ssh tunnel +# (ssh -L 6379:127.0.0.1:6379 ) over changing this. +FP_BIND_ADDR=127.0.0.1 + # ---------------------------------------------------------------------------- # POSTGRES # ---------------------------------------------------------------------------- @@ -29,6 +39,16 @@ POSTGRES_PASSWORD=fp MINIO_ROOT_USER=minioadmin MINIO_ROOT_PASSWORD=minioadmin +# ---------------------------------------------------------------------------- +# REDIS / NATS (both require auth) +# ---------------------------------------------------------------------------- +# The Go services' local defaults use these same dev values: +# FP_REDIS_URL=redis://:${REDIS_PASSWORD}@localhost:6379 +# FP_NATS_URL=nats://fp:${NATS_PASSWORD}@localhost:4222 +# If you change a password here, export the matching FP_* URL before `go run`. +REDIS_PASSWORD=fp +NATS_PASSWORD=fp + # ---------------------------------------------------------------------------- # GRAFANA # ---------------------------------------------------------------------------- diff --git a/docker-compose.yaml b/docker-compose.yaml index d889e94..1c02750 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -13,11 +13,25 @@ # VERIFICATION: # curl http://localhost:8222/healthz # NATS # psql -h localhost -U fp -c "SELECT 1" # Postgres (password: fp) -# redis-cli -h localhost ping # Redis +# redis-cli -h localhost -a fp ping # Redis (password: fp) # curl http://localhost:9000/minio/health/live # MinIO # curl http://localhost:9090/-/healthy # Prometheus # curl http://localhost:3000/api/health # Grafana (admin/admin) # +# NETWORK EXPOSURE: every published port binds to ${FP_BIND_ADDR:-127.0.0.1}. +# Docker's default for "5432:5432" is 0.0.0.0, i.e. every interface of the +# machine running the ENGINE. With a remote engine (docker context over ssh) +# that is the remote box's LAN and VPN interfaces, not your laptop. To reach +# the stack from another machine, prefer an ssh tunnel +# (ssh -L 5432:127.0.0.1:5432 ). Only set FP_BIND_ADDR to a +# non-loopback address after replacing every *_PASSWORD default in .env. +# +# AUTH: Redis (requirepass) and NATS (user/password) require credentials, +# defaulting to the same dev value as Postgres ("fp"). The defaults are +# published, so they are not the control; the loopback bind is. They exist so +# that setting real values in .env takes effect end to end. The Go services' +# local defaults (FP_REDIS_URL / FP_NATS_URL) carry the same dev credentials. +# # ARCHITECTURE: # ┌─────────────────────────────────────────────────────┐ # │ Forgepoint Services │ @@ -42,11 +56,12 @@ services: # NATS — Async event bus (JetStream for persistence) # ========================================================================== nats: - image: nats:2.11 - command: ["--jetstream", "--http_port", "8222", "-DV"] + image: nats:2.11.17@sha256:c991221cdddd53a24893cd18a90faf7a42396108496aed076bb982a349e76484 + # --user/--pass: clients must authenticate (nats://fp:@host). + command: ["--jetstream", "--http_port", "8222", "--user", "fp", "--pass", "${NATS_PASSWORD:-fp}", "-DV"] ports: - - "4222:4222" # Client connections (accessible by services) - - "127.0.0.1:8222:8222" # HTTP monitoring — localhost only (not LAN-exposed) + - "${FP_BIND_ADDR:-127.0.0.1}:4222:4222" # Client connections + - "127.0.0.1:8222:8222" # HTTP monitoring — always localhost only volumes: - nats-data:/data restart: unless-stopped @@ -61,13 +76,13 @@ services: # REGISTRY_DATABASE_URL=postgres://fp:fp@localhost:5432/fp_registry # ========================================================================== postgres: - image: postgres:17 + image: postgres:17.11@sha256:b8faeff7712663c2773a190181e1246e37e364b887611c04658c28b44e2408fe environment: POSTGRES_USER: fp POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-fp} POSTGRES_DB: fp ports: - - "5432:5432" + - "${FP_BIND_ADDR:-127.0.0.1}:5432:5432" volumes: - postgres-data:/var/lib/postgresql/data - ./scripts/init-postgres.sh:/docker-entrypoint-initdb.d/init-postgres.sh:ro @@ -77,9 +92,11 @@ services: # REDIS — Caching (registry read model, rate limiting, sessions) # ========================================================================== redis: - image: redis:7 + image: redis:7.4.11@sha256:44960b3100c48159a66d28c18b0588c193492e25f7551d60e51dd464fc3eca5b + # requirepass: every command needs AUTH (redis://:@host:6379). + command: ["redis-server", "--requirepass", "${REDIS_PASSWORD:-fp}"] ports: - - "6379:6379" + - "${FP_BIND_ADDR:-127.0.0.1}:6379:6379" volumes: - redis-data:/data restart: unless-stopped @@ -101,15 +118,18 @@ services: MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin} MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin} ports: - - "9000:9000" # S3 API (used by services — keep accessible) - - "127.0.0.1:9001:9001" # Web console — localhost only + - "${FP_BIND_ADDR:-127.0.0.1}:9000:9000" # S3 API (used by services) + - "127.0.0.1:9001:9001" # Web console — always localhost only volumes: - minio-data:/data restart: unless-stopped # Create default bucket on startup minio-init: - image: minio/mc:latest + # NOTE: minio/minio and minio/mc no longer exist on Docker Hub (the + # repositories return 404), so neither image can be pinned by digest here. + # Pulls only work from a local cache. Replacing MinIO is tracked separately. + image: minio/mc:RELEASE.2025-04-16T18-13-26Z depends_on: minio: condition: service_started @@ -128,9 +148,9 @@ services: # PROMETHEUS — Metrics collection (pull-based scraping) # ========================================================================== prometheus: - image: prom/prometheus:latest + image: prom/prometheus:v3.1.0@sha256:6559acbd5d770b15bb3c954629ce190ac3cbbdb2b7f1c30f0385c4e05104e218 ports: - - "9090:9090" + - "127.0.0.1:9090:9090" volumes: - ./deploy/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus-data:/prometheus @@ -148,7 +168,7 @@ services: # Default login: admin / admin # ========================================================================== grafana: - image: grafana/grafana:latest + image: grafana/grafana:11.5.1@sha256:5781759b3d27734d4d548fcbaf60b1180dbf4290e708f01f292faa6ae764c5e6 ports: - "127.0.0.1:3000:3000" # UI — localhost only; not exposed to LAN environment: @@ -176,11 +196,11 @@ services: # Grafana queries Tempo to display trace waterfalls. # ========================================================================== tempo: - image: grafana/tempo:latest + image: grafana/tempo:2.7.1@sha256:4443be217c396b065ee34845534199c36fdba4dc619cb96550e228d73fba6e69 command: ["-config.file=/etc/tempo.yaml"] ports: - - "4317:4317" # OTLP gRPC (OpenTelemetry traces) - - "3200:3200" # Tempo HTTP API (Grafana queries this) + - "${FP_BIND_ADDR:-127.0.0.1}:4317:4317" # OTLP gRPC (OpenTelemetry traces) + - "127.0.0.1:3200:3200" # Tempo HTTP API (Grafana queries this) volumes: - ./deploy/tempo/tempo.yaml:/etc/tempo.yaml:ro - tempo-data:/tmp/tempo @@ -194,9 +214,9 @@ services: # Locally, services can push directly to Loki or we can add promtail later. # ========================================================================== loki: - image: grafana/loki:latest + image: grafana/loki:3.4.2@sha256:58a6c186ce78ba04d58bfe2a927eff296ba733a430df09645d56cdc158f3ba08 ports: - - "3100:3100" + - "127.0.0.1:3100:3100" volumes: - loki-data:/loki restart: unless-stopped diff --git a/pkg/config/config.go b/pkg/config/config.go index 2bf84af..c7d3a03 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -90,14 +90,16 @@ import ( // because gRPC uses HTTP/2 and health checks use HTTP/1.1) // - LogLevel: Controls slog verbosity (debug/info/warn/error) // - OTelEndpoint: OpenTelemetry collector for traces/metrics -// - NATSUrl: Async event bus connection +// - NATSUrl: Async event bus connection. The default carries the local +// docker-compose dev credentials (NATS_PASSWORD, default "fp"); every real +// deployment sets FP_NATS_URL explicitly. // - DatabaseURL: Per-service PostgreSQL database type BaseConfig struct { Port int `env:"PORT" default:"8080"` GRPCPort int `env:"GRPC_PORT" default:"9090"` LogLevel string `env:"LOG_LEVEL" default:"info"` OTelEndpoint string `env:"OTEL_ENDPOINT" default:"localhost:4317"` - NATSUrl string `env:"NATS_URL" default:"nats://localhost:4222"` + NATSUrl string `env:"NATS_URL" default:"nats://fp:fp@localhost:4222"` DatabaseURL string `env:"DATABASE_URL"` } diff --git a/services/ai-gateway/cmd/server/main.go b/services/ai-gateway/cmd/server/main.go index 0f7cee7..c78f7c8 100644 --- a/services/ai-gateway/cmd/server/main.go +++ b/services/ai-gateway/cmd/server/main.go @@ -92,7 +92,7 @@ type AIConfig struct { JWTSecret string `env:"JWT_SECRET" required:"true"` // RedisURL backs the per-team token budgets. Defaulted for local docker-compose. - RedisURL string `env:"REDIS_URL" default:"redis://localhost:6379"` + RedisURL string `env:"REDIS_URL" default:"redis://:fp@localhost:6379"` // OllamaURL is the in-cluster Ollama serving endpoint. Defaulted to the fp-ml // Service; local dev can point it at a laptop Ollama or leave it (the stub serves diff --git a/services/billing/cmd/server/main.go b/services/billing/cmd/server/main.go index a9d62ba..9dc25ec 100644 --- a/services/billing/cmd/server/main.go +++ b/services/billing/cmd/server/main.go @@ -68,6 +68,7 @@ import ( "net/http" "os" "os/signal" + "strings" "time" "github.com/jackc/pgx/v5/pgxpool" @@ -139,13 +140,15 @@ type BillingConfig struct { // applies. Validated to a 3-letter uppercase code by the domain on use. DefaultCurrency string `env:"DEFAULT_CURRENCY" default:"USD"` - // RedisURL is the connection string (bare host:port) for the consumer-side - // idempotency ProcessedStore — the fast dedup layer over NATS at-least-once - // redelivery. NewClient takes an "addr", so the default is bare host:port; a - // full "redis://" URL with auth/db would need redis.ParseURL (a later concern - // when Redis grows credentials). Distinct from DatabaseURL: Redis holds only - // the short-lived dedup keys, Postgres holds the money-truth ledger + outbox. - RedisURL string `env:"REDIS_URL" default:"localhost:6379"` + // RedisURL is the connection string for the consumer-side idempotency + // ProcessedStore — the fast dedup layer over NATS at-least-once redelivery. + // Accepts either a full URL (redis:// or rediss://, parsed by redis.ParseURL, + // so credentials, db and TLS work, as ElastiCache with auth + in-transit + // encryption requires) or a bare host:port (the in-cluster Helm default). The + // default matches the local docker-compose stack, which requires a password + // (REDIS_PASSWORD, dev default "fp"). Distinct from DatabaseURL: Redis holds + // only the short-lived dedup keys, Postgres holds the ledger + outbox. + RedisURL string `env:"REDIS_URL" default:"redis://:fp@localhost:6379"` // OTelInsecure controls whether the OTLP exporter uses plaintext (no TLS). It // is true in local docker-compose (the collector has no cert) and false in @@ -268,7 +271,13 @@ func main() { // --- Redis: the consumer-side idempotency ProcessedStore (fast dedup) --- // go-redis's Client is itself a pool; Ping fails fast on an unreachable server. - rdb := goredis.NewClient(&goredis.Options{Addr: cfg.RedisURL}) + redisOpts, err := redisOptions(cfg.RedisURL) + if err != nil { + pgPool.Close() + logger.Error("invalid FP_REDIS_URL", slog.String("error", err.Error())) + os.Exit(1) + } + rdb := goredis.NewClient(redisOpts) if err := rdb.Ping(bootCtx).Err(); err != nil { _ = rdb.Close() pgPool.Close() @@ -880,3 +889,14 @@ func markUnwiredResolverActive(ctx context.Context, logger *slog.Logger, failClo // many money axes are degraded, and is unambiguously > 0 for the alert. counter.Add(ctx, 2) } + +// redisOptions turns FP_REDIS_URL into client options. A value with a scheme +// (redis:// or rediss://) goes through redis.ParseURL, which handles the +// password, db number and TLS. A bare host:port, which the Helm chart sets for +// the in-cluster Redis, is used as the address directly, as before. +func redisOptions(raw string) (*goredis.Options, error) { + if strings.Contains(raw, "://") { + return goredis.ParseURL(raw) + } + return &goredis.Options{Addr: raw}, nil +} diff --git a/services/billing/cmd/server/redis_options_test.go b/services/billing/cmd/server/redis_options_test.go new file mode 100644 index 0000000..a53d3bb --- /dev/null +++ b/services/billing/cmd/server/redis_options_test.go @@ -0,0 +1,38 @@ +package main + +import "testing" + +func TestRedisOptions(t *testing.T) { + t.Run("bare host:port is used as the address", func(t *testing.T) { + opts, err := redisOptions("redis.fp-infra.svc.cluster.local:6379") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if opts.Addr != "redis.fp-infra.svc.cluster.local:6379" || opts.Password != "" || opts.TLSConfig != nil { + t.Fatalf("got Addr=%q Password set=%t TLS=%t", opts.Addr, opts.Password != "", opts.TLSConfig != nil) + } + }) + t.Run("redis URL carries the password", func(t *testing.T) { + opts, err := redisOptions("redis://:s3cret@localhost:6379/2") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if opts.Addr != "localhost:6379" || opts.Password != "s3cret" || opts.DB != 2 { + t.Fatalf("got Addr=%q DB=%d password match=%t", opts.Addr, opts.DB, opts.Password == "s3cret") + } + }) + t.Run("rediss URL enables TLS", func(t *testing.T) { + opts, err := redisOptions("rediss://:tok@master.example.cache.amazonaws.com:6379") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if opts.TLSConfig == nil { + t.Fatal("expected TLS config for rediss://") + } + }) + t.Run("bad scheme is an error", func(t *testing.T) { + if _, err := redisOptions("http://localhost:6379"); err == nil { + t.Fatal("expected an error for a non-redis scheme") + } + }) +} diff --git a/services/feature-store/cmd/server/main.go b/services/feature-store/cmd/server/main.go index 1469fcd..6b88660 100644 --- a/services/feature-store/cmd/server/main.go +++ b/services/feature-store/cmd/server/main.go @@ -137,7 +137,7 @@ type FeatureStoreConfig struct { // RedisURL points at the Redis backing the online (latest-value) projection. // Format: redis://host:port/db. Injected via env (K8s ConfigMap, or a Secret if // it carries credentials). - RedisURL string `env:"REDIS_URL" default:"redis://localhost:6379"` + RedisURL string `env:"REDIS_URL" default:"redis://:fp@localhost:6379"` // OTelInsecure controls whether the OTLP exporter uses plaintext (no TLS). It is // true in local docker-compose (the collector has no cert) and false in diff --git a/services/inference-gateway/cmd/server/main.go b/services/inference-gateway/cmd/server/main.go index 35470c5..3027202 100644 --- a/services/inference-gateway/cmd/server/main.go +++ b/services/inference-gateway/cmd/server/main.go @@ -114,7 +114,7 @@ type InferenceConfig struct { // RedisURL is the connection string for the rate-limit buckets, the quota // cache, and the routing-table mirror. In K8s this points at the fp-infra // Redis Service. Defaulted for local docker-compose. - RedisURL string `env:"REDIS_URL" default:"redis://localhost:6379"` + RedisURL string `env:"REDIS_URL" default:"redis://:fp@localhost:6379"` // Environment ("local"/"staging"/"production") tags telemetry and gates the // in-memory idempotency-store fallback (production REFUSES it — see below). diff --git a/services/model-monitor/internal/config/config.go b/services/model-monitor/internal/config/config.go index 5e5b573..c16c7fa 100644 --- a/services/model-monitor/internal/config/config.go +++ b/services/model-monitor/internal/config/config.go @@ -45,7 +45,7 @@ type MonitorConfig struct { // semantics far better than a relational table. Postgres holds the durable // drift_reports; Redis holds the ephemeral in-flight windows. Optional at boot // (the scaffold doesn't connect yet) — required once the Redis adapter lands. - RedisURL string `env:"REDIS_URL" default:"redis://localhost:6379"` + RedisURL string `env:"REDIS_URL" default:"redis://:fp@localhost:6379"` // RetrainCooldown is the minimum gap between auto-retrains for one model — the // ANTI-STORM interval of the closed loop. A sustained drift breaches CRITICAL on diff --git a/services/notification/cmd/server/main.go b/services/notification/cmd/server/main.go index 8308c22..c474725 100644 --- a/services/notification/cmd/server/main.go +++ b/services/notification/cmd/server/main.go @@ -140,7 +140,7 @@ type NotificationConfig struct { // AND the reactor's domain-level per-(event,recipient) dedup store. A redis:// // URL (host/port/db/credentials), parsed by go-redis ParseURL. // K8s: a plain ConfigMap value pointing at the in-cluster Redis. - RedisURL string `env:"REDIS_URL" default:"redis://localhost:6379"` + RedisURL string `env:"REDIS_URL" default:"redis://:fp@localhost:6379"` // SMTPAddr is the SMTP server for the EMAIL channel (host:port). Optional — // consumed by the (not-yet-written) delivery adapter; unset is valid today. diff --git a/services/registry/cmd/server/main.go b/services/registry/cmd/server/main.go index 606aef5..b0281e3 100644 --- a/services/registry/cmd/server/main.go +++ b/services/registry/cmd/server/main.go @@ -67,6 +67,7 @@ import ( "net/http" "os" "os/signal" + "strings" "time" "github.com/jackc/pgx/v5/pgxpool" @@ -107,11 +108,12 @@ type RegistryConfig struct { // RedisURL is the connection string for the CQRS READ projection (Redis). It is // distinct from DatabaseURL (the Postgres WRITE store) precisely because the two - // stores are separate in CQRS. NewReadStore takes a host:port "addr" (not a URL), - // so the default is bare host:port and we pass it through directly. A full - // "redis://" URL with auth/db would need redis.ParseURL — a later concern when - // Redis grows credentials; bare addr is correct for the local/in-cluster stack. - RedisURL string `env:"REDIS_URL" default:"localhost:6379"` + // stores are separate in CQRS. Accepts either a full URL (redis:// or rediss://, + // parsed by redis.ParseURL, so credentials, db and TLS work, as ElastiCache with + // auth + in-transit encryption requires) or a bare host:port (the in-cluster + // Helm default). The default matches the local docker-compose stack, which + // requires a password (REDIS_PASSWORD, dev default "fp"). + RedisURL string `env:"REDIS_URL" default:"redis://:fp@localhost:6379"` // OTelInsecure controls whether the OTLP exporter uses plaintext (no TLS). It is // true in local docker-compose (the collector has no cert) and false in @@ -237,7 +239,13 @@ func main() { // --- Redis: the CQRS READ projection (eventually-consistent query side) --- // go-redis's Client is itself a pool; Ping fails fast on an unreachable server. - rdb := goredis.NewClient(&goredis.Options{Addr: cfg.RedisURL}) + redisOpts, err := redisOptions(cfg.RedisURL) + if err != nil { + pgPool.Close() + logger.Error("invalid FP_REDIS_URL", slog.String("error", err.Error())) + os.Exit(1) + } + rdb := goredis.NewClient(redisOpts) if err := rdb.Ping(bootCtx).Err(); err != nil { _ = rdb.Close() pgPool.Close() @@ -541,3 +549,14 @@ func main() { shutdown() logger.Info("registry service stopped cleanly") } + +// redisOptions turns FP_REDIS_URL into client options. A value with a scheme +// (redis:// or rediss://) goes through redis.ParseURL, which handles the +// password, db number and TLS. A bare host:port, which the Helm chart sets for +// the in-cluster Redis, is used as the address directly, as before. +func redisOptions(raw string) (*goredis.Options, error) { + if strings.Contains(raw, "://") { + return goredis.ParseURL(raw) + } + return &goredis.Options{Addr: raw}, nil +} diff --git a/services/registry/cmd/server/redis_options_test.go b/services/registry/cmd/server/redis_options_test.go new file mode 100644 index 0000000..a53d3bb --- /dev/null +++ b/services/registry/cmd/server/redis_options_test.go @@ -0,0 +1,38 @@ +package main + +import "testing" + +func TestRedisOptions(t *testing.T) { + t.Run("bare host:port is used as the address", func(t *testing.T) { + opts, err := redisOptions("redis.fp-infra.svc.cluster.local:6379") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if opts.Addr != "redis.fp-infra.svc.cluster.local:6379" || opts.Password != "" || opts.TLSConfig != nil { + t.Fatalf("got Addr=%q Password set=%t TLS=%t", opts.Addr, opts.Password != "", opts.TLSConfig != nil) + } + }) + t.Run("redis URL carries the password", func(t *testing.T) { + opts, err := redisOptions("redis://:s3cret@localhost:6379/2") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if opts.Addr != "localhost:6379" || opts.Password != "s3cret" || opts.DB != 2 { + t.Fatalf("got Addr=%q DB=%d password match=%t", opts.Addr, opts.DB, opts.Password == "s3cret") + } + }) + t.Run("rediss URL enables TLS", func(t *testing.T) { + opts, err := redisOptions("rediss://:tok@master.example.cache.amazonaws.com:6379") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if opts.TLSConfig == nil { + t.Fatal("expected TLS config for rediss://") + } + }) + t.Run("bad scheme is an error", func(t *testing.T) { + if _, err := redisOptions("http://localhost:6379"); err == nil { + t.Fatal("expected an error for a non-redis scheme") + } + }) +} From 8e81eb41127bedb27853d35d16fb95aa13ba93d5 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:26:35 +0500 Subject: [PATCH 08/42] terraform: stop public subnets auto-assigning public IPs Trivy AWS-0164 (x3, HIGH) flagged map_public_ip_on_launch = true on the three public subnets, one of the findings keeping the Security gate red. Nothing in those subnets needs it. The NAT gateway's public address is the Elastic IP passed as allocation_id, and internet-facing ALB/NLB nodes get public addresses from AWS whatever this flag says. The only thing the flag did was give a public IP to any EC2 instance later launched into those subnets (a debug box, a mis-placed node group), which is the accident the public/private split exists to prevent. The comment that said the flag was needed is corrected. `terraform validate` passes. Co-Authored-By: Claude Opus 5.5 --- deploy/terraform/modules/network/main.tf | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/deploy/terraform/modules/network/main.tf b/deploy/terraform/modules/network/main.tf index c756ba2..187a85a 100644 --- a/deploy/terraform/modules/network/main.tf +++ b/deploy/terraform/modules/network/main.tf @@ -68,15 +68,22 @@ resource "aws_internet_gateway" "this" { # ---------------------------------------------------------------------------- # Subnets # ---------------------------------------------------------------------------- -# PUBLIC subnets. map_public_ip_on_launch = true so a NAT gateway / LB placed -# here gets a public IP. The kubernetes.io/role/elb tag tells the AWS Load -# Balancer Controller "put internet-facing LBs in these subnets". +# PUBLIC subnets. The kubernetes.io/role/elb tag tells the AWS Load Balancer +# Controller "put internet-facing LBs in these subnets". +# +# map_public_ip_on_launch = false (Trivy AWS-0164). Nothing here needs it: the +# NAT gateway gets its public address from the Elastic IP passed as +# allocation_id, and internet-facing ALB/NLB nodes get public addresses from AWS +# regardless of this flag. What the flag WOULD do is give a public IP to any EC2 +# instance someone later launches into these subnets (a debug box, a mis-placed +# node group), which is exactly the accident the private/public split exists to +# prevent. resource "aws_subnet" "public" { count = var.az_count vpc_id = aws_vpc.this.id cidr_block = local.public_subnet_cidrs[count.index] availability_zone = local.azs[count.index] - map_public_ip_on_launch = true + map_public_ip_on_launch = false tags = merge(var.tags, { Name = "${var.name_prefix}-public-${local.azs[count.index]}" From a9db7938dfdf2b4dab8efb447f5024d6f2445fb2 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:27:16 +0500 Subject: [PATCH 09/42] terraform: keep the EKS API private in the example tfvars The README says to copy terraform.tfvars.example to terraform.tfvars. That file set eks_public_access = true and eks_public_access_cidrs = ["0.0.0.0/0"], which overrode the secure defaults in variables.tf and put the Kubernetes API server on the internet, guarded only by authentication. Trivy does not parse *.tfvars.example, so no gate saw it. The example now matches variables.tf (private endpoint, empty CIDR list), with a commented recipe for a throwaway cluster that enables the public endpoint for one /32 egress IP. Co-Authored-By: Claude Opus 5.5 --- .../environments/dev/terraform.tfvars.example | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/deploy/terraform/environments/dev/terraform.tfvars.example b/deploy/terraform/environments/dev/terraform.tfvars.example index 434b2a6..82d1247 100644 --- a/deploy/terraform/environments/dev/terraform.tfvars.example +++ b/deploy/terraform/environments/dev/terraform.tfvars.example @@ -16,10 +16,18 @@ az_count = 3 single_nat_gateway = true # PROD: false (one NAT per AZ for egress resilience) # ---- EKS ------------------------------------------------------------------- -cluster_version = "1.30" -eks_public_access = true # PROD: false (reach the API via VPN/bastion only) -# SECURITY: replace with your office/VPN egress CIDR. 0.0.0.0/0 = open to the world. -eks_public_access_cidrs = ["0.0.0.0/0"] +cluster_version = "1.30" +# Kubernetes API endpoint. Same secure default as variables.tf: private only, +# reached from inside the VPC (bastion / VPN / SSM port-forward). +eks_public_access = false +eks_public_access_cidrs = [] +# Need kubectl from a laptop on a throwaway cluster? Enable the public endpoint +# AND restrict it to your own egress IP (curl -s https://checkip.amazonaws.com): +# eks_public_access = true +# eks_public_access_cidrs = ["203.0.113.10/32"] +# Never 0.0.0.0/0: that puts the API server on the internet, guarded only by +# authentication. (Trivy does not scan *.tfvars.example files, so nothing in CI +# would have caught this file doing exactly that.) node_instance_types = ["t3.medium"] node_desired_size = 2 From b4ea7f22dd4c488c2fcb8bf7ee79fb48ebd9196a Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:29:53 +0500 Subject: [PATCH 10/42] terraform: let RDS manage the master password, keep it out of state The RDS module generated the master password with random_password, passed it to aws_db_instance and wrote it, plus a full DSN, into a Secrets Manager secret_string. All three persist in Terraform state, which sat in an SSE-S3 bucket. There was also a drift trap: aws_db_instance ignored password changes but the secret version did not, so an out-of-band rotation set up a later apply that would overwrite the secret with a password the DB no longer took. - aws_db_instance uses manage_master_user_password = true with master_user_secret_kms_key_id = the RDS CMK. RDS generates, stores and rotates the password in a secret it owns, and Terraform never sees it. random_password.master and the ignore_changes block are gone. - "/rds/postgres" now holds connection info only (host, port, dbname, username, sslmode, master_user_secret_arn). New outputs: master_user_secret_arn (module) and rds_master_user_secret_arn (dev). - The external_secrets IRSA role can read the RDS-managed secret. Both ExternalSecrets now build FP_DATABASE_URL with an ESO template from the managed username/password (by ARN, placeholder ) plus the connection info, URL-escaping the credentials. - ElastiCache cannot do the same: there is no managed password, and provider 5.100 has no write-only auth_token (checked against the provider schema). The token stays in state. The module and README now say so, and list the CMK on the state bucket and IAM-authenticated ElastiCache users as the mitigation and the real fix. - README: the "outputs are marked sensitive" claim was false. It now says why none are (ARNs are not secrets, and `sensitive` does not keep a value out of state). Trade-off: RDS rotates every 7 days by default, and envFrom env vars only change on pod restart, so the cluster needs a reloader or scheduled rollouts. Documented in deploy/secrets/README.md. `terraform validate` passes. Co-Authored-By: Claude Opus 5.5 --- deploy/secrets/README.md | 14 +++- .../externalsecret-fp-auth.yaml | 63 +++++++++++++---- .../externalsecret-fp-infra-creds.yaml | 55 +++++++++++---- deploy/terraform/README.md | 17 ++++- deploy/terraform/environments/dev/main.tf | 2 + deploy/terraform/environments/dev/outputs.tf | 7 +- deploy/terraform/modules/elasticache/main.tf | 12 ++++ deploy/terraform/modules/rds/main.tf | 68 ++++++++++--------- deploy/terraform/modules/rds/outputs.tf | 11 ++- deploy/terraform/modules/rds/variables.tf | 7 +- 10 files changed, 184 insertions(+), 72 deletions(-) diff --git a/deploy/secrets/README.md b/deploy/secrets/README.md index fff8569..02db5f3 100644 --- a/deploy/secrets/README.md +++ b/deploy/secrets/README.md @@ -69,16 +69,17 @@ Files: `arn:aws:iam:::role/forgepoint-dev-irsa-external_secrets`. - [`externalsecret-fp-auth.yaml`](./external-secrets/externalsecret-fp-auth.yaml) — materializes Secret `fp-auth` with `FP_JWT_SECRET` (from `/auth/jwt`) and - `FP_DATABASE_URL` (the `dsn` field of the RDS module's `/rds/postgres`). + `FP_DATABASE_URL` (templated from the RDS-managed password secret plus the + RDS module's `/rds/postgres` connection info). - [`externalsecret-fp-infra-creds.yaml`](./external-secrets/externalsecret-fp-infra-creds.yaml) — materializes Secret `fp-infra-creds` with the shared Postgres + Redis connection - info (RDS `dsn`/host/port + ElastiCache `url`/host/port/`auth_token`). + info (templated Postgres DSN + host/port, ElastiCache `url`/host/port/`auth_token`). ### Secret name ↔ Terraform source (no values, only names) | K8s Secret key | AWS SM secret (name) | JSON property | Terraform source | |---|---|---|---| -| `FP_DATABASE_URL` | `/rds/postgres` | `dsn` | `modules/rds` | +| `FP_DATABASE_URL` (templated) | RDS-managed `rds!db-...` (by ARN) + `/rds/postgres` | `username`/`password` + `host`/`port`/`dbname`/`sslmode` | `modules/rds` (`manage_master_user_password`) | | `POSTGRES_HOST`/`PORT` | `/rds/postgres` | `host`/`port` | `modules/rds` | | `FP_REDIS_URL` | `/elasticache/redis` | `url` | `modules/elasticache` | | `REDIS_*` | `/elasticache/redis` | `host`/`port`/`auth_token` | `modules/elasticache` | @@ -91,6 +92,13 @@ Files: > and adds its ARN to the `external_secrets` IRSA role's `secret_arns` in > `environments/dev/main.tf`. The generated key never touches Git. +> **Note on the Postgres password:** RDS generates, stores and rotates it +> (`manage_master_user_password`), so it never appears in Terraform state. The +> secret's name is generated, so the ExternalSecrets reference it by ARN: replace +> `` with the `rds_master_user_secret_arn` output. RDS +> rotates it every 7 days by default; env vars only change on pod restart, so run a +> reloader (or a scheduled rollout) or new connections will fail after a rotation. + ## Local path: Sealed Secrets (`sealed-secrets/`) For the k3s homelab with no AWS. Encrypt a Secret locally with `kubeseal`, commit diff --git a/deploy/secrets/external-secrets/externalsecret-fp-auth.yaml b/deploy/secrets/external-secrets/externalsecret-fp-auth.yaml index 5358afe..f45b019 100644 --- a/deploy/secrets/external-secrets/externalsecret-fp-auth.yaml +++ b/deploy/secrets/external-secrets/externalsecret-fp-auth.yaml @@ -12,9 +12,16 @@ # # WHY TWO DIFFERENT SOURCES FOR ONE TARGET SECRET # - FP_DATABASE_URL: the Postgres DSN is INFRASTRUCTURE the RDS Terraform module -# owns. It is stored as a JSON blob at "/rds/postgres" with a ready -# "dsn" field (postgres://user:pass@host:5432/db?sslmode=require). We pull the -# `dsn` property straight out — no string assembly, no password in Git. +# owns, and it is ASSEMBLED HERE from two sources so the password never passes +# through Terraform state: +# * username + password from the secret RDS itself creates and rotates +# (manage_master_user_password). Its name is generated (rds!db-...), so it +# is referenced by ARN: replace with the +# `rds_master_user_secret_arn` Terraform output. +# * host, port, dbname, sslmode from "/rds/postgres", a +# connection-info secret with no password in it. +# The template below URL-escapes the credentials into +# postgres://user:pass@host:port/db?sslmode=require. No password in Git. # - FP_JWT_SECRET: the HMAC-SHA256 signing key is an APPLICATION secret, not a # cloud resource, so Terraform does NOT create it (it has no business minting # app keys). Instead it lives in its own Secrets Manager secret @@ -31,10 +38,12 @@ # vars the service expects — no stray `host`/`port`/`username` keys leaking in as # env. Explicit is safer and self-documenting. # -# refreshInterval: ESO re-reads the backend on this cadence. If the RDS password is -# rotated in Secrets Manager (e.g. by AWS managed rotation), ESO repulls and -# updates the K8s Secret within ~1h; pair with a reloader to restart pods, or rely -# on the service reconnecting. Shorter = fresher but more AWS API calls. +# refreshInterval: ESO re-reads the backend on this cadence. RDS rotates the +# managed master password (every 7 days by default); ESO repulls and updates the +# K8s Secret within ~1h. Env vars from envFrom only change when a pod restarts, +# so pair this with a reloader (or a scheduled rollout): open connections survive +# a rotation, NEW connections need the new password. Shorter = fresher but more +# AWS API calls. # ============================================================================ apiVersion: external-secrets.io/v1 kind: ExternalSecret @@ -62,18 +71,46 @@ spec: template: # Opaque + these become env vars via the Deployment's envFrom. Key names # match what services/auth/cmd/server reads (FP_JWT_SECRET, FP_DATABASE_URL). + # With template.data set, ONLY these keys land in the Secret; the fetched + # pg_* values below are template inputs, not env vars. type: Opaque + engineVersion: v2 + data: + FP_JWT_SECRET: "{{ .jwt_secret }}" + FP_DATABASE_URL: "postgres://{{ .pg_username | urlquery }}:{{ .pg_password | urlquery }}@{{ .pg_host }}:{{ .pg_port }}/{{ .pg_dbname }}?sslmode={{ .pg_sslmode }}" data: # ---- JWT signing key (app secret, "/auth/jwt" JSON -> jwt_secret) ---- - - secretKey: FP_JWT_SECRET + - secretKey: jwt_secret remoteRef: # PLACEHOLDER name — matches the operator-created SM secret described above. key: "forgepoint-dev/auth/jwt" property: jwt_secret - # ---- Postgres DSN (infra secret, RDS module "/rds/postgres" -> dsn) -- - - secretKey: FP_DATABASE_URL + # ---- Postgres credentials (RDS-managed secret, rotated by RDS) ------------- + - secretKey: pg_username + remoteRef: + # PLACEHOLDER: the `rds_master_user_secret_arn` Terraform output. + key: "" + property: username + - secretKey: pg_password + remoteRef: + key: "" + property: password + # ---- Postgres connection info (RDS module "/rds/postgres") -------- + # Matches aws_secretsmanager_secret.db.name = "${name_prefix}/rds/postgres" + # (deploy/terraform/modules/rds/main.tf). PLACEHOLDER prefix shown. + - secretKey: pg_host + remoteRef: + key: "forgepoint-dev/rds/postgres" + property: host + - secretKey: pg_port + remoteRef: + key: "forgepoint-dev/rds/postgres" + property: port + - secretKey: pg_dbname + remoteRef: + key: "forgepoint-dev/rds/postgres" + property: dbname + - secretKey: pg_sslmode remoteRef: - # Matches aws_secretsmanager_secret.db.name = "${name_prefix}/rds/postgres" - # (deploy/terraform/modules/rds/main.tf). PLACEHOLDER prefix shown. key: "forgepoint-dev/rds/postgres" - property: dsn + property: sslmode diff --git a/deploy/secrets/external-secrets/externalsecret-fp-infra-creds.yaml b/deploy/secrets/external-secrets/externalsecret-fp-infra-creds.yaml index 86a5964..f9bde14 100644 --- a/deploy/secrets/external-secrets/externalsecret-fp-infra-creds.yaml +++ b/deploy/secrets/external-secrets/externalsecret-fp-infra-creds.yaml @@ -17,9 +17,14 @@ # needs Redis shouldn't receive the Postgres password, and vice versa — refine # with separate ExternalSecrets per store if you want stricter isolation). # -# SOURCES (both are JSON blobs Terraform writes; we extract named properties): -# - "/rds/postgres" (modules/rds) -> dsn, host, port +# SOURCES (JSON blobs; we extract named properties): +# - (created + rotated BY RDS) -> username, password +# Replace the placeholder with the `rds_master_user_secret_arn` TF output. +# - "/rds/postgres" (modules/rds, no password) -> host, port, +# dbname, sslmode # - "/elasticache/redis" (modules/elasticache)-> url, host, port, auth_token +# FP_DATABASE_URL is assembled by the template below, so the Postgres password +# never passes through Terraform state. # No password/token/URL value is ever written here — only the AWS key NAME and # the JSON property to pull. The plaintext lives in AWS, encrypted under KMS. # @@ -46,34 +51,58 @@ spec: creationPolicy: Owner template: type: Opaque + engineVersion: v2 + # With template.data set, ONLY these keys land in the Secret; the fetched + # values below (pg_*, redis_*) are template inputs. + data: + FP_DATABASE_URL: "postgres://{{ .pg_username | urlquery }}:{{ .pg_password | urlquery }}@{{ .pg_host }}:{{ .pg_port }}/{{ .pg_dbname }}?sslmode={{ .pg_sslmode }}" + POSTGRES_HOST: "{{ .pg_host }}" + POSTGRES_PORT: "{{ .pg_port }}" + FP_REDIS_URL: "{{ .redis_url }}" + REDIS_HOST: "{{ .redis_host }}" + REDIS_PORT: "{{ .redis_port }}" + REDIS_AUTH_TOKEN: "{{ .redis_auth_token }}" data: - # ---- Postgres (RDS module: "/rds/postgres") -------------------- - - secretKey: FP_DATABASE_URL + # ---- Postgres credentials (RDS-managed secret, rotated by RDS) ---------- + - secretKey: pg_username remoteRef: - key: "forgepoint-dev/rds/postgres" # PLACEHOLDER prefix - property: dsn - - secretKey: POSTGRES_HOST + key: "" # PLACEHOLDER: TF output rds_master_user_secret_arn + property: username + - secretKey: pg_password remoteRef: - key: "forgepoint-dev/rds/postgres" + key: "" + property: password + # ---- Postgres connection info (RDS module: "/rds/postgres") ----- + - secretKey: pg_host + remoteRef: + key: "forgepoint-dev/rds/postgres" # PLACEHOLDER prefix property: host - - secretKey: POSTGRES_PORT + - secretKey: pg_port remoteRef: key: "forgepoint-dev/rds/postgres" property: port + - secretKey: pg_dbname + remoteRef: + key: "forgepoint-dev/rds/postgres" + property: dbname + - secretKey: pg_sslmode + remoteRef: + key: "forgepoint-dev/rds/postgres" + property: sslmode # ---- Redis (ElastiCache module: "/elasticache/redis") ---------- - - secretKey: FP_REDIS_URL + - secretKey: redis_url remoteRef: key: "forgepoint-dev/elasticache/redis" # PLACEHOLDER prefix property: url - - secretKey: REDIS_HOST + - secretKey: redis_host remoteRef: key: "forgepoint-dev/elasticache/redis" property: host - - secretKey: REDIS_PORT + - secretKey: redis_port remoteRef: key: "forgepoint-dev/elasticache/redis" property: port - - secretKey: REDIS_AUTH_TOKEN + - secretKey: redis_auth_token remoteRef: key: "forgepoint-dev/elasticache/redis" property: auth_token diff --git a/deploy/terraform/README.md b/deploy/terraform/README.md index 81c98cc..fa91d5a 100644 --- a/deploy/terraform/README.md +++ b/deploy/terraform/README.md @@ -63,9 +63,20 @@ the standard way: - **Tagging:** every taggable resource carries `Project=forgepoint`, `Environment=`, `ManagedBy=terraform` (applied once via the provider `default_tags` — see `dev/providers.tf`). -- **No hardcoded secrets / account IDs / regions:** all of these are variables. Database and - Redis credentials are **generated by Terraform and stored in AWS Secrets Manager**, never - passed in as `.tfvars` and never printed (outputs expose only ARNs, marked `sensitive`). +- **No hardcoded secrets / account IDs / regions:** all of these are variables. No credential + is ever passed in as `.tfvars`. + - The **Postgres master password** is generated, stored and rotated by **RDS itself** + (`manage_master_user_password`). It never passes through Terraform, so it is not in + state. + - The **Redis AUTH token** is generated by Terraform (`random_password`) and stored in + Secrets Manager. ElastiCache has no managed-password option, and AWS provider 5.x has + no write-only `auth_token`, so **this token is in state**. That is one reason the state + bucket is encrypted with a customer-managed KMS key and readable only by the roles + that run Terraform (see `modules/state-backend`). + - **Outputs** expose ARNs and endpoints only. None is marked `sensitive`, because none is + a secret, and `sensitive` only hides a value from CLI output: it does not keep it out + of state. (An earlier version of this README said the outputs were marked sensitive; + they never were.) - **Encryption everywhere:** KMS for EKS secrets, RDS storage, S3 (SSE-KMS), ElastiCache at-rest + in-transit; S3 + RDS + ElastiCache are all private-subnet only. - **Private-by-default networking:** workloads live in private subnets; only the NAT gateway diff --git a/deploy/terraform/environments/dev/main.tf b/deploy/terraform/environments/dev/main.tf index bd215d6..1f44e60 100644 --- a/deploy/terraform/environments/dev/main.tf +++ b/deploy/terraform/environments/dev/main.tf @@ -180,6 +180,8 @@ module "iam" { s3_artifact_access = "" secret_arns = [ module.rds.credentials_secret_arn, + # The RDS-managed master password (username + password JSON). + module.rds.master_user_secret_arn, module.elasticache.credentials_secret_arn, ] kms_key_arns = [ diff --git a/deploy/terraform/environments/dev/outputs.tf b/deploy/terraform/environments/dev/outputs.tf index 0aa6193..eef2227 100644 --- a/deploy/terraform/environments/dev/outputs.tf +++ b/deploy/terraform/environments/dev/outputs.tf @@ -41,10 +41,15 @@ output "rds_endpoint" { } output "rds_credentials_secret_arn" { - description = "Secrets Manager ARN holding the Postgres DSN/credentials. External Secrets Operator (under the external_secrets IRSA role) syncs this into K8s." + description = "Secrets Manager ARN holding the Postgres connection info (host, port, dbname, username; no password). External Secrets Operator reads it to build the DSN." value = module.rds.credentials_secret_arn } +output "rds_master_user_secret_arn" { + description = "Secrets Manager ARN of the RDS-managed (and rotated) master password. Put this ARN in the ExternalSecret manifests under deploy/secrets/external-secrets (placeholder )." + value = module.rds.master_user_secret_arn +} + output "redis_endpoint" { description = "Redis primary endpoint. Apps read the rediss:// URL from redis_credentials_secret_arn." value = module.elasticache.primary_endpoint diff --git a/deploy/terraform/modules/elasticache/main.tf b/deploy/terraform/modules/elasticache/main.tf index e5d559a..d66c8c0 100644 --- a/deploy/terraform/modules/elasticache/main.tf +++ b/deploy/terraform/modules/elasticache/main.tf @@ -75,6 +75,18 @@ resource "aws_security_group_rule" "redis_ingress" { # ElastiCache AUTH tokens have constraints: 16-128 chars, and only a limited # special-char set. We restrict override_special accordingly so the token is # always accepted by ElastiCache. +# KNOWN RESIDUAL RISK: this token is stored in Terraform STATE (random_password +# results, the replication group's auth_token and the secret_string below are +# all persisted). Unlike RDS there is no AWS-managed password for ElastiCache, +# and AWS provider 5.x has no write-only auth_token. Mitigations: the state +# bucket is SSE-KMS with a CMK and restricted to the Terraform roles +# (modules/state-backend). The longer-term fix is ElastiCache RBAC users with +# IAM authentication, which needs a client change (short-lived IAM auth tokens). +# +# DRIFT HAZARD: the replication group ignores auth_token changes (below) but the +# secret version does not. If the token is ever rotated outside Terraform, the +# next apply rewrites the secret with the OLD token and clients break. Rotate +# by changing it here (and applying), never out of band. resource "random_password" "auth_token" { length = 48 special = true diff --git a/deploy/terraform/modules/rds/main.tf b/deploy/terraform/modules/rds/main.tf index 68bfcde..0474c2f 100644 --- a/deploy/terraform/modules/rds/main.tf +++ b/deploy/terraform/modules/rds/main.tf @@ -2,12 +2,22 @@ # rds — PostgreSQL: private, KMS-encrypted, SG-restricted, creds in Secrets Manager # ============================================================================ # The credential flow is the centerpiece: -# random_password → aws_db_instance.master_password → aws_secretsmanager_secret -# The plaintext password exists only inside Terraform's run and the encrypted -# Secrets Manager entry. It is NEVER an input var, NEVER an output, and the random -# resource is marked sensitive so it doesn't print in plan/apply logs. The app -# reads the DSN from Secrets Manager at runtime (via External Secrets Operator in -# K8s, which maps the secret into a K8s Secret the pod envFrom's). +# manage_master_user_password = true +# → RDS generates the master password itself, stores it in a Secrets Manager +# secret it owns (rds!db-...), encrypted with our CMK, and rotates it. +# Terraform never sees the password, so it is not in state, not in plan output +# and not in any secret_string Terraform writes. (The previous design generated +# it with random_password and wrote a full DSN into a secret version, which put +# the plaintext into state, and the state bucket was only SSE-S3.) +# +# The app still gets a ready DSN: External Secrets Operator reads username + +# password from the RDS-managed secret and host/port/dbname from the +# connection-info secret below, and renders FP_DATABASE_URL with a template +# (deploy/secrets/external-secrets/). Rotation: RDS rotates the managed secret +# (every 7 days by default); ESO picks the new value up on its refresh, but env +# vars only change when a pod restarts, so pair it with a reloader or a +# scheduled rollout. Existing connections survive a rotation; new ones need +# the new password. # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- @@ -65,17 +75,6 @@ resource "aws_security_group_rule" "rds_ingress" { description = "PostgreSQL from allowed (EKS node) security group" } -# ---------------------------------------------------------------------------- -# Generated master password — never typed by a human, never committed. -# ---------------------------------------------------------------------------- -# override_special avoids characters that break DSN parsing / shell quoting in -# connection strings ('@', '/', '"', spaces). 32 chars of entropy. -resource "random_password" "master" { - length = 32 - special = true - override_special = "!#$%*-_=+[]{}<>:?" -} - # ---------------------------------------------------------------------------- # The instance. # ---------------------------------------------------------------------------- @@ -94,7 +93,11 @@ resource "aws_db_instance" "this" { db_name = var.database_name username = var.master_username - password = random_password.master.result + # RDS owns the password: generated, stored in a Secrets Manager secret it + # manages (encrypted with our CMK, not the AWS-managed key) and rotated. It + # never passes through Terraform, so it never lands in state. + manage_master_user_password = true + master_user_secret_kms_key_id = aws_kms_key.rds.arn # PRIVATE: in our subnet group, attached to the restricted SG, and explicitly # NOT publicly accessible — three independent guarantees of no internet exposure. @@ -123,27 +126,26 @@ resource "aws_db_instance" "this" { tags = merge(var.tags, { Name = "${var.name_prefix}-postgres" }) - # The generated password churns plan output; don't let a password rotation - # outside TF (e.g. via Secrets Manager rotation) force a needless modify. - lifecycle { - ignore_changes = [password] - } } # ---------------------------------------------------------------------------- -# Secrets Manager — store the FULL connection material so apps consume it. +# Secrets Manager — connection INFO only (no password). # ---------------------------------------------------------------------------- -# We store a JSON blob (not just the password) so consumers get everything needed -# to build a DSN: host, port, user, password, the bootstrap dbname. External -# Secrets Operator in K8s reads this and projects it into a K8s Secret that the -# service pods envFrom — closing the loop from cloud secret → running container. +# host, port, dbname, username and the ARN of the RDS-managed password secret. +# None of it is a credential; it lives in Secrets Manager (rather than only in +# outputs) so External Secrets Operator can read it next to the password and +# render the DSN in-cluster. Keeping the password OUT of this secret is the +# point: the old design wrote the plaintext into secret_string, i.e. into state, +# and its aws_db_instance ignored password changes while this resource did not, +# so an out-of-band rotation set up a later apply that would overwrite the +# secret with a password the database no longer accepted. # # recovery_window: 0 in dev lets us delete+recreate the secret immediately on # teardown (no 7-30 day "scheduled deletion" blocking a re-apply). Prod should # RAISE this (e.g. 7) so an accidental delete is recoverable. resource "aws_secretsmanager_secret" "db" { name = "${var.name_prefix}/rds/postgres" - description = "Forgepoint Postgres master credentials + connection info" + description = "Forgepoint Postgres connection info (no password; see master_user_secret_arn)" kms_key_id = aws_kms_key.rds.arn recovery_window_in_days = 0 tags = var.tags @@ -156,10 +158,10 @@ resource "aws_secretsmanager_secret_version" "db" { host = aws_db_instance.this.address port = aws_db_instance.this.port username = var.master_username - password = random_password.master.result dbname = var.database_name - # A ready-to-use DSN with TLS required (RDS terminates TLS; sslmode=require - # ensures the client refuses an unencrypted connection). - dsn = "postgres://${var.master_username}:${random_password.master.result}@${aws_db_instance.this.address}:${aws_db_instance.this.port}/${var.database_name}?sslmode=require" + # Clients must use TLS (sslmode=require); ESO's DSN template adds it. + sslmode = "require" + # Where the password lives (RDS-managed, rotated). ESO reads it from there. + master_user_secret_arn = aws_db_instance.this.master_user_secret[0].secret_arn }) } diff --git a/deploy/terraform/modules/rds/outputs.tf b/deploy/terraform/modules/rds/outputs.tf index 0cc42b5..0f8f3e6 100644 --- a/deploy/terraform/modules/rds/outputs.tf +++ b/deploy/terraform/modules/rds/outputs.tf @@ -28,16 +28,21 @@ output "security_group_id" { } output "credentials_secret_arn" { - description = "ARN of the Secrets Manager secret holding the DB DSN/credentials. The iam module grants specific IRSA roles secretsmanager:GetSecretValue on THIS arn so only the right pods can read it. NOT sensitive (an ARN is not a secret), but the secret it points to is." + description = "ARN of the Secrets Manager secret holding the DB CONNECTION INFO (host, port, dbname, username, master_user_secret_arn). It contains no password. An ARN is not a secret." value = aws_secretsmanager_secret.db.arn } output "credentials_secret_name" { - description = "Name of the Secrets Manager secret (handy for External Secrets Operator ExternalSecret refs)." + description = "Name of the connection-info secret (for External Secrets Operator ExternalSecret refs)." value = aws_secretsmanager_secret.db.name } output "kms_key_arn" { - description = "ARN of the KMS key encrypting RDS storage + the credentials secret." + description = "ARN of the KMS key encrypting RDS storage, the RDS-managed master password secret and the connection-info secret." value = aws_kms_key.rds.arn } + +output "master_user_secret_arn" { + description = "ARN of the Secrets Manager secret RDS creates and rotates for the master user (JSON: username, password). Grant External Secrets Operator read on THIS arn plus kms:Decrypt on kms_key_arn; no application pod should read it directly." + value = aws_db_instance.this.master_user_secret[0].secret_arn +} diff --git a/deploy/terraform/modules/rds/variables.tf b/deploy/terraform/modules/rds/variables.tf index 6ffa129..a91c3d1 100644 --- a/deploy/terraform/modules/rds/variables.tf +++ b/deploy/terraform/modules/rds/variables.tf @@ -2,8 +2,9 @@ # rds — INPUTS # ============================================================================ # A PostgreSQL instance, private-subnet only, encrypted with KMS, reachable ONLY -# from the EKS nodes. Credentials are GENERATED here and stored in AWS Secrets -# Manager — they are never an input variable and never appear in plan output. +# from the EKS nodes. The master password is generated, stored and rotated by +# RDS itself (manage_master_user_password): it is never an input variable and +# never passes through Terraform, so it is not in plan output or state. # # DATABASE-PER-SERVICE note: locally we run one Postgres server with one database # per service (fp_auth, fp_registry, …). We mirror that here: one RDS INSTANCE, @@ -72,7 +73,7 @@ variable "database_name" { } variable "master_username" { - description = "Master DB username. NOT a secret on its own (the PASSWORD is what's secret); kept as a var for clarity. The password is generated by Terraform and stored in Secrets Manager." + description = "Master DB username. NOT a secret on its own (the PASSWORD is what's secret); kept as a var for clarity. The password is generated and rotated by RDS in a Secrets Manager secret it manages." type = string default = "fp_admin" } From 5a9adad36629f53aee599929e8a4f68f80373fd0 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:31:47 +0500 Subject: [PATCH 11/42] terraform: make destructive settings variables with safe defaults The README says staging and prod are made by copying environments/dev/. That directory hard-coded skip_final_snapshot = true and ECR force_delete = true, both modules hard-coded Secrets Manager recovery_window_in_days = 0, and the module and env defaults had deletion protection off. A copied prod would inherit every one of them. - Module defaults are now the safe values: rds deletion_protection = true, skip_final_snapshot = false, ecr force_delete = false, and a new secret_recovery_window_days (default 30, validated 0 or 7-30) on the rds and elasticache modules. - environments/dev exposes them as variables with the same safe defaults (rds_deletion_protection, rds_skip_final_snapshot, ecr_force_delete, secret_recovery_window_days). - terraform.tfvars.example opts the throwaway dev env into the teardown values, with each prod value next to it. The tfvars header, the variables.tf header and the README say which values are defaults and which are opt-ins. Behaviour change, on purpose: running dev without the example tfvars now yields a protected DB, a final snapshot on delete, non-force-deletable ECR repos and a 30-day secret recovery window. `terraform validate` passes. Co-Authored-By: Claude Opus 5.5 --- deploy/terraform/README.md | 7 +++-- deploy/terraform/environments/dev/main.tf | 14 ++++++--- .../environments/dev/terraform.tfvars.example | 20 +++++++++---- .../terraform/environments/dev/variables.tf | 29 ++++++++++++++++--- deploy/terraform/modules/ecr/variables.tf | 4 +-- deploy/terraform/modules/elasticache/main.tf | 2 +- .../modules/elasticache/variables.tf | 11 +++++++ deploy/terraform/modules/rds/main.tf | 12 ++++---- deploy/terraform/modules/rds/variables.tf | 19 +++++++++--- 9 files changed, 90 insertions(+), 28 deletions(-) diff --git a/deploy/terraform/README.md b/deploy/terraform/README.md index fa91d5a..ed955e2 100644 --- a/deploy/terraform/README.md +++ b/deploy/terraform/README.md @@ -41,8 +41,11 @@ deploy/terraform/ ``` `staging/` and `prod/` are produced by **copying `dev/` and tuning the variables** (bigger -instances, `multi_az = true`, `deletion_protection = true`, restricted API CIDRs). The -modules themselves do not change between environments — that's the whole point of the split. +instances, `multi_az = true`, restricted API CIDRs). Destructive settings (deletion +protection off, no final snapshot, ECR force-delete, immediate secret deletion) are +variables whose **defaults are the safe values**; only the dev `terraform.tfvars.example` +turns them on, so a copied directory starts safe. The modules themselves do not change +between environments — that's the whole point of the split. ## Bootstrapping order (chicken-and-egg with remote state) diff --git a/deploy/terraform/environments/dev/main.tf b/deploy/terraform/environments/dev/main.tf index 1f44e60..f29a321 100644 --- a/deploy/terraform/environments/dev/main.tf +++ b/deploy/terraform/environments/dev/main.tf @@ -81,8 +81,11 @@ module "rds" { multi_az = var.rds_multi_az deletion_protection = var.rds_deletion_protection backup_retention_days = var.rds_backup_retention_days - # Dev throwaway: skip the final snapshot so teardown is instant + free. - skip_final_snapshot = true + # Destructive settings come from variables with SAFE defaults; the dev + # teardown values live in terraform.tfvars.example. (They used to be + # hard-coded here, so a copy of this directory for prod inherited them.) + skip_final_snapshot = var.rds_skip_final_snapshot + secret_recovery_window_days = var.secret_recovery_window_days } # ---------------------------------------------------------------------------- @@ -100,6 +103,8 @@ module "elasticache" { node_type = var.redis_node_type num_cache_nodes = var.redis_num_nodes automatic_failover = var.redis_automatic_failover + + secret_recovery_window_days = var.secret_recovery_window_days } # ---------------------------------------------------------------------------- @@ -123,8 +128,9 @@ module "ecr" { source = "../../modules/ecr" name_prefix = local.name_prefix - # Dev: allow destroy to remove repos with images, mutable-tag off (immutable). - force_delete = true + # Images stay immutable (module default). force_delete comes from a variable + # with a safe default; dev opts in via tfvars so destroy can remove repos. + force_delete = var.ecr_force_delete } # ---------------------------------------------------------------------------- diff --git a/deploy/terraform/environments/dev/terraform.tfvars.example b/deploy/terraform/environments/dev/terraform.tfvars.example index 82d1247..638a77d 100644 --- a/deploy/terraform/environments/dev/terraform.tfvars.example +++ b/deploy/terraform/environments/dev/terraform.tfvars.example @@ -1,10 +1,12 @@ # ============================================================================ # dev — EXAMPLE TFVARS # ============================================================================ -# Copy to terraform.tfvars (gitignored) and tune. Every value here already has a -# sensible dev default in variables.tf, so this file is OPTIONAL — it exists to -# show the knobs and document how prod would differ. There are NO secrets here: -# DB/Redis credentials are generated by Terraform into Secrets Manager. +# Copy to terraform.tfvars (gitignored) and tune. Sizing values match the +# defaults in variables.tf. The DESTRUCTIVE switches (deletion protection off, +# no final snapshot, force-delete, immediate secret deletion) do NOT: their +# defaults are the safe values, and this file opts a throwaway dev env into +# them. There are NO secrets here: the Postgres password is managed by RDS and +# the Redis token is generated by Terraform into Secrets Manager. # ---------------------------------------------------------------------------- environment = "dev" @@ -39,7 +41,8 @@ node_capacity_type = "ON_DEMAND" # DEV money-saver: "SPOT" (~70% cheaper) rds_instance_class = "db.t3.micro" rds_engine_version = "16.4" rds_multi_az = false # PROD: true -rds_deletion_protection = false # PROD: true +rds_deletion_protection = false # PROD: true (the variable default) +rds_skip_final_snapshot = true # PROD: false (the variable default) rds_backup_retention_days = 7 # PROD: 14-35 # ---- ElastiCache (Redis) --------------------------------------------------- @@ -47,3 +50,10 @@ redis_node_type = "cache.t3.micro" redis_engine_version = "7.1" redis_num_nodes = 1 # PROD: >= 2 redis_automatic_failover = false # PROD: true (needs redis_num_nodes >= 2) + +# ---- Throwaway-env teardown switches ---------------------------------------- +# These make `terraform destroy` fast and complete for a disposable dev env. The +# variable defaults are the SAFE values; delete these lines for anything that +# holds data you care about. +secret_recovery_window_days = 0 # PROD: 7-30 (default 30) +ecr_force_delete = true # PROD: false (the default) diff --git a/deploy/terraform/environments/dev/variables.tf b/deploy/terraform/environments/dev/variables.tf index be35ea8..d3528f7 100644 --- a/deploy/terraform/environments/dev/variables.tf +++ b/deploy/terraform/environments/dev/variables.tf @@ -1,9 +1,11 @@ # ============================================================================ # dev — ENVIRONMENT VARIABLES # ============================================================================ -# Every knob the modules expose is surfaced here with a DEV-appropriate default -# (small + cheap). staging/prod copy this directory and override via *.tfvars — -# the modules don't change between environments, only these values do. +# Every knob the modules expose is surfaced here. Sizing defaults are DEV-sized +# (small + cheap). Anything DESTRUCTIVE (deletion protection off, no final +# snapshot, force-delete, immediate secret deletion) defaults to the SAFE value +# and the dev env opts in through terraform.tfvars, so a copy of this directory +# for staging/prod starts safe even if nobody copies the dev tfvars. # # Nothing secret lives here: DB/Redis credentials are GENERATED by Terraform and # stored in Secrets Manager (see the rds/elasticache modules). No account IDs are @@ -111,7 +113,13 @@ variable "rds_multi_az" { } variable "rds_deletion_protection" { - description = "Block deletion of the DB. Dev: FALSE (teardown). Prod: TRUE." + description = "Block deletion of the DB. SAFE DEFAULT true. The dev tfvars sets false so the throwaway env can be torn down." + type = bool + default = true +} + +variable "rds_skip_final_snapshot" { + description = "Skip the final snapshot when the DB is deleted. SAFE DEFAULT false. The dev tfvars sets true so teardown is instant and free." type = bool default = false } @@ -122,6 +130,19 @@ variable "rds_backup_retention_days" { default = 7 } +# ---- Destructive teardown switches (safe defaults; dev opts in via tfvars) -- +variable "secret_recovery_window_days" { + description = "Recovery window for the Secrets Manager secrets Terraform creates (RDS connection info, Redis credentials): 7-30 days, or 0 to delete immediately. SAFE DEFAULT 30. The dev tfvars sets 0 so destroy + re-apply does not collide with a secret pending deletion." + type = number + default = 30 +} + +variable "ecr_force_delete" { + description = "Let `terraform destroy` delete ECR repositories that still hold images. SAFE DEFAULT false. The dev tfvars sets true." + type = bool + default = false +} + # ---- ElastiCache (Redis) --------------------------------------------------- variable "redis_node_type" { description = "ElastiCache node type. Dev: cache.t3.micro." diff --git a/deploy/terraform/modules/ecr/variables.tf b/deploy/terraform/modules/ecr/variables.tf index 9a3565f..f1c6a7e 100644 --- a/deploy/terraform/modules/ecr/variables.tf +++ b/deploy/terraform/modules/ecr/variables.tf @@ -59,9 +59,9 @@ variable "max_tagged_images" { } variable "force_delete" { - description = "Allow `terraform destroy` to delete a repo that still contains images. TRUE in dev (tear it all down). FALSE in prod so you can't wipe release images by accident." + description = "Allow `terraform destroy` to delete a repo that still contains images. SAFE DEFAULT false, so release images cannot be wiped by accident. A throwaway dev env sets true in its tfvars." type = bool - default = true + default = false } variable "tags" { diff --git a/deploy/terraform/modules/elasticache/main.tf b/deploy/terraform/modules/elasticache/main.tf index d66c8c0..af07a8d 100644 --- a/deploy/terraform/modules/elasticache/main.tf +++ b/deploy/terraform/modules/elasticache/main.tf @@ -147,7 +147,7 @@ resource "aws_secretsmanager_secret" "redis" { name = "${var.name_prefix}/elasticache/redis" description = "Forgepoint Redis auth token + connection info" kms_key_id = aws_kms_key.redis.arn - recovery_window_in_days = 0 + recovery_window_in_days = var.secret_recovery_window_days tags = var.tags } diff --git a/deploy/terraform/modules/elasticache/variables.tf b/deploy/terraform/modules/elasticache/variables.tf index f80227d..2903787 100644 --- a/deploy/terraform/modules/elasticache/variables.tf +++ b/deploy/terraform/modules/elasticache/variables.tf @@ -59,6 +59,17 @@ variable "snapshot_retention_days" { default = 1 } +variable "secret_recovery_window_days" { + description = "Days Secrets Manager keeps the deleted Redis credentials secret recoverable (7-30), or 0 to delete immediately. SAFE DEFAULT 30 (the AWS default). A throwaway dev env may set 0 so destroy + re-apply does not collide with a secret pending deletion." + type = number + default = 30 + + validation { + condition = var.secret_recovery_window_days == 0 || (var.secret_recovery_window_days >= 7 && var.secret_recovery_window_days <= 30) + error_message = "secret_recovery_window_days must be 0 or between 7 and 30." + } +} + variable "tags" { description = "Additional tags (Project/Environment/ManagedBy via provider default_tags)." type = map(string) diff --git a/deploy/terraform/modules/rds/main.tf b/deploy/terraform/modules/rds/main.tf index 0474c2f..846a6b0 100644 --- a/deploy/terraform/modules/rds/main.tf +++ b/deploy/terraform/modules/rds/main.tf @@ -113,7 +113,8 @@ resource "aws_db_instance" "this" { maintenance_window = "sun:04:30-sun:05:30" copy_tags_to_snapshot = true - # Safety rails (prod tightens both via tfvars). + # Safety rails. Module defaults are the SAFE values (protected, final + # snapshot taken); a throwaway env opts out explicitly in its tfvars. deletion_protection = var.deletion_protection skip_final_snapshot = var.skip_final_snapshot final_snapshot_identifier = var.skip_final_snapshot ? null : "${var.name_prefix}-postgres-final" @@ -125,7 +126,6 @@ resource "aws_db_instance" "this" { enabled_cloudwatch_logs_exports = ["postgresql", "upgrade"] tags = merge(var.tags, { Name = "${var.name_prefix}-postgres" }) - } # ---------------------------------------------------------------------------- @@ -140,14 +140,14 @@ resource "aws_db_instance" "this" { # so an out-of-band rotation set up a later apply that would overwrite the # secret with a password the database no longer accepted. # -# recovery_window: 0 in dev lets us delete+recreate the secret immediately on -# teardown (no 7-30 day "scheduled deletion" blocking a re-apply). Prod should -# RAISE this (e.g. 7) so an accidental delete is recoverable. +# recovery_window: var.secret_recovery_window_days (safe default 30). A dev +# teardown can set 0 in tfvars so a re-apply is not blocked by a secret pending +# deletion. It used to be hard-coded to 0, which every copy of the env inherited. resource "aws_secretsmanager_secret" "db" { name = "${var.name_prefix}/rds/postgres" description = "Forgepoint Postgres connection info (no password; see master_user_secret_arn)" kms_key_id = aws_kms_key.rds.arn - recovery_window_in_days = 0 + recovery_window_in_days = var.secret_recovery_window_days tags = var.tags } diff --git a/deploy/terraform/modules/rds/variables.tf b/deploy/terraform/modules/rds/variables.tf index a91c3d1..2883a89 100644 --- a/deploy/terraform/modules/rds/variables.tf +++ b/deploy/terraform/modules/rds/variables.tf @@ -85,15 +85,26 @@ variable "backup_retention_days" { } variable "deletion_protection" { - description = "Block `terraform destroy`/console delete of the instance. FALSE in dev so the throwaway env can be torn down to save money; TRUE in prod so nobody nukes the production DB by accident." + description = "Block `terraform destroy`/console delete of the instance. SAFE DEFAULT true. A throwaway dev env sets false in its tfvars so it can be torn down." type = bool - default = false + default = true } variable "skip_final_snapshot" { - description = "Skip the final snapshot on delete. TRUE in dev (we don't care about a throwaway DB's data). FALSE in prod so a delete always leaves a recoverable snapshot." + description = "Skip the final snapshot on delete. SAFE DEFAULT false, so a delete always leaves a recoverable snapshot. A throwaway dev env sets true in its tfvars." type = bool - default = true + default = false +} + +variable "secret_recovery_window_days" { + description = "Days Secrets Manager keeps the deleted connection-info secret recoverable (7-30), or 0 to delete immediately. SAFE DEFAULT 30 (the AWS default). A throwaway dev env may set 0 so destroy + re-apply does not collide with a secret pending deletion." + type = number + default = 30 + + validation { + condition = var.secret_recovery_window_days == 0 || (var.secret_recovery_window_days >= 7 && var.secret_recovery_window_days <= 30) + error_message = "secret_recovery_window_days must be 0 or between 7 and 30." + } } variable "tags" { From 80f812ec83c197152bf6460b3cb071d356646374 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:32:32 +0500 Subject: [PATCH 12/42] terraform: give the artifacts bucket its own KMS key environments/dev passed the RDS CMK to the s3 module, and the registry and model-serving IRSA roles got kms:Decrypt on that key so they could read SSE-KMS objects. The same key wraps the database secrets, so any artifact reader was one IAM mistake (a broad secretsmanager:GetSecretValue) away from a credential read. - The s3 module creates a dedicated, rotated CMK (alias -artifacts) unless a key is passed in, always uses SSE-KMS (the SSE-S3 fallback is gone) and outputs kms_key_arn. - The iam module takes artifacts_kms_key_arn and grants it per role: kms:Decrypt for read, plus kms:GenerateDataKey for readwrite. The old grant only had Decrypt, so a registry PutObject to an SSE-KMS bucket would have been denied. - registry and model-serving no longer hold any grant on the RDS key. - Comments say plainly that no service code uses S3 yet (there is no AWS SDK in any go.mod), so these roles grant nothing until a ServiceAccount is annotated with them. `terraform validate` passes. Co-Authored-By: Claude Opus 5.5 --- deploy/terraform/environments/dev/main.tf | 32 +++++++++++--------- deploy/terraform/modules/iam/main.tf | 20 ++++++++++++ deploy/terraform/modules/iam/variables.tf | 6 ++++ deploy/terraform/modules/s3/main.tf | 37 ++++++++++++++++++----- deploy/terraform/modules/s3/outputs.tf | 5 +++ deploy/terraform/modules/s3/variables.tf | 2 +- 6 files changed, 79 insertions(+), 23 deletions(-) diff --git a/deploy/terraform/environments/dev/main.tf b/deploy/terraform/environments/dev/main.tf index f29a321..a0ad5c0 100644 --- a/deploy/terraform/environments/dev/main.tf +++ b/deploy/terraform/environments/dev/main.tf @@ -110,15 +110,14 @@ module "elasticache" { # ---------------------------------------------------------------------------- # (5) S3 — model-artifacts bucket # ---------------------------------------------------------------------------- -# Bucket names are globally unique, so suffix with the account id. We reuse the -# RDS KMS key for SSE-KMS to avoid spinning up yet another CMK in dev; prod could -# pass a dedicated artifacts key. +# Bucket names are globally unique, so suffix with the account id. The module +# creates a dedicated CMK for the bucket. (It used to reuse the RDS key, which +# gave every artifact reader kms:Decrypt on the key that wraps the DB secrets.) module "s3" { source = "../../modules/s3" name_prefix = local.name_prefix bucket_name = "${local.name_prefix}-model-artifacts-${data.aws_caller_identity.current.account_id}" - kms_key_arn = module.rds.kms_key_arn } # ---------------------------------------------------------------------------- @@ -141,9 +140,11 @@ module "ecr" { # Helm chart fullnames (e.g. fp-registry) in the fp-system namespace. # # Roles modeled here (extend as services gain AWS needs): -# - registry : read/write model artifacts in S3 + read its DB secret -# - model-serving : READ model artifacts from S3 (pulls weights) + read DB? no. -# serving holds models in-memory; it only needs S3 read. +# - registry : read/write model artifacts in S3 +# - model-serving : READ model artifacts from S3 (pulls weights) +# NOTE: no service code uses S3 yet (no AWS SDK in any go.mod; model-serving +# fetches file:// and http(s):// URLs). These two roles are the intended +# shape; they grant nothing until a ServiceAccount is annotated with them. # - external-secrets: the External Secrets Operator's controller SA — reads the # RDS + Redis secrets from Secrets Manager and projects them # into K8s Secrets for every service. Central, so each app @@ -151,10 +152,11 @@ module "ecr" { module "iam" { source = "../../modules/iam" - name_prefix = local.name_prefix - oidc_provider_arn = module.eks.oidc_provider_arn - oidc_provider_url = module.eks.oidc_provider_url - artifacts_bucket_arn = module.s3.bucket_arn + name_prefix = local.name_prefix + oidc_provider_arn = module.eks.oidc_provider_arn + oidc_provider_url = module.eks.oidc_provider_url + artifacts_bucket_arn = module.s3.bucket_arn + artifacts_kms_key_arn = module.s3.kms_key_arn roles = { # Model Registry: writes artifacts on RegisterVersion, reads on serve-prep. @@ -163,9 +165,9 @@ module "iam" { service_account_name = "fp-registry" s3_artifact_access = "readwrite" secret_arns = [] - # The artifacts bucket uses the RDS CMK for SSE-KMS (see module "s3"), so - # reading/writing objects needs kms:Decrypt on that key. - kms_key_arns = [module.rds.kms_key_arn] + # KMS for the artifacts key comes from artifacts_kms_key_arn above; this + # role needs no other key. + kms_key_arns = [] } # Model Serving: pulls (reads) model weights from S3 on startup. Read-only. @@ -174,7 +176,7 @@ module "iam" { service_account_name = "fp-model-serving" s3_artifact_access = "read" secret_arns = [] - kms_key_arns = [module.rds.kms_key_arn] + kms_key_arns = [] } # External Secrets Operator controller: the ONE workload allowed to read the diff --git a/deploy/terraform/modules/iam/main.tf b/deploy/terraform/modules/iam/main.tf index 34f7f28..a86ee9a 100644 --- a/deploy/terraform/modules/iam/main.tf +++ b/deploy/terraform/modules/iam/main.tf @@ -94,6 +94,26 @@ data "aws_iam_policy_document" "permissions" { } } + # --- KMS for the artifacts bucket (SSE-KMS) ------------------------------- + # Reading an SSE-KMS object needs kms:Decrypt; writing one needs + # kms:GenerateDataKey. Scoped to the artifacts key only. + dynamic "statement" { + for_each = (each.value.s3_artifact_access != "" && var.artifacts_bucket_arn != "" && var.artifacts_kms_key_arn != "") ? [each.value.s3_artifact_access] : [] + content { + sid = "ArtifactsKMS" + effect = "Allow" + actions = statement.value == "readwrite" ? [ + "kms:Decrypt", + "kms:GenerateDataKey", + "kms:DescribeKey", + ] : [ + "kms:Decrypt", + "kms:DescribeKey", + ] + resources = [var.artifacts_kms_key_arn] + } + } + # --- Secrets Manager: GetSecretValue on the EXACT secret ARNs listed ----- # This is how a service reads its DB/Redis credentials at runtime (directly, or # via External Secrets Operator running under its own IRSA role). Scoped to the diff --git a/deploy/terraform/modules/iam/variables.tf b/deploy/terraform/modules/iam/variables.tf index 8096a34..1d142d7 100644 --- a/deploy/terraform/modules/iam/variables.tf +++ b/deploy/terraform/modules/iam/variables.tf @@ -58,6 +58,12 @@ variable "artifacts_bucket_arn" { default = "" } +variable "artifacts_kms_key_arn" { + description = "ARN of the KMS key encrypting the artifacts bucket (from the s3 module). Roles with s3_artifact_access get kms:Decrypt on it, plus kms:GenerateDataKey for readwrite (needed to PUT an SSE-KMS object). Keeps artifact access from needing a hand-maintained kms_key_arns entry." + type = string + default = "" +} + variable "tags" { description = "Additional tags (Project/Environment/ManagedBy via provider default_tags)." type = map(string) diff --git a/deploy/terraform/modules/s3/main.tf b/deploy/terraform/modules/s3/main.tf index a30e615..b3bfd3a 100644 --- a/deploy/terraform/modules/s3/main.tf +++ b/deploy/terraform/modules/s3/main.tf @@ -21,18 +21,41 @@ resource "aws_s3_bucket_versioning" "artifacts" { } } -# SSE-KMS by default. If a KMS key ARN was supplied we use aws:kms with that CMK -# (customer-controlled key, auditable via CloudTrail). If not, fall back to SSE-S3 -# (AES256) — still encrypted at rest, just with the AWS-managed key. bucket_key -# reduces KMS API calls (and cost) by caching a bucket-level data key. +# DEDICATED CMK for the artifacts bucket (unless the caller passes one in). +# WHY a key of its own: the dev composition used to pass the RDS key, so every +# workload allowed to read model artifacts also held kms:Decrypt on the key that +# wraps the database credential secret. One later IAM mistake (a broad +# secretsmanager:GetSecretValue) would then have been a credential read. One key +# per data class keeps the blast radius of a decrypt grant to that class. +resource "aws_kms_key" "artifacts" { + count = var.kms_key_arn == "" ? 1 : 0 + description = "${var.name_prefix} model-artifacts bucket SSE-KMS key" + enable_key_rotation = true + deletion_window_in_days = 30 + tags = merge(var.tags, { Name = "${var.name_prefix}-artifacts-kms" }) +} + +resource "aws_kms_alias" "artifacts" { + count = var.kms_key_arn == "" ? 1 : 0 + name = "alias/${var.name_prefix}-artifacts" + target_key_id = aws_kms_key.artifacts[0].key_id +} + +locals { + artifacts_kms_key_arn = var.kms_key_arn != "" ? var.kms_key_arn : aws_kms_key.artifacts[0].arn +} + +# SSE-KMS with the artifacts CMK (customer-controlled key, auditable via +# CloudTrail). bucket_key reduces KMS API calls (and cost) by caching a +# bucket-level data key. resource "aws_s3_bucket_server_side_encryption_configuration" "artifacts" { bucket = aws_s3_bucket.artifacts.id rule { apply_server_side_encryption_by_default { - sse_algorithm = var.kms_key_arn != "" ? "aws:kms" : "AES256" - kms_master_key_id = var.kms_key_arn != "" ? var.kms_key_arn : null + sse_algorithm = "aws:kms" + kms_master_key_id = local.artifacts_kms_key_arn } - bucket_key_enabled = var.kms_key_arn != "" + bucket_key_enabled = true } } diff --git a/deploy/terraform/modules/s3/outputs.tf b/deploy/terraform/modules/s3/outputs.tf index 62bb12f..c207f61 100644 --- a/deploy/terraform/modules/s3/outputs.tf +++ b/deploy/terraform/modules/s3/outputs.tf @@ -11,6 +11,11 @@ output "bucket_arn" { value = aws_s3_bucket.artifacts.arn } +output "kms_key_arn" { + description = "ARN of the KMS key encrypting the bucket (the module's own CMK unless one was passed in). Readers need kms:Decrypt on it, writers also kms:GenerateDataKey." + value = local.artifacts_kms_key_arn +} + output "bucket_regional_domain_name" { description = "Regional domain name of the bucket (e.g. .s3..amazonaws.com). Useful for S3 client endpoint config." value = aws_s3_bucket.artifacts.bucket_regional_domain_name diff --git a/deploy/terraform/modules/s3/variables.tf b/deploy/terraform/modules/s3/variables.tf index 0a80496..7f57f65 100644 --- a/deploy/terraform/modules/s3/variables.tf +++ b/deploy/terraform/modules/s3/variables.tf @@ -18,7 +18,7 @@ variable "bucket_name" { } variable "kms_key_arn" { - description = "ARN of the KMS key for SSE-KMS. Passed in (created in the env layer or eks/rds module) so all artifact encryption can share one key, or set per-env. If empty, the bucket falls back to SSE-S3 (still encrypted, AWS-managed key)." + description = "ARN of an existing KMS key for SSE-KMS. Leave EMPTY (the default) and the module creates a dedicated, rotated CMK for this bucket. Do not pass a key that protects another data class (e.g. the RDS key): every reader of artifacts would then also be able to decrypt that data." type = string default = "" } From 251e68b9626c33dcf51ed69b0680085c17590586 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:43:24 +0500 Subject: [PATCH 13/42] terraform: harden the state backend and add a bootstrap root modules/state-backend was never called by any root, used SSE-S3 (Trivy AWS-0132, one of the findings keeping the gate red), had no TLS-only policy and no prevent_destroy, and locked with a DynamoDB table, which the S3 backend has deprecated. This state also holds the Redis AUTH token. modules/state-backend: - A customer-managed KMS key (rotation on, 30-day deletion window, prevent_destroy). The bucket default is SSE-KMS with that key plus a bucket key. Reading state now needs kms:Decrypt as well as s3:GetObject. - prevent_destroy on the bucket, BucketOwnerEnforced (no ACLs), and a bucket policy that denies non-TLS requests. - Optional state_access_principal_arns: when set, object read/write/delete is denied to everyone else. Bucket-level actions are deliberately not denied, so an admin cannot lock themselves out of the policy. - The DynamoDB lock table is gone. Locking is use_lockfile (S3-native, GA in Terraform 1.11), so required_version is now >= 1.11 in every root. deploy/terraform/bootstrap (new root, local state, committed lock file): calls the module with forgepoint-tfstate- and outputs a ready backend_config block (bucket, key, region, encrypt, kms_key_id, use_lockfile). Docs: backend.tf (root + dev) and the README bootstrapping section describe the real flow. The old "no CMK, to avoid a circular dependency" rationale is replaced: key and bucket are created together from local state, and the risk that matters is losing the key, which prevent_destroy covers. dev/backend.tf no longer claims CI runs plan. It refers to the terraform workflow added in the next commit, which runs fmt + validate only. Decision: CMK over SSE-S3. Alternative: keep SSE-S3 and rely on IAM. Why: the state holds a live credential, and a CMK puts a second, separately grantable and logged permission in front of it, for roughly $1/month. `terraform validate` passes for bootstrap/ and environments/dev/. Trivy finds no HIGH/CRITICAL in deploy/terraform. Co-Authored-By: Claude Opus 5.5 --- deploy/terraform/README.md | 28 ++- deploy/terraform/backend.tf | 29 +-- .../terraform/bootstrap/.terraform.lock.hcl | 26 +++ deploy/terraform/bootstrap/main.tf | 30 ++++ deploy/terraform/bootstrap/outputs.tf | 21 +++ deploy/terraform/bootstrap/providers.tf | 12 ++ deploy/terraform/bootstrap/variables.tf | 11 ++ deploy/terraform/bootstrap/versions.tf | 20 +++ deploy/terraform/environments/dev/backend.tf | 36 ++-- deploy/terraform/environments/dev/versions.tf | 3 +- .../terraform/modules/state-backend/main.tf | 170 +++++++++++++----- .../modules/state-backend/outputs.tf | 18 +- .../modules/state-backend/variables.tf | 22 +-- deploy/terraform/versions.tf | 7 +- 14 files changed, 327 insertions(+), 106 deletions(-) create mode 100644 deploy/terraform/bootstrap/.terraform.lock.hcl create mode 100644 deploy/terraform/bootstrap/main.tf create mode 100644 deploy/terraform/bootstrap/outputs.tf create mode 100644 deploy/terraform/bootstrap/providers.tf create mode 100644 deploy/terraform/bootstrap/variables.tf create mode 100644 deploy/terraform/bootstrap/versions.tf diff --git a/deploy/terraform/README.md b/deploy/terraform/README.md index ed955e2..8dcfdb8 100644 --- a/deploy/terraform/README.md +++ b/deploy/terraform/README.md @@ -28,7 +28,8 @@ deploy/terraform/ │ ├── s3/ ← model-artifacts bucket: versioned, SSE-KMS, public-access blocked │ ├── ecr/ ← one repo per service, scan-on-push, immutable tags, lifecycle │ ├── iam/ ← IRSA roles per workload, least-privilege, bound to K8s SAs via OIDC -│ └── state-backend/ ← S3 (versioned/SSE/locked) + DynamoDB lock table FOR the remote state +│ └── state-backend/ ← S3 bucket (versioned, SSE-KMS CMK, TLS-only, prevent_destroy) FOR remote state +├── bootstrap/ ← the one root with LOCAL state: applies state-backend once per account └── environments/ └── dev/ ← composes the modules with small/cheap defaults ├── versions.tf (symlink-style copy of root pins — kept per-env so each env is hermetic) @@ -49,18 +50,27 @@ between environments — that's the whole point of the split. ## Bootstrapping order (chicken-and-egg with remote state) -The `state-backend` module creates the S3 bucket + DynamoDB table that the *other* stacks -store their state in — but Terraform needs a backend before it can store state. Resolve it -the standard way: +The `state-backend` module creates the S3 bucket + KMS key that the *other* stacks store +their state in — but Terraform needs a backend before it can store state. Resolve it the +standard way: -1. **First run, local state:** apply `state-backend` (from a tiny bootstrap stack or by - targeting it) with the default *local* backend. This creates the bucket + lock table. -2. **Migrate:** fill in `backend.tf` with that bucket/table and run - `terraform init -migrate-state` to push local state into S3. +1. **First run, local state:** `terraform -chdir=deploy/terraform/bootstrap init && … apply`. + The bootstrap root calls `state-backend` with the default *local* backend and creates + the bucket (versioned, SSE-KMS with its own CMK, TLS-only policy, public access blocked, + `prevent_destroy`) and the key (rotated, `prevent_destroy`, 30-day deletion window). + Set `state_access_principal_arns` to restrict state reads/writes to the roles that run + Terraform. +2. **Migrate:** copy the bootstrap `backend_config` output into `environments//backend.tf` + (or a gitignored `*.backend.hcl`) and run `terraform init -migrate-state`. 3. Everything afterwards (network/eks/rds/…) uses the S3 backend from the start. +Locking uses the S3-native lock file (`use_lockfile = true`, Terraform ≥ 1.11). There is no +DynamoDB lock table: DynamoDB locking is deprecated in the S3 backend. + `dev/backend.tf` ships **commented out** so `terraform init -backend=false` works offline -(no AWS creds, no real bucket) for `validate`/`plan` in CI and for graders. +(no AWS creds, no real bucket). CI (`.github/workflows/terraform.yml`) runs `fmt -check`, +`init -backend=false` and `validate` on every root; it does **not** plan, because CI has +no AWS credentials and nothing has been applied. ## Conventions enforced everywhere diff --git a/deploy/terraform/backend.tf b/deploy/terraform/backend.tf index 060255c..6c5fb18 100644 --- a/deploy/terraform/backend.tf +++ b/deploy/terraform/backend.tf @@ -9,17 +9,19 @@ # WHY remote state at all: # - SHARED + LOCKED: a team (or CI) runs Terraform from many machines. Local # state on one laptop is a single point of truth/failure and invites two -# people applying at once and corrupting state. S3 stores it centrally; -# DynamoDB provides a LOCK so only one apply mutates state at a time. +# people applying at once and corrupting state. S3 stores it centrally, and +# an S3-native lock file (use_lockfile, Terraform >= 1.11) makes sure only +# one apply mutates state at a time. (DynamoDB locking is deprecated.) # - DURABLE + VERSIONED: the S3 bucket has versioning on (see the state-backend # module), so a botched apply can be rolled back to a prior state object. -# - ENCRYPTED: state contains sensitive material (resource IDs, sometimes -# secret values), so the bucket is SSE-encrypted and the backend sets -# `encrypt = true`. +# - ENCRYPTED: state contains sensitive material (resource IDs and, here, the +# Redis AUTH token), so the bucket is SSE-KMS with a customer-managed key and +# the backend sets `encrypt = true` + `kms_key_id`. # -# CHICKEN-AND-EGG: the S3 bucket + DynamoDB table that back this state are -# themselves created by modules/state-backend. Bootstrap once with LOCAL state, -# then `terraform init -migrate-state` into S3. See README.md "Bootstrapping". +# CHICKEN-AND-EGG: the S3 bucket + KMS key that back this state are themselves +# created by the bootstrap root (deploy/terraform/bootstrap, which calls +# modules/state-backend) with LOCAL state; then `terraform init -migrate-state` +# moves each environment into S3. See README.md "Bootstrapping order". # # This block is intentionally COMMENTED OUT here. The root dir is not a rootmodule # you `apply` — it just holds shared versions.tf + this reference. The real, @@ -28,10 +30,11 @@ # # terraform { # backend "s3" { -# bucket = "forgepoint-tfstate-" # from state-backend module output -# key = "/terraform.tfstate" # per-env key (dev/, staging/, prod/) -# region = "us-east-1" # bucket region (not necessarily infra region) -# dynamodb_table = "forgepoint-tflock" # lock table from state-backend module -# encrypt = true # encrypt the state object at rest +# bucket = "forgepoint-tfstate-" # bootstrap output state_bucket_name +# key = "/terraform.tfstate" # per-env key (dev/, staging/, prod/) +# region = "us-east-1" # bucket region (not necessarily infra region) +# encrypt = true # encrypt the state object at rest... +# kms_key_id = "" # ...with the state CMK +# use_lockfile = true # S3-native lock (Terraform >= 1.11) # } # } diff --git a/deploy/terraform/bootstrap/.terraform.lock.hcl b/deploy/terraform/bootstrap/.terraform.lock.hcl new file mode 100644 index 0000000..13a46db --- /dev/null +++ b/deploy/terraform/bootstrap/.terraform.lock.hcl @@ -0,0 +1,26 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.100.0" + constraints = "~> 5.60" + hashes = [ + "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "h1:edXOJWE4ORX8Fm+dpVpICzMZJat4AX0VRCAy/xkcOc0=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", + ] +} diff --git a/deploy/terraform/bootstrap/main.tf b/deploy/terraform/bootstrap/main.tf new file mode 100644 index 0000000..4b69bf5 --- /dev/null +++ b/deploy/terraform/bootstrap/main.tf @@ -0,0 +1,30 @@ +# ============================================================================ +# bootstrap — creates the remote-state backend for every other root +# ============================================================================ +# This is the ONE root that starts with local state, because the bucket it +# creates is where everything else keeps its state. Run it once per account: +# +# terraform -chdir=deploy/terraform/bootstrap init +# terraform -chdir=deploy/terraform/bootstrap apply +# +# Then copy the `backend_config` output into environments//backend.tf (or +# a gitignored *.backend.hcl passed with -backend-config) and run +# `terraform init -migrate-state` there. Optionally migrate this root's own +# state into the bucket too (key = "bootstrap/terraform.tfstate"): the bucket +# and key have prevent_destroy, so losing the local file is recoverable with +# `terraform import`, but keeping it remote is tidier. +# +# Everything here is protected from `terraform destroy` (prevent_destroy on the +# bucket and the KMS key). Tearing the backend down is a deliberate, manual act. +# ============================================================================ + +data "aws_caller_identity" "current" {} + +module "state_backend" { + source = "../modules/state-backend" + + # Bucket names are global, so suffix with the account id (read at plan time, + # never hard-coded). + bucket_name = "forgepoint-tfstate-${data.aws_caller_identity.current.account_id}" + state_access_principal_arns = var.state_access_principal_arns +} diff --git a/deploy/terraform/bootstrap/outputs.tf b/deploy/terraform/bootstrap/outputs.tf new file mode 100644 index 0000000..3520678 --- /dev/null +++ b/deploy/terraform/bootstrap/outputs.tf @@ -0,0 +1,21 @@ +output "state_bucket_name" { + description = "The remote-state bucket." + value = module.state_backend.state_bucket_name +} + +output "kms_key_arn" { + description = "The KMS key that encrypts state objects." + value = module.state_backend.kms_key_arn +} + +output "backend_config" { + description = "Backend settings for environments//backend.tf (replace ). Not secret: bucket and key names only." + value = <<-EOT + bucket = "${module.state_backend.state_bucket_name}" + key = "/terraform.tfstate" + region = "${var.aws_region}" + encrypt = true + kms_key_id = "${module.state_backend.kms_key_arn}" + use_lockfile = true + EOT +} diff --git a/deploy/terraform/bootstrap/providers.tf b/deploy/terraform/bootstrap/providers.tf new file mode 100644 index 0000000..02b6461 --- /dev/null +++ b/deploy/terraform/bootstrap/providers.tf @@ -0,0 +1,12 @@ +provider "aws" { + region = var.aws_region + + default_tags { + tags = { + Project = "forgepoint" + Environment = "shared" + ManagedBy = "terraform" + Stack = "bootstrap" + } + } +} diff --git a/deploy/terraform/bootstrap/variables.tf b/deploy/terraform/bootstrap/variables.tf new file mode 100644 index 0000000..a18d6c3 --- /dev/null +++ b/deploy/terraform/bootstrap/variables.tf @@ -0,0 +1,11 @@ +variable "aws_region" { + description = "Region for the state bucket and its KMS key. Every environment's backend block must name the same region." + type = string + default = "us-east-1" +} + +variable "state_access_principal_arns" { + description = "IAM principals (wildcards allowed) allowed to read/write state objects. Non-empty = everyone else is denied by the bucket policy. Example: [\"arn:aws:iam:::role/terraform-*\", \"arn:aws:iam:::user/\"]. Include whatever identity runs this bootstrap if you plan to migrate its own state into the bucket." + type = list(string) + default = [] +} diff --git a/deploy/terraform/bootstrap/versions.tf b/deploy/terraform/bootstrap/versions.tf new file mode 100644 index 0000000..f6b6e9f --- /dev/null +++ b/deploy/terraform/bootstrap/versions.tf @@ -0,0 +1,20 @@ +# ============================================================================ +# bootstrap — VERSION PINS +# ============================================================================ +# Same AWS provider constraint as environments/*/versions.tf. The committed +# .terraform.lock.hcl freezes the exact build and its checksums. +# +# required_version >= 1.11: the environments' S3 backend uses use_lockfile +# (S3-native state locking), which is GA from Terraform 1.11. +# ============================================================================ + +terraform { + required_version = ">= 1.11.0, < 2.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.60" + } + } +} diff --git a/deploy/terraform/environments/dev/backend.tf b/deploy/terraform/environments/dev/backend.tf index 43cd794..6f54de2 100644 --- a/deploy/terraform/environments/dev/backend.tf +++ b/deploy/terraform/environments/dev/backend.tf @@ -2,18 +2,25 @@ # dev — REMOTE STATE BACKEND # ============================================================================ # State for the DEV environment lives under its own key in the shared state -# bucket (created by modules/state-backend). Separate key per env => a dev -# destroy can never touch staging/prod state. +# bucket (created by deploy/terraform/bootstrap via modules/state-backend). +# Separate key per env => a dev destroy can never touch staging/prod state. # # WHY values are commented + placeholder: -# - The bucket/table don't exist until state-backend is bootstrapped (see -# README "Bootstrapping order"). Until then we run with LOCAL state. -# - Graders + CI validate OFFLINE with `terraform init -backend=false`, which -# SKIPS this block entirely (no AWS creds, no real bucket needed). That is the -# command in the task's VALIDATE step and the reason this stays commented. +# - The bucket and key don't exist until the bootstrap root has been applied +# (see README "Bootstrapping order"). Until then we run with LOCAL state. +# - CI (.github/workflows/terraform.yml) validates OFFLINE with +# `terraform init -backend=false`, which SKIPS this block entirely (no AWS +# creds, no real bucket). CI does not plan: there are no AWS credentials in +# CI and this stack has never been applied. # -# TO GO LIVE: uncomment, replace with your account (or use the -# state_bucket_name output from state-backend), then `terraform init -migrate-state`. +# TO GO LIVE: uncomment and fill in from the bootstrap root's `backend_config` +# output (or put the same lines in a gitignored dev.backend.hcl and pass +# -backend-config=dev.backend.hcl), then `terraform init -migrate-state`. +# +# LOCKING: use_lockfile = true (S3-native lock file, GA in Terraform 1.11). The +# old dynamodb_table setting is deprecated and the module no longer creates a +# lock table. kms_key_id makes each state write use the state CMK; without it +# the backend asks S3 for SSE-S3 on every write. # Backend config can't use variables/interpolation (a Terraform limitation — the # backend is initialized before the rest of the config is evaluated), so these are # literal strings or supplied via `-backend-config=...` flags / a *.hcl file. @@ -21,10 +28,11 @@ terraform { backend "s3" { - # bucket = "forgepoint-tfstate-" - # key = "dev/terraform.tfstate" - # region = "us-east-1" - # dynamodb_table = "forgepoint-tflock" - # encrypt = true + # bucket = "forgepoint-tfstate-" + # key = "dev/terraform.tfstate" + # region = "us-east-1" + # encrypt = true + # kms_key_id = "" + # use_lockfile = true } } diff --git a/deploy/terraform/environments/dev/versions.tf b/deploy/terraform/environments/dev/versions.tf index dfe67e9..7f2271a 100644 --- a/deploy/terraform/environments/dev/versions.tf +++ b/deploy/terraform/environments/dev/versions.tf @@ -11,7 +11,8 @@ # ============================================================================ terraform { - required_version = ">= 1.9.0, < 2.0.0" + # >= 1.11: the S3 backend's use_lockfile (backend.tf) is GA from 1.11. + required_version = ">= 1.11.0, < 2.0.0" required_providers { aws = { diff --git a/deploy/terraform/modules/state-backend/main.tf b/deploy/terraform/modules/state-backend/main.tf index 3538913..3daa419 100644 --- a/deploy/terraform/modules/state-backend/main.tf +++ b/deploy/terraform/modules/state-backend/main.tf @@ -1,17 +1,61 @@ # ============================================================================ -# state-backend — the S3 bucket + DynamoDB lock table that back REMOTE STATE +# state-backend — the S3 bucket (and its KMS key) that back REMOTE STATE # ============================================================================ -# Every other stack stores its state in THIS bucket and locks against THIS table. -# The bucket therefore gets the full hardening treatment: versioned (roll back a -# bad apply), encrypted (state can hold secrets), and public access fully blocked. +# Every other stack stores its state in THIS bucket. State is the most sensitive +# artifact in the repo: it holds every resource attribute, including the Redis +# AUTH token (see modules/elasticache) and anything else a provider persists. So +# the bucket gets the full treatment: versioned, encrypted with a customer-managed +# KMS key, TLS-only, public access blocked, ACLs disabled, and protected from +# `terraform destroy`. +# +# LOCKING: S3-native lock files (`use_lockfile = true` in the backend block, +# GA since Terraform 1.11). Terraform writes .tflock next to the state +# object with a conditional PUT, so there is no DynamoDB table any more; the +# DynamoDB lock is deprecated in the S3 backend. +# +# Created ONCE, by the bootstrap root (deploy/terraform/bootstrap), which starts +# with local state. See README.md "Bootstrapping order". # ---------------------------------------------------------------------------- -# The state bucket itself. Note: no `acl` argument — public-block (below) + -# bucket-owner-enforced object ownership is the modern, ACL-free way to keep a -# bucket private. +# ---------------------------------------------------------------------------- +# KMS key for the state objects (Trivy AWS-0132: S3 encryption should use a CMK). +# ---------------------------------------------------------------------------- +# WHY a CMK rather than SSE-S3: reading state then needs kms:Decrypt on THIS key +# as well as s3:GetObject, so a broad S3 read grant elsewhere in the account no +# longer exposes state, and every decrypt is a CloudTrail event. +# +# The old "no CMK, to avoid a bootstrap circular dependency" argument does not +# hold: the key and the bucket are created together by the bootstrap root (local +# state), before any stack stores state in the bucket. The real hazard is +# losing the key, which would make every state object unreadable, hence +# prevent_destroy and the maximum 30-day deletion window. +resource "aws_kms_key" "state" { + description = "Terraform remote state encryption key (${var.bucket_name})" + enable_key_rotation = true + deletion_window_in_days = 30 + tags = var.tags + + lifecycle { + prevent_destroy = true + } +} + +resource "aws_kms_alias" "state" { + name = "alias/${var.bucket_name}" + target_key_id = aws_kms_key.state.key_id +} + +# The state bucket itself. No `acl` argument: public-block (below) + +# BucketOwnerEnforced ownership is the modern, ACL-free way to keep it private. resource "aws_s3_bucket" "state" { bucket = var.bucket_name tags = var.tags + + # A `terraform destroy` (or a refactor that drops this resource) must not be + # able to delete the bucket holding every environment's state. + lifecycle { + prevent_destroy = true + } } # VERSIONING: keep every prior version of the state object. If an apply corrupts @@ -25,24 +69,23 @@ resource "aws_s3_bucket_versioning" "state" { } } -# ENCRYPTION AT REST: SSE with the S3-managed key (SSE-S3 / AES256). We use the -# AWS-managed key here rather than a customer KMS key on purpose — the state -# bucket must be usable during bootstrap BEFORE any KMS key exists, and a KMS -# key whose own state lives in this bucket would be circular. SSE-S3 still -# encrypts everything at rest with zero key management. +# ENCRYPTION AT REST: SSE-KMS with the CMK above. bucket_key_enabled caches a +# bucket-level data key, which cuts KMS request cost. The backend block should +# also set kms_key_id to this key (see environments/dev/backend.tf); without it +# the S3 backend asks for SSE-S3 explicitly on each write. resource "aws_s3_bucket_server_side_encryption_configuration" "state" { bucket = aws_s3_bucket.state.id rule { apply_server_side_encryption_by_default { - sse_algorithm = "AES256" + sse_algorithm = "aws:kms" + kms_master_key_id = aws_kms_key.state.arn } - # bucket_key_enabled has no effect for AES256; omitted deliberately. + bucket_key_enabled = true } } -# PUBLIC ACCESS BLOCK: all four switches on. State is the most sensitive thing in -# the repo — it must NEVER be reachable from the internet, even by accident via a -# stray ACL or bucket policy. This object is the belt-and-suspenders guard. +# PUBLIC ACCESS BLOCK: all four switches on. State must NEVER be reachable from +# the internet, even by accident via a stray ACL or bucket policy. resource "aws_s3_bucket_public_access_block" "state" { bucket = aws_s3_bucket.state.id block_public_acls = true @@ -51,37 +94,76 @@ resource "aws_s3_bucket_public_access_block" "state" { restrict_public_buckets = true } -# DynamoDB LOCK TABLE. The S3 backend uses this for advisory locking: before an -# apply mutates state it writes a lock item keyed by `LockID`; concurrent applies -# see the lock and refuse, preventing two writers from racing on one state file. -# - PAY_PER_REQUEST (on-demand): locking traffic is tiny + bursty; on-demand -# costs cents and needs no capacity planning vs provisioned throughput. -# - hash key MUST be named exactly "LockID" (string) — that's the contract the -# S3 backend expects; renaming it breaks locking. -resource "aws_dynamodb_table" "lock" { - name = var.lock_table_name - billing_mode = "PAY_PER_REQUEST" - hash_key = "LockID" - - attribute { - name = "LockID" - type = "S" +# OWNERSHIP: BucketOwnerEnforced disables ACLs entirely, so access is decided by +# IAM + the bucket policy alone. +resource "aws_s3_bucket_ownership_controls" "state" { + bucket = aws_s3_bucket.state.id + rule { + object_ownership = "BucketOwnerEnforced" } +} - # Recover the table to any point in the last 35 days if it's corrupted/deleted. - # Cheap insurance for the component that guards every other apply. - point_in_time_recovery { - enabled = true +# ---------------------------------------------------------------------------- +# BUCKET POLICY +# ---------------------------------------------------------------------------- +# 1. DenyInsecureTransport: any request over plain HTTP is refused, for every +# principal (state must never cross the wire unencrypted). +# 2. DenyStateAccessToOthers (only when state_access_principal_arns is set): +# object reads/writes/deletes are refused to every principal NOT in the +# list. Bucket-level actions (e.g. PutBucketPolicy) are deliberately left +# out of the deny so an account admin can never be locked out of fixing +# this policy. +data "aws_iam_policy_document" "state" { + statement { + sid = "DenyInsecureTransport" + effect = "Deny" + principals { + type = "*" + identifiers = ["*"] + } + actions = ["s3:*"] + resources = [ + aws_s3_bucket.state.arn, + "${aws_s3_bucket.state.arn}/*", + ] + condition { + test = "Bool" + variable = "aws:SecureTransport" + values = ["false"] + } } - # ENCRYPTION AT REST — SSE with the AWS-owned KMS key (SSE_OWNED_KEY). Like the - # S3 state bucket we deliberately avoid a customer CMK here because this table - # must be usable BEFORE any application CMK exists (bootstrap circular-dependency - # problem). AWS-owned encryption still satisfies CIS DynamoDB controls (encrypted - # at rest); it simply uses an AWS-managed root key rather than a customer one. - server_side_encryption { - enabled = true + dynamic "statement" { + for_each = length(var.state_access_principal_arns) > 0 ? [1] : [] + content { + sid = "DenyStateAccessToOthers" + effect = "Deny" + principals { + type = "*" + identifiers = ["*"] + } + actions = [ + "s3:GetObject", + "s3:GetObjectVersion", + "s3:PutObject", + "s3:DeleteObject", + "s3:DeleteObjectVersion", + ] + resources = ["${aws_s3_bucket.state.arn}/*"] + condition { + test = "ArnNotLike" + variable = "aws:PrincipalArn" + values = var.state_access_principal_arns + } + } } +} + +resource "aws_s3_bucket_policy" "state" { + bucket = aws_s3_bucket.state.id + policy = data.aws_iam_policy_document.state.json - tags = var.tags + # The public-access block must be in place first, or attaching a policy that + # references a "*" principal can transiently trip the block-public-policy guard. + depends_on = [aws_s3_bucket_public_access_block.state] } diff --git a/deploy/terraform/modules/state-backend/outputs.tf b/deploy/terraform/modules/state-backend/outputs.tf index a24b250..17f0443 100644 --- a/deploy/terraform/modules/state-backend/outputs.tf +++ b/deploy/terraform/modules/state-backend/outputs.tf @@ -2,25 +2,21 @@ # state-backend — OUTPUTS # ============================================================================ # These feed straight into environments//backend.tf after bootstrap: -# backend "s3" { bucket = , dynamodb_table = , ... } +# backend "s3" { bucket = , kms_key_id = , +# use_lockfile = true, encrypt = true, ... } # ============================================================================ output "state_bucket_name" { - description = "Name of the S3 bucket holding Terraform remote state. Paste into each environment's backend.tf `bucket`." + description = "Name of the S3 bucket holding Terraform remote state. Paste into each environment's backend config `bucket`." value = aws_s3_bucket.state.id } output "state_bucket_arn" { - description = "ARN of the state bucket (handy for least-privilege CI roles that need s3:GetObject/PutObject on just this bucket)." + description = "ARN of the state bucket (for least-privilege CI roles that need s3:GetObject/PutObject/DeleteObject on just this bucket; DeleteObject is needed to release the .tflock lock file)." value = aws_s3_bucket.state.arn } -output "lock_table_name" { - description = "Name of the DynamoDB lock table. Paste into each environment's backend.tf `dynamodb_table`." - value = aws_dynamodb_table.lock.name -} - -output "lock_table_arn" { - description = "ARN of the DynamoDB lock table (for scoping CI role permissions to just this table)." - value = aws_dynamodb_table.lock.arn +output "kms_key_arn" { + description = "ARN of the KMS key encrypting state. Paste into each environment's backend config `kms_key_id`; roles that run Terraform need kms:Decrypt and kms:GenerateDataKey on it." + value = aws_kms_key.state.arn } diff --git a/deploy/terraform/modules/state-backend/variables.tf b/deploy/terraform/modules/state-backend/variables.tf index 59ddfd4..c8c91a4 100644 --- a/deploy/terraform/modules/state-backend/variables.tf +++ b/deploy/terraform/modules/state-backend/variables.tf @@ -1,26 +1,26 @@ # ============================================================================ # state-backend — INPUTS # ============================================================================ -# Creates the S3 bucket + DynamoDB lock table that hold Terraform REMOTE STATE -# for every other stack. This module is the one exception to "state lives in S3": -# it is bootstrapped with LOCAL state (you can't store state in a bucket that -# doesn't exist yet), then the bucket it creates becomes the home for all other -# stacks. See README.md → "Bootstrapping order". +# Creates the S3 bucket + KMS key that hold Terraform REMOTE STATE for every +# other stack. This module is the one exception to "state lives in S3": the +# bootstrap root that calls it (deploy/terraform/bootstrap) starts with LOCAL +# state (you can't store state in a bucket that doesn't exist yet). See +# README.md → "Bootstrapping order". # ============================================================================ variable "bucket_name" { - description = "Globally-unique S3 bucket name for Terraform state. Convention: forgepoint-tfstate-. Passed in (not derived) so the name is explicit and stable." + description = "Globally-unique S3 bucket name for Terraform state. Convention: forgepoint-tfstate-. Passed in (not derived) so the name is explicit and stable. Also used for the KMS alias (alias/)." type = string } -variable "lock_table_name" { - description = "DynamoDB table name used for state locking. One table can lock many state keys (each stack uses a different LockID), so a single table serves all environments." - type = string - default = "forgepoint-tflock" +variable "state_access_principal_arns" { + description = "IAM principal ARNs (wildcards allowed, e.g. arn:aws:iam::123456789012:role/terraform-*) that may read, write or delete state objects. When non-empty, the bucket policy DENIES object access to every other principal, so state is readable only by the roles that run Terraform. Empty (the default) adds no such restriction; access is then whatever IAM allows, plus kms:Decrypt on the state key. Bucket-level actions are never denied, so an admin cannot be locked out of the policy itself." + type = list(string) + default = [] } variable "tags" { - description = "Tags merged onto every resource. The environments layer supplies Project/Environment/ManagedBy via provider default_tags; anything passed here is additive." + description = "Tags merged onto every resource. The calling root supplies Project/Environment/ManagedBy via provider default_tags; anything passed here is additive." type = map(string) default = {} } diff --git a/deploy/terraform/versions.tf b/deploy/terraform/versions.tf index e3d2481..d483baa 100644 --- a/deploy/terraform/versions.tf +++ b/deploy/terraform/versions.tf @@ -17,9 +17,10 @@ # ============================================================================ terraform { - # 1.14.x is what this repo is validated against. Allow forward patch/minor, - # forbid the next major where breaking language changes could land. - required_version = ">= 1.9.0, < 2.0.0" + # 1.14.x is what this repo is validated against. >= 1.11 because the S3 + # backend's use_lockfile is GA from 1.11. Allow forward patch/minor, forbid + # the next major where breaking language changes could land. + required_version = ">= 1.11.0, < 2.0.0" required_providers { # The AWS provider is the workhorse — VPC, EKS, RDS, ElastiCache, S3, ECR, IAM. From 761b0d0bcce0c888e64355f8479f8891da645c72 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:43:59 +0500 Subject: [PATCH 14/42] terraform: add a monthly cost budget with email alerts dev runs an EKS control plane, a NAT gateway, interface endpoints, two nodes, RDS and ElastiCache around the clock (roughly $200-250/month idle), and nothing in the stack would ever say so. - aws_budgets_budget "-monthly": COST, monthly, default $250 (budget_monthly_limit_usd), alerting at 50/80/100% of actual spend and at 100% of forecast. - budget_alert_emails is required (no default, validated non-empty), so the environment cannot be applied without someone receiving the alerts. The example tfvars and README show it. Decision: account-wide budget. Alternative: filter on the Project tag. Why: a tag filter reads $0 until the tag is activated as a cost allocation tag in Billing, which is exactly the silent failure a budget is meant to prevent. The comment explains how to switch once the tag is active. `terraform validate` passes. Co-Authored-By: Claude Opus 5.5 --- deploy/terraform/README.md | 3 ++ deploy/terraform/environments/dev/main.tf | 43 +++++++++++++++++++ .../environments/dev/terraform.tfvars.example | 4 ++ .../terraform/environments/dev/variables.tf | 17 ++++++++ 4 files changed, 67 insertions(+) diff --git a/deploy/terraform/README.md b/deploy/terraform/README.md index 8dcfdb8..4b95cd3 100644 --- a/deploy/terraform/README.md +++ b/deploy/terraform/README.md @@ -92,6 +92,9 @@ no AWS credentials and nothing has been applied. they never were.) - **Encryption everywhere:** KMS for EKS secrets, RDS storage, S3 (SSE-KMS), ElastiCache at-rest + in-transit; S3 + RDS + ElastiCache are all private-subnet only. +- **Cost guardrail:** each environment has a monthly `aws_budgets_budget` (default $250) that + emails `budget_alert_emails` at 50/80/100% of actual spend and 100% of forecast. The + variable has no default, so an environment cannot be applied without a recipient. - **Private-by-default networking:** workloads live in private subnets; only the NAT gateway and (optionally) the EKS public API endpoint touch the internet. S3/ECR reach via VPC endpoints to cut NAT data-processing cost. diff --git a/deploy/terraform/environments/dev/main.tf b/deploy/terraform/environments/dev/main.tf index a0ad5c0..8ad739b 100644 --- a/deploy/terraform/environments/dev/main.tf +++ b/deploy/terraform/environments/dev/main.tf @@ -17,6 +17,8 @@ # │ │ # iam ◄── consumes EKS OIDC + S3 bucket ARN + secret ARNs ───────┘ │ # └── builds IRSA roles bound to per-service ServiceAccounts ◄───┘ +# +# budget ── monthly cost budget with email alerts (account-wide) # ---------------------------------------------------------------------------- locals { @@ -199,3 +201,44 @@ module "iam" { } } } + +# ---------------------------------------------------------------------------- +# (8) BUDGET — a cost guardrail with email alerts +# ---------------------------------------------------------------------------- +# This env runs an EKS control plane, a NAT gateway, interface endpoints, RDS +# and ElastiCache around the clock, so a forgotten `terraform apply` costs +# money every hour. Nothing else in this stack would ever tell you. +# +# Scope: the WHOLE ACCOUNT's monthly cost (no cost filter). Filtering on the +# Project tag would read $0 until that tag is activated as a cost allocation +# tag in the Billing console, which is exactly the silent failure a budget +# exists to prevent. If dev and prod share an account, give prod its own +# budget and raise this one, or switch to a tag filter after activating it. +resource "aws_budgets_budget" "monthly" { + name = "${local.name_prefix}-monthly" + budget_type = "COST" + limit_amount = tostring(var.budget_monthly_limit_usd) + limit_unit = "USD" + time_unit = "MONTHLY" + + dynamic "notification" { + for_each = [50, 80, 100] + content { + comparison_operator = "GREATER_THAN" + threshold = notification.value + threshold_type = "PERCENTAGE" + notification_type = "ACTUAL" + subscriber_email_addresses = var.budget_alert_emails + } + } + + # Forecast alert: fires early in the month when the run rate says you will + # blow the budget, before the money is actually spent. + notification { + comparison_operator = "GREATER_THAN" + threshold = 100 + threshold_type = "PERCENTAGE" + notification_type = "FORECASTED" + subscriber_email_addresses = var.budget_alert_emails + } +} diff --git a/deploy/terraform/environments/dev/terraform.tfvars.example b/deploy/terraform/environments/dev/terraform.tfvars.example index 638a77d..67ca52b 100644 --- a/deploy/terraform/environments/dev/terraform.tfvars.example +++ b/deploy/terraform/environments/dev/terraform.tfvars.example @@ -51,6 +51,10 @@ redis_engine_version = "7.1" redis_num_nodes = 1 # PROD: >= 2 redis_automatic_failover = false # PROD: true (needs redis_num_nodes >= 2) +# ---- Cost guardrail (budget_alert_emails is REQUIRED) ----------------------- +budget_monthly_limit_usd = 250 +budget_alert_emails = ["you@example.com"] + # ---- Throwaway-env teardown switches ---------------------------------------- # These make `terraform destroy` fast and complete for a disposable dev env. The # variable defaults are the SAFE values; delete these lines for anything that diff --git a/deploy/terraform/environments/dev/variables.tf b/deploy/terraform/environments/dev/variables.tf index d3528f7..8744c61 100644 --- a/deploy/terraform/environments/dev/variables.tf +++ b/deploy/terraform/environments/dev/variables.tf @@ -130,6 +130,23 @@ variable "rds_backup_retention_days" { default = 7 } +# ---- Cost guardrail --------------------------------------------------------- +variable "budget_monthly_limit_usd" { + description = "Monthly cost budget in USD. This env idles at roughly $200-250/month (EKS control plane, NAT gateway, two t3.medium nodes, interface endpoints, RDS, ElastiCache, KMS keys), so the default leaves a little headroom; alerts fire at 50/80/100% of actual spend and at 100% of forecast." + type = number + default = 250 +} + +variable "budget_alert_emails" { + description = "Email addresses that receive the budget alerts. REQUIRED, with no default: an environment that runs a NAT gateway and an EKS control plane must not be applyable without someone being told what it costs. AWS sends a confirmation email to each address once." + type = list(string) + + validation { + condition = length(var.budget_alert_emails) > 0 + error_message = "budget_alert_emails must list at least one address." + } +} + # ---- Destructive teardown switches (safe defaults; dev opts in via tfvars) -- variable "secret_recovery_window_days" { description = "Recovery window for the Secrets Manager secrets Terraform creates (RDS connection info, Redis credentials): 7-30 days, or 0 to delete immediately. SAFE DEFAULT 30. The dev tfvars sets 0 so destroy + re-apply does not collide with a secret pending deletion." From f545e46e0bd93e8e79fb8446b624008c9ca87786 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:44:35 +0500 Subject: [PATCH 15/42] terraform: add the ai-gateway ECR repo and move EKS off 1.30 - The ECR module's default service list had 11 entries and no ai-gateway, although services/ai-gateway has a Dockerfile and the Security workflow builds it. It is added, and the description now says the list must match services/*/Dockerfile. - cluster_version defaulted to 1.30 (the module, dev variables and the example tfvars). By the EKS release calendar, 1.30 ended standard support in July 2025 and extended support in July 2026, so EKS will no longer create it. Moved to 1.36, which is in standard support until 2 Aug 2027. I picked 1.36 over the newest (1.37, released 1 Oct 2026) to stay one minor behind the edge. Managed node groups on 1.30+ already default to AL2023 AMIs, so the launch template needs no change. `terraform validate` passes. Nothing has been applied, so no cluster is upgraded. Co-Authored-By: Claude Opus 5.5 --- deploy/terraform/environments/dev/terraform.tfvars.example | 2 +- deploy/terraform/environments/dev/variables.tf | 4 ++-- deploy/terraform/modules/ecr/variables.tf | 3 ++- deploy/terraform/modules/eks/variables.tf | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/deploy/terraform/environments/dev/terraform.tfvars.example b/deploy/terraform/environments/dev/terraform.tfvars.example index 67ca52b..ee86cc6 100644 --- a/deploy/terraform/environments/dev/terraform.tfvars.example +++ b/deploy/terraform/environments/dev/terraform.tfvars.example @@ -18,7 +18,7 @@ az_count = 3 single_nat_gateway = true # PROD: false (one NAT per AZ for egress resilience) # ---- EKS ------------------------------------------------------------------- -cluster_version = "1.30" +cluster_version = "1.36" # Kubernetes API endpoint. Same secure default as variables.tf: private only, # reached from inside the VPC (bastion / VPN / SSM port-forward). eks_public_access = false diff --git a/deploy/terraform/environments/dev/variables.tf b/deploy/terraform/environments/dev/variables.tf index 8744c61..693378d 100644 --- a/deploy/terraform/environments/dev/variables.tf +++ b/deploy/terraform/environments/dev/variables.tf @@ -46,9 +46,9 @@ variable "single_nat_gateway" { # ---- EKS ------------------------------------------------------------------- variable "cluster_version" { - description = "EKS Kubernetes version." + description = "EKS Kubernetes version. Keep it in EKS standard support (1.36 until 2 Aug 2027); 1.30 left extended support in July 2026 and can no longer be created." type = string - default = "1.30" + default = "1.36" } variable "eks_public_access" { diff --git a/deploy/terraform/modules/ecr/variables.tf b/deploy/terraform/modules/ecr/variables.tf index f1c6a7e..944abd5 100644 --- a/deploy/terraform/modules/ecr/variables.tf +++ b/deploy/terraform/modules/ecr/variables.tf @@ -12,7 +12,7 @@ variable "name_prefix" { } variable "service_names" { - description = "The services to create repositories for. Defaults to the full 10-service set from the design doc plus the BFF. Override to add/remove." + description = "The services to create repositories for. Defaults to every directory under services/ that has a Dockerfile (the same list the Security workflow builds). Keep the two in step when a service is added." type = list(string) default = [ "auth", @@ -26,6 +26,7 @@ variable "service_names" { "model-serving", "model-monitor", "bff", + "ai-gateway", ] } diff --git a/deploy/terraform/modules/eks/variables.tf b/deploy/terraform/modules/eks/variables.tf index 3724122..cf2b6d7 100644 --- a/deploy/terraform/modules/eks/variables.tf +++ b/deploy/terraform/modules/eks/variables.tf @@ -13,9 +13,9 @@ variable "name_prefix" { } variable "cluster_version" { - description = "Kubernetes minor version for the control plane (e.g. \"1.30\"). Pin it: EKS won't auto-upgrade the control plane, and node AMIs are chosen to match. Bump deliberately, one minor at a time." + description = "Kubernetes minor version for the control plane. Pin it and bump deliberately, one minor at a time. Stay inside EKS STANDARD support: past it, EKS bills extended support per cluster-hour, and at the end of extended support it upgrades the control plane for you. 1.36 is in standard support until 2 Aug 2027 (EKS calendar, checked Oct 2026). Managed node groups on 1.30+ default to AL2023 AMIs." type = string - default = "1.30" + default = "1.36" } variable "vpc_id" { From d54ebed4edb005568f80d3af7aab05629f78638b Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:46:19 +0500 Subject: [PATCH 16/42] terraform: add an opt-in GitHub OIDC role that can push to ECR The ECR repos had no pusher and Terraform defined no CI identity at all. CI publishes to GHCR with GITHUB_TOKEN, so the gap was latent. Whatever pushes to ECR one day should not be a long-lived access key in repo secrets. modules/github-oidc (new): - the account's token.actions.githubusercontent.com provider (or reuse an existing one via create_oidc_provider = false); - role -github-ecr-push. Its trust requires aud = sts.amazonaws.com and sub StringLike one of allowed_subjects. A validation rule rejects any pull_request subject and any bare ":*" wildcard; - ecr:GetAuthorizationToken (account-level by design) plus push/pull actions on the listed repository ARNs only. environments/dev wires it behind enable_github_ecr_push (default false), allowing refs/heads/main and refs/tags/v* only, and outputs github_ecr_push_role_arn for the AWS_ROLE_ARN repository variable. The comment notes that this repo predates GitHub's 15 Jul 2026 immutable sub format, which applies if it is ever renamed or transferred. Decision: opt-in. Alternative: on by default. Why: no workflow pushes to ECR yet, and an unused push role is attack surface with no benefit. `terraform validate` passes. A scratch root confirmed the validation rejects "repo:...:pull_request" and "repo:...:*". Co-Authored-By: Claude Opus 5.5 --- deploy/terraform/README.md | 1 + deploy/terraform/environments/dev/main.tf | 21 ++++ deploy/terraform/environments/dev/outputs.tf | 5 + .../terraform/environments/dev/variables.tf | 28 +++++ deploy/terraform/modules/github-oidc/main.tf | 102 ++++++++++++++++++ .../terraform/modules/github-oidc/outputs.tf | 9 ++ .../modules/github-oidc/variables.tf | 37 +++++++ 7 files changed, 203 insertions(+) create mode 100644 deploy/terraform/modules/github-oidc/main.tf create mode 100644 deploy/terraform/modules/github-oidc/outputs.tf create mode 100644 deploy/terraform/modules/github-oidc/variables.tf diff --git a/deploy/terraform/README.md b/deploy/terraform/README.md index 4b95cd3..99884a1 100644 --- a/deploy/terraform/README.md +++ b/deploy/terraform/README.md @@ -28,6 +28,7 @@ deploy/terraform/ │ ├── s3/ ← model-artifacts bucket: versioned, SSE-KMS, public-access blocked │ ├── ecr/ ← one repo per service, scan-on-push, immutable tags, lifecycle │ ├── iam/ ← IRSA roles per workload, least-privilege, bound to K8s SAs via OIDC +│ ├── github-oidc/ ← opt-in keyless GitHub Actions role that can push to ECR (main + v* tags only) │ └── state-backend/ ← S3 bucket (versioned, SSE-KMS CMK, TLS-only, prevent_destroy) FOR remote state ├── bootstrap/ ← the one root with LOCAL state: applies state-backend once per account └── environments/ diff --git a/deploy/terraform/environments/dev/main.tf b/deploy/terraform/environments/dev/main.tf index 8ad739b..1917f0b 100644 --- a/deploy/terraform/environments/dev/main.tf +++ b/deploy/terraform/environments/dev/main.tf @@ -242,3 +242,24 @@ resource "aws_budgets_budget" "monthly" { subscriber_email_addresses = var.budget_alert_emails } } + +# ---------------------------------------------------------------------------- +# (9) CI IDENTITY — GitHub Actions → ECR push via OIDC (OPT-IN, off by default) +# ---------------------------------------------------------------------------- +# The ECR repos above had no pusher: CI publishes to GHCR with GITHUB_TOKEN and +# there was no AWS identity for it at all. This role is the keyless way to add +# one: only workflow runs on main or a v* tag can assume it (never a PR run), +# and it can push only to this env's ECR repos. Off by default because no +# workflow pushes to ECR yet and an unused push role is surface for nothing. +# Turn it on with enable_github_ecr_push = true, then store the role_arn output +# as the repository variable AWS_ROLE_ARN. +module "github_oidc" { + source = "../../modules/github-oidc" + count = var.enable_github_ecr_push ? 1 : 0 + + name_prefix = local.name_prefix + create_oidc_provider = var.create_github_oidc_provider + oidc_provider_arn = var.github_oidc_provider_arn + allowed_subjects = var.github_oidc_subjects + ecr_repository_arns = values(module.ecr.repository_arns) +} diff --git a/deploy/terraform/environments/dev/outputs.tf b/deploy/terraform/environments/dev/outputs.tf index eef2227..a1f03b8 100644 --- a/deploy/terraform/environments/dev/outputs.tf +++ b/deploy/terraform/environments/dev/outputs.tf @@ -71,6 +71,11 @@ output "ecr_repository_urls" { value = module.ecr.repository_urls } +output "github_ecr_push_role_arn" { + description = "ARN of the GitHub Actions ECR push role (null unless enable_github_ecr_push = true). Store it as the repository variable AWS_ROLE_ARN." + value = var.enable_github_ecr_push ? module.github_oidc[0].role_arn : null +} + # ---- IRSA ------------------------------------------------------------------ output "irsa_role_arns" { description = "Map of logical workload → IAM role ARN. Annotate each K8s ServiceAccount with eks.amazonaws.com/role-arn = to grant the pod its scoped AWS access without static keys." diff --git a/deploy/terraform/environments/dev/variables.tf b/deploy/terraform/environments/dev/variables.tf index 693378d..8c8bfc4 100644 --- a/deploy/terraform/environments/dev/variables.tf +++ b/deploy/terraform/environments/dev/variables.tf @@ -130,6 +130,34 @@ variable "rds_backup_retention_days" { default = 7 } +# ---- CI identity (GitHub Actions OIDC -> ECR push), opt-in -------------------- +variable "enable_github_ecr_push" { + description = "Create the GitHub OIDC provider + ECR push role (modules/github-oidc). Default false: no workflow pushes to ECR yet." + type = bool + default = false +} + +variable "create_github_oidc_provider" { + description = "Create the account-wide token.actions.githubusercontent.com provider. Set false (and pass github_oidc_provider_arn) if the account already has one." + type = bool + default = true +} + +variable "github_oidc_provider_arn" { + description = "Existing GitHub OIDC provider ARN, used when create_github_oidc_provider = false." + type = string + default = "" +} + +variable "github_oidc_subjects" { + description = "OIDC sub patterns allowed to assume the ECR push role: the default branch and release tags of this repo only. This repo predates GitHub's 15 Jul 2026 switch to immutable sub claims for new/renamed/transferred repos; if it is ever renamed or transferred, the sub becomes repo:OWNER@OWNER_ID/REPO@REPO_ID:... and these must change." + type = list(string) + default = [ + "repo:abd-ulbasit/forgepoint:ref:refs/heads/main", + "repo:abd-ulbasit/forgepoint:ref:refs/tags/v*", + ] +} + # ---- Cost guardrail --------------------------------------------------------- variable "budget_monthly_limit_usd" { description = "Monthly cost budget in USD. This env idles at roughly $200-250/month (EKS control plane, NAT gateway, two t3.medium nodes, interface endpoints, RDS, ElastiCache, KMS keys), so the default leaves a little headroom; alerts fire at 50/80/100% of actual spend and at 100% of forecast." diff --git a/deploy/terraform/modules/github-oidc/main.tf b/deploy/terraform/modules/github-oidc/main.tf new file mode 100644 index 0000000..e975967 --- /dev/null +++ b/deploy/terraform/modules/github-oidc/main.tf @@ -0,0 +1,102 @@ +# ============================================================================ +# github-oidc — a short-lived, keyless identity for GitHub Actions to push to ECR +# ============================================================================ +# HOW IT WORKS: a workflow job with `permissions: id-token: write` asks GitHub +# for an OIDC token (issuer https://token.actions.githubusercontent.com) and +# exchanges it with sts:AssumeRoleWithWebIdentity for this role (e.g. via +# aws-actions/configure-aws-credentials with role-to-assume: vars.AWS_ROLE_ARN). +# STS checks the token against the trust policy below, so no AWS access key is +# ever stored in GitHub. +# +# THE LOCK is the `sub` claim. With GitHub's default claim template it looks +# like: +# repo:abd-ulbasit/forgepoint:ref:refs/heads/main (push to main) +# repo:abd-ulbasit/forgepoint:ref:refs/tags/v1.2.3 (tag push) +# repo:abd-ulbasit/forgepoint:pull_request (any PR run) +# Allowing only main and v* tags means a pull_request run, including from a +# fork, can never assume the role. Repositories created, renamed or transferred +# after 15 Jul 2026 get the immutable form instead +# (repo:OWNER@OWNER_ID/REPO@REPO_ID:...), so check a real token's sub before +# relying on the default list. +# ---------------------------------------------------------------------------- + +# One GitHub OIDC provider per AWS account. If the account already has one +# (another repo set it up), pass its ARN and set create_oidc_provider = false. +resource "aws_iam_openid_connect_provider" "github" { + count = var.create_oidc_provider ? 1 : 0 + url = "https://token.actions.githubusercontent.com" + client_id_list = ["sts.amazonaws.com"] + # No thumbprint_list: IAM validates GitHub's issuer against its own trusted + # CA store, and the provider no longer requires a pinned thumbprint. + tags = var.tags +} + +locals { + oidc_provider_arn = var.create_oidc_provider ? aws_iam_openid_connect_provider.github[0].arn : var.oidc_provider_arn +} + +data "aws_iam_policy_document" "trust" { + statement { + effect = "Allow" + actions = ["sts:AssumeRoleWithWebIdentity"] + + principals { + type = "Federated" + identifiers = [local.oidc_provider_arn] + } + + # Audience must be STS (what configure-aws-credentials requests). + condition { + test = "StringEquals" + variable = "token.actions.githubusercontent.com:aud" + values = ["sts.amazonaws.com"] + } + + # Subject must be one of the allowed refs. StringLike so a tag pattern + # (refs/tags/v*) works; there is deliberately no bare "repo:...:*". + condition { + test = "StringLike" + variable = "token.actions.githubusercontent.com:sub" + values = var.allowed_subjects + } + } +} + +resource "aws_iam_role" "ecr_push" { + name = "${var.name_prefix}-github-ecr-push" + assume_role_policy = data.aws_iam_policy_document.trust.json + max_session_duration = 3600 + tags = var.tags +} + +data "aws_iam_policy_document" "ecr_push" { + # GetAuthorizationToken is account-level; it cannot be scoped to a repo. + statement { + sid = "ECRLogin" + effect = "Allow" + actions = ["ecr:GetAuthorizationToken"] + resources = ["*"] + } + + # Push (and the reads a push needs) on the listed repositories only. + statement { + sid = "ECRPush" + effect = "Allow" + actions = [ + "ecr:BatchCheckLayerAvailability", + "ecr:BatchGetImage", + "ecr:GetDownloadUrlForLayer", + "ecr:InitiateLayerUpload", + "ecr:UploadLayerPart", + "ecr:CompleteLayerUpload", + "ecr:PutImage", + ] + resources = var.ecr_repository_arns + } +} + +resource "aws_iam_role_policy" "ecr_push" { + name = "ecr-push" + role = aws_iam_role.ecr_push.id + policy = data.aws_iam_policy_document.ecr_push.json +} diff --git a/deploy/terraform/modules/github-oidc/outputs.tf b/deploy/terraform/modules/github-oidc/outputs.tf new file mode 100644 index 0000000..58928f8 --- /dev/null +++ b/deploy/terraform/modules/github-oidc/outputs.tf @@ -0,0 +1,9 @@ +output "role_arn" { + description = "ARN of the push role. Store it as the repository VARIABLE (not secret) AWS_ROLE_ARN and use it as role-to-assume in aws-actions/configure-aws-credentials." + value = aws_iam_role.ecr_push.arn +} + +output "oidc_provider_arn" { + description = "ARN of the GitHub OIDC provider the role trusts." + value = local.oidc_provider_arn +} diff --git a/deploy/terraform/modules/github-oidc/variables.tf b/deploy/terraform/modules/github-oidc/variables.tf new file mode 100644 index 0000000..87b948f --- /dev/null +++ b/deploy/terraform/modules/github-oidc/variables.tf @@ -0,0 +1,37 @@ +variable "name_prefix" { + description = "Name prefix, e.g. \"forgepoint-dev\". The role is \"-github-ecr-push\"." + type = string +} + +variable "create_oidc_provider" { + description = "Create the account's GitHub OIDC provider. An account can have only one provider per URL, so set false and pass oidc_provider_arn if it already exists." + type = bool + default = true +} + +variable "oidc_provider_arn" { + description = "ARN of an existing token.actions.githubusercontent.com provider, used when create_oidc_provider = false." + type = string + default = "" +} + +variable "allowed_subjects" { + description = "OIDC `sub` patterns allowed to assume the role (StringLike). Keep these to refs that only maintainers can push: the default branch and release tags. Never a pull_request subject or a bare repo:OWNER/REPO:*." + type = list(string) + + validation { + condition = length(var.allowed_subjects) > 0 && alltrue([for s in var.allowed_subjects : !endswith(s, ":*") && !strcontains(s, "pull_request")]) + error_message = "allowed_subjects must be non-empty and must not allow pull_request runs or a bare ':*' wildcard." + } +} + +variable "ecr_repository_arns" { + description = "ECR repository ARNs the role may push to (from the ecr module's repository_arns)." + type = list(string) +} + +variable "tags" { + description = "Additional tags." + type = map(string) + default = {} +} From 0f189d72a32c63e447124402c1e0e1276eb6c3fb Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:49:16 +0500 Subject: [PATCH 17/42] build: declare the VERSION build arg and stamp it into the binaries security.yml passes --build-arg VERSION=${{ github.ref_name }}, but no Dockerfile declared ARG VERSION. BuildKit ignored the value, and every service also hard-coded ServiceVersion: "dev", so no image could say which version it was in its traces or metrics. - All 12 Dockerfiles declare ARG VERSION=dev (after the dependency layers, so only the compile step reruns) and link it with -X main.version=${VERSION}. - Each services/*/cmd/server/main.go has `var version = "dev"` and passes it as observability.Config.ServiceVersion (OTel service.version). Local `go run` still reports "dev". Checked: a local build with -X main.version=v9.9.9-test embeds the string, and all 12 services build and vet. No image was built here (remote engine). Co-Authored-By: Claude Opus 5.5 --- services/ai-gateway/Dockerfile | 8 +++++++- services/ai-gateway/cmd/server/main.go | 7 ++++++- services/auth/Dockerfile | 8 +++++++- services/auth/cmd/server/main.go | 7 ++++++- services/bff/Dockerfile | 8 +++++++- services/bff/cmd/server/main.go | 7 ++++++- services/billing/Dockerfile | 8 +++++++- services/billing/cmd/server/main.go | 7 ++++++- services/experiment-tracker/Dockerfile | 8 +++++++- services/experiment-tracker/cmd/server/main.go | 7 ++++++- services/feature-store/Dockerfile | 8 +++++++- services/feature-store/cmd/server/main.go | 7 ++++++- services/inference-gateway/Dockerfile | 8 +++++++- services/inference-gateway/cmd/server/main.go | 7 ++++++- services/model-monitor/Dockerfile | 8 +++++++- services/model-monitor/cmd/server/main.go | 7 ++++++- services/model-serving/Dockerfile | 8 +++++++- services/model-serving/cmd/server/main.go | 7 ++++++- services/notification/Dockerfile | 8 +++++++- services/notification/cmd/server/main.go | 7 ++++++- services/pipeline-orchestrator/Dockerfile | 8 +++++++- services/pipeline-orchestrator/cmd/server/main.go | 7 ++++++- services/registry/Dockerfile | 8 +++++++- services/registry/cmd/server/main.go | 7 ++++++- 24 files changed, 156 insertions(+), 24 deletions(-) diff --git a/services/ai-gateway/Dockerfile b/services/ai-gateway/Dockerfile index 8120ca1..b2320f7 100644 --- a/services/ai-gateway/Dockerfile +++ b/services/ai-gateway/Dockerfile @@ -158,10 +158,16 @@ COPY services/ai-gateway/ ./services/ai-gateway/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/ai-gateway/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/ai-gateway/cmd/server diff --git a/services/ai-gateway/cmd/server/main.go b/services/ai-gateway/cmd/server/main.go index c78f7c8..d7bfcb2 100644 --- a/services/ai-gateway/cmd/server/main.go +++ b/services/ai-gateway/cmd/server/main.go @@ -74,6 +74,11 @@ import ( "github.com/abd-ulbasit/forgepoint/services/ai-gateway/internal/usage" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // serviceName is the canonical identity for telemetry, the NATS event source, and // consumer-group naming. It MUST match events.Source. const serviceName = "ai-gateway" @@ -204,7 +209,7 @@ func main() { otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: serviceName, - ServiceVersion: "dev", + ServiceVersion: version, Environment: cfg.Environment, OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: true, diff --git a/services/auth/Dockerfile b/services/auth/Dockerfile index cd96574..d20646d 100644 --- a/services/auth/Dockerfile +++ b/services/auth/Dockerfile @@ -158,10 +158,16 @@ COPY services/auth/ ./services/auth/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/auth/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/auth/cmd/server diff --git a/services/auth/cmd/server/main.go b/services/auth/cmd/server/main.go index 43bd757..a2c299c 100644 --- a/services/auth/cmd/server/main.go +++ b/services/auth/cmd/server/main.go @@ -101,6 +101,11 @@ import ( "github.com/abd-ulbasit/forgepoint/services/auth/internal/repository/postgres" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // AuthConfig extends BaseConfig with auth-specific configuration. // // WHY embed BaseConfig: @@ -199,7 +204,7 @@ func main() { // config and TLS is on. otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: "auth", - ServiceVersion: "dev", + ServiceVersion: version, Environment: "local", OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: true, diff --git a/services/bff/Dockerfile b/services/bff/Dockerfile index 340c509..8cb1080 100644 --- a/services/bff/Dockerfile +++ b/services/bff/Dockerfile @@ -79,10 +79,16 @@ COPY services/bff/ ./services/bff/ # -buildvcs=false → don't stamp VCS (the .git dir isn't in the context). # -trimpath → strip absolute /workspace paths → reproducible. ### PER-SERVICE: the `./services/bff/cmd/server` build path is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/bff/cmd/server diff --git a/services/bff/cmd/server/main.go b/services/bff/cmd/server/main.go index 75e67fd..2f64708 100644 --- a/services/bff/cmd/server/main.go +++ b/services/bff/cmd/server/main.go @@ -51,6 +51,11 @@ import ( "github.com/abd-ulbasit/forgepoint/services/bff/internal/router" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // BFFConfig is the BFF's env-driven configuration. It embeds BaseConfig (Port, // GRPCPort, LogLevel, OTelEndpoint, ...) and adds the per-service addresses and // CORS origins. Defaults target the in-cluster DNS so a vanilla deploy works; @@ -125,7 +130,7 @@ func main() { otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: "bff", - ServiceVersion: "dev", + ServiceVersion: version, Environment: "local", OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: true, diff --git a/services/billing/Dockerfile b/services/billing/Dockerfile index ebc0aa3..7b47276 100644 --- a/services/billing/Dockerfile +++ b/services/billing/Dockerfile @@ -158,10 +158,16 @@ COPY services/billing/ ./services/billing/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/billing/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/billing/cmd/server diff --git a/services/billing/cmd/server/main.go b/services/billing/cmd/server/main.go index 9dc25ec..e38b688 100644 --- a/services/billing/cmd/server/main.go +++ b/services/billing/cmd/server/main.go @@ -91,6 +91,11 @@ import ( "github.com/abd-ulbasit/forgepoint/services/billing/internal/repository/postgres" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // depConnectTimeout bounds how long we wait, AT BOOT, for each datastore's // fail-fast ping / stream-ensure. WHY a bound: a constructor that blocks forever // on an unreachable dependency would hang the pod in a not-ready state with no @@ -229,7 +234,7 @@ func main() { otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: "billing", - ServiceVersion: "dev", + ServiceVersion: version, Environment: "local", OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: cfg.OTelInsecure, // ← from config, not hard-coded diff --git a/services/experiment-tracker/Dockerfile b/services/experiment-tracker/Dockerfile index f871505..7e40dc7 100644 --- a/services/experiment-tracker/Dockerfile +++ b/services/experiment-tracker/Dockerfile @@ -158,10 +158,16 @@ COPY services/experiment-tracker/ ./services/experiment-tracker/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/experiment-tracker/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/experiment-tracker/cmd/server diff --git a/services/experiment-tracker/cmd/server/main.go b/services/experiment-tracker/cmd/server/main.go index ce8b432..6a27023 100644 --- a/services/experiment-tracker/cmd/server/main.go +++ b/services/experiment-tracker/cmd/server/main.go @@ -84,6 +84,11 @@ import ( "github.com/abd-ulbasit/forgepoint/services/experiment-tracker/internal/repository/postgres" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // serviceName is the canonical identity used for telemetry resource attributes, // the NATS event source, and the consumer-group/DLQ naming. It MUST match // events.ServiceName (the value stamped into every published EventEnvelope.source) @@ -190,7 +195,7 @@ func main() { otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: serviceName, - ServiceVersion: "dev", + ServiceVersion: version, Environment: cfg.Environment, OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: cfg.OTLPInsecure, // driven by config, not hardcoded (see field comment) diff --git a/services/feature-store/Dockerfile b/services/feature-store/Dockerfile index f8d8bd1..5a470d4 100644 --- a/services/feature-store/Dockerfile +++ b/services/feature-store/Dockerfile @@ -158,10 +158,16 @@ COPY services/feature-store/ ./services/feature-store/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/feature-store/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/feature-store/cmd/server diff --git a/services/feature-store/cmd/server/main.go b/services/feature-store/cmd/server/main.go index 6b88660..3385e62 100644 --- a/services/feature-store/cmd/server/main.go +++ b/services/feature-store/cmd/server/main.go @@ -97,6 +97,11 @@ import ( redisrepo "github.com/abd-ulbasit/forgepoint/services/feature-store/internal/repository/redis" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // FeatureStoreConfig extends BaseConfig with feature-store-specific configuration. // // WHY embed BaseConfig: every Forgepoint service needs Port, GRPCPort, LogLevel, @@ -188,7 +193,7 @@ func main() { otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: "feature-store", - ServiceVersion: "dev", + ServiceVersion: version, Environment: "local", OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: cfg.OTelInsecure, // ← from config, not hard-coded diff --git a/services/inference-gateway/Dockerfile b/services/inference-gateway/Dockerfile index 656ecad..53a5499 100644 --- a/services/inference-gateway/Dockerfile +++ b/services/inference-gateway/Dockerfile @@ -158,10 +158,16 @@ COPY services/inference-gateway/ ./services/inference-gateway/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/inference-gateway/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/inference-gateway/cmd/server diff --git a/services/inference-gateway/cmd/server/main.go b/services/inference-gateway/cmd/server/main.go index 3027202..5bf933c 100644 --- a/services/inference-gateway/cmd/server/main.go +++ b/services/inference-gateway/cmd/server/main.go @@ -78,6 +78,11 @@ import ( redisrepo "github.com/abd-ulbasit/forgepoint/services/inference-gateway/internal/repository/redis" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // serviceName is the canonical identity used for telemetry resource attributes, // the NATS event source, and the consumer-group/DLQ naming. It MUST match // events.Source (the value stamped into every published EventEnvelope.source) so @@ -171,7 +176,7 @@ func main() { otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: serviceName, - ServiceVersion: "dev", + ServiceVersion: version, Environment: cfg.Environment, OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: true, // plaintext to the local collector (no TLS cert in docker-compose) diff --git a/services/model-monitor/Dockerfile b/services/model-monitor/Dockerfile index 34c676d..f977c26 100644 --- a/services/model-monitor/Dockerfile +++ b/services/model-monitor/Dockerfile @@ -158,10 +158,16 @@ COPY services/model-monitor/ ./services/model-monitor/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/model-monitor/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/model-monitor/cmd/server diff --git a/services/model-monitor/cmd/server/main.go b/services/model-monitor/cmd/server/main.go index 9d4f2b8..dfe6d90 100644 --- a/services/model-monitor/cmd/server/main.go +++ b/services/model-monitor/cmd/server/main.go @@ -130,6 +130,11 @@ import ( redisrepo "github.com/abd-ulbasit/forgepoint/services/model-monitor/internal/repository/redis" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + func main() { // ================================================================ // 1. STRUCTURED LOGGER @@ -170,7 +175,7 @@ func main() { otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: "model-monitor", - ServiceVersion: "dev", + ServiceVersion: version, Environment: "local", OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: true, // plaintext to the local collector (no TLS cert there) diff --git a/services/model-serving/Dockerfile b/services/model-serving/Dockerfile index 1205dc4..1e69ba9 100644 --- a/services/model-serving/Dockerfile +++ b/services/model-serving/Dockerfile @@ -158,10 +158,16 @@ COPY services/model-serving/ ./services/model-serving/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/model-serving/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/model-serving/cmd/server diff --git a/services/model-serving/cmd/server/main.go b/services/model-serving/cmd/server/main.go index 43aebb7..9d84307 100644 --- a/services/model-serving/cmd/server/main.go +++ b/services/model-serving/cmd/server/main.go @@ -84,6 +84,11 @@ import ( "github.com/abd-ulbasit/forgepoint/services/model-serving/internal/repository/artifactstore" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // ServingConfig extends BaseConfig with model-serving-specific configuration. // // WHY embed BaseConfig: every Forgepoint service needs Port, GRPCPort, LogLevel, @@ -206,7 +211,7 @@ func main() { // ================================================================ otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: "model-serving", - ServiceVersion: "dev", + ServiceVersion: version, Environment: "local", OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: true, // plaintext to the local docker-compose collector (no TLS cert) diff --git a/services/notification/Dockerfile b/services/notification/Dockerfile index d0a4200..d27b8bc 100644 --- a/services/notification/Dockerfile +++ b/services/notification/Dockerfile @@ -158,10 +158,16 @@ COPY services/notification/ ./services/notification/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/notification/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/notification/cmd/server diff --git a/services/notification/cmd/server/main.go b/services/notification/cmd/server/main.go index c474725..4beed9a 100644 --- a/services/notification/cmd/server/main.go +++ b/services/notification/cmd/server/main.go @@ -113,6 +113,11 @@ import ( redisrepo "github.com/abd-ulbasit/forgepoint/services/notification/internal/repository/redis" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // NotificationConfig extends BaseConfig with notification-specific configuration. // // WHY embed BaseConfig: every Forgepoint service needs Port, GRPCPort, LogLevel, @@ -204,7 +209,7 @@ func main() { // producer's trace context per message). otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: "notification", - ServiceVersion: "dev", + ServiceVersion: version, Environment: cfg.Environment, OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: cfg.OTLPInsecure, diff --git a/services/pipeline-orchestrator/Dockerfile b/services/pipeline-orchestrator/Dockerfile index 5f6f6ee..5f5ef69 100644 --- a/services/pipeline-orchestrator/Dockerfile +++ b/services/pipeline-orchestrator/Dockerfile @@ -158,10 +158,16 @@ COPY services/pipeline-orchestrator/ ./services/pipeline-orchestrator/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/pipeline-orchestrator/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/pipeline-orchestrator/cmd/server diff --git a/services/pipeline-orchestrator/cmd/server/main.go b/services/pipeline-orchestrator/cmd/server/main.go index f2ec628..95c1341 100644 --- a/services/pipeline-orchestrator/cmd/server/main.go +++ b/services/pipeline-orchestrator/cmd/server/main.go @@ -97,6 +97,11 @@ import ( "github.com/abd-ulbasit/forgepoint/services/pipeline-orchestrator/internal/repository/postgres" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // depConnectTimeout bounds how long we wait, AT BOOT, for each datastore's // fail-fast ping / stream provisioning. WHY a bound: a constructor that blocks // forever on an unreachable dependency would hang the pod in a not-ready state @@ -262,7 +267,7 @@ func main() { otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: "pipeline-orchestrator", - ServiceVersion: "dev", + ServiceVersion: version, Environment: "local", OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: cfg.OTelInsecure, // from config, not hard-coded diff --git a/services/registry/Dockerfile b/services/registry/Dockerfile index 56e9013..dc67e4c 100644 --- a/services/registry/Dockerfile +++ b/services/registry/Dockerfile @@ -158,10 +158,16 @@ COPY services/registry/ ./services/registry/ # cache across rebuilds, turning a cold ~minute build into a warm few seconds. # `-o /out/service` uses a generic name so the final stage is service-agnostic. ### PER-SERVICE: the `./services/registry/cmd/server` path below is the only build arg to change. +# VERSION: CI passes the git ref name (tag or branch) as --build-arg VERSION. +# It is stamped into main.version, which the service reports as +# service.version on its traces and metrics. Before this ARG existed the +# build-arg was silently ignored and every image reported "dev". Declared +# after the dependency layers so a new version only re-runs the compile step. +ARG VERSION=dev ENV CGO_ENABLED=0 GOFLAGS=-mod=readonly RUN --mount=type=cache,target=/go/pkg/mod \ --mount=type=cache,target=/root/.cache/go-build \ - go build -ldflags="-s -w" -buildvcs=false -trimpath \ + go build -ldflags="-s -w -X main.version=${VERSION}" -buildvcs=false -trimpath \ -o /out/service ./services/registry/cmd/server diff --git a/services/registry/cmd/server/main.go b/services/registry/cmd/server/main.go index b0281e3..ef5e331 100644 --- a/services/registry/cmd/server/main.go +++ b/services/registry/cmd/server/main.go @@ -87,6 +87,11 @@ import ( redisstore "github.com/abd-ulbasit/forgepoint/services/registry/internal/repository/redis" ) +// version is set at build time with -ldflags "-X main.version=" (see the +// Dockerfile's VERSION build arg) and reported as the OTel service.version. +// Local `go run` builds report "dev". +var version = "dev" + // depConnectTimeout bounds how long we wait, AT BOOT, for each datastore's // fail-fast ping. WHY a bound: a constructor that blocks forever on an // unreachable dependency would hang the pod in a not-ready state with no signal; @@ -191,7 +196,7 @@ func main() { otelShutdown, err := observability.Setup(ctx, observability.Config{ ServiceName: "registry", - ServiceVersion: "dev", + ServiceVersion: version, Environment: "local", OTLPEndpoint: cfg.OTelEndpoint, OTLPInsecure: cfg.OTelInsecure, // ← from config, not hard-coded (see RegistryConfig) From d04a049248139506eed11037dc460d6b5d7e9130 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:50:18 +0500 Subject: [PATCH 18/42] ci(security): triage the red Trivy gate and widen what it actually scans The Trivy filesystem gate had been red on main since 2026-07-27 on HIGH IaC findings, with no decision recorded. The earlier commits in this branch fix eight of them (postgres, grafana and ollama KSV-0014/KSV-0118, AWS-0164 x3, AWS-0132). This commit records the rest and closes two blind spots. - .trivyignore.yaml (new, read via `trivyignores:`). Two path-scoped entries, each with a statement and an expiry: * KSV-0014 on the backup CronJob until 2027-01-31. The job installs tools at runtime and is broken in other ways too; it needs a rewrite. * KSV-0109 on the fp-ai-gateway ConfigMap until 2027-04-30. False positive: FP_TEAM_TOKEN_BUDGET is an integer, not a secret. - TRIVY_HELM_KUBE_VERSION=1.36.0. Trivy renders charts as Kubernetes v1.20.0 by default, below every chart's kubeVersion, so it skipped all 12 charts ("Failed to render Chart files") while the job reported success. - tf-vars: terraform.tfvars.example. Trivy does not read *.example files. With this set, the old example's 0.0.0.0/0 EKS endpoint would have raised AWS-0040/AWS-0041 (checked locally against the pre-fix file). - SECURITY.md: the "Open findings" section is now a triage table with a decision per finding, an "Accepted findings" policy, and the backup job's defects. Checked locally with Trivy v0.70.0 (the version trivy-action v0.36.0 installs): no HIGH/CRITICAL misconfigurations or secrets remain. The gate is still red on HIGH dependency CVEs in the Go modules and web/. Those are dependency bumps, which the open Dependabot PRs carry, so this branch does not duplicate them. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/security.yml | 22 ++++++++-- .trivyignore.yaml | 45 +++++++++++++++++++++ SECURITY.md | 73 +++++++++++++++++++++++----------- 3 files changed, 114 insertions(+), 26 deletions(-) create mode 100644 .trivyignore.yaml diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index e014d4f..382f626 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -168,9 +168,25 @@ jobs: # cannot break this gate the same way again. - name: Trivy filesystem scan uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 + env: + # Render the Helm charts against a Kubernetes version they accept. + # Trivy renders charts as Kubernetes v1.20.0 by default, below every + # chart's kubeVersion (>=1.23.0-0), so it logged "Failed to render + # Chart files" for all 12 charts and scanned NONE of them, and the job + # still passed on that part. Keep this in step with the EKS + # cluster_version in deploy/terraform. + TRIVY_HELM_KUBE_VERSION: "1.36.0" with: scan-type: fs scan-ref: . + # Evaluate the Terraform with the values people actually copy. Trivy + # does not read *.tfvars.example on its own, which is how an example + # opening the EKS API to 0.0.0.0/0 sat in the repo with the gate + # green (AWS-0040/AWS-0041 fire on it when this is set). + tf-vars: deploy/terraform/environments/dev/terraform.tfvars.example + # Accepted findings: every entry has a reason and an expiry date + # (see .trivyignore.yaml and SECURITY.md "Accepted findings"). + trivyignores: .trivyignore.yaml # Gate the build on actionable severities only; INFO/LOW noise would # train people to ignore the gate. severity: HIGH,CRITICAL @@ -179,9 +195,9 @@ jobs: # NOTE: ignore-unfixed has been intentionally removed. Keeping it would # silently pass HIGH/CRITICAL CVEs that have no upstream fix yet — # exactly the ones you most need visibility on. An unfixed CVE is a - # real risk; we want the gate to be honest. If a specific CVE must be - # accepted (e.g. no fix exists and a compensating control is in place), - # add it to a `.trivyignore` file with a documented expiry date. + # real risk; we want the gate to be honest. If a specific finding must + # be accepted, add it to .trivyignore.yaml with a statement and an + # expired_at date; after that date the gate goes red again. # Cover dependency CVEs, leaked secrets, and IaC misconfig in one pass. scanners: vuln,secret,misconfig diff --git a/.trivyignore.yaml b/.trivyignore.yaml new file mode 100644 index 0000000..e3af4f8 --- /dev/null +++ b/.trivyignore.yaml @@ -0,0 +1,45 @@ +# ============================================================================= +# Trivy accepted findings — every entry needs a reason AND an expiry. +# ============================================================================= +# Read by the Security workflow (trivyignores: .trivyignore.yaml) for both the +# filesystem and the image scans. Policy (SECURITY.md, "Accepted findings"): +# - an entry is a DECISION, not a mute button: `statement` says why the +# finding is a false positive or why the risk is accepted, and what would +# remove the entry; +# - `expired_at` is mandatory; after it, Trivy stops honouring the entry and +# the gate goes red again, forcing a re-decision; +# - scope every entry with `paths` (or a package/CVE) as tightly as possible, +# never a bare rule ID for the whole repo. +# ============================================================================= + +misconfigurations: + # FALSE POSITIVE. KSV-0109 ("ConfigMap with secrets") matches the key name + # FP_TEAM_TOKEN_BUDGET because it contains "TOKEN". The value is an integer + # token-count budget for LLM usage ("1000000"), not a credential. Renaming the + # env var would change the service's configuration contract to silence a + # heuristic. Re-check on expiry (or if the ConfigMap gains new keys). + - id: KSV-0109 + paths: + - "deploy/helm/fp-ai-gateway/templates/configmap.yaml" + statement: >- + False positive: FP_TEAM_TOKEN_BUDGET is an integer LLM token budget, not a + secret. The ConfigMap holds no credentials (those are in the chart Secret). + expired_at: 2027-04-30 + + # ACCEPTED RISK, TIME-BOXED. The backup CronJob cannot run with a read-only + # root FS as written, because its script installs tools at runtime + # (`apk add`, `curl ... -o /usr/local/bin/mc`). That script is ALSO broken + # independently of this finding: it runs as uid 999, which cannot apk add or + # write /usr/local/bin, its database names do not match + # scripts/init-postgres.sh, and the minio/mc image it would need is gone from + # Docker Hub. The fix is a rewrite (tools baked into a pinned image, no + # runtime downloads, then readOnlyRootFilesystem: true), tracked in + # SECURITY.md. Compensating controls: non-root, drop ALL, no privilege + # escalation, seccomp RuntimeDefault, no SA token. + - id: KSV-0014 + paths: + - "deploy/backup/postgres-backup-cronjob.yaml" + statement: >- + Backup job installs tools at runtime, so it cannot be read-only until it + is rewritten (see SECURITY.md). Non-root, drop ALL, no privesc, seccomp. + expired_at: 2027-01-31 diff --git a/SECURITY.md b/SECURITY.md index 377a09c..7a4e423 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -31,10 +31,14 @@ build actually reaches the vulnerable symbol. That is the reason this gate is worth failing on — it is not "a line in `go.sum` matches an OSV record". Trivy runs **without** `ignore-unfixed`. An advisory with no upstream fix is -still a real risk and deserves a decision, not a silent pass. There is currently -no `.trivyignore` in this repo and no accepted-advisory allowlist; if one becomes -necessary, each entry must carry a written justification and an expiry date, and -this file is where it gets documented. +still a real risk and deserves a decision, not a silent pass. Accepted findings +live in [`.trivyignore.yaml`](.trivyignore.yaml), never in a bare `.trivyignore` +(see "Accepted findings" below). + +The filesystem scan also renders the Helm charts (`TRIVY_HELM_KUBE_VERSION`; +before that was set, Trivy failed to render all 12 charts and silently skipped +them) and evaluates the Terraform with `terraform.tfvars.example` (`tf-vars`), +because Trivy does not read `*.example` files on its own. Known and deliberately out of scope of the gates above: the build toolchain in `web/` (vite, esbuild) carries dev-server advisories, and `react-router` 6.x @@ -42,30 +46,53 @@ carries two MODERATE advisories whose only fix is the 7.x major. Neither ships i the production bundle; the `npm audit` gate is scoped to production dependencies for that reason, and Dependabot proposes the majors as reviewable PRs. -## Open findings +## Triage of the IaC findings (opened 2026-07-27, decided 2026-10-24) The Trivy filesystem gate had never executed before 2026-07-27 — it referenced an action tag that upstream deleted, so the job died in setup. The first run -that got past setup surfaced eight HIGH **IaC misconfigurations**, all -pre-existing. They are listed here rather than suppressed, and the gate stays -red until they are resolved: +that got past setup surfaced HIGH **IaC misconfigurations**, all pre-existing, +and the gate stayed red on them for three months. Each one now has a decision: -| Rule | Where | Fix | +| Rule | Where | Decision | |---|---|---| -| KSV-0014 | `deploy/k8s/infra/postgres/postgres.yaml`, `deploy/backup/postgres-backup-cronjob.yaml`, `deploy/k8s/observability/grafana/grafana.yaml`, `deploy/llm/ollama.yaml` | `securityContext.readOnlyRootFilesystem: true` plus writable `emptyDir` mounts for each image's scratch paths | -| KSV-0118 | `deploy/llm/ollama.yaml` | give the ollama pod/container a non-default `securityContext` | -| AWS-0164 (x3) | `deploy/terraform/modules/network/main.tf:79` | `map_public_ip_on_launch = false` on the public subnets | -| AWS-0132 | `deploy/terraform/modules/state-backend/main.tf:33-41` | SSE-KMS with a customer-managed key instead of SSE-S3 | - -Three of the KSV-0014 sites carry in-file comments saying `readOnlyRootFilesystem` -was left unset on purpose because the upstream image does not cleanly support it, -with non-root, `drop: ["ALL"]` and `allowPrivilegeEscalation: false` as -compensating controls. Either those comments or this gate is wrong; resolving -that needs a cluster to test against, so it is open rather than decided. - -The `image` job `needs` this one, so build → SBOM → cosign does not run while -these stand. That is the honest state: the signing pipeline is wired and -unblocked at the action level, but it has not yet produced a Rekor entry. +| KSV-0014 | `deploy/k8s/infra/postgres/postgres.yaml` | **Fixed.** Read-only root plus emptyDirs for `/var/run/postgresql` and `/tmp`. The "image cannot run read-only" comment was wrong, and the Kyverno exception for postgres is gone. | +| KSV-0014 | `deploy/k8s/observability/grafana/grafana.yaml` | **Fixed.** Read-only root, `/tmp` emptyDir, `GF_LOG_MODE=console`. | +| KSV-0014, KSV-0118 (x2) | `deploy/llm/ollama.yaml` | **Fixed.** seccomp, drop ALL, no privilege escalation, read-only root. Still uid 0 until the PVC is chowned (see `deploy/llm/README.md`). | +| KSV-0014 | `deploy/backup/postgres-backup-cronjob.yaml` | **Accepted until 2027-01-31** (`.trivyignore.yaml`). The job installs tools at runtime and is broken for other reasons (below); a rewrite fixes both. | +| AWS-0164 (x3) | `deploy/terraform/modules/network/main.tf` | **Fixed.** `map_public_ip_on_launch = false`. NAT uses an EIP; load balancers do not need it. | +| AWS-0132 | `deploy/terraform/modules/state-backend/main.tf` | **Fixed.** SSE-KMS with a dedicated CMK. | +| KSV-0109 | `deploy/helm/fp-ai-gateway/templates/configmap.yaml` | **False positive, accepted until 2027-04-30.** Surfaced only once the charts rendered: the key `FP_TEAM_TOKEN_BUDGET` contains "TOKEN" but holds an integer budget. | + +None of the Kubernetes fixes has been run against a cluster yet. Verify postgres +(synced by the `fp-infra` Argo CD app), grafana and ollama after rollout. + +**Still red after this triage (2026-10-24):** the same scan reports HIGH +dependency CVEs in the Go modules (`golang.org/x/net`, `x/text`, `x/crypto`, +`google.golang.org/grpc`, `klauspost/compress`, `moby/go-archive`) and in +`web/package-lock.json` (`axios`, `follow-redirects`). Those are dependency +bumps, which the open Dependabot group PRs carry; they are deliberately not +duplicated here. + +**Known defect, not a scanner finding:** `postgres-backup-cronjob.yaml` cannot +succeed as written. It runs as uid 999 but `apk add`s packages and writes `mc` +to `/usr/local/bin`, downloads that binary at runtime without verification, +calls `gpg --passphrase` without `--pinentry-mode loopback`, and dumps database +names (`fp_features`, `fp_experiments`, `fp_notifications`) that +`scripts/init-postgres.sh` does not create. It also depends on `minio/mc`, +which is no longer on Docker Hub. It needs a rewrite (pinned image with the +tools baked in, no runtime downloads, read-only root), not a patch. + +## Accepted findings + +`.trivyignore.yaml` is the only allowlist, and both the filesystem and the +image scan read it. Each entry must have: + +- a `statement` that says why it is a false positive or an accepted risk, and + what would remove it; +- an `expired_at` date. After that date Trivy stops honouring the entry and the + gate fails again, which forces a fresh decision rather than a permanent mute; +- the narrowest scope possible (`paths`, or a specific package/CVE), never a + rule ID for the whole repo. ## Supply chain From 7bc38e5b1a66895815b2cfea8b163884727e65c0 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:51:24 +0500 Subject: [PATCH 19/42] docs(security): list the dependency CVEs the Dependabot PRs leave open The previous commit said the remaining HIGH dependency CVEs are carried by the open Dependabot PRs. I then checked #17 and #10 against Trivy's fixed versions, and that is only partly true: x/net (needs 0.60.0, #17 gives 0.58.0), klauspost/compress (1.18.7 vs 1.18.6), moby/go-archive (0.3.0, untouched), axios (1.20.0 vs 1.19.0) and follow-redirects (1.16.1, untouched) stay vulnerable, and #17 does not cover cli/, gen/go or services/bff. SECURITY.md now has a table of fixed-in versions against what each PR brings, so nobody merges the Dependabot PRs expecting a green gate. Co-Authored-By: Claude Opus 5.5 --- SECURITY.md | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 7a4e423..c123fa9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -67,11 +67,25 @@ None of the Kubernetes fixes has been run against a cluster yet. Verify postgres (synced by the `fp-infra` Argo CD app), grafana and ollama after rollout. **Still red after this triage (2026-10-24):** the same scan reports HIGH -dependency CVEs in the Go modules (`golang.org/x/net`, `x/text`, `x/crypto`, -`google.golang.org/grpc`, `klauspost/compress`, `moby/go-archive`) and in -`web/package-lock.json` (`axios`, `follow-redirects`). Those are dependency -bumps, which the open Dependabot group PRs carry; they are deliberately not -duplicated here. +dependency CVEs. They are dependency bumps, left to the open Dependabot PRs so +the two do not conflict, but those PRs do **not** fully clear the gate as they +stand: + +| Package | Fixed in | Open Dependabot PR brings it to | +|---|---|---| +| `golang.org/x/crypto` | 0.55.0 | 0.55.0 (#17) | +| `golang.org/x/text` | 0.41.0 | 0.41.0 (#17) | +| `google.golang.org/grpc` | 1.83.1 | 1.83.2 (#17) | +| `golang.org/x/net` | **0.60.0** (one CVE; another is fixed in 0.56.0) | 0.58.0 (#17), still vulnerable | +| `github.com/klauspost/compress` | **1.18.7** | 1.18.6 (#17), still vulnerable | +| `github.com/moby/go-archive` | **0.3.0** | unchanged | +| `axios` (web) | **1.20.0** | 1.19.0 (#10), still vulnerable | +| `follow-redirects` (web) | **1.16.1** | unchanged | + +#17 also leaves out `cli/`, `gen/go` and `services/bff`, which carry the same +`x/net`, `x/text` and `grpc` advisories. After merging #17 and #10, bump the +remaining packages by hand (or let Dependabot's next run propose them), then +re-run Security. **Known defect, not a scanner finding:** `postgres-backup-cronjob.yaml` cannot succeed as written. It runs as uid 999 but `apk add`s packages and writes `mc` From ba1e40d257ad7848e049fbc3fc138cc8d906f319 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:54:21 +0500 Subject: [PATCH 20/42] ci(security): scan images before pushing them, publish from a separate job On push events, the image job pushed to GHCR inside build-push-action and only then ran the Trivy image scan, against the first metadata tag (the mutable :main) rather than the digest it had just built. An image with a HIGH CVE was already pullable when the gate went red. The job also held packages:write and id-token:write statically, including on same-repo pull_request runs, and published under ghcr.io//forgepoint-, a name nothing that deploys images referenced. image (every run, contents: read only): - builds into a local docker-archive tarball (no push, no registry ref); - Trivy scans that tarball (input:) and Syft makes the SBOM from it; - on main/v* pushes, hands the tarball and its config digest (build imageid) to publish as a one-day artifact. publish (pushes to main or a v* tag only; the only job with packages:write and id-token:write): - refuses a v* tag whose commit is not an ancestor of origin/main; - recomputes the tarball's config digest and requires it to equal the scanned one, so the check does not depend on the runner's image store; - pushes all tags, asks the registry for the sha-<40> manifest and requires its config digest to equal the scanned one; - cosign signs by digest and attests the SBOM. Image name: IMAGE_PREFIX = ghcr.io/${{ github.repository }}, giving ghcr.io/abd-ulbasit/forgepoint/, the name the charts, Rollouts and Kyverno already use. SECURITY.md documents the split and the corrected `cosign verify` command. Decisions: - Push on main and v* tags only. Alternative: tags only. Why: Argo CD tracks main, so main builds are deployable and should exist as scanned, signed images. Tags must still be on main. - Sign every published image, not only tags. Alternative: tags only, as before. Why: an admission policy can then require a signature for every image from this repo, instead of having to exempt main builds. - Scan a tarball and push that tarball. Alternative: build with load:true, scan, then rebuild with push:true from cache. Why: the rebuild is a second artifact. Here the bytes scanned are the bytes pushed, and both digest checks prove it. Trade-off: the docker exporter cannot carry buildx provenance attestations, so provenance/sbom are off in the build. The Syft SBOM is attested with cosign instead. Build provenance (actions/attest-build-provenance) is a follow-up. Not run: no actionlint locally. Reviewed by hand; YAML parses. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/security.yml | 305 ++++++++++++++++++++++----------- SECURITY.md | 31 +++- 2 files changed, 223 insertions(+), 113 deletions(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 382f626..67a4e70 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -15,14 +15,17 @@ # line is in the OSV database." # - Trivy (fs): scans go.sum/lockfiles + IaC/secrets in the working tree — # a broad net for dependency and config issues before anything is built. -# - Trivy (image): scans the BUILT container (OS packages + app deps). Our -# distroless base means this should find ~zero OS CVEs; it gates HIGH/CRITICAL. +# - Trivy (image): scans the BUILT container (OS packages + app deps) as a +# local tarball, BEFORE anything is pushed; `publish` pushes that same +# tarball. Our distroless base means this should find ~zero OS CVEs; it +# gates HIGH/CRITICAL. # - Syft SBOM (CycloneDX): the bill of materials — required for provenance, # consumed by downstream policy (e.g. "no GPL", "no log4j") and audits. -# - cosign keyless: signs the image using a short-lived Sigstore cert tied to -# this workflow's OIDC identity — NO long-lived private key to leak. The -# signature + Rekor transparency-log entry let anyone verify the image came -# from THIS repo's release workflow. +# - cosign keyless: signs every published image (main and v* tags) using a +# short-lived Sigstore cert tied to this workflow's OIDC identity — NO +# long-lived private key to leak. The signature + Rekor transparency-log +# entry let anyone (and the Kyverno verifyImages policy) verify the image +# came from THIS repo's Security workflow on main or a release tag. # # STRUCTURE — onboarding a service costs nothing here: # Both matrices are RESOLVED FROM THE REPO by the `matrix` job below — @@ -51,10 +54,11 @@ on: # without a code change. workflow_dispatch: -# SECURITY: least privilege at the TOP. The default for every job is read-only; -# the two jobs that need more elevate locally: -# - The image job adds id-token:write (Sigstore OIDC for keyless cosign) and -# packages:write (push to GHCR) ONLY when it actually signs/pushes. +# SECURITY: least privilege at the TOP. The default for every job is read-only. +# Exactly one job elevates: `publish`, which runs only for pushes to main or a +# v* tag (never for pull_request or workflow_dispatch), adds packages:write +# (push to GHCR) and id-token:write (Sigstore OIDC for keyless cosign). The +# `image` job, which builds pull-request code, keeps contents:read. permissions: contents: read @@ -64,10 +68,10 @@ concurrency: env: GO_VERSION: "1.26" - # Container registry + image namespace. GHCR keyed to the repo owner so - # `cosign verify` can assert the image came from this org's workflows. REGISTRY: ghcr.io - IMAGE_NAMESPACE: ${{ github.repository_owner }} + # Every image is ghcr.io///, the name the Helm charts, + # Rollouts and the Kyverno allowlist use (ghcr.io/abd-ulbasit/forgepoint/auth). + IMAGE_PREFIX: ghcr.io/${{ github.repository }} jobs: # =========================================================================== @@ -202,8 +206,19 @@ jobs: scanners: vuln,secret,misconfig # =========================================================================== - # 3. Image: build → Trivy image scan → SBOM → cosign sign (per service). + # 3. image — build → Trivy image scan → SBOM, per service. NEVER pushes. # =========================================================================== + # ORDER OF OPERATIONS (the point of splitting this from `publish`): + # build to a local tarball → scan that tarball → SBOM it → (main/tags only) + # hand the SAME tarball to `publish`. Nothing reaches the registry unless + # the scan of those exact bytes passed. The old single job pushed on every + # push event BEFORE Trivy ran, and scanned the first mutable tag (:main) + # rather than what it had just built, so an image with a HIGH CVE was + # already pullable by the time the gate went red. + # + # PERMISSIONS: contents:read only. This job builds code from pull requests, + # so it must not hold packages:write or id-token:write. (It used to hold both + # statically, on same-repo PR runs too.) image: name: image (${{ matrix.service }}) runs-on: ubuntu-latest @@ -214,55 +229,37 @@ jobs: service: ${{ fromJSON(needs.matrix.outputs.services) }} permissions: contents: read - # Push images to GHCR (only used on push/tag, see the `if` on push/sign). - packages: write - # Sigstore keyless signing: mints a short-lived OIDC token as the cert - # subject. WITHOUT this, cosign would need a long-lived key (the thing we - # are deliberately avoiding). - id-token: write steps: - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 # Buildx gives us the modern BuildKit builder (cache mounts in the - # Dockerfile, multi-stage, provenance) used by build-push-action. + # Dockerfile, multi-stage) used by build-push-action. - name: Set up Docker Buildx uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 - # Derive tags/labels from git context. On a PR we build but do NOT push - # (no login below); on push/tag we push and sign. metadata-action emits a - # canonical ${{ steps.meta.outputs.tags }} + OCI labels. + # Tags/labels from git context. The image NAME is the one the Helm charts, + # Rollouts and Kyverno allowlist already use: + # ghcr.io/// e.g. ghcr.io/abd-ulbasit/forgepoint/auth + # (it used to be ghcr.io//forgepoint-, which nothing that + # deploys images referenced). - name: Docker metadata id: meta uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/forgepoint-${{ matrix.service }} + images: ${{ env.IMAGE_PREFIX }}/${{ matrix.service }} tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=sha,format=long - # Log in to GHCR ONLY when we intend to push (push to main or a tag). - # On PRs from forks the GITHUB_TOKEN can't push anyway; gating the login - # keeps PR runs read-only and avoids a useless auth attempt. - - name: Log in to GHCR - if: github.event_name == 'push' - uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - # Build the image from the REPO ROOT context (context: .) with the - # service's Dockerfile. Root context is mandatory: the Dockerfile copies - # sibling modules (pkg, gen/go) and generates a per-service go.work on the - # fly — those paths don't exist in a services// context. See the long - # header in services//Dockerfile for the full rationale. - # - load:true on PR → image stays local for the Trivy scan, no push. - # - push only on a real push event. - # - digest output feeds the SBOM + cosign steps (sign by digest, not tag, - # so the signature is immutable even if the tag is later re-pointed). + # Build from the REPO ROOT context (the Dockerfile copies sibling modules: + # pkg, gen/go). Output is a docker-archive TARBALL, not a push and not a + # registry ref: the scan and the SBOM below read this file, and `publish` + # pushes this file. provenance/sbom attestations are off because the + # docker exporter cannot carry them (Syft's SBOM below is attached with + # cosign instead). - name: Build image id: build uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0 @@ -271,59 +268,37 @@ jobs: file: services/${{ matrix.service }}/Dockerfile tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - push: ${{ github.event_name == 'push' }} - load: ${{ github.event_name != 'push' }} + outputs: type=docker,dest=${{ runner.temp }}/image.tar + provenance: false + sbom: false build-args: | VERSION=${{ github.ref_name }} cache-from: type=gha cache-to: type=gha,mode=max - # Scan the BUILT image. On push we built with push:true (no local image), - # so scan the pushed ref; on PR we scan the locally loaded tag. Either way - # we reference the first metadata tag. FAIL on HIGH/CRITICAL — distroless - # should keep this green; a red here means a dependency CVE shipped. - - name: Resolve scan target - id: target - # SECURITY: steps.meta.outputs.tags is derived from git context (branch - # name, PR ref, SHA). Interpolating ${{ ... }} directly into `run:` shell - # is a script-injection vector — a maliciously crafted branch name could - # embed shell metacharacters or commands that execute in the runner. - # Fix: pass the value through an environment variable (env:) instead of - # inline interpolation. The shell receives it as a plain string ($TAGS), - # so metacharacters are never interpreted by bash. This is the standard - # GitHub Actions mitigation for CWE-78 / GHSA script injection. - env: - TAGS: ${{ steps.meta.outputs.tags }} - run: | - # Take the first line of the multi-line tags output as the scan ref. - ref="$(printf '%s\n' "${TAGS}" | head -n1)" - echo "image=${ref}" >> "$GITHUB_OUTPUT" - + # Scan the BUILT bytes (the tarball), not a tag. FAIL on HIGH/CRITICAL. - name: Trivy image scan uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 with: scan-type: image - image-ref: ${{ steps.target.outputs.image }} + input: ${{ runner.temp }}/image.tar severity: HIGH,CRITICAL exit-code: "1" # NOTE: ignore-unfixed has been intentionally removed — same rationale - # as the fs scan above. A HIGH/CRITICAL with no upstream fix is still a - # real risk that deserves a decision, not a silent pass. Add a - # .trivyignore entry with justification if a specific CVE must be - # accepted (e.g. distroless ships an unfixed low-risk OpenSSL build). + # as the fs scan above. Accept a specific CVE only through + # .trivyignore.yaml (statement + expiry). vuln-type: os,library + trivyignores: .trivyignore.yaml - # Generate a CycloneDX SBOM from the built image. anchore/sbom-action wraps - # Syft; CycloneDX is the format policy engines + `cosign attest` consume. - # Uploaded as an artifact (and as a release asset on a tag). + # CycloneDX SBOM of the same tarball. Uploaded as an artifact on every + # run; attached to the pushed image as a signed attestation in `publish`. - name: Generate CycloneDX SBOM (Syft) uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0 with: - image: ${{ steps.target.outputs.image }} + image: docker-archive:${{ runner.temp }}/image.tar format: cyclonedx-json output-file: sbom-${{ matrix.service }}.cyclonedx.json - # Don't auto-publish to a GitHub release on tags from here; we attach - # explicitly so the artifact name is deterministic. + upload-artifact: false upload-release-assets: false - name: Upload SBOM artifact @@ -333,40 +308,162 @@ jobs: path: sbom-${{ matrix.service }}.cyclonedx.json if-no-files-found: error - # Install cosign for keyless signing. - - name: Install cosign - # Sign only on TAGGED release builds. We don't sign every main push — - # signatures are a release artifact; signing dev images is noise. + # Hand the scanned tarball (and its config digest = image ID) to + # `publish`. Only on events that publish, so PR runs do not store + # 12 images. One-day retention: this is a hand-off, not an archive. + - name: Record scanned image ID + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) + env: + IMAGE_ID: ${{ steps.build.outputs.imageid }} + run: | + set -euo pipefail + [ -n "${IMAGE_ID}" ] || { echo "build produced no image id" >&2; exit 1; } + mkdir -p "${RUNNER_TEMP}/publish" + mv "${RUNNER_TEMP}/image.tar" "${RUNNER_TEMP}/publish/image.tar" + printf '%s\n' "${IMAGE_ID}" > "${RUNNER_TEMP}/publish/scanned-imageid.txt" + + - name: Upload scanned image for publish + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: image-${{ matrix.service }} + path: ${{ runner.temp }}/publish/ + if-no-files-found: error + retention-days: 1 + + # =========================================================================== + # 4. publish — push the SCANNED image, then sign it. main and v* tags only. + # =========================================================================== + # Runs only after `image` passed for every service (a matrix `needs` waits + # for all legs), only for pushes to main or a v* tag, and only here do the + # write permissions exist: + # packages:write — push to GHCR with GITHUB_TOKEN + # id-token:write — Sigstore keyless signing (a short-lived Fulcio cert bound + # to this workflow's OIDC identity; no long-lived key) + # pull_request and workflow_dispatch runs never reach this job. + publish: + name: publish (${{ matrix.service }}) + runs-on: ubuntu-latest + needs: [matrix, image] + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) + strategy: + fail-fast: false + matrix: + service: ${{ fromJSON(needs.matrix.outputs.services) }} + permissions: + contents: read + packages: write + id-token: write + steps: + # Full history so the tag check below can see main. + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + + # A v* tag can point at ANY commit, including one that never went through + # review on main. Publish (and sign) only commits that are on main. + - name: Refuse tags that are not on main if: startsWith(github.ref, 'refs/tags/v') + run: | + set -euo pipefail + git fetch --no-tags origin main + if ! git merge-base --is-ancestor "${GITHUB_SHA}" origin/main; then + echo "::error::${GITHUB_REF_NAME} points at ${GITHUB_SHA}, which is not on main; refusing to publish" >&2 + exit 1 + fi + + - name: Download scanned image + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + name: image-${{ matrix.service }} + path: scanned + + - name: Download SBOM + uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 + with: + name: sbom-${{ matrix.service }} + path: sbom + + # Prove the tarball is the image that was scanned, then load it. The + # "image ID" buildx reported is the digest of the image CONFIG, which + # lists every layer's uncompressed digest: same config digest, same + # layers. It is recomputed from the tarball itself, so the check does not + # depend on which image store the runner's Docker uses. + - name: Verify and load the scanned image + id: load + env: + SERVICE: ${{ matrix.service }} + run: | + set -euo pipefail + expected="$(cat scanned/scanned-imageid.txt)" + config_path="$(tar -xOf scanned/image.tar manifest.json | jq -r '.[0].Config')" + actual="sha256:$(tar -xOf scanned/image.tar "${config_path}" | sha256sum | cut -d' ' -f1)" + if [ "${actual}" != "${expected}" ]; then + echo "::error::tarball config ${actual} != scanned image ${expected}" >&2 + exit 1 + fi + docker load --input scanned/image.tar + repo="$(printf '%s/%s' "${IMAGE_PREFIX}" "${SERVICE}" | tr '[:upper:]' '[:lower:]')" + echo "repo=${repo}" >> "$GITHUB_OUTPUT" + echo "image_id=${expected}" >> "$GITHUB_OUTPUT" + + - name: Log in to GHCR + uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Push every tag metadata-action put on the image (main or the semver, + # plus sha-<40>), then ask the REGISTRY for the manifest digest of the + # sha-<40> tag and check that manifest's config is the scanned image. + - name: Push + id: push + env: + REPO: ${{ steps.load.outputs.repo }} + IMAGE_ID: ${{ steps.load.outputs.image_id }} + run: | + set -euo pipefail + docker push --all-tags "${REPO}" + digest="$(docker buildx imagetools inspect --format '{{json .Manifest}}' "${REPO}:sha-${GITHUB_SHA}" | jq -r .digest)" + case "${digest}" in sha256:*) ;; *) echo "::error::no digest for ${REPO}:sha-${GITHUB_SHA}" >&2; exit 1 ;; esac + remote_config="$(docker buildx imagetools inspect --raw "${REPO}@${digest}" | jq -r .config.digest)" + if [ "${remote_config}" != "${IMAGE_ID}" ]; then + echo "::error::pushed config ${remote_config} != scanned image ${IMAGE_ID}" >&2 + exit 1 + fi + echo "digest=${digest}" >> "$GITHUB_OUTPUT" + echo "pushed ${REPO}@${digest}" + + - name: Install cosign uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2 - # Keyless sign the image BY DIGEST. COSIGN_EXPERIMENTAL/--yes drive the - # OIDC keyless flow: cosign requests a token from GitHub's OIDC provider - # (enabled by id-token:write), Fulcio issues a short-lived cert bound to - # this workflow's identity, the signature + cert land in Rekor (public - # transparency log). Verifiers run: - # cosign verify --certificate-identity-regexp '...forgepoint/.github/...' \ - # --certificate-oidc-issuer https://token.actions.githubusercontent.com \ - # ghcr.io//forgepoint-@ - # We sign the DIGEST (immutable), not a tag, so re-pointing the tag can't - # invalidate or hijack the signature. + # Keyless sign the image BY DIGEST: cosign exchanges this job's GitHub + # OIDC token for a short-lived Fulcio cert, and the signature + cert land + # in the public Rekor log. Every published image is signed, main builds + # included, so the cluster can require a signature on ANY image from this + # repository (deploy/policies/base/50-verify-images.yaml). Verify with: + # cosign verify \ + # --certificate-identity-regexp '^https://github\.com/abd-ulbasit/forgepoint/\.github/workflows/security\.yml@refs/(heads/main|tags/v.*)$' \ + # --certificate-oidc-issuer https://token.actions.githubusercontent.com \ + # ghcr.io/abd-ulbasit/forgepoint/@ - name: Cosign sign (keyless) - if: startsWith(github.ref, 'refs/tags/v') env: - DIGEST: ${{ steps.build.outputs.digest }} - IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/forgepoint-${{ matrix.service }} + REPO: ${{ steps.load.outputs.repo }} + DIGEST: ${{ steps.push.outputs.digest }} run: | - cosign sign --yes "${IMAGE}@${DIGEST}" + cosign sign --yes "${REPO}@${DIGEST}" - # Attach the SBOM to the image as a signed CycloneDX attestation so the - # bill of materials travels WITH the image and is itself verifiable. + # Attach the SBOM as a signed CycloneDX attestation so the bill of + # materials travels WITH the image and is itself verifiable. - name: Cosign attest SBOM (keyless) - if: startsWith(github.ref, 'refs/tags/v') env: - DIGEST: ${{ steps.build.outputs.digest }} - IMAGE: ${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/forgepoint-${{ matrix.service }} + REPO: ${{ steps.load.outputs.repo }} + DIGEST: ${{ steps.push.outputs.digest }} + SERVICE: ${{ matrix.service }} run: | cosign attest --yes \ - --predicate "sbom-${{ matrix.service }}.cyclonedx.json" \ + --predicate "sbom/sbom-${SERVICE}.cyclonedx.json" \ --type cyclonedx \ - "${IMAGE}@${DIGEST}" + "${REPO}@${DIGEST}" diff --git a/SECURITY.md b/SECURITY.md index c123fa9..e4ea6b9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -110,13 +110,24 @@ image scan read it. Each entry must have: ## Supply chain -On a `v*` tag the image job additionally: - -1. builds the service image from the repo root context (distroless runtime, no - shell, no package manager), -2. generates a CycloneDX SBOM with Syft and uploads it as a build artifact, -3. signs the image **by digest** with `cosign` in keyless mode, and -4. attaches the SBOM as a signed CycloneDX attestation. +Every image is `ghcr.io/abd-ulbasit/forgepoint/`, the name the Helm +charts, the Rollouts and the Kyverno allowlist use. The pipeline is split so +that nothing reaches the registry unscanned: + +1. **`image`** (every run, `contents: read` only): builds the service image from + the repo root context (distroless runtime, no shell, no package manager) into + a local tarball, scans **that tarball** with Trivy (HIGH/CRITICAL fail), and + generates a CycloneDX SBOM of it with Syft. It never pushes. +2. **`publish`** (pushes to `main` and `v*` tags only; the only job with + `packages: write` and `id-token: write`): refuses a `v*` tag whose commit is + not on `main`, checks the tarball's config digest against the one that was + scanned, pushes it, checks the registry's manifest still points at that + config, then signs the image **by digest** with `cosign` in keyless mode and + attaches the SBOM as a signed CycloneDX attestation. + +Pull requests build and scan but never push or sign. Every published image, +`main` builds included, is signed, so the cluster can require a signature on +any image from this repository. Keyless means there is no long-lived signing key to leak: cosign exchanges the workflow's GitHub OIDC token for a short-lived Fulcio certificate, and the @@ -128,11 +139,13 @@ To verify a published image: ```sh cosign verify \ - --certificate-identity-regexp '^https://github.com/abd-ulbasit/forgepoint/\.github/workflows/security\.yml@refs/tags/v' \ + --certificate-identity-regexp '^https://github\.com/abd-ulbasit/forgepoint/\.github/workflows/security\.yml@refs/(heads/main|tags/v.*)$' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ - ghcr.io/abd-ulbasit/forgepoint-@ + ghcr.io/abd-ulbasit/forgepoint/@ ``` +Use `@refs/tags/v.*$` instead to accept release builds only. + ## Keeping it that way Dependency drift is what put ten reachable CVEs in this repo in the first place, From d35fa3be26a28184590485e0ce409f76310538a0 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:55:11 +0500 Subject: [PATCH 21/42] ci: add a Terraform workflow (fmt, init with read-only lock, validate) No workflow ran terraform fmt, validate or plan, although environments/dev/backend.tf said CI validated offline. The only thing reading the .tf files was Trivy's misconfiguration scanner. .github/workflows/terraform.yml: - fmt: `terraform fmt -check -recursive -diff deploy/terraform`. - validate, one leg per root (bootstrap, environments/dev): `init -backend=false -lockfile=readonly`, then `validate`. -lockfile=readonly makes CI install exactly what the committed .terraform.lock.hcl records, and fail if a constraint changes without a regenerated lock. - Terraform pinned to 1.14.8. hashicorp/setup-terraform pinned by SHA (v4.0.1, the current release). Top-level permissions are {}, each job gets contents: read, and checkout does not persist credentials. - No plan: CI has no AWS credentials and nothing has been applied. The header says how to add one later (a read-only OIDC role). - No path filter, so the check can be made required without deadlocking unrelated PRs. Ran the same commands locally with Terraform 1.14.8: fmt clean, both roots validate, and the lock files are unchanged. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/terraform.yml | 102 ++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 .github/workflows/terraform.yml diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml new file mode 100644 index 0000000..3440082 --- /dev/null +++ b/.github/workflows/terraform.yml @@ -0,0 +1,102 @@ +# ============================================================================= +# TERRAFORM — offline checks for every root module in deploy/terraform +# ============================================================================= +# +# Until this workflow existed nothing ran `terraform fmt` or `validate` in CI, +# although environments/dev/backend.tf said CI did; the only thing that read +# the .tf files was Trivy's misconfiguration scanner. +# +# WHAT IT CHECKS (no cloud credentials, nothing is planned or applied): +# - fmt -check: formatting drift fails the build. +# - init -backend=false -lockfile=readonly: providers are installed from the +# COMMITTED .terraform.lock.hcl and must match its checksums. A constraint +# change without a regenerated lock file fails here instead of silently +# resolving a different provider build. +# - validate: syntax, references, types and variable validation rules. +# +# WHAT IT DOES NOT DO: `plan`. There are no AWS credentials in this repo's CI +# and nothing has been applied, so a plan would have no state to compare to. +# When an environment goes live, add a plan job that assumes a read-only role +# through GitHub OIDC (see modules/github-oidc for the trust pattern). +# +# No path filter on purpose: if this check is ever made required in branch +# protection, a path-filtered workflow never reports on unrelated PRs and +# blocks them forever. +# ============================================================================= + +name: Terraform + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +# Nothing by default; the jobs ask for read access to the repo and no more. +permissions: {} + +concurrency: + group: terraform-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +env: + # The version the lock files and README are validated against. + TERRAFORM_VERSION: "1.14.8" + +jobs: + fmt: + name: terraform fmt + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Set up Terraform + uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1 + with: + terraform_version: ${{ env.TERRAFORM_VERSION }} + terraform_wrapper: false + + - name: terraform fmt -check + run: terraform fmt -check -recursive -diff deploy/terraform + + validate: + name: validate (${{ matrix.root }}) + runs-on: ubuntu-latest + permissions: + contents: read + strategy: + fail-fast: false + matrix: + # Every ROOT module (a directory you run terraform in). Modules under + # deploy/terraform/modules are validated through the roots that call + # them. Add staging/prod here when they exist. + root: + - deploy/terraform/bootstrap + - deploy/terraform/environments/dev + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Set up Terraform + uses: hashicorp/setup-terraform@dfe3c3f87815947d99a8997f908cb6525fc44e9e # v4.0.1 + with: + terraform_version: ${{ env.TERRAFORM_VERSION }} + terraform_wrapper: false + + - name: terraform init (no backend, lock file read-only) + env: + ROOT: ${{ matrix.root }} + run: terraform -chdir="${ROOT}" init -backend=false -input=false -lockfile=readonly + + - name: terraform validate + env: + ROOT: ${{ matrix.root }} + run: terraform -chdir="${ROOT}" validate -no-color From e8d76e1b89b1fcb8c99f3b512b5475d2d44ef4e8 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:55:56 +0500 Subject: [PATCH 22/42] deps: add docker, helm, docker-compose and terraform to Dependabot Dependabot covered gomod, npm and github-actions only. Nothing refreshed the digest-pinned base images in the 12 Dockerfiles, the infra images now pinned by digest in deploy/, the migrate image in the charts, the compose stack or the AWS provider. A digest pin without automation rots silently: the image keeps its CVEs and the pin looks fine. - docker: /services/*, /deploy/k8s/infra/*, /deploy/k8s/observability/*, /deploy/llm, /deploy/backup (Dockerfiles and, per GitHub's docs, Kubernetes manifests). Minor/patch grouped. postgres and redis majors ignored, because a database major is a migration. - helm: /deploy/helm/* (images referenced by the charts). - docker-compose: / (same postgres/redis major ignore). - terraform: deploy/terraform/bootstrap and environments/dev. It updates the constraint and the committed .terraform.lock.hcl. Majors stay separate PRs. GitHub's docs say the docker ecosystem handles Kubernetes manifests and that the helm ecosystem updates images inside charts. Check the first PRs to see whether the tag@digest form is rewritten as expected. Co-Authored-By: Claude Opus 5.5 --- .github/dependabot.yml | 104 +++++++++++++++++++++++++++++++++++++++++ SECURITY.md | 7 ++- 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 4f92ed5..8f19c21 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -19,6 +19,10 @@ # that would have caught the failure that kept Security red for a month: # the pinned trivy-action v0.29.0 referenced aquasecurity/setup-trivy@v0.2.2, # a tag upstream deleted, so the job died in "Set up job" in four seconds. +# - docker / helm / docker-compose: the digest-pinned base images, the infra +# images in deploy/, the migrate image in the charts, and the compose +# stack. (Added 2026-10: before that nothing refreshed a single digest pin.) +# - terraform: provider constraints + .terraform.lock.hcl per root module. # # WHY GROUPED UPDATES: # 15 modules x N dependencies of individual PRs is noise nobody reads, and @@ -102,3 +106,103 @@ updates: update-types: - minor - patch + + # --------------------------------------------------------------------------- + # Docker images — base images in the Dockerfiles and the images the raw + # Kubernetes manifests run. + # --------------------------------------------------------------------------- + # WHY: every Dockerfile pins golang:-alpine and distroless by DIGEST, and + # the infra manifests pin postgres/redis/nats/ollama/... by tag AND digest. A + # digest pin is only safe while something refreshes it: without this entry + # the pins silently go stale and the images keep their CVEs forever. + # Dependabot's docker ecosystem reads Dockerfiles and, per GitHub's docs, + # Kubernetes manifests; it rewrites tag and digest together. + - package-ecosystem: docker + directories: + - /services/* + - /deploy/k8s/infra/* + - /deploy/k8s/observability/* + - /deploy/llm + - /deploy/backup + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 10 + commit-message: + prefix: deps(docker) + groups: + docker-minor-and-patch: + update-types: + - minor + - patch + ignore: + # A database major is a data migration (pg_upgrade / dump-restore for + # Postgres, a licence and persistence-format change for Redis 8), not a + # dependency bump. Plan those by hand. + - dependency-name: postgres + update-types: ["version-update:semver-major"] + - dependency-name: redis + update-types: ["version-update:semver-major"] + + # --------------------------------------------------------------------------- + # Helm charts — images referenced in deploy/helm/*/values.yaml (the + # migrate/migrate initContainer, pinned by digest). + # --------------------------------------------------------------------------- + - package-ecosystem: helm + directories: + - /deploy/helm/* + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 5 + commit-message: + prefix: deps(helm) + groups: + helm-minor-and-patch: + update-types: + - minor + - patch + + # --------------------------------------------------------------------------- + # docker-compose — the local dev stack (docker-compose.yaml). + # --------------------------------------------------------------------------- + - package-ecosystem: docker-compose + directory: / + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 5 + commit-message: + prefix: deps(compose) + groups: + compose-minor-and-patch: + update-types: + - minor + - patch + ignore: + - dependency-name: postgres + update-types: ["version-update:semver-major"] + - dependency-name: redis + update-types: ["version-update:semver-major"] + + # --------------------------------------------------------------------------- + # Terraform — provider constraints AND the committed .terraform.lock.hcl, + # one entry per root module. + # --------------------------------------------------------------------------- + # Majors stay separate (an AWS provider major, e.g. 5 -> 6, renames and + # removes arguments and needs a reviewed migration). + - package-ecosystem: terraform + directories: + - /deploy/terraform/bootstrap + - /deploy/terraform/environments/dev + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 5 + commit-message: + prefix: deps(terraform) + groups: + terraform-minor-and-patch: + update-types: + - minor + - patch diff --git a/SECURITY.md b/SECURITY.md index e4ea6b9..edbc7ca 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -150,8 +150,11 @@ Use `@refs/tags/v.*$` instead to accept release builds only. Dependency drift is what put ten reachable CVEs in this repo in the first place, so the gates above are paired with [Dependabot](.github/dependabot.yml): weekly -updates for all 15 Go modules, the `web/` npm tree, and every pinned GitHub -Action. Actions are pinned by commit SHA with the version in a trailing comment — +updates for all 15 Go modules, the `web/` npm tree, every pinned GitHub Action, +the digest-pinned Docker base images and deploy images (`docker`, `helm`, +`docker-compose`), and the Terraform providers with their lock files. Database +majors (postgres, redis) are excluded: those are migrations, not bumps. +Actions are pinned by commit SHA with the version in a trailing comment — a moved tag cannot swap an action out from under a run, and Dependabot rewrites the SHA and the comment together so the pin stays a pin. From fd5ffaea74287516e810cdc257ce06bd7cf4f5b1 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:56:56 +0500 Subject: [PATCH 23/42] policies: verify cosign signatures and stop trusting every AWS account's ECR Nothing in the cluster checked the signatures CI makes, so keyless signing stopped no attack. The registry allowlist also had two holes: - "*.dkr.ecr.*.amazonaws.com/*". Kyverno's `*` matches the account id too, so images from ANY AWS account's ECR were allowed, an attacker's included. The base no longer has an ECR entry (nothing deploys from ECR yet), and the comment says the EKS overlay must add one named account and repo prefix. - migrate/migrate was not allowlisted, although every Postgres-backed chart runs it as an initContainer. Flipping to Enforce would have blocked every schema migration. It is added (both spellings). New base/50-verify-images.yaml, verify-image-signatures (Audit, like every base policy): ghcr.io/abd-ulbasit/forgepoint/* must carry a cosign keyless signature with issuer https://token.actions.githubusercontent.com subject ^https://github\.com/abd-ulbasit/forgepoint/\.github/workflows/security\.yml@refs/(heads/main|tags/v.*)$ which is the identity the new publish job signs with. mutateDigest and verifyDigest are off while auditing (no mutation from an audit policy, and the charts still deploy by tag). The file and README say to turn both on with Enforce. The README table, the allowlist section and a new "Signature verification" section match. The stale "the chart points TODAY" wording is updated now that CI publishes to that path. Not tested against a cluster or the Kyverno CLI. YAML parses. Co-Authored-By: Claude Opus 5.5 --- deploy/policies/README.md | 25 ++++++- deploy/policies/base/20-image-policies.yaml | 40 +++++++---- deploy/policies/base/50-verify-images.yaml | 76 +++++++++++++++++++++ deploy/policies/base/kustomization.yaml | 1 + 4 files changed, 125 insertions(+), 17 deletions(-) create mode 100644 deploy/policies/base/50-verify-images.yaml diff --git a/deploy/policies/README.md b/deploy/policies/README.md index 2f9967b..7e84db1 100644 --- a/deploy/policies/README.md +++ b/deploy/policies/README.md @@ -25,7 +25,8 @@ This is part of milestone **M6 — Platform security, GitOps & autoscaling** | `require-seccomp-runtimedefault` | `seccompProfile.type` is `RuntimeDefault`/`Localhost` | all pods' podSecurityContext | | `require-resource-requests-and-limits` | cpu+memory **requests AND limits** on every container | fp-auth `resources`; all infra pods | | `disallow-latest-tag` | image is tagged and not `:latest` | pinned infra tags; appVersion tag | -| `restrict-image-registries` | image from the **allowlist** (parameterized) | ghcr today, ECR in prod, distroless, pinned infra | +| `restrict-image-registries` | image from the **allowlist** (parameterized) | ghcr, distroless, migrate, pinned infra; ECR only per-account in the EKS overlay | +| `verify-image-signatures` | `ghcr.io/abd-ulbasit/forgepoint/*` carries a cosign **keyless** signature from this repo's `security.yml` on `main` or a `v*` tag | the Security workflow's `publish` job | | `require-part-of-label` | `app.kubernetes.io/part-of=forgepoint` on pod templates | recommended labels everywhere | | `disallow-host-namespaces` | no `hostPID`/`hostIPC`/`hostNetwork` | (none of ours use them) | | `disallow-host-path` | no `hostPath` volumes | we use PVCs/emptyDir only | @@ -67,12 +68,30 @@ exception was removed. If an image genuinely cannot run read-only, add a `base/20-image-policies.yaml`. Add or remove a trusted registry by editing that single list. It currently allows: -- `*.dkr.ecr.*.amazonaws.com/*` — prod ECR (any account/region; M5 AWS plan) -- `ghcr.io/abd-ulbasit/forgepoint/*` — where the chart points **today** +- `ghcr.io/abd-ulbasit/forgepoint/*` — where every chart and Rollout points and + where CI publishes - `gcr.io/distroless/*` — the distroless runtime base (hermetic builds) +- `migrate/migrate` — the golang-migrate initContainer in the Postgres-backed + charts (previously missing: Enforce would have blocked every migration) - the **specific pinned infra images**: `postgres`, `redis`, `nats`, `minio/minio`, `minio/mc` (both short and `docker.io/...` spellings) +There is deliberately **no ECR entry** in the base. The old +`*.dkr.ecr.*.amazonaws.com/*` glob matched any AWS account's registry, an +attacker's included. The EKS overlay adds exactly one, e.g. +`123456789012.dkr.ecr.us-east-1.amazonaws.com/forgepoint-dev/*`. + +### Signature verification + +The allowlist says *where* an image may come from; `verify-image-signatures` +(`base/50-verify-images.yaml`) checks *who built it*. Every image the Security +workflow publishes is signed with cosign keyless. The policy requires, for +`ghcr.io/abd-ulbasit/forgepoint/*`, a Fulcio certificate with issuer +`https://token.actions.githubusercontent.com` and a subject matching +`https://github.com/abd-ulbasit/forgepoint/.github/workflows/security.yml@refs/(heads/main|tags/v.*)`. +It ships in Audit with `mutateDigest`/`verifyDigest` off. When it moves to +Enforce, turn both on so the pod runs the exact digest that was verified. + --- ## Scope: `fp-*` namespaces only diff --git a/deploy/policies/base/20-image-policies.yaml b/deploy/policies/base/20-image-policies.yaml index 546a73e..031b0e5 100644 --- a/deploy/policies/base/20-image-policies.yaml +++ b/deploy/policies/base/20-image-policies.yaml @@ -109,11 +109,17 @@ spec: # and the per-collection rules below reference it — no duplication, no drift. # # The allowlist below covers, intentionally: -# - .dkr.ecr..amazonaws.com/* → our prod ECR (M5 AWS plan). -# Wildcarded on account+region so we don't hard-code one account here. -# - ghcr.io/abd-ulbasit/forgepoint/* → where fp-auth's chart points -# TODAY (values.yaml). Keeping it prevents the current platform from -# regressing the moment we flip to Enforce. +# - ghcr.io/abd-ulbasit/forgepoint/* → where every chart, Rollout +# and (since 2026-10) the Security workflow's publish job point. Signatures +# on these are checked separately by 50-verify-images.yaml. +# - NO ECR entry in the base. It used to allow "*.dkr.ecr.*.amazonaws.com/*", +# and Kyverno's `*` also matches the account id, so that admitted images +# from ANY AWS account's registry, an attacker's included. Nothing deploys +# from ECR yet. The EKS overlay must add the ONE account and repo prefix it +# uses, e.g. "123456789012.dkr.ecr.us-east-1.amazonaws.com/forgepoint-dev/*". +# - migrate/migrate → the golang-migrate +# initContainer every Postgres-backed chart runs (pinned by digest). It was +# missing, so flipping to Enforce would have blocked every schema migration. # - gcr.io/distroless/* → distroless runtime base # (the hermetic-builds requirement). # - the PINNED infra images: docker.io/library/{postgres,redis,nats} and @@ -143,9 +149,10 @@ metadata: policies.kyverno.io/severity: high policies.kyverno.io/subject: Pod policies.kyverno.io/description: >- - Container images may only come from an allowlisted set of registries: the - platform ECR (prod), ghcr.io/abd-ulbasit/forgepoint (current), the - distroless base, and the specific pinned infra images. + Container images may only come from an allowlisted set of registries: + ghcr.io/abd-ulbasit/forgepoint, the distroless base, the golang-migrate + initContainer and the specific pinned infra images. ECR is added per + environment for one named account, never as a wildcard. spec: validationFailureAction: Audit background: true @@ -177,8 +184,9 @@ spec: # `allowedRegistries`. Edit this list to add/remove a trusted registry. variable: value: - - "*.dkr.ecr.*.amazonaws.com/*" # prod ECR (any account/region) - - "ghcr.io/abd-ulbasit/forgepoint/*" # current GHCR images + # ECR: add ".dkr.ecr..amazonaws.com/forgepoint-/*" + # in the EKS overlay. Never wildcard the account (see above). + - "ghcr.io/abd-ulbasit/forgepoint/*" # platform images (CI-published) - "gcr.io/distroless/*" # distroless runtime base # Pinned infra images (full repo path, both spellings). We include # BOTH the docker.io-qualified form (what Kyverno normalizes to) AND @@ -194,12 +202,16 @@ spec: - "docker.io/minio/minio:*" - "minio/mc:*" - "docker.io/minio/mc:*" + # golang-migrate initContainer in the fp-* charts. + - "migrate/migrate:*" + - "docker.io/migrate/migrate:*" validate: message: >- - Image registry is not allowlisted. Allowed: ECR - (*.dkr.ecr.*.amazonaws.com), ghcr.io/abd-ulbasit/forgepoint, - gcr.io/distroless, and the pinned infra images (postgres, redis, nats, - minio/minio, minio/mc). Edit restrict-image-registries to add one. + Image registry is not allowlisted. Allowed: + ghcr.io/abd-ulbasit/forgepoint, gcr.io/distroless, migrate/migrate, + and the pinned infra images (postgres, redis, nats, minio/minio, + minio/mc). ECR is allowed only for the single account added by the + EKS overlay. Edit restrict-image-registries to add one. # foreach + deny: for each container, count how many allowlist globs the # image matches; deny when ZERO match. # diff --git a/deploy/policies/base/50-verify-images.yaml b/deploy/policies/base/50-verify-images.yaml new file mode 100644 index 0000000..9b960bb --- /dev/null +++ b/deploy/policies/base/50-verify-images.yaml @@ -0,0 +1,76 @@ +# ============================================================================= +# verify-image-signatures — admission-time check of the cosign signatures CI makes +# ============================================================================= +# +# The Security workflow's `publish` job signs every image it pushes (main and +# v* tags) with cosign KEYLESS: the signature is bound to the workflow's GitHub +# OIDC identity through a short-lived Fulcio certificate and logged in Rekor. +# Until this policy existed nothing in the cluster checked that signature, so +# signing stopped no attack at all: anyone able to push to the GHCR path, or to +# point a manifest at a look-alike image, could run unsigned code. +# +# WHAT IS PINNED (both must match, or the image is rejected): +# issuer : https://token.actions.githubusercontent.com (GitHub Actions OIDC) +# subject : https://github.com/abd-ulbasit/forgepoint/.github/workflows/security.yml@refs/heads/main +# or ...@refs/tags/v +# i.e. "signed by THIS repo's Security workflow, running on main or a release +# tag". A fork, another repo, another workflow file, or a PR run cannot produce +# a certificate with that subject. +# +# AUDIT FIRST, like every policy in base/ (the enforce overlay flips it). +# - mutateDigest: false. Kyverno would otherwise rewrite tags to digests, a +# mutation that is wrong to make while only auditing. Turn it on with +# Enforce, so the pod runs exactly the digest that was verified. +# - verifyDigest: false for the same reason: the charts still deploy by tag +# (Chart.appVersion). Flip both when CI pins digests in Git. +# - No forgepoint image had ever been published when this policy was added +# (the image job never ran on main), so the first signed images arrive +# with the next push to main or release tag. Until then every fp-* pod +# shows up as an audit failure, which is accurate. +# +# Kyverno needs network access to ghcr.io (signature) and rekor.sigstore.dev +# (transparency log) from its admission controller. +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: verify-image-signatures + annotations: + policies.kyverno.io/title: Verify Image Signatures + policies.kyverno.io/category: Supply Chain Security + policies.kyverno.io/severity: high + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Images from ghcr.io/abd-ulbasit/forgepoint must carry a cosign keyless + signature made by this repository's Security workflow on main or a v* tag. +spec: + validationFailureAction: Audit + # Image verification runs at admission; background re-scans would re-fetch + # signatures for every existing pod on every cycle. + background: false + webhookTimeoutSeconds: 30 + rules: + - name: verify-forgepoint-cosign-keyless + match: + any: + - resources: + kinds: + - Pod + namespaces: + - fp-system + - fp-models + - fp-jobs + - fp-infra + verifyImages: + - imageReferences: + - "ghcr.io/abd-ulbasit/forgepoint/*" + mutateDigest: false + verifyDigest: false + required: true + attestors: + - count: 1 + entries: + - keyless: + issuer: "https://token.actions.githubusercontent.com" + subjectRegExp: '^https://github\.com/abd-ulbasit/forgepoint/\.github/workflows/security\.yml@refs/(heads/main|tags/v.*)$' + rekor: + url: https://rekor.sigstore.dev diff --git a/deploy/policies/base/kustomization.yaml b/deploy/policies/base/kustomization.yaml index 1d1bcf6..ffa252b 100644 --- a/deploy/policies/base/kustomization.yaml +++ b/deploy/policies/base/kustomization.yaml @@ -18,3 +18,4 @@ resources: - 20-image-policies.yaml - 30-workload-policies.yaml - 40-ai-gateway-policies.yaml + - 50-verify-images.yaml From d04b80e01b3a9d70aa3b421f738b43893a3f6339 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:58:52 +0500 Subject: [PATCH 24/42] argocd: split the AppProject, keep child apps out of the argocd namespace The single "forgepoint" AppProject allowed `argocd` as a destination (so the root app-of-apps could create child Applications) and also whitelisted Secret, Role, RoleBinding and CustomResourceDefinition. Any chart or manifest merged to main, auto-synced, could therefore write a cluster/repo credential Secret or a RoleBinding into Argo CD's own namespace, which is privilege escalation through Git. It still did not whitelist the Application kind the root app exists to create, nor batch/Job, which the infra kustomization renders (the MinIO bucket init). - forgepoint-bootstrap (new, used by root.yaml): sourceRepos = this repo, destination = argocd only, no cluster-scoped kinds, one namespaced kind: argoproj.io/Application. - forgepoint (child apps): fp-system/fp-infra/fp-models/fp-jobs only (argocd removed). Cluster kinds: Namespace only (CRD removed). Namespaced kinds: exactly what the charts and infra render (checked with helm template), batch/Job added, Role/RoleBinding removed. - default-project.yaml (new): empties the built-in `default` project. An Application picks its own spec.project, so without this a child app could name `project: default` and bypass both projects. Applied by hand like project.yaml, never synced from Git. - Every apps/fp-*.yaml said "CI overwrites with the built image's immutable tag". No CI step does that (ADR-0002's tag bump was never built). The comments and README now say so and describe the manual, reviewed-PR path. Not applied to a cluster. All manifests parse. Before applying default-project.yaml, check that nothing in the cluster uses `default` (command in the file header). Co-Authored-By: Claude Opus 5.5 --- deploy/argocd/README.md | 54 ++++--- deploy/argocd/apps/fp-auth.yaml | 19 +-- deploy/argocd/apps/fp-billing.yaml | 19 +-- deploy/argocd/apps/fp-experiment-tracker.yaml | 19 +-- deploy/argocd/apps/fp-feature-store.yaml | 19 +-- deploy/argocd/apps/fp-inference-gateway.yaml | 19 +-- deploy/argocd/apps/fp-model-monitor.yaml | 19 +-- deploy/argocd/apps/fp-model-serving.yaml | 19 +-- deploy/argocd/apps/fp-notification.yaml | 19 +-- .../argocd/apps/fp-pipeline-orchestrator.yaml | 19 +-- deploy/argocd/apps/fp-registry.yaml | 19 +-- deploy/argocd/default-project.yaml | 27 ++++ deploy/argocd/project.yaml | 134 ++++++++++-------- deploy/argocd/root.yaml | 9 +- 14 files changed, 248 insertions(+), 166 deletions(-) create mode 100644 deploy/argocd/default-project.yaml diff --git a/deploy/argocd/README.md b/deploy/argocd/README.md index 882efa9..d2d0cc0 100644 --- a/deploy/argocd/README.md +++ b/deploy/argocd/README.md @@ -6,8 +6,10 @@ cluster to match Git and **self-heals** drift. This is the realization of [ADR-0002](../../docs/adr/0002-gitops-with-argocd.md) and Milestone **M6 (GitOps)**. > **This REPLACES the CI `helm upgrade` push step.** CI no longer deploys. -> CI's job ends at *build → scan → sign → push image → bump the image tag in Git*. -> ArgoCD does the deploying. No cluster credentials live in CI anymore. +> CI's job ends at *build → scan → sign → push image*. The planned last step, +> *bump the image tag in Git*, is **not implemented yet**: `image.tag` in every +> `apps/fp-*.yaml` is `""` (Chart.appVersion) and is changed by hand in a +> reviewed PR. ArgoCD does the deploying. No cluster credentials live in CI. `REPO_URL` placeholder used throughout: `https://github.com/abd-ulbasit/forgepoint.git` (swap for your fork in `project.yaml`, `root.yaml`, and each `apps/*.yaml`). @@ -18,9 +20,13 @@ cluster to match Git and **self-heals** drift. This is the realization of ``` deploy/argocd/ -├── project.yaml AppProject "forgepoint" — the guardrail (least privilege): -│ allowed source repos, destination namespaces (fp-*), -│ and allowed resource kinds. Denies cluster RBAC. +├── project.yaml Two AppProjects (the guardrails, least privilege): +│ forgepoint-bootstrap — root only: Application objects +│ in `argocd`, nothing else; +│ forgepoint — child apps: fp-* namespaces only, never +│ `argocd`, no RBAC kinds, no CRDs. +├── default-project.yaml The built-in `default` project emptied, so an app +│ naming `project: default` can deploy nothing. ├── root.yaml ROOT Application (app-of-apps). The ONE thing you apply by │ hand. Watches apps/ and manages the child Applications. ├── apps/ Child Applications (root reconciles this directory): @@ -34,7 +40,8 @@ deploy/argocd/ ``` operator (once) ArgoCD controller (forever) ────────────── ─────────────────────────── - kubectl apply project.yaml ─► AppProject enforces guardrails on every app + kubectl apply project.yaml ─► AppProjects enforce guardrails on every app + kubectl apply default-project.yaml ─► `default` project can deploy nothing kubectl apply root.yaml ─► root watches apps/ ──► creates child Apps │ ├─ fp-infra (wave -1) ─► fp-infra ns @@ -60,6 +67,7 @@ reverted state. No imperative `helm rollback`. # 1. Install ArgoCD into the argocd namespace (Helm or upstream manifests). # 2. Apply the guardrail, then the root. That's the entire bootstrap. kubectl apply -n argocd -f deploy/argocd/project.yaml +kubectl apply -n argocd -f deploy/argocd/default-project.yaml kubectl apply -n argocd -f deploy/argocd/root.yaml # Everything else (infra + every service) appears via the app-of-apps. ``` @@ -101,8 +109,10 @@ the diff per service is ~3 lines. (Once all 10 are truly uniform, an ArgoCD Two supported paths. **Git is always the trigger** — ArgoCD only ever reacts to a commit. -**1. CI bumps the tag in Git (default, used here).** -After build → scan → sign → push, CI rewrites the image tag in Git and pushes: +**1. CI bumps the tag in Git (the plan; NOT implemented yet).** +After build → scan → sign → push, CI would rewrite the image tag in Git and push. +Today the Security workflow stops at push + sign, and the tag is edited by hand +in a reviewed PR. The intended flow: ``` service code change @@ -182,19 +192,29 @@ and whose own `syncPolicy` is also manual, so even adding a prod app is reviewed --- -## Guardrails recap (`project.yaml`) +## Guardrails recap (`project.yaml`, `default-project.yaml`) -The AppProject is least privilege for the delivery layer itself: +The AppProjects are least privilege for the delivery layer itself: +- **Two projects.** `forgepoint-bootstrap` (root only) may create + `argoproj.io/Application` in `argocd` and nothing else. `forgepoint` (every + child app) may never write to `argocd`. Before the split, one project allowed + `argocd` as a destination *and* Secret/Role/RoleBinding, so any merged chart + could drop a cluster/repo credential Secret or a RoleBinding into Argo CD's + own namespace. - **sourceRepos** — only the forgepoint repo may be a source (supply-chain guard). -- **destinations** — only `fp-system / fp-infra / fp-models / fp-jobs` (+ `argocd` - for the child Application CRs). Nothing lands in `kube-system` / `default`. -- **clusterResourceWhitelist** — only `Namespace` and `CustomResourceDefinition`. - **No ClusterRole/ClusterRoleBinding** — a child app can't mint cluster-wide RBAC. -- **namespacedResourceWhitelist** — exactly the kinds the fp-auth chart + infra - kustomize render (Deployment, Service, ConfigMap, Secret, HPA, PDB, - NetworkPolicy, namespaced Role/RoleBinding, ServiceMonitor, ...). Deny-by-default: +- **destinations** — `forgepoint`: only `fp-system / fp-infra / fp-models / fp-jobs`. + Nothing lands in `argocd` / `kube-system` / `default`. +- **clusterResourceWhitelist** — only `Namespace`. No CRDs (a CRD write can + redefine any API group) and **no ClusterRole/ClusterRoleBinding**. +- **namespacedResourceWhitelist** — exactly the kinds the charts + infra + kustomize render (Deployment, StatefulSet, Job, Service, ConfigMap, Secret, + ServiceAccount, PVC, HPA, PDB, NetworkPolicy, ServiceMonitor). No Role or + RoleBinding: namespaced RBAC from Git is a privilege grant. Deny-by-default: add a kind here the day a chart needs it. +- **`default` project emptied** — an Application chooses its own `spec.project`, + so without this a child app could name `project: default` and bypass all of the + above. --- diff --git a/deploy/argocd/apps/fp-auth.yaml b/deploy/argocd/apps/fp-auth.yaml index 8503646..aa6b536 100644 --- a/deploy/argocd/apps/fp-auth.yaml +++ b/deploy/argocd/apps/fp-auth.yaml @@ -67,19 +67,20 @@ spec: valueFiles: - values.yaml # ---------------------------------------------------------------------- - # IMAGE TAG — the ONE value CI bumps in Git (see README "how images update"). - # The chart defaults image.tag to "" → falls back to Chart.appVersion. In a - # real GitOps flow, CI rewrites THIS line (or a values-.yaml) to the - # freshly built immutable tag (git SHA / semver), commits, and pushes. That - # Git commit is the deploy trigger — ArgoCD syncs the new tag. No cluster - # creds in CI; the only thing CI touches is Git. + # IMAGE TAG — the value a GitOps flow bumps in Git. The chart defaults + # image.tag to "" → falls back to Chart.appVersion. # - # Left empty here so the committed default (appVersion) renders; CI's job is - # to fill it. Never set ":latest" — immutable tags make rollbacks a revert. + # CURRENT STATE: NOTHING bumps it. ADR-0002 plans for CI to rewrite this + # line (or a values-.yaml) after build → scan → sign → push, but that + # step does not exist (an earlier comment here claimed "CI overwrites" it). + # Until it does, deploy a build by setting this to its published tag + # (the semver, e.g. "0.2.0", or "sha-<40-char commit>") in a reviewed PR. + # Images: ghcr.io/abd-ulbasit/forgepoint/, signed by the Security + # workflow. Never ":latest" — immutable tags make rollbacks a revert. # ---------------------------------------------------------------------- parameters: - name: image.tag - value: "" # CI overwrites with the built image's immutable tag + value: "" # empty = Chart.appVersion; set by hand until CI bumps it destination: server: https://kubernetes.default.svc diff --git a/deploy/argocd/apps/fp-billing.yaml b/deploy/argocd/apps/fp-billing.yaml index f7ecd4f..c84ece5 100644 --- a/deploy/argocd/apps/fp-billing.yaml +++ b/deploy/argocd/apps/fp-billing.yaml @@ -67,19 +67,20 @@ spec: valueFiles: - values.yaml # ---------------------------------------------------------------------- - # IMAGE TAG — the ONE value CI bumps in Git (see README "how images update"). - # The chart defaults image.tag to "" → falls back to Chart.appVersion. In a - # real GitOps flow, CI rewrites THIS line (or a values-.yaml) to the - # freshly built immutable tag (git SHA / semver), commits, and pushes. That - # Git commit is the deploy trigger — ArgoCD syncs the new tag. No cluster - # creds in CI; the only thing CI touches is Git. + # IMAGE TAG — the value a GitOps flow bumps in Git. The chart defaults + # image.tag to "" → falls back to Chart.appVersion. # - # Left empty here so the committed default (appVersion) renders; CI's job is - # to fill it. Never set ":latest" — immutable tags make rollbacks a revert. + # CURRENT STATE: NOTHING bumps it. ADR-0002 plans for CI to rewrite this + # line (or a values-.yaml) after build → scan → sign → push, but that + # step does not exist (an earlier comment here claimed "CI overwrites" it). + # Until it does, deploy a build by setting this to its published tag + # (the semver, e.g. "0.2.0", or "sha-<40-char commit>") in a reviewed PR. + # Images: ghcr.io/abd-ulbasit/forgepoint/, signed by the Security + # workflow. Never ":latest" — immutable tags make rollbacks a revert. # ---------------------------------------------------------------------- parameters: - name: image.tag - value: "" # CI overwrites with the built image's immutable tag + value: "" # empty = Chart.appVersion; set by hand until CI bumps it destination: server: https://kubernetes.default.svc diff --git a/deploy/argocd/apps/fp-experiment-tracker.yaml b/deploy/argocd/apps/fp-experiment-tracker.yaml index 59f4885..1021916 100644 --- a/deploy/argocd/apps/fp-experiment-tracker.yaml +++ b/deploy/argocd/apps/fp-experiment-tracker.yaml @@ -68,19 +68,20 @@ spec: valueFiles: - values.yaml # ---------------------------------------------------------------------- - # IMAGE TAG — the ONE value CI bumps in Git (see README "how images update"). - # The chart defaults image.tag to "" → falls back to Chart.appVersion. In a - # real GitOps flow, CI rewrites THIS line (or a values-.yaml) to the - # freshly built immutable tag (git SHA / semver), commits, and pushes. That - # Git commit is the deploy trigger — ArgoCD syncs the new tag. No cluster - # creds in CI; the only thing CI touches is Git. + # IMAGE TAG — the value a GitOps flow bumps in Git. The chart defaults + # image.tag to "" → falls back to Chart.appVersion. # - # Left empty here so the committed default (appVersion) renders; CI's job is - # to fill it. Never set ":latest" — immutable tags make rollbacks a revert. + # CURRENT STATE: NOTHING bumps it. ADR-0002 plans for CI to rewrite this + # line (or a values-.yaml) after build → scan → sign → push, but that + # step does not exist (an earlier comment here claimed "CI overwrites" it). + # Until it does, deploy a build by setting this to its published tag + # (the semver, e.g. "0.2.0", or "sha-<40-char commit>") in a reviewed PR. + # Images: ghcr.io/abd-ulbasit/forgepoint/, signed by the Security + # workflow. Never ":latest" — immutable tags make rollbacks a revert. # ---------------------------------------------------------------------- parameters: - name: image.tag - value: "" # CI overwrites with the built image's immutable tag + value: "" # empty = Chart.appVersion; set by hand until CI bumps it destination: server: https://kubernetes.default.svc diff --git a/deploy/argocd/apps/fp-feature-store.yaml b/deploy/argocd/apps/fp-feature-store.yaml index 3e60100..21831a4 100644 --- a/deploy/argocd/apps/fp-feature-store.yaml +++ b/deploy/argocd/apps/fp-feature-store.yaml @@ -62,19 +62,20 @@ spec: valueFiles: - values.yaml # ---------------------------------------------------------------------- - # IMAGE TAG — the ONE value CI bumps in Git (see README "how images update"). - # The chart defaults image.tag to "" → falls back to Chart.appVersion. In a - # real GitOps flow, CI rewrites THIS line (or a values-.yaml) to the - # freshly built immutable tag (git SHA / semver), commits, and pushes. That - # Git commit is the deploy trigger — ArgoCD syncs the new tag. No cluster - # creds in CI; the only thing CI touches is Git. + # IMAGE TAG — the value a GitOps flow bumps in Git. The chart defaults + # image.tag to "" → falls back to Chart.appVersion. # - # Left empty here so the committed default (appVersion) renders; CI's job is - # to fill it. Never set ":latest" — immutable tags make rollbacks a revert. + # CURRENT STATE: NOTHING bumps it. ADR-0002 plans for CI to rewrite this + # line (or a values-.yaml) after build → scan → sign → push, but that + # step does not exist (an earlier comment here claimed "CI overwrites" it). + # Until it does, deploy a build by setting this to its published tag + # (the semver, e.g. "0.2.0", or "sha-<40-char commit>") in a reviewed PR. + # Images: ghcr.io/abd-ulbasit/forgepoint/, signed by the Security + # workflow. Never ":latest" — immutable tags make rollbacks a revert. # ---------------------------------------------------------------------- parameters: - name: image.tag - value: "" # CI overwrites with the built image's immutable tag + value: "" # empty = Chart.appVersion; set by hand until CI bumps it destination: server: https://kubernetes.default.svc diff --git a/deploy/argocd/apps/fp-inference-gateway.yaml b/deploy/argocd/apps/fp-inference-gateway.yaml index 9193edd..e61ad5b 100644 --- a/deploy/argocd/apps/fp-inference-gateway.yaml +++ b/deploy/argocd/apps/fp-inference-gateway.yaml @@ -74,19 +74,20 @@ spec: valueFiles: - values.yaml # ---------------------------------------------------------------------- - # IMAGE TAG — the ONE value CI bumps in Git (see README "how images update"). - # The chart defaults image.tag to "" → falls back to Chart.appVersion. In a - # real GitOps flow, CI rewrites THIS line (or a values-.yaml) to the - # freshly built immutable tag (git SHA / semver), commits, and pushes. That - # Git commit is the deploy trigger — ArgoCD syncs the new tag. No cluster - # creds in CI; the only thing CI touches is Git. + # IMAGE TAG — the value a GitOps flow bumps in Git. The chart defaults + # image.tag to "" → falls back to Chart.appVersion. # - # Left empty here so the committed default (appVersion) renders; CI's job is - # to fill it. Never set ":latest" — immutable tags make rollbacks a revert. + # CURRENT STATE: NOTHING bumps it. ADR-0002 plans for CI to rewrite this + # line (or a values-.yaml) after build → scan → sign → push, but that + # step does not exist (an earlier comment here claimed "CI overwrites" it). + # Until it does, deploy a build by setting this to its published tag + # (the semver, e.g. "0.2.0", or "sha-<40-char commit>") in a reviewed PR. + # Images: ghcr.io/abd-ulbasit/forgepoint/, signed by the Security + # workflow. Never ":latest" — immutable tags make rollbacks a revert. # ---------------------------------------------------------------------- parameters: - name: image.tag - value: "" # CI overwrites with the built image's immutable tag + value: "" # empty = Chart.appVersion; set by hand until CI bumps it destination: server: https://kubernetes.default.svc diff --git a/deploy/argocd/apps/fp-model-monitor.yaml b/deploy/argocd/apps/fp-model-monitor.yaml index 80035b6..ade67d0 100644 --- a/deploy/argocd/apps/fp-model-monitor.yaml +++ b/deploy/argocd/apps/fp-model-monitor.yaml @@ -63,19 +63,20 @@ spec: valueFiles: - values.yaml # ---------------------------------------------------------------------- - # IMAGE TAG — the ONE value CI bumps in Git (see README "how images update"). - # The chart defaults image.tag to "" → falls back to Chart.appVersion. In a - # real GitOps flow, CI rewrites THIS line (or a values-.yaml) to the - # freshly built immutable tag (git SHA / semver), commits, and pushes. That - # Git commit is the deploy trigger — ArgoCD syncs the new tag. No cluster - # creds in CI; the only thing CI touches is Git. + # IMAGE TAG — the value a GitOps flow bumps in Git. The chart defaults + # image.tag to "" → falls back to Chart.appVersion. # - # Left empty here so the committed default (appVersion) renders; CI's job is - # to fill it. Never set ":latest" — immutable tags make rollbacks a revert. + # CURRENT STATE: NOTHING bumps it. ADR-0002 plans for CI to rewrite this + # line (or a values-.yaml) after build → scan → sign → push, but that + # step does not exist (an earlier comment here claimed "CI overwrites" it). + # Until it does, deploy a build by setting this to its published tag + # (the semver, e.g. "0.2.0", or "sha-<40-char commit>") in a reviewed PR. + # Images: ghcr.io/abd-ulbasit/forgepoint/, signed by the Security + # workflow. Never ":latest" — immutable tags make rollbacks a revert. # ---------------------------------------------------------------------- parameters: - name: image.tag - value: "" # CI overwrites with the built image's immutable tag + value: "" # empty = Chart.appVersion; set by hand until CI bumps it destination: server: https://kubernetes.default.svc diff --git a/deploy/argocd/apps/fp-model-serving.yaml b/deploy/argocd/apps/fp-model-serving.yaml index 976c346..1561ecc 100644 --- a/deploy/argocd/apps/fp-model-serving.yaml +++ b/deploy/argocd/apps/fp-model-serving.yaml @@ -56,19 +56,20 @@ spec: valueFiles: - values.yaml # ---------------------------------------------------------------------- - # IMAGE TAG — the ONE value CI bumps in Git (see README "how images update"). - # The chart defaults image.tag to "" → falls back to Chart.appVersion. In a - # real GitOps flow, CI rewrites THIS line (or a values-.yaml) to the - # freshly built immutable tag (git SHA / semver), commits, and pushes. That - # Git commit is the deploy trigger — ArgoCD syncs the new tag. No cluster - # creds in CI; the only thing CI touches is Git. + # IMAGE TAG — the value a GitOps flow bumps in Git. The chart defaults + # image.tag to "" → falls back to Chart.appVersion. # - # Left empty here so the committed default (appVersion) renders; CI's job is - # to fill it. Never set ":latest" — immutable tags make rollbacks a revert. + # CURRENT STATE: NOTHING bumps it. ADR-0002 plans for CI to rewrite this + # line (or a values-.yaml) after build → scan → sign → push, but that + # step does not exist (an earlier comment here claimed "CI overwrites" it). + # Until it does, deploy a build by setting this to its published tag + # (the semver, e.g. "0.2.0", or "sha-<40-char commit>") in a reviewed PR. + # Images: ghcr.io/abd-ulbasit/forgepoint/, signed by the Security + # workflow. Never ":latest" — immutable tags make rollbacks a revert. # ---------------------------------------------------------------------- parameters: - name: image.tag - value: "" # CI overwrites with the built image's immutable tag + value: "" # empty = Chart.appVersion; set by hand until CI bumps it destination: server: https://kubernetes.default.svc diff --git a/deploy/argocd/apps/fp-notification.yaml b/deploy/argocd/apps/fp-notification.yaml index ea38a6d..5105fc7 100644 --- a/deploy/argocd/apps/fp-notification.yaml +++ b/deploy/argocd/apps/fp-notification.yaml @@ -69,19 +69,20 @@ spec: valueFiles: - values.yaml # ---------------------------------------------------------------------- - # IMAGE TAG — the ONE value CI bumps in Git (see README "how images update"). - # The chart defaults image.tag to "" → falls back to Chart.appVersion. In a - # real GitOps flow, CI rewrites THIS line (or a values-.yaml) to the - # freshly built immutable tag (git SHA / semver), commits, and pushes. That - # Git commit is the deploy trigger — ArgoCD syncs the new tag. No cluster - # creds in CI; the only thing CI touches is Git. + # IMAGE TAG — the value a GitOps flow bumps in Git. The chart defaults + # image.tag to "" → falls back to Chart.appVersion. # - # Left empty here so the committed default (appVersion) renders; CI's job is - # to fill it. Never set ":latest" — immutable tags make rollbacks a revert. + # CURRENT STATE: NOTHING bumps it. ADR-0002 plans for CI to rewrite this + # line (or a values-.yaml) after build → scan → sign → push, but that + # step does not exist (an earlier comment here claimed "CI overwrites" it). + # Until it does, deploy a build by setting this to its published tag + # (the semver, e.g. "0.2.0", or "sha-<40-char commit>") in a reviewed PR. + # Images: ghcr.io/abd-ulbasit/forgepoint/, signed by the Security + # workflow. Never ":latest" — immutable tags make rollbacks a revert. # ---------------------------------------------------------------------- parameters: - name: image.tag - value: "" # CI overwrites with the built image's immutable tag + value: "" # empty = Chart.appVersion; set by hand until CI bumps it destination: server: https://kubernetes.default.svc diff --git a/deploy/argocd/apps/fp-pipeline-orchestrator.yaml b/deploy/argocd/apps/fp-pipeline-orchestrator.yaml index f5b01a1..c8a3ab1 100644 --- a/deploy/argocd/apps/fp-pipeline-orchestrator.yaml +++ b/deploy/argocd/apps/fp-pipeline-orchestrator.yaml @@ -71,19 +71,20 @@ spec: valueFiles: - values.yaml # ---------------------------------------------------------------------- - # IMAGE TAG — the ONE value CI bumps in Git (see README "how images update"). - # The chart defaults image.tag to "" → falls back to Chart.appVersion. In a - # real GitOps flow, CI rewrites THIS line (or a values-.yaml) to the - # freshly built immutable tag (git SHA / semver), commits, and pushes. That - # Git commit is the deploy trigger — ArgoCD syncs the new tag. No cluster - # creds in CI; the only thing CI touches is Git. + # IMAGE TAG — the value a GitOps flow bumps in Git. The chart defaults + # image.tag to "" → falls back to Chart.appVersion. # - # Left empty here so the committed default (appVersion) renders; CI's job is - # to fill it. Never set ":latest" — immutable tags make rollbacks a revert. + # CURRENT STATE: NOTHING bumps it. ADR-0002 plans for CI to rewrite this + # line (or a values-.yaml) after build → scan → sign → push, but that + # step does not exist (an earlier comment here claimed "CI overwrites" it). + # Until it does, deploy a build by setting this to its published tag + # (the semver, e.g. "0.2.0", or "sha-<40-char commit>") in a reviewed PR. + # Images: ghcr.io/abd-ulbasit/forgepoint/, signed by the Security + # workflow. Never ":latest" — immutable tags make rollbacks a revert. # ---------------------------------------------------------------------- parameters: - name: image.tag - value: "" # CI overwrites with the built image's immutable tag + value: "" # empty = Chart.appVersion; set by hand until CI bumps it destination: server: https://kubernetes.default.svc diff --git a/deploy/argocd/apps/fp-registry.yaml b/deploy/argocd/apps/fp-registry.yaml index f8549b2..2461977 100644 --- a/deploy/argocd/apps/fp-registry.yaml +++ b/deploy/argocd/apps/fp-registry.yaml @@ -65,19 +65,20 @@ spec: valueFiles: - values.yaml # ---------------------------------------------------------------------- - # IMAGE TAG — the ONE value CI bumps in Git (see README "how images update"). - # The chart defaults image.tag to "" → falls back to Chart.appVersion. In a - # real GitOps flow, CI rewrites THIS line (or a values-.yaml) to the - # freshly built immutable tag (git SHA / semver), commits, and pushes. That - # Git commit is the deploy trigger — ArgoCD syncs the new tag. No cluster - # creds in CI; the only thing CI touches is Git. + # IMAGE TAG — the value a GitOps flow bumps in Git. The chart defaults + # image.tag to "" → falls back to Chart.appVersion. # - # Left empty here so the committed default (appVersion) renders; CI's job is - # to fill it. Never set ":latest" — immutable tags make rollbacks a revert. + # CURRENT STATE: NOTHING bumps it. ADR-0002 plans for CI to rewrite this + # line (or a values-.yaml) after build → scan → sign → push, but that + # step does not exist (an earlier comment here claimed "CI overwrites" it). + # Until it does, deploy a build by setting this to its published tag + # (the semver, e.g. "0.2.0", or "sha-<40-char commit>") in a reviewed PR. + # Images: ghcr.io/abd-ulbasit/forgepoint/, signed by the Security + # workflow. Never ":latest" — immutable tags make rollbacks a revert. # ---------------------------------------------------------------------- parameters: - name: image.tag - value: "" # CI overwrites with the built image's immutable tag + value: "" # empty = Chart.appVersion; set by hand until CI bumps it destination: server: https://kubernetes.default.svc diff --git a/deploy/argocd/default-project.yaml b/deploy/argocd/default-project.yaml new file mode 100644 index 0000000..e97d0bb --- /dev/null +++ b/deploy/argocd/default-project.yaml @@ -0,0 +1,27 @@ +# ============================================================================ +# The built-in `default` AppProject, locked to nothing +# ============================================================================ +# Argo CD creates a `default` project that allows any repo, any cluster, any +# namespace and any kind. The root app (project forgepoint-bootstrap) may create +# Application objects, and an Application chooses its own `spec.project`, so a +# child Application merged to main that says `project: default` would escape +# every guardrail in project.yaml. Emptying `default` closes that door: an +# Application in it can deploy nothing. +# +# Apply once, by hand, with the other projects (it is not under apps/, so the +# root app never syncs it): +# kubectl apply -n argocd -f deploy/argocd/default-project.yaml +# Check first that nothing else in the cluster relies on `default`: +# kubectl -n argocd get applications -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.project}{"\n"}{end}' +# ============================================================================ +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: default + namespace: argocd +spec: + description: Locked down. Use the forgepoint or forgepoint-bootstrap project. + sourceRepos: [] + destinations: [] + clusterResourceWhitelist: [] + namespacedResourceWhitelist: [] diff --git a/deploy/argocd/project.yaml b/deploy/argocd/project.yaml index 5774ef7..0b9e25a 100644 --- a/deploy/argocd/project.yaml +++ b/deploy/argocd/project.yaml @@ -1,25 +1,67 @@ # ============================================================================ -# ARGOCD APPPROJECT — forgepoint +# ARGOCD APPPROJECTS — forgepoint-bootstrap (root app) + forgepoint (workloads) # ============================================================================ # An AppProject is ArgoCD's TENANCY + GUARDRAIL boundary. Every Application # belongs to exactly one project, and the project caps what those Applications # are ALLOWED to do, regardless of what their manifests ask for. Think of it as # an RBAC + admission-policy envelope around a set of apps. # -# WHY a dedicated project (not the built-in "default")? -# The "default" project is wide open: any repo, any cluster, any namespace, -# any resource kind. That is fine for a toy, dangerous for a platform. A -# compromised or fat-fingered Application in `default` could deploy a -# cluster-admin ClusterRoleBinding into kube-system. Scoping a project to -# "only this repo, only fp-* namespaces, only these kinds" is LEAST PRIVILEGE -# applied to the delivery layer itself. +# WHY TWO PROJECTS (this used to be one): +# The single "forgepoint" project allowed the `argocd` namespace as a +# destination (so the root app could create child Applications) AND +# whitelisted Secret, Role and RoleBinding. Together that meant ANY chart or +# manifest merged to main could write a Secret into `argocd` (e.g. a cluster +# or repository credential Secret with argocd.argoproj.io/secret-type) or a +# RoleBinding granting itself read on Argo CD's own secrets: privilege +# escalation through Git, auto-synced. It also never whitelisted the +# Application kind, which the root app-of-apps exists to create. # -# HOW GitOps IS STOPPED FROM BECOMING A CLUSTER-ADMIN BACKDOOR: this object — +# Now: +# - forgepoint-bootstrap (root.yaml only): may create ONE kind, +# argoproj.io/Application, and only in `argocd`. Nothing else. +# - forgepoint (every child app): fp-* namespaces only, never `argocd`, no +# RBAC kinds, no CRDs. +# - default: locked to nothing (default-project.yaml), so a child Application +# that names `project: default` cannot escape both of the above. +# +# HOW GitOps IS STOPPED FROM BECOMING A CLUSTER-ADMIN BACKDOOR: these objects — # the sourceRepos allow-list, the destinations allow-list, and the -# namespaced/clusterResource allow-lists below. +# namespaced/clusterResource allow-lists below. They are applied by hand +# (kubectl), never synced by the root app, so a Git change cannot widen them. # ============================================================================ apiVersion: argoproj.io/v1alpha1 kind: AppProject +metadata: + name: forgepoint-bootstrap + namespace: argocd + labels: + app.kubernetes.io/part-of: forgepoint +spec: + description: Root app-of-apps only — may create Application objects in argocd, nothing else. + + sourceRepos: + - https://github.com/abd-ulbasit/forgepoint.git + + # The child Application CRs live in the namespace Argo CD runs in. + destinations: + - server: https://kubernetes.default.svc + namespace: argocd + + # No cluster-scoped kinds at all. + clusterResourceWhitelist: [] + + # Exactly one kind. In particular NOT Secret (Argo CD reads cluster and repo + # credentials from Secrets in this namespace) and NOT AppProject (a project + # that could edit projects could lift its own limits). + namespacedResourceWhitelist: + - group: argoproj.io + kind: Application + + orphanedResources: + warn: true +--- +apiVersion: argoproj.io/v1alpha1 +kind: AppProject metadata: name: forgepoint # AppProjects live in the namespace ArgoCD itself runs in (conventionally @@ -37,26 +79,19 @@ spec: # -------------------------------------------------------------------------- # sourceRepos — WHICH Git repos Applications in this project may pull from. # A wildcard "*" would let anyone point an app at an arbitrary repo (supply- - # chain risk). We pin to this one mono-repo. Add more entries only when a - # second trusted repo genuinely exists (e.g. a separate Helm chart registry). - # - # REPO_URL placeholder: this is THE forgepoint repo. Keep it generic; no creds - # belong here. For a private repo, ArgoCD reads credentials from a separately - # managed `repo-creds` Secret (label argocd.argoproj.io/secret-type=repository) - # — never inline a token in this manifest. + # chain risk). We pin to this one mono-repo. For a private repo, ArgoCD reads + # credentials from a separately managed `repo-creds` Secret (label + # argocd.argoproj.io/secret-type=repository) — never inline a token here. # -------------------------------------------------------------------------- sourceRepos: - https://github.com/abd-ulbasit/forgepoint.git # -------------------------------------------------------------------------- # destinations — WHICH (cluster, namespace) pairs apps may deploy into. - # We allow only the four Forgepoint namespaces, all on the in-cluster server - # (https://kubernetes.default.svc = the cluster ArgoCD runs in). Anything - # outside fp-* (kube-system, argocd, default) is denied even if a child app - # asks for it. This is the namespace half of least privilege. - # - # Multi-cluster later: to deploy prod to a remote cluster, add a destination - # with that cluster's API server URL (registered as an ArgoCD cluster Secret). + # Only the four Forgepoint namespaces on the in-cluster server. `argocd`, + # kube-system and default are denied even if a child app asks for them. + # (`argocd` used to be listed here for the root app; it now has its own + # project, forgepoint-bootstrap.) # -------------------------------------------------------------------------- destinations: - server: https://kubernetes.default.svc @@ -67,43 +102,34 @@ spec: namespace: fp-models - server: https://kubernetes.default.svc namespace: fp-jobs - # The root app-of-apps creates CHILD Applications, which are themselves - # objects living in the `argocd` namespace. Allow that one namespace so the - # project can manage its own Application CRs (app-of-apps needs this). - - server: https://kubernetes.default.svc - namespace: argocd # -------------------------------------------------------------------------- # clusterResourceWhitelist — CLUSTER-SCOPED kinds apps may create. - # Cluster-scoped resources have no namespace, so destinations can't gate them; - # this list is the only guard. We allow exactly two: - # Namespace — infra creates fp-infra/fp-system/fp-models/fp-jobs. - # CustomResourceDefinition — reserved for future operators we install via - # GitOps (e.g. Prometheus Operator, Argo Rollouts). - # NOTE the conspicuous ABSENCE of ClusterRole / ClusterRoleBinding here: no - # child app may mint cluster-wide RBAC. That is the single most important - # privilege to withhold from a delivery controller. + # Only Namespace (infra creates fp-infra/fp-system/fp-models/fp-jobs). + # CustomResourceDefinition was listed "for future operators"; nothing creates + # one, and a CRD write can replace the schema of ANY API group in the + # cluster, so it is removed until an operator genuinely needs it (and then + # belongs in its own project). No ClusterRole / ClusterRoleBinding, ever. # -------------------------------------------------------------------------- clusterResourceWhitelist: - group: "" kind: Namespace - - group: apiextensions.k8s.io - kind: CustomResourceDefinition # -------------------------------------------------------------------------- # namespacedResourceWhitelist — NAMESPACED kinds apps may create. - # This is an ALLOW-list (deny-by-default): if a kind isn't named here, a child - # app cannot create it. It covers exactly what the fp-auth reference chart and - # the infra kustomize render today: - # workloads Deployment, StatefulSet, Pod, Service, ConfigMap, Secret, - # ServiceAccount, PersistentVolumeClaim + # Deny-by-default. Exactly what the fp-* charts and deploy/k8s/infra render + # today (checked with `helm template` / the infra manifests): + # workloads Deployment, StatefulSet, Job (the MinIO bucket init), + # Service, ConfigMap, Secret, ServiceAccount, + # PersistentVolumeClaim # scaling/avail HorizontalPodAutoscaler, PodDisruptionBudget - # security NetworkPolicy, Role, RoleBinding (namespaced RBAC is OK; - # cluster RBAC is not — see whitelist above) + # network NetworkPolicy # operator CRs ServiceMonitor (Prometheus Operator) - # Add a kind here the day a chart needs it (e.g. Rollout, Ingress, KEDA - # ScaledObject) — a missing entry yields a clear "resource not permitted in - # project" sync error rather than a silent deploy of something unexpected. + # Role/RoleBinding were whitelisted but nothing renders them; namespaced RBAC + # written from Git is a privilege grant, so add it back only with a reason. + # batch/Job was MISSING although the infra kustomization renders one, so the + # fp-infra sync could not have succeeded. Secret stays (infra placeholders and + # the charts' optional dev Secret), but only in fp-* namespaces now. # -------------------------------------------------------------------------- namespacedResourceWhitelist: - group: "" @@ -120,24 +146,20 @@ spec: kind: Deployment - group: apps kind: StatefulSet + - group: batch + kind: Job - group: autoscaling kind: HorizontalPodAutoscaler - group: policy kind: PodDisruptionBudget - group: networking.k8s.io kind: NetworkPolicy - - group: rbac.authorization.k8s.io - kind: Role - - group: rbac.authorization.k8s.io - kind: RoleBinding - group: monitoring.coreos.com kind: ServiceMonitor # -------------------------------------------------------------------------- # orphanedResources — surface (don't auto-delete) resources that exist in a - # project namespace but aren't tracked by any Application. warn:true flags them - # in the UI as a hygiene signal without taking destructive action. We keep this - # informational; prune (below, per-app) handles deletion of MANAGED resources. + # project namespace but aren't tracked by any Application. # -------------------------------------------------------------------------- orphanedResources: warn: true diff --git a/deploy/argocd/root.yaml b/deploy/argocd/root.yaml index 20f08d8..eef82ac 100644 --- a/deploy/argocd/root.yaml +++ b/deploy/argocd/root.yaml @@ -51,9 +51,12 @@ metadata: labels: app.kubernetes.io/part-of: forgepoint spec: - # Bind to the guardrail project from project.yaml. The root only manages - # Application CRs in the `argocd` namespace, which the project permits. - project: forgepoint + # Bind to the bootstrap project from project.yaml. It permits exactly one + # thing: Application objects in the `argocd` namespace. The child apps it + # creates run under the separate `forgepoint` project, which cannot touch + # `argocd` at all. (The root used to share that project, which is why the + # workload project had to allow writes into `argocd`.) + project: forgepoint-bootstrap source: # REPO_URL — the one forgepoint mono-repo (must match an entry in the From 753661d4c8836448a2084ef161421d36d7128dfd Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 00:59:47 +0500 Subject: [PATCH 25/42] rollouts: pin images, drop the phantom fetcher, query the real Prometheus The canary path was broken as written: - Both Rollouts ran :latest images. Kyverno's disallow-latest-tag flags that, and rollback means nothing when the "previous" version is also :latest. - model-serving's Rollout ran a model-artifact-fetcher:latest initContainer. That image was never built (there is no services/model-artifact-fetcher), so every canary pod would sit in ImagePullBackOff. model-serving fetches artifacts in-process into the OS temp dir. - All five AnalysisTemplate queries used prometheus-operated.fp-infra.svc, the Service name the Prometheus Operator creates. This repo runs plain Prometheus, whose Service is `prometheus` (deploy/k8s/observability/prometheus/prometheus.yaml), so every analysis run would fail and abort the rollout. Changes: - Images: ghcr.io/abd-ulbasit/forgepoint/{inference-gateway,model-serving} at 0.1.0 (Chart.appVersion), with the tag set in one place, an images: block in kustomization.yaml. Comments say how to bump it. - model-serving: the fetcher initContainer and the /models volume are removed. A /tmp emptyDir (sizeLimit 2Gi) matches the Helm chart. - AnalysisTemplates and the README point at http://prometheus.fp-infra.svc.cluster.local:9090. `kubectl kustomize deploy/rollouts` renders the pinned images and the new address. Not applied to a cluster. Not changed: the ECR lifecycle cap of 20 tagged images also limits how far back a rollback can go, but nothing pushes to ECR yet, so it is left for when ECR is used. Co-Authored-By: Claude Opus 5.5 --- deploy/rollouts/README.md | 9 ++- .../analysis-template-inference-gateway.yaml | 4 +- .../analysis-template-model-serving.yaml | 6 +- deploy/rollouts/kustomization.yaml | 10 +++ .../rollouts/rollout-inference-gateway.yaml | 9 +-- deploy/rollouts/rollout-model-serving.yaml | 68 ++++++------------- 6 files changed, 49 insertions(+), 57 deletions(-) diff --git a/deploy/rollouts/README.md b/deploy/rollouts/README.md index 4a649f8..6f0e9d7 100644 --- a/deploy/rollouts/README.md +++ b/deploy/rollouts/README.md @@ -96,9 +96,14 @@ PDB, ServiceMonitor) remain managed by Helm. The Rollout owns only the pod templ The AnalysisTemplates query: ``` -http://prometheus-operated.fp-infra.svc.cluster.local:9090 +http://prometheus.fp-infra.svc.cluster.local:9090 ``` +That is the `prometheus` Service in `deploy/k8s/observability/prometheus/`. (Earlier +revisions pointed at `prometheus-operated`, the Service name the Prometheus +*Operator* creates; this repo runs plain Prometheus, so that name never resolved +and every analysis run would have failed.) + This is the kube-prometheus-stack (or Prometheus Operator) address. Adjust if your Prometheus service has a different name or namespace. @@ -164,7 +169,7 @@ instruments OpenTelemetry metrics: 1. Find the actual metric names: ```bash - kubectl port-forward svc/prometheus-operated 9090:9090 -n fp-infra + kubectl port-forward svc/prometheus 9090:9090 -n fp-infra # Open http://localhost:9090 and search for "forgepoint_" or "grpc_server_" ``` diff --git a/deploy/rollouts/analysis-template-inference-gateway.yaml b/deploy/rollouts/analysis-template-inference-gateway.yaml index b0b54d6..8cda2c4 100644 --- a/deploy/rollouts/analysis-template-inference-gateway.yaml +++ b/deploy/rollouts/analysis-template-inference-gateway.yaml @@ -92,7 +92,7 @@ spec: # Prometheus endpoint — the in-cluster address of the Prometheus # server deployed in Phase 10 (or the OTel Collector's Prometheus # remote-write receiver). - address: http://prometheus-operated.fp-infra.svc.cluster.local:9090 + address: http://prometheus.fp-infra.svc.cluster.local:9090 # Query: 1 - (error_rate). Uses the `service` arg from the Rollout. # PLACEHOLDER: replace metric names with actual OTel-emitted names. @@ -120,7 +120,7 @@ spec: provider: prometheus: - address: http://prometheus-operated.fp-infra.svc.cluster.local:9090 + address: http://prometheus.fp-infra.svc.cluster.local:9090 # histogram_quantile over the grpc/http duration histogram. # PLACEHOLDER: replace with the actual OTel duration histogram metric name. diff --git a/deploy/rollouts/analysis-template-model-serving.yaml b/deploy/rollouts/analysis-template-model-serving.yaml index f145830..6e665cb 100644 --- a/deploy/rollouts/analysis-template-model-serving.yaml +++ b/deploy/rollouts/analysis-template-model-serving.yaml @@ -58,7 +58,7 @@ spec: provider: prometheus: - address: http://prometheus-operated.fp-infra.svc.cluster.local:9090 + address: http://prometheus.fp-infra.svc.cluster.local:9090 # PLACEHOLDER: replace with actual OTel-emitted metric name for # model-serving gRPC errors (e.g. grpc_server_handled_total with @@ -98,7 +98,7 @@ spec: provider: prometheus: - address: http://prometheus-operated.fp-infra.svc.cluster.local:9090 + address: http://prometheus.fp-infra.svc.cluster.local:9090 # PLACEHOLDER: replace with the actual gRPC server duration histogram. # grpc_server_handling_seconds_bucket is the typical name from the @@ -155,7 +155,7 @@ spec: provider: prometheus: - address: http://prometheus-operated.fp-infra.svc.cluster.local:9090 + address: http://prometheus.fp-infra.svc.cluster.local:9090 # PLACEHOLDER: replace with the actual Prometheus metric name that # model-monitor exposes for drift score. This is a gauge that diff --git a/deploy/rollouts/kustomization.yaml b/deploy/rollouts/kustomization.yaml index fe3f466..f12856a 100644 --- a/deploy/rollouts/kustomization.yaml +++ b/deploy/rollouts/kustomization.yaml @@ -75,6 +75,16 @@ resources: # model-serving: success-rate + latency + drift-score (closed-loop gate). - analysis-template-model-serving.yaml +# THE deployed image tags, in one place. Bump with e.g. +# kustomize edit set image ghcr.io/abd-ulbasit/forgepoint/model-serving:0.2.0 +# to a tag the Security workflow published (semver or sha-<40>). 0.1.0 matches +# Chart.appVersion, the tag the Helm charts fall back to. +images: + - name: ghcr.io/abd-ulbasit/forgepoint/inference-gateway + newTag: "0.1.0" + - name: ghcr.io/abd-ulbasit/forgepoint/model-serving + newTag: "0.1.0" + labels: - pairs: forgepoint.io/managed-by-phase: "21" diff --git a/deploy/rollouts/rollout-inference-gateway.yaml b/deploy/rollouts/rollout-inference-gateway.yaml index 2d48ebd..586910c 100644 --- a/deploy/rollouts/rollout-inference-gateway.yaml +++ b/deploy/rollouts/rollout-inference-gateway.yaml @@ -123,11 +123,12 @@ spec: containers: - name: inference-gateway - # Image tag is overridden per deploy via: + # Pinned tag (never :latest, which Kyverno disallow-latest-tag rejects and + # which makes rollback meaningless). Set the deployed tag in ONE place, + # the images: block of kustomization.yaml (or for a one-off canary: # kubectl argo rollouts set image fp-inference-gateway \ - # inference-gateway=ghcr.io/abd-ulbasit/forgepoint/inference-gateway: - # or via ArgoCD image updater. - image: ghcr.io/abd-ulbasit/forgepoint/inference-gateway:latest + # inference-gateway=ghcr.io/abd-ulbasit/forgepoint/inference-gateway:). + image: ghcr.io/abd-ulbasit/forgepoint/inference-gateway:0.1.0 imagePullPolicy: IfNotPresent ports: diff --git a/deploy/rollouts/rollout-model-serving.yaml b/deploy/rollouts/rollout-model-serving.yaml index 59fc14c..81c6ed6 100644 --- a/deploy/rollouts/rollout-model-serving.yaml +++ b/deploy/rollouts/rollout-model-serving.yaml @@ -6,8 +6,8 @@ # MODEL SERVING CANARY — ADDITIONAL CONSIDERATIONS # -------------------------------------------------- # model-serving is DIFFERENT from inference-gateway in one critical way: -# it runs a sidecar-based ONNX serving pattern where the sidecar (the model -# file downloader + ONNX runtime) and the main container are tightly coupled. +# the binary fetches model artifacts itself (in-process ModelFetcher) and +# serves them, so the code and the model it loads are tightly coupled. # A "new version" of model-serving may mean: # (a) a new service binary (Go code change), OR # (b) a new model version artifact (model weights change), OR @@ -92,48 +92,21 @@ spec: type: RuntimeDefault # ----------------------------------------------------------------------- - # Sidecar pattern: model-artifact-fetcher runs first (initContainer) to - # download model weights into a shared emptyDir; the ONNX runtime in the - # main container reads from that volume. This matches the Phase 3 design - # (Model Serving — Sidecar, HPA on custom metrics). - # The sidecar image tag is separately versioned from the main container; - # update them independently via `kubectl argo rollouts set image`. + # No init/sidecar fetcher. An earlier revision ran a + # "model-artifact-fetcher:latest" initContainer here; that image was never + # built (there is no such directory under services/), so every canary pod + # would have sat in ImagePullBackOff. model-serving fetches artifacts + # IN-PROCESS (ModelFetcher: file:// and http(s)://, see + # services/model-serving/cmd/server/main.go) into its scratch dir, which + # defaults to the OS temp dir: /tmp below, the same emptyDir the Helm + # chart mounts. # ----------------------------------------------------------------------- - initContainers: - - name: model-artifact-fetcher - image: ghcr.io/abd-ulbasit/forgepoint/model-artifact-fetcher:latest - imagePullPolicy: IfNotPresent - command: - - /fetcher - - --artifact-path=$(MODEL_ARTIFACT_PATH) - - --output-dir=/models - envFrom: - - configMapRef: - name: fp-model-serving - - secretRef: - name: fp-model-serving - volumeMounts: - - name: model-weights - mountPath: /models - securityContext: - allowPrivilegeEscalation: false - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 65532 - capabilities: - drop: - - ALL - resources: - requests: - cpu: 50m - memory: 64Mi - limits: - cpu: 200m - memory: 256Mi - containers: - name: model-serving - image: ghcr.io/abd-ulbasit/forgepoint/model-serving:latest + # Pinned tag (never :latest, which Kyverno disallow-latest-tag rejects and + # which makes rollback meaningless). The deployed tag is set in ONE + # place, the images: block of kustomization.yaml; 0.1.0 = Chart.appVersion. + image: ghcr.io/abd-ulbasit/forgepoint/model-serving:0.1.0 imagePullPolicy: IfNotPresent ports: @@ -151,9 +124,9 @@ spec: name: fp-model-serving volumeMounts: - - name: model-weights - mountPath: /models - readOnly: true + # Writable scratch for the fetched artifact (read-only root FS). + - name: tmp + mountPath: /tmp securityContext: allowPrivilegeEscalation: false @@ -201,8 +174,11 @@ spec: timeoutSeconds: 3 volumes: - - name: model-weights - emptyDir: {} + - name: tmp + # Same as the chart: node-disk-backed, capped so an oversized artifact + # cannot fill the node. + emptyDir: + sizeLimit: 2Gi strategy: canary: From c8207ac17e5be0e49b09535355bcc12234340981 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:03:27 +0500 Subject: [PATCH 26/42] ci(security): scan the full git history for secrets with gitleaks Trivy's secret scanner only reads the working tree, and there was no pre-commit hook. A secret committed and later removed was invisible to every gate while it stayed in every clone. A dev JWT key was in fact committed at some point. - New `gitleaks` job in security.yml: checkout with fetch-depth 0, build gitleaks v8.30.1 with `go install` (module checksum DB verified, like govulncheck) rather than a binary download or a third-party action, run `gitleaks git --redact --exit-code 1` over every commit. `image` now also needs it. - .gitleaks.toml extends the default rules with a narrow allowlist of published placeholders only: the old dev JWT value (public, and denylisted in the charts), the dev-only-change-me* and changeme-* chart/Secret placeholders, and the pkg/auth unit-test key. - .pre-commit-config.yaml runs the same rules on staged changes, pinned to the v8.30.1 commit SHA. Dependabot's pre-commit ecosystem keeps that pin current. - SECURITY.md: a gitleaks row in the gates table, plus a "Secrets in history" note. Any environment that ever signed tokens with the public dev JWT value must rotate it. A history purge needs a force-push, does not reach existing clones, and is not done here. Not run locally (no gitleaks binary here, and I did not download one). A grep of all 129 commits for high-signal formats (AWS, GitHub, OpenAI, Anthropic, Google, Slack keys, private-key headers) found nothing. The generic-API-key rule may still flag something the allowlist does not cover; if so, the first CI run shows it, redacted. Co-Authored-By: Claude Opus 5.5 --- .github/dependabot.yml | 12 +++++++++++ .github/workflows/security.yml | 37 +++++++++++++++++++++++++++++++++- .gitleaks.toml | 29 ++++++++++++++++++++++++++ .pre-commit-config.yaml | 12 +++++++++++ SECURITY.md | 21 ++++++++++++++++++- 5 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 .gitleaks.toml create mode 100644 .pre-commit-config.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8f19c21..db917c7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -185,6 +185,18 @@ updates: - dependency-name: redis update-types: ["version-update:semver-major"] + # --------------------------------------------------------------------------- + # pre-commit — the pinned gitleaks hook in .pre-commit-config.yaml. + # --------------------------------------------------------------------------- + - package-ecosystem: pre-commit + directory: / + schedule: + interval: weekly + day: monday + open-pull-requests-limit: 2 + commit-message: + prefix: deps(pre-commit) + # --------------------------------------------------------------------------- # Terraform — provider constraints AND the committed .terraform.lock.hcl, # one entry per root module. diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 67a4e70..03e97de 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -205,6 +205,41 @@ jobs: # Cover dependency CVEs, leaked secrets, and IaC misconfig in one pass. scanners: vuln,secret,misconfig + # =========================================================================== + # 2b. gitleaks — secrets in the FULL git history, not just the working tree. + # =========================================================================== + # Trivy's secret scanner (above) only sees the current checkout. A credential + # committed and later deleted is invisible to it, yet still in every clone. + # This job walks every commit. Findings fail the gate; a known-safe value is + # allowlisted in .gitleaks.toml with a reason, a real one is ROTATED (removing + # it from history does not un-leak it). + # + # gitleaks is built from source at a pinned version with `go install`, so the + # module checksum database verifies it (the same way govulncheck is installed + # above) instead of trusting a downloaded binary or a third-party action. + # --redact keeps any finding's value out of the job log. + gitleaks: + name: gitleaks (full history) + runs-on: ubuntu-latest + steps: + - name: Checkout (full history) + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 0 + persist-credentials: false + + - name: Set up Go + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version: ${{ env.GO_VERSION }} + cache: false + + - name: Install gitleaks + run: go install github.com/zricethezav/gitleaks/v8@v8.30.1 + + - name: Scan every commit + run: gitleaks git --config .gitleaks.toml --redact --verbose --exit-code 1 . + # =========================================================================== # 3. image — build → Trivy image scan → SBOM, per service. NEVER pushes. # =========================================================================== @@ -222,7 +257,7 @@ jobs: image: name: image (${{ matrix.service }}) runs-on: ubuntu-latest - needs: [matrix, govulncheck, trivy-fs] + needs: [matrix, govulncheck, trivy-fs, gitleaks] strategy: fail-fast: false matrix: diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 0000000..27d9e65 --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,29 @@ +# ============================================================================= +# gitleaks configuration — used by the Security workflow (full git history) and +# the pre-commit hook (staged changes). +# ============================================================================= +# Start from gitleaks' built-in rules and add a NARROW allowlist of published +# development placeholders. Every value below is deliberately public, appears +# in docs or committed dev values, and is never a working credential anywhere. +# Do not add a real secret here "temporarily": rotate it instead. +# ============================================================================= + +title = "forgepoint" + +[extend] +useDefault = true + +[[allowlists]] +description = "Published dev/test placeholders, never valid credentials" +# Matched against the extracted SECRET (gitleaks' default regexTarget). +regexes = [ + # The old dev JWT placeholder. It is public (in git history and in the + # fp-*/_helpers.tpl denylist), so the charts refuse to render with it. Any + # environment that ever used it as its signing key must rotate (SECURITY.md). + '''^dev-only-change-me-in-prod-min-32-bytes-of-entropy$''', + # Other dev-only placeholders in chart values and placeholder Secrets. + '''^dev-only-change-me(-[a-z0-9-]+)?$''', + '''^changeme-[a-z0-9-]+$''', + # The fixed HMAC key used by pkg/auth unit tests. + '''^unit-test-jwt-secret-32bytes-ok!$''', +] diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..81d8321 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,12 @@ +# Local secret scanning before a commit exists. Install once per clone: +# pipx install pre-commit (or: brew install pre-commit) +# pre-commit install +# The same gitleaks rules run in CI over the FULL history (security.yml), so +# skipping the hook (git commit --no-verify) only moves the failure to the PR. +# rev is pinned to a commit SHA (tag in the comment); Dependabot's pre-commit +# ecosystem keeps it current. +repos: + - repo: https://github.com/gitleaks/gitleaks + rev: 83d9cd684c87d95d656c1458ef04895a7f1cbd8e # frozen: v8.30.1 + hooks: + - id: gitleaks diff --git a/SECURITY.md b/SECURITY.md index edbc7ca..db05f6e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -17,12 +17,13 @@ contracts, the Helm values, and the CLI flags alike as unstable until there is a ## What CI enforces The [`Security`](.github/workflows/security.yml) workflow runs on every push to -`main`, every pull request, every `v*` tag, and on demand. Four gates, in order: +`main`, every pull request, every `v*` tag, and on demand. The gates: | Gate | Tool | Fails on | |---|---|---| | Go dependencies | [`govulncheck`](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck) v1.1.4, one leg per module in `go.work` | any **reachable** vulnerability | | Working tree | Trivy `fs` — `vuln,secret,misconfig` | HIGH / CRITICAL | +| Git history | [`gitleaks`](https://github.com/gitleaks/gitleaks) v8.30.1 over **every commit** (`.gitleaks.toml`) | any secret not in the allowlist | | Built image | Trivy `image` — `os,library` | HIGH / CRITICAL | | Shipped web deps | `npm audit --omit=dev` (in [`CI`](.github/workflows/ci.yml)) | HIGH / CRITICAL | @@ -46,6 +47,24 @@ carries two MODERATE advisories whose only fix is the 7.x major. Neither ships i the production bundle; the `npm audit` gate is scoped to production dependencies for that reason, and Dependabot proposes the majors as reviewable PRs. +### Secrets in history + +Trivy's secret scanner only sees the current checkout, so a credential that was +committed and later deleted passed every gate while remaining in every clone. +The `gitleaks` job scans the full history, and the same rules run locally as a +pre-commit hook (`.pre-commit-config.yaml`; `pre-commit install`). The first +history run may surface old findings. Triage each one: rotate a real +credential (deleting it from history does not un-leak it), and allowlist a +published placeholder in `.gitleaks.toml` with a comment. + +One such placeholder is already known: the old dev JWT key +`dev-o****` (the full value is in the `fp-*/_helpers.tpl` denylist). It was +committed as a chart default, so it is public. The charts refuse to render +with it, but **any environment that ever used it as its HS256 signing key must +rotate that key**, because anyone can mint tokens with it. Purging it from +history would need a force-push and does not help anyone who has already +cloned the repo, so it is allowlisted rather than purged. + ## Triage of the IaC findings (opened 2026-07-27, decided 2026-10-24) The Trivy filesystem gate had never executed before 2026-07-27 — it referenced From b8e1d59a6d94fe0743e6094b8fe4eeeb48b910f4 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:03:43 +0500 Subject: [PATCH 27/42] ci(security): drop the literal dev JWT value from .gitleaks.toml The previous commit allowlisted the old dev JWT placeholder by its full value. That value is already public (git history, and the denylist in every chart's _helpers.tpl), but it was a signing key once and should not be repeated in new files. The existing ^dev-only-change-me(-[a-z0-9-]+)?$ pattern already covers it, so the explicit line is removed and the comment moved onto that pattern. Co-Authored-By: Claude Opus 5.5 --- .gitleaks.toml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitleaks.toml b/.gitleaks.toml index 27d9e65..93805ff 100644 --- a/.gitleaks.toml +++ b/.gitleaks.toml @@ -17,11 +17,10 @@ useDefault = true description = "Published dev/test placeholders, never valid credentials" # Matched against the extracted SECRET (gitleaks' default regexTarget). regexes = [ - # The old dev JWT placeholder. It is public (in git history and in the - # fp-*/_helpers.tpl denylist), so the charts refuse to render with it. Any + # dev-only-change-me* placeholders in chart values and placeholder Secrets. + # This also covers the old dev JWT placeholder, which is public (git history + # and the fp-*/_helpers.tpl denylist, which makes the charts refuse it). Any # environment that ever used it as its signing key must rotate (SECURITY.md). - '''^dev-only-change-me-in-prod-min-32-bytes-of-entropy$''', - # Other dev-only placeholders in chart values and placeholder Secrets. '''^dev-only-change-me(-[a-z0-9-]+)?$''', '''^changeme-[a-z0-9-]+$''', # The fixed HMAC key used by pkg/auth unit tests. From 90f45e7be00835e36fbaefdd299b573e04196543 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:04:56 +0500 Subject: [PATCH 28/42] docs(adr): propose asymmetric JWT signing and per-service DB users Two audit findings are redesigns that should not be half-implemented in a fix branch. Following the repo's ADR convention (immutable once Accepted, new ADRs for changes), each gets a Proposed ADR with problem, options, recommendation and migration: - ADR 0010: replace the one HS256 key shared by 11 services with Ed25519 (EdDSA) signing in auth and a published public key set with `kid`. Today every verifier can mint admin tokens, and rotation means restarting all services in lockstep. The migration ships a dual-accepting validator first, then switches issuance, then removes HS256 and FP_JWT_SECRET from the 11 non-auth charts. - ADR 0011: one owner role per service database (no CREATEROLE/CREATEDB, PUBLIC connect revoked) instead of the RDS master / local superuser DSN in every pod. Master credentials are confined to a provisioning Job, with IAM database auth on RDS as the later step. Both are listed in docs/adr/README.md. No code changes. Co-Authored-By: Claude Opus 5.5 --- docs/adr/0010-asymmetric-jwt-signing.md | 94 +++++++++++++++++++++ docs/adr/0011-per-service-database-users.md | 85 +++++++++++++++++++ docs/adr/README.md | 2 + 3 files changed, 181 insertions(+) create mode 100644 docs/adr/0010-asymmetric-jwt-signing.md create mode 100644 docs/adr/0011-per-service-database-users.md diff --git a/docs/adr/0010-asymmetric-jwt-signing.md b/docs/adr/0010-asymmetric-jwt-signing.md new file mode 100644 index 0000000..dd0835b --- /dev/null +++ b/docs/adr/0010-asymmetric-jwt-signing.md @@ -0,0 +1,94 @@ +# ADR 0010: Asymmetric JWT signing with a published key set (replace the shared HS256 key) + +**Status:** Proposed +**Date:** 2026-10-24 +**Deciders:** Abdul Basit Sajid +**Context phase:** Security audit follow-up (October 2026). Design note only; no code changes yet. + +## Context + +`services/auth` mints access tokens with **HS256** (`services/auth/internal/domain/jwt.go`), +and every other service verifies them locally with `pkg/auth/validator.go`, using the +**same** symmetric key. That key, `FP_JWT_SECRET`, is rendered into the Secret of 11 Helm +charts (12 `templates/secret.yaml` files reference it) and stored once in Secrets Manager +(`/auth/jwt`, created by hand with the aws CLI). + +The verifier side is careful: it pins the algorithm (identity check on +`jwt.SigningMethodHS256` plus `WithValidMethods`), rejects `alg=none` and enforces a +key of at least 32 bytes. The weakness is structural: + +1. **Every verifier can mint.** With HMAC the verification key *is* the signing key. + Compromising any one of the 11 services (billing, notification, the BFF's + neighbours...) yields a key that forges a token for **any** identity and role, + including admin, accepted by every other service. +2. **No key rotation without an outage.** The validator holds exactly one key and + tokens carry no `kid`. Rotating means updating 11 Secrets and restarting 11 + services in lockstep; any service still on the old key rejects new tokens (or + the reverse) until it restarts. +3. **The blast radius of a leaked key is the whole platform,** and the old dev + placeholder value is already public in git history (see SECURITY.md), so any + environment that ever used it must rotate. Today that rotation is the painful + lockstep in point 2. + +## Options Considered + +### Option A — Keep HS256, add a `kid` and accept a key *set* in the validator +- **Pro:** smallest change; enables zero-downtime rotation (sign with the new key, + verify with old+new, then drop the old one). +- **Con:** does not fix point 1. Every verifier still holds a minting key. + +### Option B — Asymmetric signing (EdDSA/Ed25519 or ES256), JWKS published by auth (recommended) +- **Pro:** only `auth` holds a private key; the other services get **public** keys + that cannot mint anything, so a compromised service can no longer forge + identities. Key IDs (`kid`) and a key set give zero-downtime rotation. Public keys + are not secrets, so they no longer need a Secret per chart. +- **Con:** a key-distribution path is needed (a JWKS endpoint on auth, or a ConfigMap / + Secrets Manager entry with the public set); validators must cache and refresh it; + the token format changes (`alg`, `kid`), so the migration has a dual-accept window. + +### Option C — Opaque tokens with introspection at auth (or the mesh) +- **Pro:** no signing key outside auth at all; instant revocation. +- **Con:** a network call per request (or per cache miss) to auth, and a hard runtime + dependency on auth for every RPC. It undoes the design choice of local verification. + +## Decision + +Proposed: **Option B, with Ed25519 (`EdDSA`)**. Small keys and fast verification, +and the algorithm admits no parameter choices that could go wrong. `ES256` is the +fallback if a client library lacks EdDSA. + +- auth holds the private key(s) (Secrets Manager, read only by the External Secrets + Operator into the `fp-auth` Secret). It signs with the active key, puts its `kid` in + the header, and serves the **public** key set at an internal JWKS endpoint (and/or + writes it to a ConfigMap that charts mount). +- `pkg/auth` validator: accept exactly `EdDSA`, look up the key by `kid` in a cached + set (refresh on unknown `kid`, rate-limited), and keep the existing + algorithm-pinning and claim checks. Add `iss` and `aud` checks while there. +- Charts: drop `FP_JWT_SECRET` from every chart except `fp-auth`. + +## Migration + +1. **Validator first (no behaviour change):** `pkg/auth` accepts a *set* of keys: + the current HS256 secret **and** an Ed25519 public key set. HS256 tokens still + verify. Ship to all services. +2. **auth signs EdDSA with `kid`:** generate the first Ed25519 key, publish its public + half, and switch issuance. Old HS256 tokens keep verifying until they expire + (access-token TTL). +3. **Remove HS256:** after one TTL plus a margin, drop HS256 acceptance from the + validator and remove `FP_JWT_SECRET` from the 11 non-auth charts, the ExternalSecret + and Secrets Manager. Keep the dev-placeholder denylist in the fp-auth chart until + then. +4. **Rotation runbook:** add key N+1 to the published set, wait for every validator's + cache refresh interval, switch signing to N+1, and remove N after one token TTL. + No restarts are needed. + +## Consequences + +- **Positive:** a compromised non-auth service can no longer mint tokens; rotation is + routine instead of a coordinated outage; fewer Secrets to manage. +- **Negative:** auth gains a JWKS endpoint and key-management code; validators gain a + cache with refresh logic; a short dual-algorithm window. +- **Follow-ups:** decide JWKS-over-HTTP vs ConfigMap distribution (ConfigMap is simpler + inside one cluster; HTTP is needed once anything outside the cluster verifies); + until this lands, any environment that ever used the public dev placeholder as its + HS256 key must rotate it now. diff --git a/docs/adr/0011-per-service-database-users.md b/docs/adr/0011-per-service-database-users.md new file mode 100644 index 0000000..db5ef0a --- /dev/null +++ b/docs/adr/0011-per-service-database-users.md @@ -0,0 +1,85 @@ +# ADR 0011: Per-service database users instead of the shared master DSN + +**Status:** Proposed +**Date:** 2026-10-24 +**Deciders:** Abdul Basit Sajid +**Context phase:** Security audit follow-up (October 2026). Design note only; no code changes yet. + +## Context + +The architecture is database-per-service ("each service owns its Postgres database and +migrations; no cross-service DB access", per `deploy/k8s/infra/postgres/postgres.yaml` +and the `fp_` databases in `scripts/init-postgres.sh`), but the *credentials* +are not per-service: + +- **AWS:** both ExternalSecrets (`fp-auth`, `fp-infra-creds`) build `FP_DATABASE_URL` from + the **RDS master user**, now RDS-managed (`manage_master_user_password`) but still the + master. Every consumer of `fp-infra-creds` and the auth service connect as a role that + owns every database, can create roles, and can read and alter any service's data. +- **Local / k3s:** every service connects as `fp`, the Postgres superuser created by the + image entrypoint. + +So the isolation boundary the architecture promises exists only by convention. One +compromised service, or one SQL injection, gets read/write on billing's ledger, auth's +users and the audit log, and could create a login role to persist. The repo already +shows the pattern it should follow in one place: `fp_audit_app`, a NOLOGIN least-privilege +role for the audit sink. + +## Options Considered + +### Option A — Status quo: one master DSN, rely on network policy and mesh authz +- **Pro:** nothing to build. +- **Con:** database-level isolation is zero; the master credential sits in many pods' env. + +### Option B — One LOGIN role per service, owner of its own database only (recommended) +- **Pro:** a compromised service reaches only its own database; the credential has no + `CREATEROLE`/`CREATEDB`/superuser; audit logs show *which* service did what. +- **Con:** role provisioning, password storage and rotation for ~8 roles; migrations + must run as the service's owner role. + +### Option C — Option B with IAM database authentication on RDS +- **Pro:** no stored passwords at all; pods get 15-minute tokens via IRSA + (`rds-db:connect` scoped to one DB user); rotation is free. +- **Con:** RDS-only (the local stack still needs passwords); a client change to fetch + tokens and reconnect before expiry; IAM auth has connection-rate limits to plan around. + +## Decision + +Proposed: **Option B now, Option C for AWS later.** + +- Each service gets a role `fp__app` (LOGIN, NOINHERIT, no CREATEROLE/CREATEDB) + that **owns only** `fp_`. `REVOKE CONNECT ON DATABASE ... FROM PUBLIC` on + every service database, so a role cannot even connect to another service's DB. +- The master/superuser credential is used **only** by a one-shot provisioning Job (or + Terraform's `postgresql` provider in a separate, operator-run stack) and is never + mounted into an application pod. +- Passwords: one Secrets Manager secret per service role (AWS), synced by its own + ExternalSecret into that service's Secret only (`fp-`), replacing the shared + `fp-infra-creds` DSN. + +## Migration + +1. Provisioning: extend `scripts/init-postgres.sh` (local) and add an idempotent + provisioning Job for RDS that creates the roles, transfers ownership of each + `fp_` database and its objects (`REASSIGN OWNED`), and revokes PUBLIC + connect. +2. Secrets: create per-service secrets; add one ExternalSecret per service; point each + chart's `secrets.existingSecret` at it (the charts already default to a Secret named + after the chart, see `secrets.create: false`). +3. Cut over one service at a time; migrations (the `migrate` initContainer) already use + the same DSN as the app, so they run as the owner role automatically. +4. Remove `FP_DATABASE_URL` from `fp-infra-creds`, and drop the master user secret ARN + from every role except the provisioning path. +5. Later (Option C): enable IAM auth on RDS, grant `rds_iam` to the service roles, give + each service's IRSA role `rds-db:connect` on its own user only, and switch clients to + token auth. + +## Consequences + +- **Positive:** database isolation matches the architecture; credential blast radius is + one service; the master credential leaves the application path entirely. +- **Negative:** ~8 more secrets to provision and rotate (until IAM auth); a provisioning + step that must run before a new service's first deploy. +- **Follow-ups:** decide where role provisioning lives (Job vs operator-run Terraform + stack); the RDS-managed master password rotation (every 7 days) then affects only + that provisioning path, not every pod. diff --git a/docs/adr/README.md b/docs/adr/README.md index c77469a..423202c 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -18,3 +18,5 @@ zero-padded (`0001`, `0002`, …). Use `docs/adr/template.md` as the starting po | [0007](0007-one-pattern-per-service.md) | One distributed-systems pattern per service | Accepted | 2026-06-17 | | [0008](0008-istio-service-mesh.md) | Istio service mesh — STRICT mTLS, deny-by-default authz, mesh resilience | Accepted | 2026-06-18 | | [0009](0009-tamper-evident-audit-log.md) | Tamper-evident, hash-chained audit log (interceptor capture + append-only sink) | Accepted | 2026-06-18 | +| [0010](0010-asymmetric-jwt-signing.md) | Asymmetric JWT signing with a published key set (replace the shared HS256 key) | Proposed | 2026-10-24 | +| [0011](0011-per-service-database-users.md) | Per-service database users instead of the shared master DSN | Proposed | 2026-10-24 | From b1e2b19bd67f1dddfa5985cbfaef1a412970665f Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:06:21 +0500 Subject: [PATCH 29/42] ci(security): scan third-party images weekly, document every gate's blind spots Two audit findings: - The images the cluster runs but this repo does not build (postgres, redis, nats, grafana, prometheus, tempo, loki, otel-collector, ollama, migrate) were never scanned. The image job covers first-party services only. - SECURITY.md described what each gate catches and nothing about what it misses (history secrets, third-party images, *.tfvars.example, runtime signature verification, npm devDependencies...). security.yml: - New `schedule` trigger (Mondays 04:17 UTC) so the existing gates also re-run against a fresh vulnerability DB. - third-party-matrix derives the image list from the repo: every `image: ...@sha256:` in deploy/ and docker-compose.yaml, plus repository/tag@sha256 pairs in chart values. A newly pinned image is covered without editing the workflow. - third-party-images: Trivy per image, HIGH/CRITICAL, exit-code 1, .trivyignore.yaml honoured. Schedule/dispatch only. Decision: third-party scans use ignore-unfixed and run off the PR path. Alternative: same settings as the first-party gates, on every push. Why: these CVEs are fixed by bumping a pin (which Dependabot proposes), not by the change under review. An unfixed upstream CVE cannot be fixed by bumping at all, so reporting it every week would only teach people to ignore the run. SECURITY.md: - "Third-party images" explains the above. - "What the gates do not see" is a catches/misses table for every gate, ending with the gap no workflow can close: main is unprotected, so red checks block nothing. Not run: no actionlint locally. The resolve script was run against the working tree and lists 11 images. YAML parses. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/security.yml | 76 ++++++++++++++++++++++++++++++++++ SECURITY.md | 31 ++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 03e97de..84c38fd 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -53,6 +53,10 @@ on: # Allow on-demand runs (e.g. to re-scan after a base-image CVE disclosure) # without a code change. workflow_dispatch: + # Weekly re-scan with a fresh vulnerability DB, plus the third-party image + # scan below, which only runs on schedule/dispatch. + schedule: + - cron: "17 4 * * 1" # SECURITY: least privilege at the TOP. The default for every job is read-only. # Exactly one job elevates: `publish`, which runs only for pushes to main or a @@ -240,6 +244,78 @@ jobs: - name: Scan every commit run: gitleaks git --config .gitleaks.toml --redact --verbose --exit-code 1 . + # =========================================================================== + # 2c. third-party images — the images we RUN but do not build. + # =========================================================================== + # The image job scans only first-party services. postgres, redis, nats, + # grafana, prometheus, tempo, loki, the OTel collector, ollama and the + # migrate initContainer also run in the cluster and were never scanned. The + # list is derived from the repo (every `image: ...@sha256:` in deploy/ and + # docker-compose.yaml, plus repository/tag@sha256 pairs in chart values), so + # a newly pinned image is covered automatically. The minio images are absent + # because they cannot be digest-pinned any more (see deploy/k8s/infra/minio). + # + # Runs on the weekly schedule and on demand, NOT on push/PR: these CVEs are + # fixed by bumping a pin (Dependabot's docker ecosystem proposes those), not + # by the change under review, so they must not block unrelated merges. A red + # scheduled run is the alert. + # + # Unlike the first-party gates this uses ignore-unfixed: an upstream CVE with + # no fixed release cannot be acted on by bumping, so reporting it weekly would + # only train people to ignore the run. Accept anything else via + # .trivyignore.yaml (statement + expiry) like every other finding. + third-party-matrix: + name: resolve third-party images + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + runs-on: ubuntu-latest + outputs: + images: ${{ steps.set.outputs.images }} + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Resolve + id: set + run: | + set -euo pipefail + images=$( { + grep -rhoE '^[[:space:]]*image:[[:space:]]*"?[^"[:space:]]+@sha256:[0-9a-f]{64}' deploy docker-compose.yaml \ + | sed -E 's/^[[:space:]]*image:[[:space:]]*"?//' + for f in deploy/helm/*/values.yaml; do + awk '/^[[:space:]]+repository:/{r=$2} /^[[:space:]]+tag:.*@sha256:/{print r":"$2}' "$f" + done + } | sort -u | jq -R . | jq -sc . ) + [ "$(jq -r 'length' <<<"$images")" -gt 0 ] || { echo "no digest-pinned third-party images found" >&2; exit 1; } + echo "images=$images" >> "$GITHUB_OUTPUT" + jq -r '.[]' <<<"$images" + + third-party-images: + name: third-party (${{ matrix.image }}) + needs: [third-party-matrix] + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + image: ${{ fromJSON(needs.third-party-matrix.outputs.images) }} + steps: + - name: Checkout (for .trivyignore.yaml) + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Trivy image scan + uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 + with: + scan-type: image + image-ref: ${{ matrix.image }} + severity: HIGH,CRITICAL + exit-code: "1" + ignore-unfixed: true + vuln-type: os,library + trivyignores: .trivyignore.yaml + # =========================================================================== # 3. image — build → Trivy image scan → SBOM, per service. NEVER pushes. # =========================================================================== diff --git a/SECURITY.md b/SECURITY.md index db05f6e..362cc1a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -65,6 +65,37 @@ rotate that key**, because anyone can mint tokens with it. Purging it from history would need a force-push and does not help anyone who has already cloned the repo, so it is allowlisted rather than purged. +### Third-party images + +The images the cluster runs but this repo does not build (postgres, redis, +nats, grafana, prometheus, tempo, loki, the OTel collector, ollama, migrate) +are pinned by tag **and** digest, refreshed by Dependabot's docker/helm/compose +ecosystems, and scanned weekly (and on demand) by the `third-party-images` job. +That job runs on schedule only, so a new upstream CVE never blocks an unrelated +PR, and it uses `ignore-unfixed`, because a CVE with no fixed release cannot be +fixed by bumping a pin. A red scheduled run is the signal to bump. + +## What the gates do not see + +Each gate is narrower than its name suggests. Known blind spots, so nobody +reads a green run as more than it is: + +| Gate | Catches | Misses | +|---|---|---| +| govulncheck | Go vulnerabilities your code **reaches** | Non-Go code; vulnerable code reached only via reflection or `unsafe`; anything not in the Go vuln DB yet | +| Trivy `fs` (vuln) | CVEs in `go.mod`/`go.sum` and `package-lock.json` | npm **devDependencies** (Trivy skips them unless `--include-dev-deps`), so the vite/esbuild toolchain is not covered | +| Trivy `fs` (misconfig) | Terraform, Kubernetes YAML, Helm charts **rendered with default values**, Dockerfiles | Values passed at deploy time (`--set`, Argo CD parameters, real `terraform.tfvars`); only the example tfvars is evaluated | +| Trivy `fs` (secret) | Secrets in the **current checkout** | History (that is gitleaks' job) and formats without a rule | +| gitleaks | Secrets in **every commit**, by rule and entropy | Formats no rule knows; anything allowlisted in `.gitleaks.toml` | +| Trivy `image` | OS + library CVEs in the **first-party** images, before push | Third-party images (scanned weekly by `third-party-images`, not per PR); MinIO, which can no longer be pinned | +| `npm audit` | HIGH/CRITICAL in **production** web deps | Dev deps (deliberately `--omit=dev`); MODERATE advisories | +| Terraform workflow | Formatting, syntax, references, variable validation, lock-file drift | Anything a `plan` would show: there are no AWS credentials in CI and nothing has been applied | +| Kyverno (cluster) | Pod settings, registries, tags, image signatures | Everything ships in **Audit**, so nothing is blocked until the enforce overlay is applied; `fp-ml` (ollama) is outside the matched namespaces | + +And one gap no workflow can close: **`main` has no branch protection or required +checks**, so a red Security, CI or Terraform run blocks nothing. Making these +gates real is a repository-settings change (protect `main`, require the checks). + ## Triage of the IaC findings (opened 2026-07-27, decided 2026-10-24) The Trivy filesystem gate had never executed before 2026-07-27 — it referenced From aaa484bfc59b99eb00131ee65f973b9948fa96b5 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:54:30 +0500 Subject: [PATCH 30/42] argocd: spell namespaceResourceWhitelist correctly, deny-all the default project The AppProject key is `namespaceResourceWhitelist` (CRD and Go json tag). Every project here spelled it `namespacedResourceWhitelist`, already on main and carried into d04b80e, which built its claims on it. Two outcomes, both bad: - kubectl apply (strict field validation) rejects all three AppProjects with `unknown field "spec.namespacedResourceWhitelist"`, so root.yaml points at a project that does not exist. - Applied with validation off, the key is dropped and the whitelist is nil. Argo CD's IsGroupKindNamePermitted treats a nil namespaced whitelist as "every kind allowed", so forgepoint-bootstrap (destination argocd) could write Secrets, RoleBindings or AppProjects into argocd: the escalation d04b80e says it closes. The Role/RoleBinding removal in `forgepoint` was a no-op for the same reason. Changes: - Rename the key in both projects in project.yaml and in the README. - default-project.yaml: replace the empty whitelist with a `*/*` namespaceResourceBlacklist, the lock-down the Argo CD docs recommend. The field is `omitempty`, so an empty list does not survive a round trip through Argo CD (UI or `argocd proj`), and nil means allow-all. The blacklist denies every kind regardless. - Document the spelling trap and the server-side dry run in project.yaml and the README. Checked against a throwaway kube-apiserver v1.35.0 with the Argo CD v3.5.6 CRDs (since removed): - origin/main and the previous branch head: `kubectl apply --dry-run=server` fails with the strict-decoding error above. - This commit: all three AppProjects, root.yaml and the 11 child Applications pass the server-side dry run. - Stored objects evaluated with the permission logic copied from argo-cd v3.5.6: forgepoint-bootstrap allows only Application; forgepoint allows its listed kinds plus Namespace and denies Role, RoleBinding, AppProject; default allows nothing. The pre-fix spelling allowed every kind. Co-Authored-By: Claude Opus 5.5 --- deploy/argocd/README.md | 12 +++++++++--- deploy/argocd/default-project.yaml | 13 ++++++++++++- deploy/argocd/project.yaml | 13 ++++++++++--- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/deploy/argocd/README.md b/deploy/argocd/README.md index d2d0cc0..3268bb3 100644 --- a/deploy/argocd/README.md +++ b/deploy/argocd/README.md @@ -207,14 +207,20 @@ The AppProjects are least privilege for the delivery layer itself: Nothing lands in `argocd` / `kube-system` / `default`. - **clusterResourceWhitelist** — only `Namespace`. No CRDs (a CRD write can redefine any API group) and **no ClusterRole/ClusterRoleBinding**. -- **namespacedResourceWhitelist** — exactly the kinds the charts + infra +- **namespaceResourceWhitelist** — exactly the kinds the charts + infra kustomize render (Deployment, StatefulSet, Job, Service, ConfigMap, Secret, ServiceAccount, PVC, HPA, PDB, NetworkPolicy, ServiceMonitor). No Role or RoleBinding: namespaced RBAC from Git is a privilege grant. Deny-by-default: - add a kind here the day a chart needs it. + add a kind here the day a chart needs it. Spell the key exactly + `namespaceResourceWhitelist`: Argo CD treats a missing namespaced whitelist + as "allow every kind", so a typo removes the guardrail instead of tightening it. - **`default` project emptied** — an Application chooses its own `spec.project`, so without this a child app could name `project: default` and bypass all of the - above. + above. It has no repos, no destinations and a `*/*` namespaced blacklist (the + lock-down the Argo CD docs recommend; an empty whitelist alone is fragile). +- **Check before you trust it:** `kubectl apply --dry-run=server -f deploy/argocd/project.yaml -f deploy/argocd/default-project.yaml` + against a cluster with the Argo CD CRDs. kubectl's strict field validation + rejects a misspelled key. --- diff --git a/deploy/argocd/default-project.yaml b/deploy/argocd/default-project.yaml index e97d0bb..3a1a186 100644 --- a/deploy/argocd/default-project.yaml +++ b/deploy/argocd/default-project.yaml @@ -8,6 +8,13 @@ # every guardrail in project.yaml. Emptying `default` closes that door: an # Application in it can deploy nothing. # +# This is the lock-down the Argo CD docs recommend ("The Default Project"): +# no repos, no destinations, and a `*/*` namespaced BLACKLIST. The blacklist is +# what actually denies namespaced kinds. An empty namespaceResourceWhitelist +# alone is fragile: the Go field is `omitempty`, so anything that round-trips +# the object through Argo CD (UI, `argocd proj` CLI) drops the empty list, and +# a missing namespaced whitelist means "allow every kind". +# # Apply once, by hand, with the other projects (it is not under apps/, so the # root app never syncs it): # kubectl apply -n argocd -f deploy/argocd/default-project.yaml @@ -23,5 +30,9 @@ spec: description: Locked down. Use the forgepoint or forgepoint-bootstrap project. sourceRepos: [] destinations: [] + # Cluster-scoped kinds: an empty (or missing) whitelist already denies all. clusterResourceWhitelist: [] - namespacedResourceWhitelist: [] + # Namespaced kinds: deny every group and kind. + namespaceResourceBlacklist: + - group: "*" + kind: "*" diff --git a/deploy/argocd/project.yaml b/deploy/argocd/project.yaml index 0b9e25a..b473f58 100644 --- a/deploy/argocd/project.yaml +++ b/deploy/argocd/project.yaml @@ -28,6 +28,13 @@ # the sourceRepos allow-list, the destinations allow-list, and the # namespaced/clusterResource allow-lists below. They are applied by hand # (kubectl), never synced by the root app, so a Git change cannot widen them. +# +# SPELLING MATTERS: the field is `namespaceResourceWhitelist` (no "d"). Argo CD +# treats a MISSING namespaced whitelist as "every namespaced kind is allowed", +# so a misspelled key is not just ignored, it silently removes the guardrail +# (if it gets past kubectl's strict field validation at all). Validate with +# kubectl apply --dry-run=server -f deploy/argocd/project.yaml +# against a cluster that has the Argo CD CRDs before relying on these limits. # ============================================================================ apiVersion: argoproj.io/v1alpha1 kind: AppProject @@ -53,7 +60,7 @@ spec: # Exactly one kind. In particular NOT Secret (Argo CD reads cluster and repo # credentials from Secrets in this namespace) and NOT AppProject (a project # that could edit projects could lift its own limits). - namespacedResourceWhitelist: + namespaceResourceWhitelist: - group: argoproj.io kind: Application @@ -116,7 +123,7 @@ spec: kind: Namespace # -------------------------------------------------------------------------- - # namespacedResourceWhitelist — NAMESPACED kinds apps may create. + # namespaceResourceWhitelist — NAMESPACED kinds apps may create. # Deny-by-default. Exactly what the fp-* charts and deploy/k8s/infra render # today (checked with `helm template` / the infra manifests): # workloads Deployment, StatefulSet, Job (the MinIO bucket init), @@ -131,7 +138,7 @@ spec: # fp-infra sync could not have succeeded. Secret stays (infra placeholders and # the charts' optional dev Secret), but only in fp-* namespaces now. # -------------------------------------------------------------------------- - namespacedResourceWhitelist: + namespaceResourceWhitelist: - group: "" kind: ConfigMap - group: "" From 5710920561d50f078412a97a003c9cdbc2c9383b Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:54:39 +0500 Subject: [PATCH 31/42] ci(security): allowlist the one gitleaks false positive in history The gitleaks job added in c8207ac failed on every run, and `image` needs it, so nothing was ever built, scanned, published or signed. Running the pinned gitleaks v8.30.1 exactly as the job does (`gitleaks git --config .gitleaks.toml --redact --exit-code 1 .`) over all 141 commits found one hit: generic-api-key at docs/diagrams/c4-architecture.md:112 in commit d553f7fe. The rule captured the C4 technology label "Traefik/Kong" as a key. It is not a secret. Add a second [[allowlists]] entry with condition = "AND": the value must be exactly "Traefik/Kong" AND the file must be that diagram. A path-and- value pair survives later edits of the line (a .gitleaksignore fingerprint is tied to one commit and line) and still reports the same string anywhere else. SECURITY.md records the finding and why it is allowlisted. Checked locally with gitleaks v8.30.1: - full history with the new config: "no leaks found", exit 0 - the flagged line copied into the diagram path and into another path: only the other path is reported, so the allowlist is scoped as intended Co-Authored-By: Claude Opus 5.5 --- .gitleaks.toml | 10 ++++++++++ SECURITY.md | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/.gitleaks.toml b/.gitleaks.toml index 93805ff..687da60 100644 --- a/.gitleaks.toml +++ b/.gitleaks.toml @@ -26,3 +26,13 @@ regexes = [ # The fixed HMAC key used by pkg/auth unit tests. '''^unit-test-jwt-secret-32bytes-ok!$''', ] + +[[allowlists]] +description = "False positive: the C4 diagram's technology label for the API gateway" +# generic-api-key matches `Container(gateway_edge, "API Gateway", "Traefik/Kong", ...)` +# in docs/diagrams/c4-architecture.md (commit d553f7fe, line 112) and captures +# the label "Traefik/Kong" as a key. Both conditions must hold (AND): this exact +# value AND this one file, so the same string anywhere else is still scanned. +condition = "AND" +paths = ['''^docs/diagrams/c4-architecture\.md$'''] +regexes = ['''^Traefik/Kong$'''] diff --git a/SECURITY.md b/SECURITY.md index 362cc1a..09acdac 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -65,6 +65,13 @@ rotate that key**, because anyone can mint tokens with it. Purging it from history would need a force-push and does not help anyone who has already cloned the repo, so it is allowlisted rather than purged. +The first full-history run (gitleaks v8.30.1, 141 commits) found exactly one +other hit, a false positive: `generic-api-key` matched the C4 diagram's +technology label `Traefik/Kong` in `docs/diagrams/c4-architecture.md` (commit +`d553f7fe`, line 112). It is allowlisted for that value in that one file only +(`condition = "AND"`), so the same string elsewhere is still reported. With +that entry, `gitleaks git --config .gitleaks.toml --exit-code 1 .` exits 0. + ### Third-party images The images the cluster runs but this repo does not build (postgres, redis, From bc44e4e94fe5cd5d11fcb9fc80eb7ac468f6328f Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:55:04 +0500 Subject: [PATCH 32/42] terraform: percent-encode the Redis token in the ElastiCache rediss:// URL 1899dc1 moved billing and registry to redis.ParseURL so they accept the rediss:// URL from ElastiCache, but the URL the module writes (Secrets Manager property `url`, projected to FP_REDIS_URL by fp-infra-creds) embedded the raw token. override_special is "!&#$^<>-", and Go's net/url, which go-redis ParseURL uses, rejects `#` ("invalid port") and `^ < >` ("invalid userinfo") in the userinfo. The chance that a 48-character token avoids all four is (66/70)^48, about 6%, so roughly 94% of applies would have produced a URL that crashes billing and registry at boot with "invalid FP_REDIS_URL". ai-gateway, inference-gateway, feature-store, notification and model-monitor call ParseURL directly and had the same problem before this branch. Build the URL with urlencode(token). go-redis decodes the userinfo, so clients still send the exact token. This changes only the secret version's `url`; the token itself, the replication group and `auth_token` (raw, for clients that build their own connection) are untouched, so applying it does not rotate anything. Restricting override_special instead would have replaced random_password and rotated the token. Tests: billing and registry redisOptions gain a case with a token containing ! & # $ ^ < > -. It asserts the raw form is rejected and the url.QueryEscape form parses to the exact token with TLS on. Terraform's urlencode and Go's url.QueryEscape give the same output for this alphabet (checked with `terraform console` 1.14.8 and a Go probe). Correction to the 1899dc1 message: "Every Helm ConfigMap sets these URLs explicitly" is not accurate. fp-ai-gateway, fp-feature-store, fp-inference-gateway and fp-model-monitor set FP_REDIS_URL only in their Secret, which is now supplied out of band (secrets.create=false). Co-Authored-By: Claude Opus 5.5 --- deploy/secrets/README.md | 2 +- deploy/terraform/modules/elasticache/main.tf | 10 ++++++-- .../billing/cmd/server/redis_options_test.go | 23 ++++++++++++++++++- .../registry/cmd/server/redis_options_test.go | 23 ++++++++++++++++++- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/deploy/secrets/README.md b/deploy/secrets/README.md index 02db5f3..4874417 100644 --- a/deploy/secrets/README.md +++ b/deploy/secrets/README.md @@ -81,7 +81,7 @@ Files: |---|---|---|---| | `FP_DATABASE_URL` (templated) | RDS-managed `rds!db-...` (by ARN) + `/rds/postgres` | `username`/`password` + `host`/`port`/`dbname`/`sslmode` | `modules/rds` (`manage_master_user_password`) | | `POSTGRES_HOST`/`PORT` | `/rds/postgres` | `host`/`port` | `modules/rds` | -| `FP_REDIS_URL` | `/elasticache/redis` | `url` | `modules/elasticache` | +| `FP_REDIS_URL` | `/elasticache/redis` | `url` (`rediss://`, token percent-encoded) | `modules/elasticache` | | `REDIS_*` | `/elasticache/redis` | `host`/`port`/`auth_token` | `modules/elasticache` | | `FP_JWT_SECRET` | `/auth/jwt` | `jwt_secret` | operator-created (see note) | diff --git a/deploy/terraform/modules/elasticache/main.tf b/deploy/terraform/modules/elasticache/main.tf index af07a8d..cd5db87 100644 --- a/deploy/terraform/modules/elasticache/main.tf +++ b/deploy/terraform/modules/elasticache/main.tf @@ -74,7 +74,8 @@ resource "aws_security_group_rule" "redis_ingress" { # ---------------------------------------------------------------------------- # ElastiCache AUTH tokens have constraints: 16-128 chars, and only a limited # special-char set. We restrict override_special accordingly so the token is -# always accepted by ElastiCache. +# always accepted by ElastiCache. Several of these characters are not legal raw +# in a URL, so the `url` field below percent-encodes the token. # KNOWN RESIDUAL RISK: this token is stored in Terraform STATE (random_password # results, the replication group's auth_token and the secret_string below are # all persisted). Unlike RDS there is no AWS-managed password for ElastiCache, @@ -159,6 +160,11 @@ resource "aws_secretsmanager_secret_version" "redis" { auth_token = random_password.auth_token.result # rediss:// (note the double-s) = Redis over TLS, required because transit # encryption is on. The app uses this URL form instead of plain redis://. - url = "rediss://:${random_password.auth_token.result}@${aws_elasticache_replication_group.this.primary_endpoint_address}:${aws_elasticache_replication_group.this.port}" + # The token is percent-encoded: override_special includes # ^ < >, which + # Go's net/url (used by go-redis ParseURL) rejects in the userinfo part, so + # a raw token makes most generated URLs unparseable ("invalid FP_REDIS_URL" + # at boot). ParseURL decodes it back, so clients still send the real token. + # auth_token above stays raw for clients that build their own connection. + url = "rediss://:${urlencode(random_password.auth_token.result)}@${aws_elasticache_replication_group.this.primary_endpoint_address}:${aws_elasticache_replication_group.this.port}" }) } diff --git a/services/billing/cmd/server/redis_options_test.go b/services/billing/cmd/server/redis_options_test.go index a53d3bb..a4b35ee 100644 --- a/services/billing/cmd/server/redis_options_test.go +++ b/services/billing/cmd/server/redis_options_test.go @@ -1,6 +1,9 @@ package main -import "testing" +import ( + "net/url" + "testing" +) func TestRedisOptions(t *testing.T) { t.Run("bare host:port is used as the address", func(t *testing.T) { @@ -30,6 +33,24 @@ func TestRedisOptions(t *testing.T) { t.Fatal("expected TLS config for rediss://") } }) + // The ElastiCache module generates the token from [A-Za-z0-9] plus + // "!&#$^<>-". Go's net/url rejects #, ^, < and > raw in the userinfo, so + // Terraform writes the URL with urlencode(token). This pins both halves: + // the raw form fails, and the encoded form round-trips to the exact token. + t.Run("ElastiCache token must be percent-encoded in the URL", func(t *testing.T) { + const token = "Ab1!&#$^<>-z9Ab1!&#$^<>-z9" + const host = "master.example.cache.amazonaws.com:6379" + if _, err := redisOptions("rediss://:" + token + "@" + host); err == nil { + t.Fatal("expected the raw token to be rejected by net/url") + } + opts, err := redisOptions("rediss://:" + url.QueryEscape(token) + "@" + host) + if err != nil { + t.Fatalf("encoded token should parse: %v", err) + } + if opts.Password != token || opts.Addr != host || opts.TLSConfig == nil { + t.Fatalf("got Addr=%q password match=%t TLS=%t", opts.Addr, opts.Password == token, opts.TLSConfig != nil) + } + }) t.Run("bad scheme is an error", func(t *testing.T) { if _, err := redisOptions("http://localhost:6379"); err == nil { t.Fatal("expected an error for a non-redis scheme") diff --git a/services/registry/cmd/server/redis_options_test.go b/services/registry/cmd/server/redis_options_test.go index a53d3bb..a4b35ee 100644 --- a/services/registry/cmd/server/redis_options_test.go +++ b/services/registry/cmd/server/redis_options_test.go @@ -1,6 +1,9 @@ package main -import "testing" +import ( + "net/url" + "testing" +) func TestRedisOptions(t *testing.T) { t.Run("bare host:port is used as the address", func(t *testing.T) { @@ -30,6 +33,24 @@ func TestRedisOptions(t *testing.T) { t.Fatal("expected TLS config for rediss://") } }) + // The ElastiCache module generates the token from [A-Za-z0-9] plus + // "!&#$^<>-". Go's net/url rejects #, ^, < and > raw in the userinfo, so + // Terraform writes the URL with urlencode(token). This pins both halves: + // the raw form fails, and the encoded form round-trips to the exact token. + t.Run("ElastiCache token must be percent-encoded in the URL", func(t *testing.T) { + const token = "Ab1!&#$^<>-z9Ab1!&#$^<>-z9" + const host = "master.example.cache.amazonaws.com:6379" + if _, err := redisOptions("rediss://:" + token + "@" + host); err == nil { + t.Fatal("expected the raw token to be rejected by net/url") + } + opts, err := redisOptions("rediss://:" + url.QueryEscape(token) + "@" + host) + if err != nil { + t.Fatalf("encoded token should parse: %v", err) + } + if opts.Password != token || opts.Addr != host || opts.TLSConfig == nil { + t.Fatalf("got Addr=%q password match=%t TLS=%t", opts.Addr, opts.Password == token, opts.TLSConfig != nil) + } + }) t.Run("bad scheme is an error", func(t *testing.T) { if _, err := redisOptions("http://localhost:6379"); err == nil { t.Fatal("expected an error for a non-redis scheme") From dc5486585993f7e2ffe42b47385313441340ab4d Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:55:13 +0500 Subject: [PATCH 33/42] terraform: stop claiming the state bucket is already restricted to Terraform roles deploy/terraform/README.md and the ElastiCache module said the state bucket is "readable only by the roles that run Terraform" / "restricted to the Terraform roles", as fact. state_access_principal_arns defaults to [] in both the state-backend module and the bootstrap root, and an empty list adds no deny statement, so until someone sets it any principal in the account with S3 and KMS read access can read state, including the ElastiCache AUTH token. Say what is true: restricted to the roles in state_access_principal_arns once that variable is set. The variable is left optional on purpose: the bootstrap runs before the Terraform roles necessarily exist, and a wrong list would lock the operator out of their own state. Setting it is listed as an owner action in the PR. Co-Authored-By: Claude Opus 5.5 --- deploy/terraform/README.md | 6 ++++-- deploy/terraform/modules/elasticache/main.tf | 8 +++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/deploy/terraform/README.md b/deploy/terraform/README.md index 99884a1..68276f7 100644 --- a/deploy/terraform/README.md +++ b/deploy/terraform/README.md @@ -85,8 +85,10 @@ no AWS credentials and nothing has been applied. - The **Redis AUTH token** is generated by Terraform (`random_password`) and stored in Secrets Manager. ElastiCache has no managed-password option, and AWS provider 5.x has no write-only `auth_token`, so **this token is in state**. That is one reason the state - bucket is encrypted with a customer-managed KMS key and readable only by the roles - that run Terraform (see `modules/state-backend`). + bucket is encrypted with a customer-managed KMS key. It is readable only by the roles + in `state_access_principal_arns` **once you set that variable**: it defaults to `[]`, + and an empty list adds no deny statement, so until then any principal in the account + with S3 and KMS read access can read state (see `modules/state-backend`). - **Outputs** expose ARNs and endpoints only. None is marked `sensitive`, because none is a secret, and `sensitive` only hides a value from CLI output: it does not keep it out of state. (An earlier version of this README said the outputs were marked sensitive; diff --git a/deploy/terraform/modules/elasticache/main.tf b/deploy/terraform/modules/elasticache/main.tf index cd5db87..47784d6 100644 --- a/deploy/terraform/modules/elasticache/main.tf +++ b/deploy/terraform/modules/elasticache/main.tf @@ -80,9 +80,11 @@ resource "aws_security_group_rule" "redis_ingress" { # results, the replication group's auth_token and the secret_string below are # all persisted). Unlike RDS there is no AWS-managed password for ElastiCache, # and AWS provider 5.x has no write-only auth_token. Mitigations: the state -# bucket is SSE-KMS with a CMK and restricted to the Terraform roles -# (modules/state-backend). The longer-term fix is ElastiCache RBAC users with -# IAM authentication, which needs a client change (short-lived IAM auth tokens). +# bucket is SSE-KMS with a CMK, and restricted to the roles listed in +# state_access_principal_arns once that is set (it defaults to [], which adds +# no restriction; modules/state-backend). The longer-term fix is ElastiCache +# RBAC users with IAM authentication, which needs a client change (short-lived +# IAM auth tokens). # # DRIFT HAZARD: the replication group ignores auth_token changes (below) but the # secret version does not. If the token is ever rotated outside Terraform, the From 6b82d5ee5c79b70ba1296320c8c40c0b6aebe664 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:55:23 +0500 Subject: [PATCH 34/42] argocd: say which apps need a Secret before their first sync 0f0fcb8 set secrets.create=false in every chart, which is the right default, but nothing said what that means for the GitOps apps. Every Deployment still mounts a Secret named after its release via envFrom, and nothing the root app syncs creates one. Only fp-auth has an ExternalSecret in the repo (applied by hand). The other nine apps would sync and then sit in CreateContainerConfigError. That is fail-closed by design, but an operator should not have to discover it from pod events. - deploy/argocd/README.md: a table of all ten apps with Secret name, namespace, the keys the chart expects (from each templates/secret.yaml) and what the repo provides today, plus how to fill the gap (ExternalSecret per app modelled on externalsecret-fp-auth.yaml, or a SealedSecret) and the reminder that FP_JWT_SECRET must match across all ten. - apps/fp-*.yaml: the valueFiles comment still said the committed values carry an "in-chart Secret with placeholder creds". It now says the in-chart Secret is off and the release-named Secret must already exist. Secret names were checked by rendering each chart with its app's release name and namespace (helm template, default values). Co-Authored-By: Claude Opus 5.5 --- deploy/argocd/README.md | 32 +++++++++++++++++++ deploy/argocd/apps/fp-auth.yaml | 3 +- deploy/argocd/apps/fp-billing.yaml | 3 +- deploy/argocd/apps/fp-experiment-tracker.yaml | 3 +- deploy/argocd/apps/fp-feature-store.yaml | 3 +- deploy/argocd/apps/fp-inference-gateway.yaml | 3 +- deploy/argocd/apps/fp-model-monitor.yaml | 3 +- deploy/argocd/apps/fp-model-serving.yaml | 3 +- deploy/argocd/apps/fp-notification.yaml | 3 +- .../argocd/apps/fp-pipeline-orchestrator.yaml | 3 +- deploy/argocd/apps/fp-registry.yaml | 3 +- 11 files changed, 52 insertions(+), 10 deletions(-) diff --git a/deploy/argocd/README.md b/deploy/argocd/README.md index 3268bb3..2cbf85b 100644 --- a/deploy/argocd/README.md +++ b/deploy/argocd/README.md @@ -231,4 +231,36 @@ chart's optional in-chart Secret holds **dev-only placeholders** (see its values SECURITY CONTRACT), so `secrets.create` defaults to `false` and the real Secret comes from **External Secrets Operator** or **Sealed Secrets** (ADR-0002 follow-up, Phase 17) — the encrypted/sealed material is safe to commit, the plaintext never is. + +### Every app needs its Secret before the first sync + +`secrets.create` is `false` in every chart, and nothing the root app syncs +creates the Secrets. Each Deployment still mounts a Secret **named after its +release** (`envFrom`), so an app whose Secret does not exist yet still syncs, +but its pods sit in `CreateContainerConfigError` and the app goes Progressing, +then Degraded. That is deliberate +(fail closed instead of running on placeholder credentials), but plan for it: + +| App (Secret name) | Namespace | Keys the chart expects | Provided in this repo | +|---|---|---|---| +| `fp-auth` | fp-system | `FP_DATABASE_URL`, `FP_JWT_SECRET` (optional: `FP_BOOTSTRAP_ADMIN_PASSWORD`) | ExternalSecret `deploy/secrets/external-secrets/externalsecret-fp-auth.yaml` (applied by hand, not synced) | +| `fp-billing` | fp-system | `FP_DATABASE_URL`, `FP_JWT_SECRET` | **nothing yet** | +| `fp-experiment-tracker` | fp-system | `FP_DATABASE_URL`, `FP_JWT_SECRET` | **nothing yet** | +| `fp-feature-store` | fp-system | `FP_DATABASE_URL`, `FP_JWT_SECRET`, `FP_REDIS_URL` | **nothing yet** | +| `fp-inference-gateway` | fp-system | `FP_JWT_SECRET`, `FP_REDIS_URL` | **nothing yet** | +| `fp-model-monitor` | fp-system | `FP_DATABASE_URL`, `FP_JWT_SECRET`, `FP_REDIS_URL` | **nothing yet** | +| `fp-model-serving` | fp-models | `FP_JWT_SECRET` | **nothing yet** | +| `fp-notification` | fp-system | `FP_DATABASE_URL`, `FP_JWT_SECRET` | **nothing yet** | +| `fp-pipeline-orchestrator` | fp-system | `FP_DATABASE_URL`, `FP_JWT_SECRET` | **nothing yet** | +| `fp-registry` | fp-system | `FP_DATABASE_URL`, `FP_JWT_SECRET` | **nothing yet** | + +The key lists come from each chart's `templates/secret.yaml` (the dev Secret it +renders when `secrets.create=true`); that file is the reference if they drift. +`FP_JWT_SECRET` must be the same value in all ten. For the nine without one, +add an ExternalSecret (modelled on `externalsecret-fp-auth.yaml`, which also +shows how to template a DSN) or a SealedSecret per app, and apply it before +enabling the app. `fp-infra-creds` (`externalsecret-fp-infra-creds.yaml`) +carries the shared Postgres and Redis URLs, but no chart reads it by default. +For local Kind clusters, `make helm-install` passes `--set secrets.create=true` +with the dev placeholders, so this only bites GitOps installs. ``` diff --git a/deploy/argocd/apps/fp-auth.yaml b/deploy/argocd/apps/fp-auth.yaml index aa6b536..1597a82 100644 --- a/deploy/argocd/apps/fp-auth.yaml +++ b/deploy/argocd/apps/fp-auth.yaml @@ -61,7 +61,8 @@ spec: releaseName: fp-auth # valueFiles layered LEFT→RIGHT (later overrides earlier). The chart's # committed values.yaml carries DEV-safe defaults (per its SECURITY - # CONTRACT: in-chart Secret with placeholder creds, FP_ENV=local). For prod + # CONTRACT: secrets.create=false, so a Secret named after the release + # must already exist, see README "Secrets note"; FP_ENV=local). For prod # you ADD `- values-prod.yaml` here (External Secrets, real image tag, # higher replicas) — that file is the env override surface. valueFiles: diff --git a/deploy/argocd/apps/fp-billing.yaml b/deploy/argocd/apps/fp-billing.yaml index c84ece5..28f6eda 100644 --- a/deploy/argocd/apps/fp-billing.yaml +++ b/deploy/argocd/apps/fp-billing.yaml @@ -61,7 +61,8 @@ spec: releaseName: fp-billing # valueFiles layered LEFT→RIGHT (later overrides earlier). The chart's # committed values.yaml carries DEV-safe defaults (per its SECURITY - # CONTRACT: in-chart Secret with placeholder creds, FP_ENV=local). For prod + # CONTRACT: secrets.create=false, so a Secret named after the release + # must already exist, see README "Secrets note"; FP_ENV=local). For prod # you ADD `- values-prod.yaml` here (External Secrets, real image tag, # higher replicas) — that file is the env override surface. valueFiles: diff --git a/deploy/argocd/apps/fp-experiment-tracker.yaml b/deploy/argocd/apps/fp-experiment-tracker.yaml index 1021916..4546c0f 100644 --- a/deploy/argocd/apps/fp-experiment-tracker.yaml +++ b/deploy/argocd/apps/fp-experiment-tracker.yaml @@ -62,7 +62,8 @@ spec: releaseName: fp-experiment-tracker # valueFiles layered LEFT→RIGHT (later overrides earlier). The chart's # committed values.yaml carries DEV-safe defaults (per its SECURITY - # CONTRACT: in-chart Secret with placeholder creds, FP_ENV=local). For prod + # CONTRACT: secrets.create=false, so a Secret named after the release + # must already exist, see README "Secrets note"; FP_ENV=local). For prod # you ADD `- values-prod.yaml` here (External Secrets, real image tag, # higher replicas) — that file is the env override surface. valueFiles: diff --git a/deploy/argocd/apps/fp-feature-store.yaml b/deploy/argocd/apps/fp-feature-store.yaml index 21831a4..b581461 100644 --- a/deploy/argocd/apps/fp-feature-store.yaml +++ b/deploy/argocd/apps/fp-feature-store.yaml @@ -56,7 +56,8 @@ spec: releaseName: fp-feature-store # valueFiles layered LEFT→RIGHT (later overrides earlier). The chart's # committed values.yaml carries DEV-safe defaults (per its SECURITY - # CONTRACT: in-chart Secret with placeholder creds, FP_ENV=local). For prod + # CONTRACT: secrets.create=false, so a Secret named after the release + # must already exist, see README "Secrets note"; FP_ENV=local). For prod # you ADD `- values-prod.yaml` here (External Secrets, real image tag, # higher replicas) — that file is the env override surface. valueFiles: diff --git a/deploy/argocd/apps/fp-inference-gateway.yaml b/deploy/argocd/apps/fp-inference-gateway.yaml index e61ad5b..bb2b8a8 100644 --- a/deploy/argocd/apps/fp-inference-gateway.yaml +++ b/deploy/argocd/apps/fp-inference-gateway.yaml @@ -68,7 +68,8 @@ spec: releaseName: fp-inference-gateway # valueFiles layered LEFT→RIGHT (later overrides earlier). The chart's # committed values.yaml carries DEV-safe defaults (per its SECURITY - # CONTRACT: in-chart Secret with placeholder creds, FP_ENV=local). For prod + # CONTRACT: secrets.create=false, so a Secret named after the release + # must already exist, see README "Secrets note"; FP_ENV=local). For prod # you ADD `- values-prod.yaml` here (External Secrets, real image tag, # higher replicas) — that file is the env override surface. valueFiles: diff --git a/deploy/argocd/apps/fp-model-monitor.yaml b/deploy/argocd/apps/fp-model-monitor.yaml index ade67d0..91c81c6 100644 --- a/deploy/argocd/apps/fp-model-monitor.yaml +++ b/deploy/argocd/apps/fp-model-monitor.yaml @@ -57,7 +57,8 @@ spec: releaseName: fp-model-monitor # valueFiles layered LEFT→RIGHT (later overrides earlier). The chart's # committed values.yaml carries DEV-safe defaults (per its SECURITY - # CONTRACT: in-chart Secret with placeholder creds, FP_ENV=local). For prod + # CONTRACT: secrets.create=false, so a Secret named after the release + # must already exist, see README "Secrets note"; FP_ENV=local). For prod # you ADD `- values-prod.yaml` here (External Secrets, real image tag, # higher replicas) — that file is the env override surface. valueFiles: diff --git a/deploy/argocd/apps/fp-model-serving.yaml b/deploy/argocd/apps/fp-model-serving.yaml index 1561ecc..fc93399 100644 --- a/deploy/argocd/apps/fp-model-serving.yaml +++ b/deploy/argocd/apps/fp-model-serving.yaml @@ -49,7 +49,8 @@ spec: releaseName: fp-model-serving # valueFiles layered LEFT→RIGHT (later overrides earlier). The chart's # committed values.yaml carries DEV-safe defaults (per its SECURITY - # CONTRACT: in-chart Secret with placeholder creds, FP_ENV=local). For prod + # CONTRACT: secrets.create=false, so a Secret named after the release + # must already exist, see README "Secrets note"; FP_ENV=local). For prod # you ADD `- values-prod.yaml` here (External Secrets, real image tag, # higher replicas, the per-version model identity) — that file is the env # override surface. diff --git a/deploy/argocd/apps/fp-notification.yaml b/deploy/argocd/apps/fp-notification.yaml index 5105fc7..21471d7 100644 --- a/deploy/argocd/apps/fp-notification.yaml +++ b/deploy/argocd/apps/fp-notification.yaml @@ -63,7 +63,8 @@ spec: releaseName: fp-notification # valueFiles layered LEFT→RIGHT (later overrides earlier). The chart's # committed values.yaml carries DEV-safe defaults (per its SECURITY - # CONTRACT: in-chart Secret with placeholder creds, FP_ENV=local). For prod + # CONTRACT: secrets.create=false, so a Secret named after the release + # must already exist, see README "Secrets note"; FP_ENV=local). For prod # you ADD `- values-prod.yaml` here (External Secrets, real image tag, # higher replicas) — that file is the env override surface. valueFiles: diff --git a/deploy/argocd/apps/fp-pipeline-orchestrator.yaml b/deploy/argocd/apps/fp-pipeline-orchestrator.yaml index c8a3ab1..69ce455 100644 --- a/deploy/argocd/apps/fp-pipeline-orchestrator.yaml +++ b/deploy/argocd/apps/fp-pipeline-orchestrator.yaml @@ -65,7 +65,8 @@ spec: releaseName: fp-pipeline-orchestrator # valueFiles layered LEFT→RIGHT (later overrides earlier). The chart's # committed values.yaml carries DEV-safe defaults (per its SECURITY - # CONTRACT: in-chart Secret with placeholder creds, FP_ENV=local). For prod + # CONTRACT: secrets.create=false, so a Secret named after the release + # must already exist, see README "Secrets note"; FP_ENV=local). For prod # you ADD `- values-prod.yaml` here (External Secrets, real image tag, # higher replicas) — that file is the env override surface. valueFiles: diff --git a/deploy/argocd/apps/fp-registry.yaml b/deploy/argocd/apps/fp-registry.yaml index 2461977..fe774db 100644 --- a/deploy/argocd/apps/fp-registry.yaml +++ b/deploy/argocd/apps/fp-registry.yaml @@ -59,7 +59,8 @@ spec: releaseName: fp-registry # valueFiles layered LEFT→RIGHT (later overrides earlier). The chart's # committed values.yaml carries DEV-safe defaults (per its SECURITY - # CONTRACT: in-chart Secret with placeholder creds, FP_ENV=local). For prod + # CONTRACT: secrets.create=false, so a Secret named after the release + # must already exist, see README "Secrets note"; FP_ENV=local). For prod # you ADD `- values-prod.yaml` here (External Secrets, real image tag, # higher replicas) — that file is the env override surface. valueFiles: From bde56b9b33a6e60e7e4253fa9056f5a336ad85b3 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:55:39 +0500 Subject: [PATCH 35/42] policies: allowlist the pinned observability images restrict-image-registries matches fp-infra, where deploy/k8s/observability runs grafana/grafana, grafana/loki, grafana/tempo, prom/prometheus and otel/opentelemetry-collector-contrib. None was allowlisted. fd5ffae rewrote the allowlist and d3da918 pinned these images by digest, but only migrate/migrate was called out as an Enforce blocker; applying overlays/enforce would have blocked the whole observability plane. The gap predates this branch. Add each one as a full repo path, in both the short and docker.io- qualified spellings like the other infra images (never "grafana/*" or "docker.io/*"). The deny message and policies/README.md list them, and the README notes that ollama/ollama runs in fp-ml, which these policies do not match. Checked: every container and initContainer image rendered from deploy/k8s/infra, deploy/k8s/observability, deploy/backup, deploy/rollouts and all fp-* charts (24 distinct refs, digests included) matches at least one allowlist glob. overlays/audit and overlays/enforce still render. Co-Authored-By: Claude Opus 5.5 --- deploy/policies/README.md | 9 +++++++- deploy/policies/base/20-image-policies.yaml | 25 ++++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/deploy/policies/README.md b/deploy/policies/README.md index 7e84db1..46230a5 100644 --- a/deploy/policies/README.md +++ b/deploy/policies/README.md @@ -25,7 +25,7 @@ This is part of milestone **M6 — Platform security, GitOps & autoscaling** | `require-seccomp-runtimedefault` | `seccompProfile.type` is `RuntimeDefault`/`Localhost` | all pods' podSecurityContext | | `require-resource-requests-and-limits` | cpu+memory **requests AND limits** on every container | fp-auth `resources`; all infra pods | | `disallow-latest-tag` | image is tagged and not `:latest` | pinned infra tags; appVersion tag | -| `restrict-image-registries` | image from the **allowlist** (parameterized) | ghcr, distroless, migrate, pinned infra; ECR only per-account in the EKS overlay | +| `restrict-image-registries` | image from the **allowlist** (parameterized) | ghcr, distroless, migrate, pinned infra and observability images; ECR only per-account in the EKS overlay | | `verify-image-signatures` | `ghcr.io/abd-ulbasit/forgepoint/*` carries a cosign **keyless** signature from this repo's `security.yml` on `main` or a `v*` tag | the Security workflow's `publish` job | | `require-part-of-label` | `app.kubernetes.io/part-of=forgepoint` on pod templates | recommended labels everywhere | | `disallow-host-namespaces` | no `hostPID`/`hostIPC`/`hostNetwork` | (none of ours use them) | @@ -75,6 +75,13 @@ single list. It currently allows: charts (previously missing: Enforce would have blocked every migration) - the **specific pinned infra images**: `postgres`, `redis`, `nats`, `minio/minio`, `minio/mc` (both short and `docker.io/...` spellings) +- the **specific pinned observability images** in `fp-infra`: + `grafana/grafana`, `grafana/loki`, `grafana/tempo`, `prom/prometheus`, + `otel/opentelemetry-collector-contrib` (both spellings; previously missing, so + Enforce would have blocked the whole observability plane) + +`ollama/ollama` (`deploy/llm`) runs in `fp-ml`, which these policies do not +match, so it needs no entry unless the scope grows. There is deliberately **no ECR entry** in the base. The old `*.dkr.ecr.*.amazonaws.com/*` glob matched any AWS account's registry, an diff --git a/deploy/policies/base/20-image-policies.yaml b/deploy/policies/base/20-image-policies.yaml index 031b0e5..70ac46c 100644 --- a/deploy/policies/base/20-image-policies.yaml +++ b/deploy/policies/base/20-image-policies.yaml @@ -126,6 +126,11 @@ spec: # docker.io/minio/{minio,mc}. We pin the FULL repo path (not a bare # "docker.io/*") so only these specific, reviewed infra images are allowed — # not all of Docker Hub. +# - the PINNED observability images in fp-infra (deploy/k8s/observability): +# grafana/{grafana,loki,tempo}, prom/prometheus and +# otel/opentelemetry-collector-contrib. They were missing, so flipping to +# Enforce would have blocked the whole observability plane. Same rule: one +# full repo path each, never "grafana/*" or "docker.io/*". # # HOW THE CHECK WORKS: for each container we test whether its image matches ANY # entry in `allowedRegistries`. JMESPath has no "matches any glob" builtin, so we @@ -205,13 +210,27 @@ spec: # golang-migrate initContainer in the fp-* charts. - "migrate/migrate:*" - "docker.io/migrate/migrate:*" + # Pinned observability images (deploy/k8s/observability, fp-infra). + - "grafana/grafana:*" + - "docker.io/grafana/grafana:*" + - "grafana/loki:*" + - "docker.io/grafana/loki:*" + - "grafana/tempo:*" + - "docker.io/grafana/tempo:*" + - "prom/prometheus:*" + - "docker.io/prom/prometheus:*" + - "otel/opentelemetry-collector-contrib:*" + - "docker.io/otel/opentelemetry-collector-contrib:*" validate: message: >- Image registry is not allowlisted. Allowed: ghcr.io/abd-ulbasit/forgepoint, gcr.io/distroless, migrate/migrate, - and the pinned infra images (postgres, redis, nats, minio/minio, - minio/mc). ECR is allowed only for the single account added by the - EKS overlay. Edit restrict-image-registries to add one. + the pinned infra images (postgres, redis, nats, minio/minio, + minio/mc) and the pinned observability images (grafana/grafana, + grafana/loki, grafana/tempo, prom/prometheus, + otel/opentelemetry-collector-contrib). ECR is allowed only for the + single account added by the EKS overlay. Edit + restrict-image-registries to add one. # foreach + deny: for each container, count how many allowlist globs the # image matches; deny when ZERO match. # From c83159259ef042fda292438c1381fe6e9b99707e Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:55:39 +0500 Subject: [PATCH 36/42] docs: fix three stale or contradictory statements - deploy/rollouts/README.md: the paragraph added in 753661d says the AnalysisTemplates now query the plain `prometheus` Service because this repo does not run the Prometheus Operator, but the old line below it still called that address "the kube-prometheus-stack (or Prometheus Operator) address". Removed; kept the "adjust if yours differs" advice. - deploy/rollouts/kustomization.yaml: the comment called newTag "0.1.0" a tag the Security workflow published. Nothing has been published: GHCR returns 404 for forgepoint/inference-gateway and model-serving (checked again today), and the existing v0.1.0 git tag predates the publish job. The comment now says 0.1.0 is a placeholder, that the Rollouts will be in ImagePullBackOff until a release passes a green pipeline, and how to get one (push a new v* tag once the gates pass). The pin is unchanged. - docs/adr/0010: "12 templates/secret.yaml files" is 11. All 11 reference JWT_SECRET (fp-bff has no secret.yaml). Co-Authored-By: Claude Opus 5.5 --- deploy/rollouts/README.md | 4 ++-- deploy/rollouts/kustomization.yaml | 8 ++++++-- docs/adr/0010-asymmetric-jwt-signing.md | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/deploy/rollouts/README.md b/deploy/rollouts/README.md index 6f0e9d7..b32a89a 100644 --- a/deploy/rollouts/README.md +++ b/deploy/rollouts/README.md @@ -104,8 +104,8 @@ revisions pointed at `prometheus-operated`, the Service name the Prometheus *Operator* creates; this repo runs plain Prometheus, so that name never resolved and every analysis run would have failed.) -This is the kube-prometheus-stack (or Prometheus Operator) address. Adjust if -your Prometheus service has a different name or namespace. +Adjust the address in both AnalysisTemplates if your Prometheus Service has a +different name or namespace. --- diff --git a/deploy/rollouts/kustomization.yaml b/deploy/rollouts/kustomization.yaml index f12856a..1a0b5ab 100644 --- a/deploy/rollouts/kustomization.yaml +++ b/deploy/rollouts/kustomization.yaml @@ -77,8 +77,12 @@ resources: # THE deployed image tags, in one place. Bump with e.g. # kustomize edit set image ghcr.io/abd-ulbasit/forgepoint/model-serving:0.2.0 -# to a tag the Security workflow published (semver or sha-<40>). 0.1.0 matches -# Chart.appVersion, the tag the Helm charts fall back to. +# to a tag the Security workflow published (semver or sha-<40>). +# PLACEHOLDER: 0.1.0 matches Chart.appVersion, the tag the Helm charts fall back +# to, but NO image has been published yet (GHCR has none for these repos, and +# the existing v0.1.0 git tag predates the publish job). These Rollouts will sit +# in ImagePullBackOff until a release goes through a green Security pipeline: +# push a new v* tag once the gates pass, then set that version here. images: - name: ghcr.io/abd-ulbasit/forgepoint/inference-gateway newTag: "0.1.0" diff --git a/docs/adr/0010-asymmetric-jwt-signing.md b/docs/adr/0010-asymmetric-jwt-signing.md index dd0835b..11f2d07 100644 --- a/docs/adr/0010-asymmetric-jwt-signing.md +++ b/docs/adr/0010-asymmetric-jwt-signing.md @@ -10,7 +10,7 @@ `services/auth` mints access tokens with **HS256** (`services/auth/internal/domain/jwt.go`), and every other service verifies them locally with `pkg/auth/validator.go`, using the **same** symmetric key. That key, `FP_JWT_SECRET`, is rendered into the Secret of 11 Helm -charts (12 `templates/secret.yaml` files reference it) and stored once in Secrets Manager +charts (all 11 `templates/secret.yaml` files reference it) and stored once in Secrets Manager (`/auth/jwt`, created by hand with the aws CLI). The verifier side is careful: it pins the algorithm (identity check on From a3d222b0d415e65cc823dcc0e26df5daf4cd2adb Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 01:55:40 +0500 Subject: [PATCH 37/42] ci(security): keep scheduled runs from cancelling pending push runs The weekly schedule added in b1e2b19 shared the concurrency group security-- with pushes to main. GitHub keeps at most one pending run per group and cancels it when another queues, regardless of cancel-in-progress. So a scheduled run that queued while a push run was in progress and another push run was pending cancelled that pending push run, and its commit was never published or signed. Add github.event_name to the group. Schedule and workflow_dispatch runs now queue separately and never displace a push. Pull-request runs are unaffected (their ref is already per PR). Push runs to main still queue behind each other as before; a burst of merges still publishes only the newest pending commit, which is the existing trade-off. actionlint passes. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/security.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 84c38fd..b55d989 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -66,8 +66,14 @@ on: permissions: contents: read +# The event is part of the group. GitHub keeps at most one PENDING run per +# group and cancels it when another run queues, whatever cancel-in-progress +# says. Without the event, the weekly schedule run (ref = main) could queue +# behind an in-progress push run and cancel a pending push run, so that commit +# would never be published or signed. Schedule and dispatch runs now queue in +# their own groups and never displace a push. concurrency: - group: security-${{ github.workflow }}-${{ github.ref }} + group: security-${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} env: From dc9a4e3f3e02f93618c9ab0e83c23193d9ec038a Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 04:25:38 +0500 Subject: [PATCH 38/42] build: pin Go 1.26.10 in go.mod, go.work, CI and Dockerfiles govulncheck failed in all 15 modules on GO-2026-6809 (crypto/x509, reachable from every service's http.Server). The workflows asked setup-go for a bare "1.26", which resolved to the runner's cached 1.26.9; the builder images were pinned to a golang:1.26-alpine digest that is Go 1.26.4. Go 1.26.10 fixes it. Set the exact patch release everywhere the version is chosen: - go.work and all 15 go.mod files: `go 1.26.10` (was 1.26.0 / 1.25.0). setup-go and the golang image both set GOTOOLCHAIN=local, so an older toolchain now refuses to build instead of silently compiling on an unpatched standard library. - GO_VERSION "1.26.10" in ci.yml and security.yml. - All 12 Dockerfiles: golang:1.26.10-alpine by multi-arch index digest (sha256:27f2d3b8..., GOLANG_VERSION=1.26.10 in its config). - README prerequisites and ADR 0006 now name the same version. Stayed on 1.26.x rather than 1.27.3: a patch bump fixes the advisory without a minor-version upgrade in a security PR. This clears only the standard-library finding. govulncheck still fails every module on reachable third-party advisories (x/net, grpc, x/text, otel, x/crypto, moby/go-archive), which are dependency bumps left to Dependabot #17 (see SECURITY.md). Checked with GOTOOLCHAIN=go1.26.10: govulncheck v1.1.4 reports no standard-library finding in any module; go build, go vet and go test -race -shuffle=on pass in all 15 modules (Docker-backed tests not run locally); golangci-lint v2.12.2 (release binary) reports 0 issues in the 14 linted modules; GOTOOLCHAIN=go1.26.9 is refused. services/ai-gateway built with buildx on the remote engine: its binary reports go1.26.10 and Trivy (image, os,library) finds no stdlib or OS CVE, only the dependency CVEs above. The other 11 images share the same FROM line; their builds could not finish (engine disk full). Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 12 ++++++++---- .github/workflows/security.yml | 6 +++++- README.md | 2 +- cli/go.mod | 2 +- docs/adr/0006-go-workspace-monorepo.md | 6 +++--- gen/go/go.mod | 2 +- go.work | 2 +- pkg/go.mod | 2 +- services/ai-gateway/Dockerfile | 19 +++++++++++-------- services/ai-gateway/go.mod | 2 +- services/auth/Dockerfile | 19 +++++++++++-------- services/auth/go.mod | 2 +- services/bff/Dockerfile | 9 +++++---- services/bff/go.mod | 2 +- services/billing/Dockerfile | 19 +++++++++++-------- services/billing/go.mod | 2 +- services/experiment-tracker/Dockerfile | 19 +++++++++++-------- services/experiment-tracker/go.mod | 2 +- services/feature-store/Dockerfile | 19 +++++++++++-------- services/feature-store/go.mod | 2 +- services/inference-gateway/Dockerfile | 19 +++++++++++-------- services/inference-gateway/go.mod | 2 +- services/model-monitor/Dockerfile | 19 +++++++++++-------- services/model-monitor/go.mod | 2 +- services/model-serving/Dockerfile | 19 +++++++++++-------- services/model-serving/go.mod | 2 +- services/notification/Dockerfile | 19 +++++++++++-------- services/notification/go.mod | 2 +- services/pipeline-orchestrator/Dockerfile | 19 +++++++++++-------- services/pipeline-orchestrator/go.mod | 2 +- services/registry/Dockerfile | 19 +++++++++++-------- services/registry/go.mod | 2 +- 32 files changed, 159 insertions(+), 117 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d644ff7..5070cd5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,11 +50,15 @@ concurrency: group: ci-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} -# Pin the toolchain to the go.work `go 1.26.0` directive. The Go toolchain -# refuses to build a workspace whose go directive is newer than the toolchain, -# so this MUST track go.work (bump both together on a Go upgrade). +# Pin the toolchain to the exact patch release in go.work's `go 1.26.10` +# directive. setup-go sets GOTOOLCHAIN=local, so a toolchain older than that +# directive refuses to build the workspace; this MUST track go.work, every +# go.mod and the golang builder image in services/*/Dockerfile (bump all of +# them together on a Go upgrade). A bare "1.26" let setup-go pick whatever +# 1.26.x the runner had cached (1.26.9, which govulncheck flags for +# GO-2026-6809 in crypto/x509). env: - GO_VERSION: "1.26" + GO_VERSION: "1.26.10" jobs: # --------------------------------------------------------------------------- diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index b55d989..f73ed74 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -77,7 +77,11 @@ concurrency: cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} env: - GO_VERSION: "1.26" + # Exact patch release, kept equal to go.work, every go.mod and the golang + # builder image in services/*/Dockerfile. govulncheck reports standard-library + # vulnerabilities against THIS toolchain, so a bare "1.26" made the result + # depend on whichever 1.26.x the runner had cached. + GO_VERSION: "1.26.10" REGISTRY: ghcr.io # Every image is ghcr.io///, the name the Helm charts, # Rollouts and the Kyverno allowlist use (ghcr.io/abd-ulbasit/forgepoint/auth). diff --git a/README.md b/README.md index 55d2694..adb58f0 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ Reusable building blocks every service imports: ## Getting started -Prerequisites: Go 1.26+, Docker, `make`. +Prerequisites: Go 1.26.10+ (the `go` directive in `go.work`; an older Go downloads 1.26.10 unless `GOTOOLCHAIN=local`), Docker, `make`. ```bash # Start local infrastructure (NATS, Postgres, Redis, MinIO, monitoring) diff --git a/cli/go.mod b/cli/go.mod index c5559e4..20b44db 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/cli -go 1.25.0 +go 1.26.10 require ( google.golang.org/grpc v1.82.1 diff --git a/docs/adr/0006-go-workspace-monorepo.md b/docs/adr/0006-go-workspace-monorepo.md index e99d86a..0cfb6f4 100644 --- a/docs/adr/0006-go-workspace-monorepo.md +++ b/docs/adr/0006-go-workspace-monorepo.md @@ -71,7 +71,7 @@ its own `go.mod`; `pkg/` and `gen/go/` are sibling modules the workspace resolve Adopt **Option D**: a **Go workspace monorepo** — `go.work` + a module per service + `gen/go` + `pkg`. The `go.work` `use(...)` block lists `./gen/go`, `./pkg`, `./cli` and every -`./services/*` module (15 entries today); the workspace declares `go 1.26.0`. +`./services/*` module (15 entries today); the workspace declares `go 1.26.10`. Three gotchas are part of the decision (each cost real debugging; all are now encoded in `docs/design/service-architecture.md` and `services/auth/Dockerfile`): @@ -108,8 +108,8 @@ RUN go work init ./pkg ./gen/go ./services/auth && go mod download -x all This is **self-contained** (adding another service never breaks an existing image), **correct** (`./pkg`/`./gen/go` resolve to local source exactly as on a laptop), and keeps **module isolation honest** — a service image can only build against `pkg`, `gen/go`, and its own -source, never another service's. The builder image is pinned to `golang:1.26-alpine` to match -the workspace's `go 1.26.0` directive (an older toolchain refuses to build a newer workspace). +source, never another service's. The builder image is pinned to `golang:1.26.10-alpine` to match +the `go 1.26.10` directive in the workspace and every module (an older toolchain refuses to build a newer workspace). Deciding factor: Option D is the only one that delivers share-without-publish **and** per-service dependency/build isolation; the gotchas are one-time costs already paid and diff --git a/gen/go/go.mod b/gen/go/go.mod index 96d8e2c..fa56287 100644 --- a/gen/go/go.mod +++ b/gen/go/go.mod @@ -10,7 +10,7 @@ // bump protobuf/grpc versions for the whole platform. module github.com/abd-ulbasit/forgepoint/gen/go -go 1.25.0 +go 1.26.10 require ( google.golang.org/grpc v1.82.1 diff --git a/go.work b/go.work index 4267844..66fa859 100644 --- a/go.work +++ b/go.work @@ -33,7 +33,7 @@ // NOTE: Services are added to `use()` as they're built. Start with just // pkg (shared libs) and auth (first service). -go 1.26.0 +go 1.26.10 use ( ./cli diff --git a/pkg/go.mod b/pkg/go.mod index ba01a95..7b90c2f 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/pkg -go 1.25.0 +go 1.26.10 require ( github.com/golang-jwt/jwt/v5 v5.3.1 diff --git a/services/ai-gateway/Dockerfile b/services/ai-gateway/Dockerfile index b2320f7..ae2c51c 100644 --- a/services/ai-gateway/Dockerfile +++ b/services/ai-gateway/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/ai-gateway/go.mod b/services/ai-gateway/go.mod index c599910..6ca4875 100644 --- a/services/ai-gateway/go.mod +++ b/services/ai-gateway/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/ai-gateway -go 1.25.0 +go 1.26.10 require ( github.com/google/uuid v1.6.0 diff --git a/services/auth/Dockerfile b/services/auth/Dockerfile index d20646d..a2bec65 100644 --- a/services/auth/Dockerfile +++ b/services/auth/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/auth/go.mod b/services/auth/go.mod index 21bb3b3..2dfd701 100644 --- a/services/auth/go.mod +++ b/services/auth/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/auth -go 1.25.0 +go 1.26.10 require ( github.com/golang-jwt/jwt/v5 v5.3.1 diff --git a/services/bff/Dockerfile b/services/bff/Dockerfile index 8cb1080..d1f530a 100644 --- a/services/bff/Dockerfile +++ b/services/bff/Dockerfile @@ -34,10 +34,11 @@ # Stage 1: builder — full Go toolchain, compiles the static binary. # ---------------------------------------------------------------------------- # Pinned by multi-arch index DIGEST (not a floating tag) for hermetic, reproducible -# builds across amd64/arm64. The builder is 1.26 to match go.work's `go 1.26.0` -# directive (a 1.25 toolchain refuses to build a workspace declaring a newer Go). -# Refresh with: docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# builds across amd64/arm64. The builder is 1.26.10 to match the `go 1.26.10` +# directive in go.work and every go.mod (with GOTOOLCHAIN=local an older +# toolchain refuses to build them; 1.26.9 carried GO-2026-6809 in crypto/x509). +# Refresh with: docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: VCS stamping/tooling. ca-certificates: HTTPS module fetches. We pass # -buildvcs=false below so the .git dir need not be in the context. diff --git a/services/bff/go.mod b/services/bff/go.mod index 6137d6d..b3ef21c 100644 --- a/services/bff/go.mod +++ b/services/bff/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/bff -go 1.25.0 +go 1.26.10 require ( google.golang.org/grpc v1.82.1 diff --git a/services/billing/Dockerfile b/services/billing/Dockerfile index 7b47276..12aa538 100644 --- a/services/billing/Dockerfile +++ b/services/billing/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/billing/go.mod b/services/billing/go.mod index 752dd7b..1de20dd 100644 --- a/services/billing/go.mod +++ b/services/billing/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/billing -go 1.25.0 +go 1.26.10 require ( github.com/google/uuid v1.6.0 diff --git a/services/experiment-tracker/Dockerfile b/services/experiment-tracker/Dockerfile index 7e40dc7..e0891e1 100644 --- a/services/experiment-tracker/Dockerfile +++ b/services/experiment-tracker/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/experiment-tracker/go.mod b/services/experiment-tracker/go.mod index 43b3bda..fe5f100 100644 --- a/services/experiment-tracker/go.mod +++ b/services/experiment-tracker/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/experiment-tracker -go 1.25.0 +go 1.26.10 require ( github.com/google/uuid v1.6.0 diff --git a/services/feature-store/Dockerfile b/services/feature-store/Dockerfile index 5a470d4..62f5faa 100644 --- a/services/feature-store/Dockerfile +++ b/services/feature-store/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/feature-store/go.mod b/services/feature-store/go.mod index 776c745..39fa1e1 100644 --- a/services/feature-store/go.mod +++ b/services/feature-store/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/feature-store -go 1.25.0 +go 1.26.10 require ( github.com/google/uuid v1.6.0 diff --git a/services/inference-gateway/Dockerfile b/services/inference-gateway/Dockerfile index 53a5499..042b2bc 100644 --- a/services/inference-gateway/Dockerfile +++ b/services/inference-gateway/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/inference-gateway/go.mod b/services/inference-gateway/go.mod index e26a166..a8c279f 100644 --- a/services/inference-gateway/go.mod +++ b/services/inference-gateway/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/inference-gateway -go 1.25.0 +go 1.26.10 require ( github.com/google/uuid v1.6.0 diff --git a/services/model-monitor/Dockerfile b/services/model-monitor/Dockerfile index f977c26..3198442 100644 --- a/services/model-monitor/Dockerfile +++ b/services/model-monitor/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/model-monitor/go.mod b/services/model-monitor/go.mod index 6abfef3..0d691f9 100644 --- a/services/model-monitor/go.mod +++ b/services/model-monitor/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/model-monitor -go 1.25.0 +go 1.26.10 require ( github.com/google/uuid v1.6.0 diff --git a/services/model-serving/Dockerfile b/services/model-serving/Dockerfile index 1e69ba9..43413ee 100644 --- a/services/model-serving/Dockerfile +++ b/services/model-serving/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/model-serving/go.mod b/services/model-serving/go.mod index 05f1601..97d4f01 100644 --- a/services/model-serving/go.mod +++ b/services/model-serving/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/model-serving -go 1.25.0 +go 1.26.10 require ( github.com/google/uuid v1.6.0 diff --git a/services/notification/Dockerfile b/services/notification/Dockerfile index d27b8bc..dd99797 100644 --- a/services/notification/Dockerfile +++ b/services/notification/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/notification/go.mod b/services/notification/go.mod index 158b091..e751776 100644 --- a/services/notification/go.mod +++ b/services/notification/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/notification -go 1.25.0 +go 1.26.10 require ( github.com/google/uuid v1.6.0 diff --git a/services/pipeline-orchestrator/Dockerfile b/services/pipeline-orchestrator/Dockerfile index 5f5ef69..7291845 100644 --- a/services/pipeline-orchestrator/Dockerfile +++ b/services/pipeline-orchestrator/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/pipeline-orchestrator/go.mod b/services/pipeline-orchestrator/go.mod index 420c329..5986522 100644 --- a/services/pipeline-orchestrator/go.mod +++ b/services/pipeline-orchestrator/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/pipeline-orchestrator -go 1.25.0 +go 1.26.10 require ( github.com/google/uuid v1.6.0 diff --git a/services/registry/Dockerfile b/services/registry/Dockerfile index dc67e4c..02b7f96 100644 --- a/services/registry/Dockerfile +++ b/services/registry/Dockerfile @@ -69,13 +69,16 @@ # isolation is enforced at build time, not just by convention). # # ----------------------------------------------------------------------------- -# WHY golang:1.26-alpine (NOT 1.25) +# WHY golang:1.26.10-alpine (AN EXACT PATCH RELEASE) # ----------------------------------------------------------------------------- -# `go.work` declares `go 1.26.0`. The Go toolchain refuses to build a workspace -# whose go directive is NEWER than the toolchain, so a 1.25 image cannot build -# this repo (it would either error or trigger a slow toolchain auto-download). -# We pin the builder to 1.26 to match the workspace. Bump this line in lockstep -# with the `go` directive in go.work when the platform upgrades Go. +# go.work and every go.mod declare `go 1.26.10`. The image sets +# GOTOOLCHAIN=local, so the Go toolchain refuses to build modules whose go +# directive is NEWER than the toolchain: an older image errors out instead of +# compiling a binary on an unpatched standard library. The patch level matters +# because the binary's standard library IS this image's Go (1.26.9 carried +# GO-2026-6809 in crypto/x509). Bump this line (tag AND digest) in lockstep +# with the `go` directive in go.work and every go.mod, and GO_VERSION in +# .github/workflows/{ci,security}.yml. # # ----------------------------------------------------------------------------- # WHY distroless/static + nonroot for the final image @@ -106,8 +109,8 @@ # reproducible builds: the same Dockerfile resolves to the identical bytes today # and a year from now. These are multi-arch index digests, so the build works on # amd64 and arm64 hosts alike. Refresh with: -# docker buildx imagetools inspect golang:1.26-alpine -FROM golang:1.26-alpine@sha256:f1ddd9fe14fffc091dd98cb4bfa999f32c5fc77d2f2305ea9f0e2595c5437c14 AS builder +# docker buildx imagetools inspect golang:1.26.10-alpine +FROM golang:1.26.10-alpine@sha256:27f2d3b83cfc5803c8078f8e730af0f7c431bf067afaec8f60a36fb763187cba AS builder # git: some Go tooling/VCS stamping needs it. ca-certificates: for module fetches # over HTTPS. We disable VCS stamping at build time anyway (-buildvcs=false) so diff --git a/services/registry/go.mod b/services/registry/go.mod index 5aff1d8..524ebbe 100644 --- a/services/registry/go.mod +++ b/services/registry/go.mod @@ -1,6 +1,6 @@ module github.com/abd-ulbasit/forgepoint/services/registry -go 1.25.0 +go 1.26.10 require ( github.com/jackc/pgx/v5 v5.10.0 From 7168edd8c226bc38371c5362b76363e5b7545a33 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 04:25:44 +0500 Subject: [PATCH 39/42] web: bump axios to 1.20.0 and follow-redirects to 1.16.1 The CI web job failed at `npm audit --omit=dev --audit-level=high` on HIGH advisories in two production packages: - axios 1.18.0: GHSA-542g-h47m-68v8 (HTTP/2 session DoS) and eleven others, all fixed in 1.20.0. Dependabot #10 only reaches 1.19.0, which is still in the vulnerable range. - follow-redirects 1.16.0 (axios' transitive dependency): GHSA-q3jh-wrc6-jgq8 and GHSA-8r9p-f939-6h3c, fixed in 1.16.1. `npm install axios@1.20.0` raises the package.json floor to ^1.20.0; `npm update follow-redirects` moves the transitive pin within axios' existing ^1.16.0 range. Both with --package-lock-only --ignore-scripts. The lockfile diff is those two packages and axios' form-data range (already satisfied by the locked 4.0.6). Trivy's fs scan reported the same nine CVEs in web/package-lock.json; it no longer does. react-router-dom stays on 6.30.4. Its two advisories (GHSA-337j-9hxr-rhxg, GHSA-wrjc-x8rr-h8h6) are MODERATE, below the gate, and fixed only in the 7.x major (Dependabot #4). GHSA-337j only affects SSR hydration in Data/Framework mode; this app uses declarative with no SSR. Checked in node:22 (npm 10.9.9, as CI): npm ci --ignore-scripts, npm run typecheck, npm run build, and npm audit --omit=dev --audit-level=high (exit 0, 2 moderate left). Co-Authored-By: Claude Opus 5.5 --- web/package-lock.json | 16 ++++++++-------- web/package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/web/package-lock.json b/web/package-lock.json index 85241b1..32bb8b3 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@tanstack/react-query": "^5.59.0", - "axios": "^1.7.7", + "axios": "^1.20.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.27.0", @@ -1499,13 +1499,13 @@ } }, "node_modules/axios": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.18.0.tgz", - "integrity": "sha512-E32NzpYKp++W7XRe52rHiXV2ehxmh3wbdgO7MHeFM+vqxLBYHzt0ElkiImtOBxtOmyp0yoC8C6uESVV84Y2/hw==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz", + "integrity": "sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==", "license": "MIT", "dependencies": { "follow-redirects": "^1.16.0", - "form-data": "^4.0.5", + "form-data": "^4.0.6", "https-proxy-agent": "^5.0.1", "proxy-from-env": "^2.1.0" } @@ -2083,9 +2083,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", - "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.1.tgz", + "integrity": "sha512-FNvFGzoMLWmE6Yj9spb/zjd7yiNCHiAW9/Tg9CXrQ8wuu32HtlJOwWO11OJafl5FfY3DxTdQ0vj42zU1kvv5jg==", "funding": [ { "type": "individual", diff --git a/web/package.json b/web/package.json index e8469ac..8809c31 100644 --- a/web/package.json +++ b/web/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "@tanstack/react-query": "^5.59.0", - "axios": "^1.7.7", + "axios": "^1.20.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.27.0", From ece4442d9d20e7bd3e42e86762485952085e3b77 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 04:25:44 +0500 Subject: [PATCH 40/42] docs(security): record what still keeps Security red The "Still red" table listed axios and follow-redirects, which the previous commit fixes, and said nothing about govulncheck. After the Go 1.26.10 pin, govulncheck still fails every module, on reachable third-party advisories rather than the standard library. - Drop the axios and follow-redirects rows; note they and GO-2026-6809 are fixed on this branch. - Add otel (GO-2026-6505, fixed in 1.45.0; #17 brings 1.46.0) and note that govulncheck wants x/crypto 0.56.0 for GO-2026-6354/6355, one past the 0.55.0 that Trivy and #17 use. - Note that bff also carries the otel advisory #17 does not reach. Versions are from govulncheck v1.1.4 and Trivy v0.70.0 run on this branch. Co-Authored-By: Claude Opus 5.5 --- SECURITY.md | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 09acdac..7288652 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -124,25 +124,37 @@ None of the Kubernetes fixes has been run against a cluster yet. Verify postgres (synced by the `fp-infra` Argo CD app), grafana and ollama after rollout. **Still red after this triage (2026-10-24):** the same scan reports HIGH -dependency CVEs. They are dependency bumps, left to the open Dependabot PRs so -the two do not conflict, but those PRs do **not** fully clear the gate as they -stand: +dependency CVEs in the Go modules, and govulncheck fails every module on the +reachable subset of them. They are dependency bumps, left to the open +Dependabot PR so the two do not conflict, but #17 does **not** fully clear +either gate as it stands: | Package | Fixed in | Open Dependabot PR brings it to | |---|---|---| -| `golang.org/x/crypto` | 0.55.0 | 0.55.0 (#17) | +| `golang.org/x/crypto` | 0.55.0 (Trivy); **0.56.0** for govulncheck (GO-2026-6354, GO-2026-6355, reachable from `pkg`) | 0.55.0 (#17), still red in govulncheck | | `golang.org/x/text` | 0.41.0 | 0.41.0 (#17) | | `google.golang.org/grpc` | 1.83.1 | 1.83.2 (#17) | | `golang.org/x/net` | **0.60.0** (one CVE; another is fixed in 0.56.0) | 0.58.0 (#17), still vulnerable | +| `go.opentelemetry.io/otel/sdk`, `.../exporters/otlp/otlptrace` | 1.45.0 (govulncheck only, GO-2026-6505) | 1.46.0 (#17) | | `github.com/klauspost/compress` | **1.18.7** | 1.18.6 (#17), still vulnerable | | `github.com/moby/go-archive` | **0.3.0** | unchanged | -| `axios` (web) | **1.20.0** | 1.19.0 (#10), still vulnerable | -| `follow-redirects` (web) | **1.16.1** | unchanged | #17 also leaves out `cli/`, `gen/go` and `services/bff`, which carry the same -`x/net`, `x/text` and `grpc` advisories. After merging #17 and #10, bump the -remaining packages by hand (or let Dependabot's next run propose them), then -re-run Security. +`x/net`, `x/text` and `grpc` advisories (and, in `bff`, the `otel` one). After +merging #17, bump the remaining packages by hand (or let Dependabot's next run +propose them), then re-run Security. + +Fixed on this branch rather than left to Dependabot: + +- the web findings: `axios` 1.20.0 and `follow-redirects` 1.16.1 (#10 only + reached axios 1.19.0, still vulnerable); +- the standard-library finding govulncheck reported in every module, + GO-2026-6809 (`crypto/x509`, Go 1.26.9). Go is pinned to **1.26.10** in + `go.work`, every `go.mod`, `GO_VERSION` in both workflows and the + `golang:1.26.10-alpine` builder digest in every Dockerfile. With + `GOTOOLCHAIN=local` (setup-go and the golang image both set it) an older + toolchain now refuses to build instead of silently compiling on an unpatched + standard library. **Known defect, not a scanner finding:** `postgres-backup-cronjob.yaml` cannot succeed as written. It runs as uid 999 but `apk add`s packages and writes `mc` From 4915ca93857b3236496f0fb112dd96bd69cc1404 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 14:55:36 +0500 Subject: [PATCH 41/42] deps: clear the Go advisories still failing govulncheck and Trivy govulncheck failed in all 15 workspace modules and the Trivy filesystem scan failed on every go.mod, all on third-party module advisories. This moves each affected module to the lowest release that clears every advisory, keeping majors unchanged: golang.org/x/net v0.55.0 -> v0.60.0 GO-2026-6603/6611/6612/6617, CVE-2026-46600, CVE-2026-78669 google.golang.org/grpc v1.82.1 -> v1.83.2 GO-2026-6348 (fixed 1.83.1), GO-2026-6443 (1.83.x fix is 1.83.2), CVE-2026-84304/84445 golang.org/x/text v0.39.0 -> v0.42.0 GO-2026-6629, CVE-2026-56851 golang.org/x/crypto v0.52.0 -> v0.57.0 GO-2026-6354/6355, CVE-2026-56854 go.opentelemetry.io/otel/* v1.44.0 -> v1.45.0 GO-2026-6505 (sdk, otlptrace, otlptracegrpc) github.com/moby/go-archive v0.2.0 -> v0.3.0 GO-2026-6253, CVE-2026-17106 github.com/klauspost/compress v1.18.0, v1.18.5 -> v1.18.7 CVE-2026-63209 x/text and x/crypto land one release above their advisory floors (v0.41.0, v0.56.0) because x/net v0.60.0 itself requires x/text v0.42.0 and x/crypto v0.57.0. The other otel v1 modules pkg lists (exporters, sdk/metric, trace, metric) move to v1.45.0 with the SDK, since otel-go releases them as one set. otelgrpc stays at v0.69.0. One code change falls out of the otel bump, in the same place as the last two: otel 1.45's resource.Default() carries semconv schema 1.43.0, so resource.Merge() in observability.Setup() rejected the v1.41.0 resource with "conflicting Schema URL" and every service would have failed to start. TestSetup_* caught it; the import moves to semconv/v1.43.0. The API used there is unchanged. SECURITY.md's "Still red" section deferred these bumps to Dependabot PR #17, which clears neither gate. It now records them as fixed here, with the advisory, fixed-in and resulting version for each. Verified with GOTOOLCHAIN=go1.26.10 in every module: go build, go vet, go test -race -shuffle=on pass; govulncheck v1.1.4 exits 0; Trivy v0.70.0 fs with the workflow's settings exits 0. Testcontainers-backed tests skip locally (no Docker engine reachable); CI runs them. Co-Authored-By: Claude Opus 5.5 --- SECURITY.md | 45 +++++++++++------------ cli/go.mod | 22 ++++++------ cli/go.sum | 22 ++++++++++++ gen/go/go.mod | 22 ++++++------ gen/go/go.sum | 22 ++++++++++++ pkg/go.mod | 48 ++++++++++++------------- pkg/go.sum | 51 +++++++++++++++++++++++++++ pkg/observability/setup.go | 14 ++++---- services/ai-gateway/go.mod | 28 +++++++-------- services/ai-gateway/go.sum | 28 +++++++++++++++ services/auth/go.mod | 28 +++++++-------- services/auth/go.sum | 28 +++++++++++++++ services/bff/go.mod | 22 ++++++------ services/bff/go.sum | 22 ++++++++++++ services/billing/go.mod | 28 +++++++-------- services/billing/go.sum | 28 +++++++++++++++ services/experiment-tracker/go.mod | 28 +++++++-------- services/experiment-tracker/go.sum | 28 +++++++++++++++ services/feature-store/go.mod | 28 +++++++-------- services/feature-store/go.sum | 28 +++++++++++++++ services/inference-gateway/go.mod | 26 +++++++------- services/inference-gateway/go.sum | 26 ++++++++++++++ services/model-monitor/go.mod | 28 +++++++-------- services/model-monitor/go.sum | 28 +++++++++++++++ services/model-serving/go.mod | 26 +++++++------- services/model-serving/go.sum | 26 ++++++++++++++ services/notification/go.mod | 28 +++++++-------- services/notification/go.sum | 28 +++++++++++++++ services/pipeline-orchestrator/go.mod | 28 +++++++-------- services/pipeline-orchestrator/go.sum | 28 +++++++++++++++ services/registry/go.mod | 28 +++++++-------- services/registry/go.sum | 28 +++++++++++++++ 32 files changed, 660 insertions(+), 238 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 7288652..21139c1 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -123,28 +123,29 @@ and the gate stayed red on them for three months. Each one now has a decision: None of the Kubernetes fixes has been run against a cluster yet. Verify postgres (synced by the `fp-infra` Argo CD app), grafana and ollama after rollout. -**Still red after this triage (2026-10-24):** the same scan reports HIGH -dependency CVEs in the Go modules, and govulncheck fails every module on the -reachable subset of them. They are dependency bumps, left to the open -Dependabot PR so the two do not conflict, but #17 does **not** fully clear -either gate as it stands: - -| Package | Fixed in | Open Dependabot PR brings it to | -|---|---|---| -| `golang.org/x/crypto` | 0.55.0 (Trivy); **0.56.0** for govulncheck (GO-2026-6354, GO-2026-6355, reachable from `pkg`) | 0.55.0 (#17), still red in govulncheck | -| `golang.org/x/text` | 0.41.0 | 0.41.0 (#17) | -| `google.golang.org/grpc` | 1.83.1 | 1.83.2 (#17) | -| `golang.org/x/net` | **0.60.0** (one CVE; another is fixed in 0.56.0) | 0.58.0 (#17), still vulnerable | -| `go.opentelemetry.io/otel/sdk`, `.../exporters/otlp/otlptrace` | 1.45.0 (govulncheck only, GO-2026-6505) | 1.46.0 (#17) | -| `github.com/klauspost/compress` | **1.18.7** | 1.18.6 (#17), still vulnerable | -| `github.com/moby/go-archive` | **0.3.0** | unchanged | - -#17 also leaves out `cli/`, `gen/go` and `services/bff`, which carry the same -`x/net`, `x/text` and `grpc` advisories (and, in `bff`, the `otel` one). After -merging #17, bump the remaining packages by hand (or let Dependabot's next run -propose them), then re-run Security. - -Fixed on this branch rather than left to Dependabot: +**Go dependency advisories (2026-10-24):** after this triage the same scan +still reported HIGH dependency CVEs in every Go module, and govulncheck failed +all 15 modules on the reachable subset. These were first left to Dependabot PR +#17, but #17 cleared neither gate. It stopped short on `x/net`, `x/crypto`, +`klauspost/compress` and `moby/go-archive`, and it did not touch `cli/`, +`gen/go` or `services/bff`. This branch bumps them instead, to the lowest +release that clears every advisory, so #17 is superseded: + +| Package | Advisories | Fixed in | Now | +|---|---|---|---| +| `golang.org/x/net` | GO-2026-6603, -6611, -6612, -6617; CVE-2026-46600, CVE-2026-78669 | 0.60.0 | 0.60.0 | +| `google.golang.org/grpc` | GO-2026-6348 (1.83.1), GO-2026-6443 (1.83.2 on the 1.83 line) | 1.83.2 | 1.83.2 | +| `golang.org/x/text` | GO-2026-6629, CVE-2026-56851 | 0.41.0 | 0.42.0, the floor `x/net` 0.60.0 requires | +| `golang.org/x/crypto` | GO-2026-6354, GO-2026-6355 (reachable from `pkg`), CVE-2026-56854 | 0.56.0 | 0.57.0, the floor `x/net` 0.60.0 requires | +| `go.opentelemetry.io/otel/sdk`, `.../exporters/otlp/otlptrace` | GO-2026-6505 | 1.45.0 | 1.45.0, with the rest of the otel v1 set | +| `github.com/klauspost/compress` | CVE-2026-63209 | 1.18.7 | 1.18.7 | +| `github.com/moby/go-archive` | GO-2026-6253, CVE-2026-17106 | 0.3.0 | 0.3.0 | + +The otel bump also moves the semconv import in `pkg/observability` to v1.43.0. +That is the schema otel 1.45's `resource.Default()` carries; the comment there +explains why the two must match. + +Also fixed on this branch rather than left to Dependabot: - the web findings: `axios` 1.20.0 and `follow-redirects` 1.16.1 (#10 only reached axios 1.19.0, still vulnerable); diff --git a/cli/go.mod b/cli/go.mod index 20b44db..11c6e68 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -3,23 +3,23 @@ module github.com/abd-ulbasit/forgepoint/cli go 1.26.10 require ( - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/cli/go.sum b/cli/go.sum index 0ff5c3a..8417f6d 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -3,6 +3,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -17,52 +19,72 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/gen/go/go.mod b/gen/go/go.mod index fa56287..5d41b69 100644 --- a/gen/go/go.mod +++ b/gen/go/go.mod @@ -13,23 +13,23 @@ module github.com/abd-ulbasit/forgepoint/gen/go go 1.26.10 require ( - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/gen/go/go.sum b/gen/go/go.sum index 754ac92..835e995 100644 --- a/gen/go/go.sum +++ b/gen/go/go.sum @@ -3,6 +3,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -19,43 +21,59 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= @@ -63,9 +81,13 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/pkg/go.mod b/pkg/go.mod index 7b90c2f..7a17643 100644 --- a/pkg/go.mod +++ b/pkg/go.mod @@ -12,15 +12,15 @@ require ( github.com/testcontainers/testcontainers-go/modules/postgres v0.43.0 github.com/testcontainers/testcontainers-go/modules/redis v0.43.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0 - go.opentelemetry.io/otel v1.44.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.44.0 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0 - go.opentelemetry.io/otel/sdk v1.44.0 - go.opentelemetry.io/otel/sdk/metric v1.44.0 - go.opentelemetry.io/otel/trace v1.44.0 - google.golang.org/grpc v1.82.1 + go.opentelemetry.io/otel v1.45.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.45.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.45.0 + go.opentelemetry.io/otel/sdk v1.45.0 + go.opentelemetry.io/otel/sdk/metric v1.45.0 + go.opentelemetry.io/otel/trace v1.45.0 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) @@ -42,22 +42,22 @@ require ( github.com/docker/go-units v0.5.0 // indirect github.com/ebitengine/purego v0.10.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect github.com/jackc/pgx/v5 v5.10.0 // indirect - github.com/klauspost/compress v1.18.5 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.10 // indirect github.com/mdelapenya/tlscert v0.2.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/go-archive v0.2.0 // indirect + github.com/moby/go-archive v0.3.0 // indirect github.com/moby/moby/api v1.54.2 // indirect github.com/moby/moby/client v0.4.0 // indirect github.com/moby/patternmatcher v0.6.1 // indirect - github.com/moby/sys/sequential v0.6.0 // indirect - github.com/moby/sys/user v0.4.0 // indirect + github.com/moby/sys/sequential v0.7.0 // indirect + github.com/moby/sys/user v0.4.1 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/moby/term v0.5.2 // indirect github.com/nats-io/nkeys v0.4.11 // indirect @@ -74,15 +74,15 @@ require ( github.com/tklauser/numcpus v0.11.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/proto/otlp v1.10.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/proto/otlp v1.11.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/pkg/go.sum b/pkg/go.sum index 6aa1c73..553948f 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -43,6 +43,8 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= @@ -70,6 +72,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -94,6 +98,8 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8= github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU= +github.com/moby/go-archive v0.3.0 h1:nos4BtzzUIqB406BgQnWGMI4qib9BZ8XUHU+ucv/n1c= +github.com/moby/go-archive v0.3.0/go.mod h1:Npdv43fFqlhZW7Xo8fbm3ZMYFvAGNviUPqX21VERbcE= github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg= github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= github.com/moby/moby/client v0.4.0 h1:S+2XegzHQrrvTCvF6s5HFzcrywWQmuVnhOXe2kiWjIw= @@ -102,8 +108,12 @@ github.com/moby/patternmatcher v0.6.1 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x github.com/moby/patternmatcher v0.6.1/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= +github.com/moby/sys/sequential v0.7.0 h1:ASQNGNROJSuOO6LL6bPHbKvuZu6NU8P4ldPWk31zj/8= +github.com/moby/sys/sequential v0.7.0/go.mod h1:NfSTAp6V3fw4tmkD62PEcOKeZKquXT8VKCkf7aVR79o= github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/user v0.4.1 h1:RgjRlaDKi/Xmyrz4t8lyzXT6v2ooFeO/7xtchmhVWE0= +github.com/moby/sys/user v0.4.1/go.mod h1:E9QsW5WRe1kUAf7kW8hXKwu1uhsZEAdPLYHYSDudF4Y= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= @@ -162,58 +172,99 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0/go.mod h1:D7J12YRapIekYyPWgGPlA/23pRmpSEZC5xJC/TTLI9U= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0 h1:SUplec5dp06reu1zaXmOXdvqH398taqrDXqUl99jxSc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0/go.mod h1:ho2g4N+ane+swq5I/VBkKWnRDY4kUINH3FuqyZqX/Ug= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0 h1:klTViGcsvLCd1xN3rZzfZ12NslC/OimbmR+k+A006RI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0/go.mod h1:jRsK04CWmXuY8A0O+wMpSf+t90RHZ53o5Qmxn2PQPfk= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 h1:QRefszxJmfPdjXUUm3j6iDzY03mTPXMjqErFqQ67vUg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0/go.mod h1:Tiz03lTBVBrm7eWZBOidzEaYaJa8tjwGUGv6d8mlTyk= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 h1:qazEJlUOQzhCpzQpFETGby7EdqjI1wsd0W+6Gg1SCTU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0/go.mod h1:fOD2Yefuxixkx3ahVNf0O/PERb6r4OlbxfATVnYvzCo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 h1:fG5MCxGz8+2VtrN/WgqSpJFctVz24gpxj8CxkKmc8Ww= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0/go.mod h1:BmAYTn+3ysbRe+IU2msxmf5Rx3g6DHvex+tWI3LdhYI= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.44.0 h1:hqxVTu/GtBF+vJ8d1fzW7fRxZFvgoDjWcxwwCaFDYpU= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.44.0/go.mod h1:z5fVEF4X5v0ESvlJqBrrFlBVoj5EQuefZpzsu7R+x5Q= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.45.0 h1:dm9iyzn6tioYZtwqaiBSU0TSI8Yu/8dTIbfG0+B49DY= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.45.0/go.mod h1:xAvxYjYK28qvt+yu4BYZ/zMmAjwMXINXD6JiMyeB8iI= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0 h1:bl2S7Ubua0Nms+D/gAmznQTd4dxxMA93aKbcpKqiTCs= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0/go.mod h1:L0hRV50XdVIODHUfWEqGRCXQvj2rV82STVo12FMFBU0= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.45.0 h1:lsA/S1bxgdbyFGkTj+3meEdJ6ADVU7QoFstV6MXgE68= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.45.0/go.mod h1:L7u+MirGoB1bjeLH66+xDykF4RC8C3RN7lIFpBiewUo= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/metric/x v0.67.0 h1:PcicCNZFkZ4bXfSooXdo3WN7RBOVOtjVdo1wD358Uns= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.opentelemetry.io/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6TbEdMIk= +go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= +golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= +google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d h1:FarXi840EJWSHYTN3ERkADbPWjl307+FGrA22KAVjjc= +google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d/go.mod h1:K/+WGbmBY7aNW1HDw1fJnKYo10i0DkAX6pows00dLig= google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/observability/setup.go b/pkg/observability/setup.go index c41e158..018c031 100644 --- a/pkg/observability/setup.go +++ b/pkg/observability/setup.go @@ -85,15 +85,15 @@ import ( // resource.Default() for this otel release. resource.Merge() rejects two // resources whose Schema URLs differ, so a mismatch makes Setup() return // "conflicting Schema URL" — a RUNTIME failure in every service's - // composition root, invisible to the compiler. otel 1.44's - // resource.Default() carries schema 1.41.0. + // composition root, invisible to the compiler. otel 1.45's + // resource.Default() carries schema 1.43.0. // // Bump this together with the otel modules. TestSetup_* in this package is - // what catches it if you don't: it has now caught it on two consecutive - // otel upgrades (1.40 -> 1.42 -> 1.44), which is the argument for keeping - // the version pinned here rather than reaching for resource.NewSchemaless - // to make the mismatch impossible-and-silent. - semconv "go.opentelemetry.io/otel/semconv/v1.41.0" + // what catches it if you don't: it has now caught it on three consecutive + // otel upgrades (1.40 -> 1.42 -> 1.44 -> 1.45), which is the argument for + // keeping the version pinned here rather than reaching for + // resource.NewSchemaless to make the mismatch impossible-and-silent. + semconv "go.opentelemetry.io/otel/semconv/v1.43.0" ) // setupCalled (guarded by setupMu) ensures Setup() runs at most once per process. diff --git a/services/ai-gateway/go.mod b/services/ai-gateway/go.mod index 6ca4875..cf8d63a 100644 --- a/services/ai-gateway/go.mod +++ b/services/ai-gateway/go.mod @@ -7,7 +7,7 @@ require ( github.com/jackc/pgx/v5 v5.10.0 github.com/nats-io/nats.go v1.48.0 github.com/redis/go-redis/v9 v9.20.1 - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) @@ -19,24 +19,24 @@ require ( ) require ( - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sync v0.21.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sync v0.23.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/ai-gateway/go.sum b/services/ai-gateway/go.sum index 58875f2..8f65e80 100644 --- a/services/ai-gateway/go.sum +++ b/services/ai-gateway/go.sum @@ -8,6 +8,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -26,6 +28,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= @@ -52,54 +56,74 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= @@ -107,10 +131,14 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/services/auth/go.mod b/services/auth/go.mod index 2dfd701..38682f5 100644 --- a/services/auth/go.mod +++ b/services/auth/go.mod @@ -6,36 +6,36 @@ require ( github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/uuid v1.6.0 github.com/nats-io/nats.go v1.48.0 - golang.org/x/crypto v0.52.0 - google.golang.org/grpc v1.82.1 + golang.org/x/crypto v0.57.0 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - golang.org/x/sync v0.21.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + golang.org/x/sync v0.23.0 // indirect ) require ( github.com/jackc/pgx/v5 v5.10.0 - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/auth/go.sum b/services/auth/go.sum index 7ae00d6..f5b3105 100644 --- a/services/auth/go.sum +++ b/services/auth/go.sum @@ -6,6 +6,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= @@ -24,6 +26,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0= @@ -45,59 +49,83 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/services/bff/go.mod b/services/bff/go.mod index b3ef21c..5c4dde8 100644 --- a/services/bff/go.mod +++ b/services/bff/go.mod @@ -3,23 +3,23 @@ module github.com/abd-ulbasit/forgepoint/services/bff go 1.26.10 require ( - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/bff/go.sum b/services/bff/go.sum index 0ff5c3a..8417f6d 100644 --- a/services/bff/go.sum +++ b/services/bff/go.sum @@ -3,6 +3,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -17,52 +19,72 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/services/billing/go.mod b/services/billing/go.mod index 1de20dd..df84d98 100644 --- a/services/billing/go.mod +++ b/services/billing/go.mod @@ -6,37 +6,37 @@ require ( github.com/google/uuid v1.6.0 github.com/nats-io/nats.go v1.48.0 github.com/redis/go-redis/v9 v9.20.1 - go.opentelemetry.io/otel/metric v1.44.0 - go.opentelemetry.io/otel/trace v1.44.0 - google.golang.org/grpc v1.82.1 + go.opentelemetry.io/otel/metric v1.45.0 + go.opentelemetry.io/otel/trace v1.45.0 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/sync v0.21.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/sync v0.23.0 // indirect ) require ( github.com/jackc/pgx/v5 v5.10.0 - go.opentelemetry.io/otel v1.44.0 - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/billing/go.sum b/services/billing/go.sum index ff37975..f23a0ea 100644 --- a/services/billing/go.sum +++ b/services/billing/go.sum @@ -8,6 +8,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -24,6 +26,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= @@ -49,63 +53,87 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/services/experiment-tracker/go.mod b/services/experiment-tracker/go.mod index fe5f100..6c94d8a 100644 --- a/services/experiment-tracker/go.mod +++ b/services/experiment-tracker/go.mod @@ -5,36 +5,36 @@ go 1.26.10 require ( github.com/google/uuid v1.6.0 github.com/nats-io/nats.go v1.48.0 - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/sync v0.21.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/sync v0.23.0 // indirect ) require ( github.com/jackc/pgx/v5 v5.10.0 - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/experiment-tracker/go.sum b/services/experiment-tracker/go.sum index 744a5b4..353465f 100644 --- a/services/experiment-tracker/go.sum +++ b/services/experiment-tracker/go.sum @@ -6,6 +6,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -22,6 +24,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0= @@ -43,59 +47,83 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/services/feature-store/go.mod b/services/feature-store/go.mod index 39fa1e1..c999c43 100644 --- a/services/feature-store/go.mod +++ b/services/feature-store/go.mod @@ -6,37 +6,37 @@ require ( github.com/google/uuid v1.6.0 github.com/nats-io/nats.go v1.48.0 github.com/redis/go-redis/v9 v9.20.1 - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/sync v0.21.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/sync v0.23.0 // indirect ) require ( github.com/jackc/pgx/v5 v5.10.0 - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/feature-store/go.sum b/services/feature-store/go.sum index c729741..00f27d8 100644 --- a/services/feature-store/go.sum +++ b/services/feature-store/go.sum @@ -8,6 +8,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -24,6 +26,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= @@ -49,61 +53,85 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/services/inference-gateway/go.mod b/services/inference-gateway/go.mod index a8c279f..13e7376 100644 --- a/services/inference-gateway/go.mod +++ b/services/inference-gateway/go.mod @@ -6,7 +6,7 @@ require ( github.com/google/uuid v1.6.0 github.com/nats-io/nats.go v1.48.0 github.com/redis/go-redis/v9 v9.20.1 - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) @@ -19,20 +19,20 @@ require ( ) require ( - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/inference-gateway/go.sum b/services/inference-gateway/go.sum index 7f4e29d..9e2a4f0 100644 --- a/services/inference-gateway/go.sum +++ b/services/inference-gateway/go.sum @@ -7,6 +7,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -17,6 +19,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= @@ -39,50 +43,68 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= @@ -90,10 +112,14 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/services/model-monitor/go.mod b/services/model-monitor/go.mod index 0d691f9..b42b195 100644 --- a/services/model-monitor/go.mod +++ b/services/model-monitor/go.mod @@ -6,37 +6,37 @@ require ( github.com/google/uuid v1.6.0 github.com/nats-io/nats.go v1.48.0 github.com/redis/go-redis/v9 v9.20.1 - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/sync v0.21.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/sync v0.23.0 // indirect ) require ( github.com/jackc/pgx/v5 v5.10.0 - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/model-monitor/go.sum b/services/model-monitor/go.sum index c729741..00f27d8 100644 --- a/services/model-monitor/go.sum +++ b/services/model-monitor/go.sum @@ -8,6 +8,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -24,6 +26,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= @@ -49,61 +53,85 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/services/model-serving/go.mod b/services/model-serving/go.mod index 97d4f01..41c273d 100644 --- a/services/model-serving/go.mod +++ b/services/model-serving/go.mod @@ -5,26 +5,26 @@ go 1.26.10 require ( github.com/google/uuid v1.6.0 github.com/nats-io/nats.go v1.48.0 - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/model-serving/go.sum b/services/model-serving/go.sum index 72c568b..fa0a108 100644 --- a/services/model-serving/go.sum +++ b/services/model-serving/go.sum @@ -3,6 +3,8 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -11,6 +13,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0= @@ -25,54 +29,76 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= diff --git a/services/notification/go.mod b/services/notification/go.mod index e751776..23e67d8 100644 --- a/services/notification/go.mod +++ b/services/notification/go.mod @@ -6,37 +6,37 @@ require ( github.com/google/uuid v1.6.0 github.com/nats-io/nats.go v1.48.0 github.com/redis/go-redis/v9 v9.20.1 - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/sync v0.21.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/sync v0.23.0 // indirect ) require ( github.com/jackc/pgx/v5 v5.10.0 - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/notification/go.sum b/services/notification/go.sum index c729741..00f27d8 100644 --- a/services/notification/go.sum +++ b/services/notification/go.sum @@ -8,6 +8,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -24,6 +26,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= @@ -49,61 +53,85 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/services/pipeline-orchestrator/go.mod b/services/pipeline-orchestrator/go.mod index 5986522..0725348 100644 --- a/services/pipeline-orchestrator/go.mod +++ b/services/pipeline-orchestrator/go.mod @@ -5,36 +5,36 @@ go 1.26.10 require ( github.com/google/uuid v1.6.0 github.com/nats-io/nats.go v1.48.0 - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/sync v0.21.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/sync v0.23.0 // indirect ) require ( github.com/jackc/pgx/v5 v5.10.0 - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/pipeline-orchestrator/go.sum b/services/pipeline-orchestrator/go.sum index 744a5b4..353465f 100644 --- a/services/pipeline-orchestrator/go.sum +++ b/services/pipeline-orchestrator/go.sum @@ -6,6 +6,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -22,6 +24,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= github.com/nats-io/nkeys v0.4.11 h1:q44qGV008kYd9W1b1nEBkNzvnWxtRSQ7A8BoqRrcfa0= @@ -43,59 +47,83 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/services/registry/go.mod b/services/registry/go.mod index 524ebbe..397d194 100644 --- a/services/registry/go.mod +++ b/services/registry/go.mod @@ -6,34 +6,34 @@ require ( github.com/jackc/pgx/v5 v5.10.0 github.com/nats-io/nats.go v1.48.0 github.com/redis/go-redis/v9 v9.20.1 - google.golang.org/grpc v1.82.1 + google.golang.org/grpc v1.83.2 google.golang.org/protobuf v1.36.11 ) require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect - github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel v1.44.0 // indirect - go.opentelemetry.io/otel/metric v1.44.0 // indirect - go.opentelemetry.io/otel/sdk v1.44.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect - go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.opentelemetry.io/otel v1.45.0 // indirect + go.opentelemetry.io/otel/metric v1.45.0 // indirect + go.opentelemetry.io/otel/sdk v1.45.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect + go.opentelemetry.io/otel/trace v1.45.0 // indirect go.uber.org/atomic v1.11.0 // indirect - golang.org/x/crypto v0.52.0 // indirect - golang.org/x/net v0.55.0 // indirect - golang.org/x/sync v0.21.0 // indirect - golang.org/x/sys v0.45.0 // indirect - golang.org/x/text v0.39.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect + golang.org/x/crypto v0.57.0 // indirect + golang.org/x/net v0.60.0 // indirect + golang.org/x/sync v0.23.0 // indirect + golang.org/x/sys v0.48.0 // indirect + golang.org/x/text v0.42.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect ) diff --git a/services/registry/go.sum b/services/registry/go.sum index c729741..00f27d8 100644 --- a/services/registry/go.sum +++ b/services/registry/go.sum @@ -8,6 +8,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -24,6 +26,8 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= +github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= +github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= github.com/nats-io/nats.go v1.48.0/go.mod h1:iRWIPokVIFbVijxuMQq4y9ttaBTMe0SFdlZfMDd+33g= @@ -49,61 +53,85 @@ go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= +go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= +go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= +go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= +go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= +go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= +golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= +golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= +golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= +golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= +golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= +golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= +golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= +golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= +google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From b00771f6d1162b687938d44cb41a874fa63ebf32 Mon Sep 17 00:00:00 2001 From: abd-ulbasit Date: Sat, 24 Oct 2026 14:56:16 +0500 Subject: [PATCH 42/42] deps: run go work sync and tidy gen/go after the bump ADR 0006 has `go work sync` manage the requires, so this runs it after the advisory bump. It changes no version the workspace resolves. - go work sync moves genproto/googleapis/rpc to the version pkg already resolves (v0.0.0-20260803160001-6ac0973c030d), so each go.mod names the version the workspace builds. - go work sync also drops indirect requires that no package in the module itself needs, from cli, gen/go and the 12 services. In the workspace, and in the minimal go.work each Dockerfile generates, pkg's go.mod supplies them: otel, otel/sdk, otel/trace, otel/metric, auto/sdk, go-logr, xxhash, google/uuid. go.sum loses the matching hashes. - gen/go is tidied as well. It is the only module that imports no sibling module, so `go mod tidy` cannot reach for one. After the sync its go.sum lacked two go.mod hashes, and `GOWORK=off go build` failed. That build passes again. The other modules are not tidied. They import pkg or gen/go, which `go mod tidy` ignores go.work for, so tidy pins a proxy pseudo-version of main for them. ADR 0006 gotcha #1 forbids that. Verified on this tree with GOTOOLCHAIN=go1.26.10: - go build, go vet, go test -race -shuffle=on and golangci-lint v2.12.2 pass in all 15 modules. - govulncheck v1.1.4 exits 0 in all 15. - Trivy fs with the workflow's settings exits 0. - Each service's Dockerfile Go steps were replayed without Docker: go work init with pkg, gen/go and the service, then go mod download all, then a -mod=readonly build of cmd/server. All 12 build. Trivy finds no HIGH/CRITICAL in the 12 binaries. Co-Authored-By: Claude Opus 5.5 --- cli/go.mod | 10 +--- cli/go.sum | 58 +--------------------- gen/go/go.mod | 10 +--- gen/go/go.sum | 61 ++--------------------- pkg/go.sum | 56 --------------------- services/ai-gateway/go.mod | 8 +-- services/ai-gateway/go.sum | 70 +-------------------------- services/auth/go.mod | 9 +--- services/auth/go.sum | 66 +------------------------ services/bff/go.mod | 10 +--- services/bff/go.sum | 58 +--------------------- services/billing/go.mod | 3 +- services/billing/go.sum | 67 +------------------------ services/experiment-tracker/go.mod | 9 +--- services/experiment-tracker/go.sum | 66 +------------------------ services/feature-store/go.mod | 8 +-- services/feature-store/go.sum | 66 +------------------------ services/inference-gateway/go.mod | 8 +-- services/inference-gateway/go.sum | 66 +------------------------ services/model-monitor/go.mod | 8 +-- services/model-monitor/go.sum | 66 +------------------------ services/model-serving/go.mod | 9 +--- services/model-serving/go.sum | 62 +----------------------- services/notification/go.mod | 8 +-- services/notification/go.sum | 66 +------------------------ services/pipeline-orchestrator/go.mod | 9 +--- services/pipeline-orchestrator/go.sum | 66 +------------------------ services/registry/go.mod | 9 +--- services/registry/go.sum | 66 +------------------------ 29 files changed, 30 insertions(+), 1048 deletions(-) diff --git a/cli/go.mod b/cli/go.mod index 11c6e68..bb6d34f 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -8,18 +8,10 @@ require ( ) require ( - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/uuid v1.6.0 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.45.0 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/cli/go.sum b/cli/go.sum index 8417f6d..d27c2c2 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -1,8 +1,5 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -13,77 +10,24 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/gen/go/go.mod b/gen/go/go.mod index 5d41b69..2c03c43 100644 --- a/gen/go/go.mod +++ b/gen/go/go.mod @@ -18,18 +18,10 @@ require ( ) require ( - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/uuid v1.6.0 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.45.0 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/gen/go/go.sum b/gen/go/go.sum index 835e995..39b943e 100644 --- a/gen/go/go.sum +++ b/gen/go/go.sum @@ -1,8 +1,5 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -15,78 +12,26 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/pkg/go.sum b/pkg/go.sum index 553948f..0de6e5a 100644 --- a/pkg/go.sum +++ b/pkg/go.sum @@ -6,8 +6,6 @@ github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEK github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/abd-ulbasit/forgepoint/gen/go v0.0.0-20260727085324-627e50284248 h1:4wApdYdDzHhen3IrQ44bwbV9hsh2AEdaE2KKJNYkIQI= -github.com/abd-ulbasit/forgepoint/gen/go v0.0.0-20260727085324-627e50284248/go.mod h1:GHrtFUKXypVBbvIrPMs18u2+G3F8goedJ6C8utK232s= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= @@ -41,8 +39,6 @@ github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLA github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -70,8 +66,6 @@ github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= -github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= @@ -96,8 +90,6 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8= -github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU= github.com/moby/go-archive v0.3.0 h1:nos4BtzzUIqB406BgQnWGMI4qib9BZ8XUHU+ucv/n1c= github.com/moby/go-archive v0.3.0/go.mod h1:Npdv43fFqlhZW7Xo8fbm3ZMYFvAGNviUPqX21VERbcE= github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg= @@ -106,12 +98,8 @@ github.com/moby/moby/client v0.4.0 h1:S+2XegzHQrrvTCvF6s5HFzcrywWQmuVnhOXe2kiWjI github.com/moby/moby/client v0.4.0/go.mod h1:QWPbvWchQbxBNdaLSpoKpCdf5E+WxFAgNHogCWDoa7g= github.com/moby/patternmatcher v0.6.1 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x084U= github.com/moby/patternmatcher v0.6.1/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= -github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= github.com/moby/sys/sequential v0.7.0 h1:ASQNGNROJSuOO6LL6bPHbKvuZu6NU8P4ldPWk31zj/8= github.com/moby/sys/sequential v0.7.0/go.mod h1:NfSTAp6V3fw4tmkD62PEcOKeZKquXT8VKCkf7aVR79o= -github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= -github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= github.com/moby/sys/user v0.4.1 h1:RgjRlaDKi/Xmyrz4t8lyzXT6v2ooFeO/7xtchmhVWE0= github.com/moby/sys/user v0.4.1/go.mod h1:E9QsW5WRe1kUAf7kW8hXKwu1uhsZEAdPLYHYSDudF4Y= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= @@ -170,99 +158,55 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0 h1:2yEATaop1/a1I4psnSLgWVPLWwCzkqWakgJy7xTDVy0= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0/go.mod h1:D7J12YRapIekYyPWgGPlA/23pRmpSEZC5xJC/TTLI9U= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0 h1:SUplec5dp06reu1zaXmOXdvqH398taqrDXqUl99jxSc= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0/go.mod h1:ho2g4N+ane+swq5I/VBkKWnRDY4kUINH3FuqyZqX/Ug= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0 h1:klTViGcsvLCd1xN3rZzfZ12NslC/OimbmR+k+A006RI= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0/go.mod h1:jRsK04CWmXuY8A0O+wMpSf+t90RHZ53o5Qmxn2PQPfk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 h1:QRefszxJmfPdjXUUm3j6iDzY03mTPXMjqErFqQ67vUg= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0/go.mod h1:Tiz03lTBVBrm7eWZBOidzEaYaJa8tjwGUGv6d8mlTyk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 h1:qazEJlUOQzhCpzQpFETGby7EdqjI1wsd0W+6Gg1SCTU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0/go.mod h1:fOD2Yefuxixkx3ahVNf0O/PERb6r4OlbxfATVnYvzCo= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 h1:fG5MCxGz8+2VtrN/WgqSpJFctVz24gpxj8CxkKmc8Ww= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0/go.mod h1:BmAYTn+3ysbRe+IU2msxmf5Rx3g6DHvex+tWI3LdhYI= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.44.0 h1:hqxVTu/GtBF+vJ8d1fzW7fRxZFvgoDjWcxwwCaFDYpU= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.44.0/go.mod h1:z5fVEF4X5v0ESvlJqBrrFlBVoj5EQuefZpzsu7R+x5Q= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.45.0 h1:dm9iyzn6tioYZtwqaiBSU0TSI8Yu/8dTIbfG0+B49DY= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.45.0/go.mod h1:xAvxYjYK28qvt+yu4BYZ/zMmAjwMXINXD6JiMyeB8iI= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0 h1:bl2S7Ubua0Nms+D/gAmznQTd4dxxMA93aKbcpKqiTCs= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0/go.mod h1:L0hRV50XdVIODHUfWEqGRCXQvj2rV82STVo12FMFBU0= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.45.0 h1:lsA/S1bxgdbyFGkTj+3meEdJ6ADVU7QoFstV6MXgE68= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.45.0/go.mod h1:L7u+MirGoB1bjeLH66+xDykF4RC8C3RN7lIFpBiewUo= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= -go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= go.opentelemetry.io/otel/metric/x v0.67.0 h1:PcicCNZFkZ4bXfSooXdo3WN7RBOVOtjVdo1wD358Uns= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= -go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= -go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.opentelemetry.io/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6TbEdMIk= go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= -golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8= -google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY= google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d h1:FarXi840EJWSHYTN3ERkADbPWjl307+FGrA22KAVjjc= google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d/go.mod h1:K/+WGbmBY7aNW1HDw1fJnKYo10i0DkAX6pows00dLig= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/ai-gateway/go.mod b/services/ai-gateway/go.mod index cf8d63a..1dac093 100644 --- a/services/ai-gateway/go.mod +++ b/services/ai-gateway/go.mod @@ -19,24 +19,18 @@ require ( ) require ( - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.45.0 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/net v0.60.0 // indirect golang.org/x/sync v0.23.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/ai-gateway/go.sum b/services/ai-gateway/go.sum index 8f65e80..3f2d873 100644 --- a/services/ai-gateway/go.sum +++ b/services/ai-gateway/go.sum @@ -5,9 +5,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -26,8 +23,6 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= @@ -50,93 +45,30 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/auth/go.mod b/services/auth/go.mod index 38682f5..ad41fda 100644 --- a/services/auth/go.mod +++ b/services/auth/go.mod @@ -12,10 +12,7 @@ require ( ) require ( - github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect @@ -23,10 +20,6 @@ require ( github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect golang.org/x/sync v0.23.0 // indirect ) @@ -37,5 +30,5 @@ require ( golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/auth/go.sum b/services/auth/go.sum index f5b3105..ec496ea 100644 --- a/services/auth/go.sum +++ b/services/auth/go.sum @@ -3,9 +3,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -24,8 +21,6 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= @@ -43,87 +38,28 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/bff/go.mod b/services/bff/go.mod index 5c4dde8..c5d0dab 100644 --- a/services/bff/go.mod +++ b/services/bff/go.mod @@ -8,18 +8,10 @@ require ( ) require ( - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/uuid v1.6.0 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.45.0 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/bff/go.sum b/services/bff/go.sum index 8417f6d..d27c2c2 100644 --- a/services/bff/go.sum +++ b/services/bff/go.sum @@ -1,8 +1,5 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -13,77 +10,24 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/billing/go.mod b/services/billing/go.mod index df84d98..ffa437f 100644 --- a/services/billing/go.mod +++ b/services/billing/go.mod @@ -25,7 +25,6 @@ require ( github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/sync v0.23.0 // indirect @@ -38,5 +37,5 @@ require ( golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/billing/go.sum b/services/billing/go.sum index f23a0ea..f4d0f4c 100644 --- a/services/billing/go.sum +++ b/services/billing/go.sum @@ -6,8 +6,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -24,8 +22,6 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= @@ -47,91 +43,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/experiment-tracker/go.mod b/services/experiment-tracker/go.mod index 6c94d8a..177a6ea 100644 --- a/services/experiment-tracker/go.mod +++ b/services/experiment-tracker/go.mod @@ -10,10 +10,7 @@ require ( ) require ( - github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect @@ -21,10 +18,6 @@ require ( github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/sync v0.23.0 // indirect ) @@ -36,5 +29,5 @@ require ( golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/experiment-tracker/go.sum b/services/experiment-tracker/go.sum index 353465f..fe19636 100644 --- a/services/experiment-tracker/go.sum +++ b/services/experiment-tracker/go.sum @@ -3,9 +3,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -22,8 +19,6 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= @@ -41,87 +36,28 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/feature-store/go.mod b/services/feature-store/go.mod index c999c43..3c0cbc9 100644 --- a/services/feature-store/go.mod +++ b/services/feature-store/go.mod @@ -13,8 +13,6 @@ require ( require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect @@ -22,10 +20,6 @@ require ( github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/sync v0.23.0 // indirect @@ -38,5 +32,5 @@ require ( golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/feature-store/go.sum b/services/feature-store/go.sum index 00f27d8..f3045ab 100644 --- a/services/feature-store/go.sum +++ b/services/feature-store/go.sum @@ -5,9 +5,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -24,8 +21,6 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= @@ -47,89 +42,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/inference-gateway/go.mod b/services/inference-gateway/go.mod index 13e7376..c0022c8 100644 --- a/services/inference-gateway/go.mod +++ b/services/inference-gateway/go.mod @@ -19,20 +19,14 @@ require ( ) require ( - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.45.0 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/inference-gateway/go.sum b/services/inference-gateway/go.sum index 9e2a4f0..3dc0847 100644 --- a/services/inference-gateway/go.sum +++ b/services/inference-gateway/go.sum @@ -4,9 +4,6 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -17,8 +14,6 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= @@ -37,87 +32,28 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/model-monitor/go.mod b/services/model-monitor/go.mod index b42b195..8cf8e68 100644 --- a/services/model-monitor/go.mod +++ b/services/model-monitor/go.mod @@ -13,8 +13,6 @@ require ( require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect @@ -22,10 +20,6 @@ require ( github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/sync v0.23.0 // indirect @@ -38,5 +32,5 @@ require ( golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/model-monitor/go.sum b/services/model-monitor/go.sum index 00f27d8..f3045ab 100644 --- a/services/model-monitor/go.sum +++ b/services/model-monitor/go.sum @@ -5,9 +5,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -24,8 +21,6 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= @@ -47,89 +42,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/model-serving/go.mod b/services/model-serving/go.mod index 41c273d..221ce2f 100644 --- a/services/model-serving/go.mod +++ b/services/model-serving/go.mod @@ -10,21 +10,14 @@ require ( ) require ( - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/klauspost/compress v1.18.7 // indirect github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.45.0 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/model-serving/go.sum b/services/model-serving/go.sum index fa0a108..68cd61f 100644 --- a/services/model-serving/go.sum +++ b/services/model-serving/go.sum @@ -1,8 +1,5 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -11,8 +8,6 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= @@ -23,81 +18,26 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/notification/go.mod b/services/notification/go.mod index 23e67d8..63d1b53 100644 --- a/services/notification/go.mod +++ b/services/notification/go.mod @@ -13,8 +13,6 @@ require ( require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect @@ -22,10 +20,6 @@ require ( github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/sync v0.23.0 // indirect @@ -38,5 +32,5 @@ require ( golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/notification/go.sum b/services/notification/go.sum index 00f27d8..f3045ab 100644 --- a/services/notification/go.sum +++ b/services/notification/go.sum @@ -5,9 +5,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -24,8 +21,6 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= @@ -47,89 +42,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/pipeline-orchestrator/go.mod b/services/pipeline-orchestrator/go.mod index 0725348..1789027 100644 --- a/services/pipeline-orchestrator/go.mod +++ b/services/pipeline-orchestrator/go.mod @@ -10,10 +10,7 @@ require ( ) require ( - github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect @@ -21,10 +18,6 @@ require ( github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/sync v0.23.0 // indirect ) @@ -36,5 +29,5 @@ require ( golang.org/x/net v0.60.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/pipeline-orchestrator/go.sum b/services/pipeline-orchestrator/go.sum index 353465f..fe19636 100644 --- a/services/pipeline-orchestrator/go.sum +++ b/services/pipeline-orchestrator/go.sum @@ -3,9 +3,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -22,8 +19,6 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/nats-io/nats.go v1.48.0 h1:pSFyXApG+yWU/TgbKCjmm5K4wrHu86231/w84qRVR+U= @@ -41,87 +36,28 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= diff --git a/services/registry/go.mod b/services/registry/go.mod index 397d194..5b5295a 100644 --- a/services/registry/go.mod +++ b/services/registry/go.mod @@ -13,9 +13,6 @@ require ( require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-logr/logr v1.4.4 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/uuid v1.6.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect @@ -23,17 +20,13 @@ require ( github.com/nats-io/nkeys v0.4.11 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel v1.45.0 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/crypto v0.57.0 // indirect golang.org/x/net v0.60.0 // indirect golang.org/x/sync v0.23.0 // indirect golang.org/x/sys v0.48.0 // indirect golang.org/x/text v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect ) diff --git a/services/registry/go.sum b/services/registry/go.sum index 00f27d8..f3045ab 100644 --- a/services/registry/go.sum +++ b/services/registry/go.sum @@ -5,9 +5,6 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -24,8 +21,6 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/compress v1.18.7 h1:aUyZsS4kH3QTKurYhAOwAHxllVPnOthb3vPfnF1Ehjw= github.com/klauspost/compress v1.18.7/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= @@ -47,89 +42,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= -go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= -go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= -go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= -go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= -go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= -golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988= -golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc= golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M= golang.org/x/crypto v0.57.0/go.mod h1:Fdz0i5U6CoizGwLda9DttjSk6qlZo25zYNtR+ycvuZA= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/net v0.54.0 h1:2zJIZAxAHV/OHCDTCOHAYehQzLfSXuf/5SoL/Dv6w/w= -golang.org/x/net v0.54.0/go.mod h1:Sj4oj8jK6XmHpBZU/zWHw3BV3abl4Kvi+Ut7cQcY+cQ= -golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= -golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU= golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk= golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= -golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo= golang.org/x/sys v0.48.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus= -golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM= golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI= golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0= google.golang.org/grpc v1.83.2 h1:EManeRomTObA0BU7I8vXgg/78uE5MJ9M8B39EX2WscU= google.golang.org/grpc v1.83.2/go.mod h1:YPI1hK3kDked6iHvgX3tR0y+nX/qpMFKhPgFsokw1S8= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=