Sourced from go.opentelemetry.io/contrib/instrumentation/runtime's releases.
v1.42.0/v2.4.0/v0.67.0/v0.36.0/v0.22.0/v0.17.0/v0.15.0/v0.14.0
Added
- Add environment variables propagation carrier in
go.opentelemetry.io/contrib/propagators/envcar. (#8442)Changed
Upgrade
go.opentelemetry.io/otel/semconvtov1.40.0, including updates across instrumentation and detector modules. (#8631)
- The semantic conventions v1.40.0 release introduces RPC breaking changes applied in this repository:
- RPC spans and metrics no longer include
network.protocol.name,network.protocol.version, ornetwork.transportattributes.rpc.client.request.size,rpc.client.response.size,rpc.server.request.size, andrpc.server.response.sizeare no longer emitted ingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc.rpc.messagespan events and their message attributes are no longer emitted ingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc(including whenWithMessageEventsis configured).See semantic-conventions v1.40.0 release for complete details.
Fixed
- Ignore informational response status codes (
100-199) except101 Switching Protocolswhen storing the HTTP status code ingo.opentelemetry.io/contrib/instrumentation/net/http/otelhttpandgo.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux. (#6913)- Make
Bodyhandling inTransportconsistent with stdlib ingo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp. (#8618)- Fix bucket boundaries for
rpc.server.call.durationandrpc.client.call.durationingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc. (#8642)- Host resource detector in
go.opentelemetry.io/contrib/otelconfnow includesos.attributes. (#8578)Removed
What's Changed
- chore(deps): update github artifact actions to v7 (major) by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8605- chore(deps): update module github.com/sonatard/noctx to v0.5.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8610- chore(deps): update github/codeql-action action to v4.32.5 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8620- fix(deps): update module github.com/aws/smithy-go to v1.24.2 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8614- chore(deps): update go-openapi packages by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8621- fix(deps): update module github.com/shirou/gopsutil/v4 to v4.26.2 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8622- chore(deps): update module github.com/kisielk/errcheck to v1.10.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8608- chore(deps): update module github.com/protonmail/go-crypto to v1.4.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8609- chore(deps): update otel/opentelemetry-collector-contrib docker tag to v0.147.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8625- chore(deps): update module github.com/daixiang0/gci to v0.14.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8623- Drop support for 1.24 by
@dmathieuin open-telemetry/opentelemetry-go-contrib#8628- fix(deps): update golang.org/x by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8554- fix(deps): update kubernetes packages to v0.35.2 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8626- fix(deps): update aws-sdk-go-v2 monorepo by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8598- fix(deps): update module github.com/aws/aws-lambda-go to v1.53.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8630- otelgrpc: modernize the example project by
@ash2kin open-telemetry/opentelemetry-go-contrib#8619- chore(deps): update googleapis to a57be14 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8606- fix(deps): update module github.com/gin-gonic/gin to v1.12.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8627- chore(deps): update module github.com/prometheus/procfs to v0.20.1 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8624- fix(otelhttp): make Body handling in Transport consistent with stdlib by
@ash2kin open-telemetry/opentelemetry-go-contrib#8618- otelhttp: Ignore informational response status codes when persisting status by
@VirrageSin open-telemetry/opentelemetry-go-contrib#6913
... (truncated)
Sourced from go.opentelemetry.io/contrib/instrumentation/runtime's changelog.
[1.42.0/2.4.0/0.67.0/0.36.0/0.22.0/0.17.0/0.15.0/0.14.0] - 2026-03-06
Added
- Add environment variables propagation carrier in
go.opentelemetry.io/contrib/propagators/envcar. (#8442)Changed
Upgrade
go.opentelemetry.io/otel/semconvtov1.40.0, including updates across instrumentation and detector modules. (#8631)
- The semantic conventions v1.40.0 release introduces RPC breaking changes applied in this repository:
- RPC spans and metrics no longer include
network.protocol.name,network.protocol.version, ornetwork.transportattributes.rpc.client.request.size,rpc.client.response.size,rpc.server.request.size, andrpc.server.response.sizeare no longer emitted ingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc.rpc.messagespan events and their message attributes are no longer emitted ingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc(including whenWithMessageEventsis configured).See semantic-conventions v1.40.0 release for complete details.
Fixed
- Ignore informational response status codes (
100-199) except101 Switching Protocolswhen storing the HTTP status code ingo.opentelemetry.io/contrib/instrumentation/net/http/otelhttpandgo.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux. (#6913)- Make
Bodyhandling inTransportconsistent with stdlib ingo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp. (#8618)- Fix bucket boundaries for
rpc.server.call.durationandrpc.client.call.durationingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc. (#8642)- Host resource detector in
go.opentelemetry.io/contrib/otelconfnow includesos.attributes. (#8578)Removed
- Drop support for [Go 1.24]. (#8628)
d8dabf6
Release v1.42.0/v2.4.0/v0.67.0/v0.36.0/v0.22.0/v0.17.0/v0.15.0/v0.14.0
(#8649)b1de2c7
otelconf: host detector should include os as well (#8578)b228c0f
fix(deps): update module google.golang.org/grpc to v1.79.2 (#8644)e70fd97
Use correct bucket boundaries for otelgrpc client and server histograms
(#8642)b018d98
fix(deps): update aws-sdk-go-v2 monorepo (#8643)fb6a351
chore(deps): update github/codeql-action action to v4.32.6 (#8641)2c9c10e
chore(deps): update dependency codespell to v2.4.2 (#8640)22248d4
chore: enable modernize linter (#8583)324662a
envcar: add environment carrier (#8442)69addb4
chore(deps): update k8s.io/kube-openapi digest to 5b3e3fd (#8636)Sourced from go.opentelemetry.io/otel's changelog.
[1.42.0/0.64.0/0.18.0/0.0.16] 2026-03-06
Added
- Add
go.opentelemetry.io/otel/semconv/v1.40.0package. The package contains semantic conventions from thev1.40.0version of the OpenTelemetry Semantic Conventions. See the migration documentation for information on how to upgrade fromgo.opentelemetry.io/otel/semconv/v1.39.0. (#7985)- Add
ErrandSetErronRecordingo.opentelemetry.io/otel/logto attach an error and set record exception attributes ingo.opentelemetry.io/otel/log/sdk. (#7924)Changed
TracerProvider.ForceFlushingo.opentelemetry.io/otel/sdk/tracejoins errors together and continues iteration through SpanProcessors as opposed to returning the first encountered error without attempting exports on subsequent SpanProcessors. (#7856)Fixed
- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto correctly handle HTTP2 GOAWAY frame. (#7931)- Fix semconv v1.39.0 generated metric helpers skipping required attributes when extra attributes were empty. (#7964)
- Preserve W3C TraceFlags bitmask (including the random Trace ID flag) during trace context extraction and injection in
go.opentelemetry.io/otel/propagation. (#7834)Removed
- Drop support for [Go 1.24]. (#7984)
a3941ff
Release v1.42.0/v0.64.0/v0.18.0/v0.0.16 (#8006)6059c47
chore(deps): update golang.org/x/telemetry digest to e526e8a (#8010)44c7edf
chore(deps): update module github.com/mgechev/revive to v1.15.0 (#8009)de5fb3a
fix(deps): update module google.golang.org/grpc to v1.79.2 (#8007)0b82ded
chore(deps): update codspeedhq/action action to v4.11.1 (#8001)aa3660f
chore(deps): update github/codeql-action action to v4.32.6 (#8004)9be8c92
chore(deps): update dependency codespell to v2.4.2 (#8003)c9d2015
log: add error field to Record and make SDK to emit exception attributes
(#7924)fdd1320
TracerProvider ForceFlush() Error Fix (#7856)78f9904
chore(deps): update golang.org/x/telemetry digest to 18da590 (#8000)Sourced from go.opentelemetry.io/otel/exporters/prometheus's releases.
v1.42.0/v0.64.0/v0.18.0/v0.0.16
Added
- Add
go.opentelemetry.io/otel/semconv/v1.40.0package. The package contains semantic conventions from thev1.40.0version of the OpenTelemetry Semantic Conventions. See the migration documentation for information on how to upgrade fromgo.opentelemetry.io/otel/semconv/v1.39.0. (#7985)- Add
ErrandSetErronRecordingo.opentelemetry.io/otel/logto attach an error and set record exception attributes ingo.opentelemetry.io/otel/log/sdk. (#7924)Changed
TracerProvider.ForceFlushingo.opentelemetry.io/otel/sdk/tracejoins errors together and continues iteration through SpanProcessors as opposed to returning the first encountered error without attempting exports on subsequent SpanProcessors. (#7856)Fixed
- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto correctly handle HTTP2 GOAWAY frame. (#7931)- Fix semconv v1.39.0 generated metric helpers skipping required attributes when extra attributes were empty. (#7964)
- Preserve W3C TraceFlags bitmask (including the random Trace ID flag) during trace context extraction and injection in
go.opentelemetry.io/otel/propagation. (#7834)Removed
- Drop support for [Go 1.24]. (#7984)
What's Changed
- fix changelog protection marker by
@pellaredin open-telemetry/opentelemetry-go#7986- Drop support for Go 1.24 by
@MrAliasin open-telemetry/opentelemetry-go#7984- fix(deps): update golang.org/x by
@renovate[bot] in open-telemetry/opentelemetry-go#7907- chore(deps): update module go.opentelemetry.io/collector/featuregate to v1.53.0 by
@renovate[bot] in open-telemetry/opentelemetry-go#7981- chore(deps): update benchmark-action/github-action-benchmark action to v1.21.0 by
@renovate[bot] in open-telemetry/opentelemetry-go#7989- fix(deps): update module go.opentelemetry.io/collector/pdata to v1.53.0 by
@renovate[bot] in open-telemetry/opentelemetry-go#7982- Revert "Revert "Generate semconv/v1.40.0"" by
@MrAliasin open-telemetry/opentelemetry-go#7985- support stdlib request.GetBody on metrics by
@marifari-huein open-telemetry/opentelemetry-go#7931- attribute: add TestNotEquivalence and equality operator tests by
@pellaredin open-telemetry/opentelemetry-go#7979- Refactor benchmark CI by
@XSAMin open-telemetry/opentelemetry-go#7873- chore(deps): update module github.com/securego/gosec/v2 to v2.24.7 by
@renovate[bot] in open-telemetry/opentelemetry-go#7988- chore(deps): pin codspeedhq/action action to df47568 by
@renovate[bot] in open-telemetry/opentelemetry-go#7996- chore(deps): update actions/checkout action to v6.0.2 by
@renovate[bot] in open-telemetry/opentelemetry-go#7997- chore(deps): update codspeedhq/action action to v4.11.0 by
@renovate[bot] in open-telemetry/opentelemetry-go#7999- Upgrade to semconv/v1.40.0 by
@MrAliasin open-telemetry/opentelemetry-go#7991- Regenerate semconv/v1.40.0/MIGRATION.md by
@MrAliasin open-telemetry/opentelemetry-go#7992- fix: generated semconv helpers skipping attributes by
@victoraugustollsin open-telemetry/opentelemetry-go#7964- Feat: Have SpanContext support the new W3C random flag. by
@nikhilmantri0902in open-telemetry/opentelemetry-go#7834- Semconv metric helper caller-slice mutation fix by
@MrAliasin open-telemetry/opentelemetry-go#7993- Fix semconv generated error type to check error chain for custom type declaration by
@MrAliasin open-telemetry/opentelemetry-go#7994- refactor: replace uint64 and int32 with atomic types in tests by
@alexandearin open-telemetry/opentelemetry-go#7941- chore(deps): update golang.org/x/telemetry digest to 18da590 by
@renovate[bot] in open-telemetry/opentelemetry-go#8000- TracerProvider ForceFlush() Error Fix by
@sawamurataxmanin open-telemetry/opentelemetry-go#7856- log: add error field to Record and make SDK to emit exception attributes by
@iblancasain open-telemetry/opentelemetry-go#7924- chore(deps): update dependency codespell to v2.4.2 by
@renovate[bot] in open-telemetry/opentelemetry-go#8003- chore(deps): update github/codeql-action action to v4.32.6 by
@renovate[bot] in open-telemetry/opentelemetry-go#8004- chore(deps): update codspeedhq/action action to v4.11.1 by
@renovate[bot] in open-telemetry/opentelemetry-go#8001
... (truncated)
Sourced from go.opentelemetry.io/otel/exporters/prometheus's changelog.
[1.42.0/0.64.0/0.18.0/0.0.16] 2026-03-06
Added
- Add
go.opentelemetry.io/otel/semconv/v1.40.0package. The package contains semantic conventions from thev1.40.0version of the OpenTelemetry Semantic Conventions. See the migration documentation for information on how to upgrade fromgo.opentelemetry.io/otel/semconv/v1.39.0. (#7985)- Add
ErrandSetErronRecordingo.opentelemetry.io/otel/logto attach an error and set record exception attributes ingo.opentelemetry.io/otel/log/sdk. (#7924)Changed
TracerProvider.ForceFlushingo.opentelemetry.io/otel/sdk/tracejoins errors together and continues iteration through SpanProcessors as opposed to returning the first encountered error without attempting exports on subsequent SpanProcessors. (#7856)Fixed
- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto correctly handle HTTP2 GOAWAY frame. (#7931)- Fix semconv v1.39.0 generated metric helpers skipping required attributes when extra attributes were empty. (#7964)
- Preserve W3C TraceFlags bitmask (including the random Trace ID flag) during trace context extraction and injection in
go.opentelemetry.io/otel/propagation. (#7834)Removed
- Drop support for [Go 1.24]. (#7984)
a3941ff
Release v1.42.0/v0.64.0/v0.18.0/v0.0.16 (#8006)6059c47
chore(deps): update golang.org/x/telemetry digest to e526e8a (#8010)44c7edf
chore(deps): update module github.com/mgechev/revive to v1.15.0 (#8009)de5fb3a
fix(deps): update module google.golang.org/grpc to v1.79.2 (#8007)0b82ded
chore(deps): update codspeedhq/action action to v4.11.1 (#8001)aa3660f
chore(deps): update github/codeql-action action to v4.32.6 (#8004)9be8c92
chore(deps): update dependency codespell to v2.4.2 (#8003)c9d2015
log: add error field to Record and make SDK to emit exception attributes
(#7924)fdd1320
TracerProvider ForceFlush() Error Fix (#7856)78f9904
chore(deps): update golang.org/x/telemetry digest to 18da590 (#8000)Sourced from go.opentelemetry.io/otel/metric's changelog.
[1.42.0/0.64.0/0.18.0/0.0.16] 2026-03-06
Added
- Add
go.opentelemetry.io/otel/semconv/v1.40.0package. The package contains semantic conventions from thev1.40.0version of the OpenTelemetry Semantic Conventions. See the migration documentation for information on how to upgrade fromgo.opentelemetry.io/otel/semconv/v1.39.0. (#7985)- Add
ErrandSetErronRecordingo.opentelemetry.io/otel/logto attach an error and set record exception attributes ingo.opentelemetry.io/otel/log/sdk. (#7924)Changed
TracerProvider.ForceFlushingo.opentelemetry.io/otel/sdk/tracejoins errors together and continues iteration through SpanProcessors as opposed to returning the first encountered error without attempting exports on subsequent SpanProcessors. (#7856)Fixed
- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto correctly handle HTTP2 GOAWAY frame. (#7931)- Fix semconv v1.39.0 generated metric helpers skipping required attributes when extra attributes were empty. (#7964)
- Preserve W3C TraceFlags bitmask (including the random Trace ID flag) during trace context extraction and injection in
go.opentelemetry.io/otel/propagation. (#7834)Removed
- Drop support for [Go 1.24]. (#7984)
a3941ff
Release v1.42.0/v0.64.0/v0.18.0/v0.0.16 (#8006)6059c47
chore(deps): update golang.org/x/telemetry digest to e526e8a (#8010)44c7edf
chore(deps): update module github.com/mgechev/revive to v1.15.0 (#8009)de5fb3a
fix(deps): update module google.golang.org/grpc to v1.79.2 (#8007)0b82ded
chore(deps): update codspeedhq/action action to v4.11.1 (#8001)aa3660f
chore(deps): update github/codeql-action action to v4.32.6 (#8004)9be8c92
chore(deps): update dependency codespell to v2.4.2 (#8003)c9d2015
log: add error field to Record and make SDK to emit exception attributes
(#7924)fdd1320
TracerProvider ForceFlush() Error Fix (#7856)78f9904
chore(deps): update golang.org/x/telemetry digest to 18da590 (#8000)Sourced from go.opentelemetry.io/otel/sdk's changelog.
[1.42.0/0.64.0/0.18.0/0.0.16] 2026-03-06
Added
- Add
go.opentelemetry.io/otel/semconv/v1.40.0package. The package contains semantic conventions from thev1.40.0version of the OpenTelemetry Semantic Conventions. See the migration documentation for information on how to upgrade fromgo.opentelemetry.io/otel/semconv/v1.39.0. (#7985)- Add
ErrandSetErronRecordingo.opentelemetry.io/otel/logto attach an error and set record exception attributes ingo.opentelemetry.io/otel/log/sdk. (#7924)Changed
TracerProvider.ForceFlushingo.opentelemetry.io/otel/sdk/tracejoins errors together and continues iteration through SpanProcessors as opposed to returning the first encountered error without attempting exports on subsequent SpanProcessors. (#7856)Fixed
- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto correctly handle HTTP2 GOAWAY frame. (#7931)- Fix semconv v1.39.0 generated metric helpers skipping required attributes when extra attributes were empty. (#7964)
- Preserve W3C TraceFlags bitmask (including the random Trace ID flag) during trace context extraction and injection in
go.opentelemetry.io/otel/propagation. (#7834)Removed
- Drop support for [Go 1.24]. (#7984)
a3941ff
Release v1.42.0/v0.64.0/v0.18.0/v0.0.16 (#8006)6059c47
chore(deps): update golang.org/x/telemetry digest to e526e8a (#8010)44c7edf
chore(deps): update module github.com/mgechev/revive to v1.15.0 (#8009)de5fb3a
fix(deps): update module google.golang.org/grpc to v1.79.2 (#8007)0b82ded
chore(deps): update codspeedhq/action action to v4.11.1 (#8001)aa3660f
chore(deps): update github/codeql-action action to v4.32.6 (#8004)9be8c92
chore(deps): update dependency codespell to v2.4.2 (#8003)c9d2015
log: add error field to Record and make SDK to emit exception attributes
(#7924)fdd1320
TracerProvider ForceFlush() Error Fix (#7856)78f9904
chore(deps): update golang.org/x/telemetry digest to 18da590 (#8000)Sourced from go.opentelemetry.io/otel/sdk/metric's changelog.
[1.42.0/0.64.0/0.18.0/0.0.16] 2026-03-06
Added
- Add
go.opentelemetry.io/otel/semconv/v1.40.0package. The package contains semantic conventions from thev1.40.0version of the OpenTelemetry Semantic Conventions. See the migration documentation for information on how to upgrade fromgo.opentelemetry.io/otel/semconv/v1.39.0. (#7985)- Add
ErrandSetErronRecordingo.opentelemetry.io/otel/logto attach an error and set record exception attributes ingo.opentelemetry.io/otel/log/sdk. (#7924)Changed
TracerProvider.ForceFlushingo.opentelemetry.io/otel/sdk/tracejoins errors together and continues iteration through SpanProcessors as opposed to returning the first encountered error without attempting exports on subsequent SpanProcessors. (#7856)Fixed
- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto correctly handle HTTP2 GOAWAY frame. (#7931)- Fix semconv v1.39.0 generated metric helpers skipping required attributes when extra attributes were empty. (#7964)
- Preserve W3C TraceFlags bitmask (including the random Trace ID flag) during trace context extraction and injection in
go.opentelemetry.io/otel/propagation. (#7834)Removed
- Drop support for [Go 1.24]. (#7984)
a3941ff
Release v1.42.0/v0.64.0/v0.18.0/v0.0.16 (#8006)6059c47
chore(deps): update golang.org/x/telemetry digest to e526e8a (#8010)44c7edf
chore(deps): update module github.com/mgechev/revive to v1.15.0 (#8009)de5fb3a
fix(deps): update module google.golang.org/grpc to v1.79.2 (#8007)0b82ded
chore(deps): update codspeedhq/action action to v4.11.1 (#8001)aa3660f
chore(deps): update github/codeql-action action to v4.32.6 (#8004)9be8c92
chore(deps): update dependency codespell to v2.4.2 (#8003)c9d2015
log: add error field to Record and make SDK to emit exception attributes
(#7924)fdd1320
TracerProvider ForceFlush() Error Fix (#7856)78f9904
chore(deps): update golang.org/x/telemetry digest to 18da590 (#8000)Sourced from github.com/google/go-containerregistry's releases.
v0.21.2
What's Changed
- Better handle redirects to https in ping by
@jonjohnsonjrin google/go-containerregistry#2225Full Changelog: https://github.com/google/go-containerregistry/compare/v0.21.1...v0.21.2
v0.21.1
This release fixes a regression in
craneintroduced in the previous release.What's Changed
- Add WithFileBufferedOpener for file-backed daemon image buffering by
@twdamhorein google/go-containerregistry#2214- crane: fix case in auth response json by
@aelindemanin google/go-containerregistry#2218New Contributors
@twdamhoremade their first contribution in google/go-containerregistry#2214@aelindemanmade their first contribution in google/go-containerregistry#2218Full Changelog: https://github.com/google/go-containerregistry/compare/v0.21.0...v0.21.1
v0.21.0
This release updates the minimum Go version to
1.25.6.What's Changed
- fix(mutate): don't skip dir replacements via whiteout in export by
@r4f4in google/go-containerregistry#2191- Improve performance of v1.NewHash by
@bmoylanin google/go-containerregistry#2194- Bump the actions group across 1 directory with 4 updates by
@dependabot[bot] in google/go-containerregistry#2207- Bump the root-deps group across 1 directory with 7 updates by
@dependabot[bot] in google/go-containerregistry#2195- Fix error messages in crane_test.go by
@jammie-jellyin google/go-containerregistry#2189- Bump go version across packages to 1.25.6 by
@Subserialin google/go-containerregistry#2211- Join go.mod dependency updates by
@Subserialin google/go-containerregistry#2212- Bump the go-deps group across 3 directories with 3 updates by
@dependabot[bot] in google/go-containerregistry#2213- Disable taint gosec lints by
@Subserialin google/go-containerregistry#2215- Update go version used in goreleaser by
@Subserialin google/go-containerregistry#2216New Contributors
@r4f4made their first contribution in google/go-containerregistry#2191@jammie-jellymade their first contribution in google/go-containerregistry#2189Full Changelog: https://github.com/google/go-containerregistry/compare/v0.20.7...v0.21.0
9e0ccb0
Better handle redirects to https in ping (#2225)85f2bf5
crane: fix case in auth response json (#2218)e971d63
Add WithFileBufferedOpener for file-backed daemon image buffering (#2214)8e2d6a6
Update go version used in goreleaser (#2216)b58334f
Disable taint gosec lints (#2215)88b39ed
Bump the go-deps group across 3 directories with 3 updates (#2213)102ac75
join go.mod dependency updates (#2212)d5817d5
Bump go version across packages to 1.25.6 (#2211)23f0632
Fix error messages in crane_test.go (#2189)438abde
Bump the root-deps group across 1 directory with 7 updates (#2195)Sourced from sigstore/cosign-installer's releases.
v4.1.0
What's Changed
We recommend updating as soon as possible as this includes bug fixes for Cosign. We also recommend removing
with: cosign-releaseand strongly discourage usingcosign-releaseunless you have a specific reason to use an older version of Cosign.
- Bump cosign to 3.0.5 in sigstore/cosign-installer#220
- fix: add retry to curl downloads for transient network failures in sigstore/cosign-installer#210
Full Changelog: https://github.com/sigstore/cosign-installer/compare/v4.0.0...v4.1.0
ba7bc0a
fix: add retry to curl downloads for transient network failures (#210)5a292e1
Bump cosign to 3.0.5 (#220)351ea76
Bump actions/checkout from 6.0.1 to 6.0.2 (#217)c17565f
test with go 1.26 too (#221)a6fdd19
Bump actions/setup-go from 6.1.0 to 6.3.0 (#218)430b6a7
docs: fix registry from gcr.io to ghcr.io (#213)4d14d7f
feat: update to v3.0.3 (#212)f148005
fix: use env vars for template expansions; show curl errors (#207)c3f2d79
Bump actions/checkout from 6.0.0 to 6.0.1 (#208)b9a9af4
drop tests with go1.24 as it cant build (#211)Sourced from anchore/sbom-action's releases.
v0.23.1
⬆️ Dependencies
- chore(deps): update Syft to v1.42.2 (#607) [@anchore-actions-token-generator[bot]]
- chore(deps): bump fast-xml-parser and all other deps (#604) [@dependabot[bot]]
57aae52
chore(deps): update Syft to v1.42.2 (#607)c29e913
chore(deps): bump fast-xml-parser and other deps (#604)1ac721d
go.mod: update golang.org/x dependenciesfb1fac8
all: upgrade go directive to at least 1.25.0 [generated]Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.226.0
3.226.0 (2026-03-11)
Features
[backend/service] Automatically repair snapshot integrity issues, while sending an error event to the backend for further diagnosis #22179
[cli] Add a --otel-traces flag, that allows writing otel traces to a file, or directly to a grpc interface #22129
[engine] Engine will use provider references from
__self__arguments to calls #22114[sdk/bun] Add debugger support for the bun runtime #22177
[sdk/bun] Add support for Bun as a plugin runtime #22189
Bug Fixes
[engine] Fix ReplacementTrigger firing due to dependency changes #22119
[engine] Correctly serialize output values to the snapshot rather than always recording them as computed even when known #22120
[pcl] Support resource ranges in PCL #22144
[cli/config] Include environments used when refreshing a stack's config #22103
[cli/display] Fix
pulumi destroynot showing parent resource hierarchy #22148[cli/package] Correctly parse package URLs with .git in them #22174
[cli/plugin] Fix package get-schema for binary providers at relative paths #22107
[sdk/python] Handle null detailedDiff in automation StepEventMetadata JSON parsing
... (truncated)
94ee966
Bump the SDKs for 3.226.0 (#22195)4f16f96
Fix Mise deprecation warnings (#22186)b0a5846
Tighten CLI error typing for exit code mapping (#22176)6ebc01e
Add support for Bun as a plugin runtime (#22189)a42977b
Revert "Pin Node.js to 25.6" (#22188)c1dabce
rename env variable used for otel internal endpoint (#22187)646a020
Read Poetry and uv lockfiles to determine program dependencies (#22072)32871e0
Add l3-for & l3-for-resource (#22180)b190b8b
Include environment when re-loading config from cloud state
(#22103)e5e3a1d
auto repair snapshot integrity errors and send error event (#22179)Sourced from github.com/pulumi/pulumi-kubernetes/sdk/v4's releases.
v4.28.0
No release notes provided.
Sourced from github.com/pulumi/pulumi-kubernetes/sdk/v4's changelog.
4.28.0 (March 12, 2026)
Changed
- Upgrade Kubernetes schema and libraries to v1.35.2.
1655f4c
Prepare for v4.28.0 release (#4230)dbeeb56
Update module github.com/pulumi/pulumi-dotnet/pulumi-language-dotnet/v3
to v3...c6b1c91
Automated upgrade: bump Kubernetes to v1.35.2 (#4223)fedb665
Run build on patch upgrade PRs (#4221)4b3e1f4
Fix misplaced closing paren in kubernetes-update-check workflow (#4218)1737d00
Combined dependencies PR (#4209)be0dfed
Update GitHub Actions workflows. (#4217)4ecded1
Fix make lint to run to completion (#4213)af862bb
Move cloud-ready-checks back to pulumi-kubernetes (#4196)ecf6701
Update GitHub Actions workflows. (#4208)Sourced from github.com/danielgtaylor/huma/v2's releases.
v2.37.2
Overview
This bugfix release fixes an issue with how form data was being documented in OpenAPI.
This also fixes embedded objects with valid JSON tags being incorrectly embedded in the OpenAPI docs.
What's Changed
- Don't embed embedded objects with valid JSON tags by
@wolveixin danielgtaylor/huma#978- Fix OpenAPI path prefix regression from $schema fix PR by
@wolveixin danielgtaylor/huma#979- Fix form param doc regression by
@wolveixin danielgtaylor/huma#981Full Changelog: https://github.com/danielgtaylor/huma/compare/v2.37.1...v2.37.2
v2.37.1
Overview
This bugfix release fixes an issue regarding the Swagger UI docs renderer, as well as fixes an issue preventing Groups from using the configurable options released in v2.37.1.
This also brings interface constructors to
humamux.What's Changed
- Export Gorilla Mux interface constructors by
@RangelRealein danielgtaylor/huma#965- fix(api): use proper CSP hash for inline script in Swagger doc renderer by
@leonklingelein danielgtaylor/huma#977- fix(group): ensure "Group" satisfies the configProvider interface by
@leonklingelein danielgtaylor/huma#976Full Changelog: https://github.com/danielgtaylor/huma/compare/v2.37.0...v2.37.1
v2.37.0
Overview
Dropped Explicit IDN-Hostname Validation
This validation unintentionally imported an external library to the base Huma library. Since this was not a requested feature, it has been removed for now. The
idn-hostnameformat value has become an alias forhostnamein the meantime.Operation ID Normalization
Spaces in operation IDs get automatically converted to hyphens now.
Optimizations & Fixed Memory Leak
Various internal operations have been optimized (~7% overall improvement): danielgtaylor/huma#973
A memory leak when using
MultipartFormFileshas been resolved.New Configurable Options
Allow Additional Properties By Default
A new config option has been added to allow additional properties by default. This can be set in the API config.
config.AllowAdditionalPropertiesByDefault = true
... (truncated)
887f7d4
Fix form param doc regression (#981)f02efeb
Fix OpenAPI path prefix regression from $schema fix PR (#979)cbf60b6
Don't embed embedded objects with valid JSON tags (#978)6d0295c
fix(group): ensure "Group" satisfies the configProvider
interface (#976)07ca6c5
fix(api): use proper CSP hash for inline script in Swagger doc renderer
(#977)58edcf2
Export humamux constructors (#965)6c29f67
chore(api,docs): update unpkg libraries, specify SRI hash, add strict
CSP (#916)3aee9bd
Additional docs + normalize operation IDs (#974)e31a819
Resource optimizations, Go 1.25, remove IDNA library, add benchmark CI
(#973)ddbb810
Implement Registry and Query Validation Options (#925)Sourced from github.com/google/go-containerregistry's releases.
v0.21.3
What's Changed
- Adds local file support to the
crane indexsubcommand by@edwardthielein google/go-containerregistry#2223- migrate to github.com/moby/moby modules by
@thaJeztahin google/go-containerregistry#2228- Bump the go-deps group across 4 directories with 7 updates by
@dependabot[bot] in google/go-containerregistry#2233- Bump goreleaser/goreleaser-action from 6.4.0 to 7.0.0 in the actions group by
@dependabot[bot] in google/go-containerregistry#2220- mutate: reject path traversal and symlink escape in Extract by
@KevinZhaoin google/go-containerregistry#2227- tarball: detect symlink cycles in extractFileFromTar by
@vnykmshrin google/go-containerregistry#2232- bump golang to 1.25.7 by
@Subserialin google/go-containerregistry#2236New Contributors
@edwardthielemade their first contribution in google/go-containerregistry#2223@thaJeztahmade their first contribution in google/go-containerregistry#2228@KevinZhaomade their first contribution in google/go-containerregistry#2227@vnykmshrmade their first contribution in google/go-containerregistry#2232Full Changelog: https://github.com/google/go-containerregistry/compare/v0.21.2...v0.21.3
3888fb8
bump golang to 1.25.7 (#2236)f439624
tarball: detect symlink cycles in extractFileFromTar (#2232)400c263
mutate: reject path traversal and symlink escape in Extract (#2227)47eedc9
Bump goreleaser/goreleaser-action in the actions group (#2220)be0a845
Bump the go-deps group across 4 directories with 7 updates (#2233)e916301
migrate to github.com/moby/moby modules (#2228)8b2478e
Adds local file support to the crane index subcommand (#2223)Sourced from google.golang.org/grpc's releases.
Release 1.79.3
Security
- server: fix an authorization bypass where malformed :path headers (missing the leading slash) could bypass path-based restricted "deny" rules in interceptors like
grpc/authz. Any request with a non-canonical path is now immediately rejected with anUnimplementederror. (#8981)Release 1.79.2
Bug Fixes
- stats: Prevent redundant error logging in health/ORCA producers by skipping stats/tracing processing when no stats handler is configured. (grpc/grpc-go#8874)
dda86db
Change version to 1.79.3 (#8983)72186f1
grpc: enforce strict path checking for incoming requests on the server
(#8981)97ca352
Changing version to 1.79.3-dev (#8954)8902ab6
Change the version to release 1.79.2 (#8947)a928670
Cherry-pick #8874 to
v1.79.x (#8904)06df363
Change version to 1.79.2-dev (#8903)Sourced from google.golang.org/grpc's releases.
Release 1.79.3
Security
- server: fix an authorization bypass where malformed :path headers (missing the leading slash) could bypass path-based restricted "deny" rules in interceptors like
grpc/authz. Any request with a non-canonical path is now immediately rejected with anUnimplementederror. (#8981)Release 1.79.2
Bug Fixes
- stats: Prevent redundant error logging in health/ORCA producers by skipping stats/tracing processing when no stats handler is configured. (grpc/grpc-go#8874)
Release 1.79.1
Bug Fixes
- grpc: Remove the
-devsuffix from the User-Agent header. (grpc/grpc-go#8902)Release 1.79.0
API Changes
- mem: Add experimental API
SetDefaultBufferPoolto change the default buffer pool. (#8806)
- Special Thanks:
@vanja-p- experimental/stats: Update
MetricsRecorderto require embedding the newUnimplementedMetricsRecorder(a no-op struct) in all implementations for forward compatibility. (#8780)Behavior Changes
- balancer/weightedtarget: Remove handling of
Addressesand only handleEndpointsin resolver updates. (#8841)New Features
- experimental/stats: Add support for asynchronous gauge metrics through the new
AsyncMetricReporterandRegisterAsyncReporterAPIs. (#8780)- pickfirst: Add support for weighted random shuffling of endpoints, as described in gRFC A113.
- This is enabled by default, and can be turned off using the environment variable
GRPC_EXPERIMENTAL_PF_WEIGHTED_SHUFFLING. (#8864)- xds: Implement
:authorityrewriting, as specified in gRFC A81. (#8779)- balancer/randomsubsetting: Implement the
random_subsettingLB policy, as specified in gRFC A68. (#8650)
- Special Thanks:
@marek-szewsBug Fixes
- credentials/tls: Fix a bug where the port was not stripped from the authority override before validation. (#8726)
- Special Thanks:
@Atul1710- xds/priority: Fix a bug causing delayed failover to lower-priority clusters when a higher-priority cluster is stuck in
CONNECTINGstate. (#8813)- health: Fix a bug where health checks failed for clients using legacy compression options (
WithDecompressororRPCDecompressor). (#8765)
- Special Thanks:
@sanki92- transport: Fix an issue where the HTTP/2 server could skip header size checks when terminating a stream early. (#8769)
- Special Thanks:
@joybestourous- server: Propagate status detail headers, if available, when terminating a stream during request header processing. (#8754)
- Special Thanks:
@joybestourousPerformance Improvements
dda86db
Change version to 1.79.3 (#8983)72186f1
grpc: enforce strict path checking for incoming requests on the server
(#8981)97ca352
Changing version to 1.79.3-dev (#8954)8902ab6
Change the version to release 1.79.2 (#8947)a928670
Cherry-pick #8874 to
v1.79.x (#8904)06df363
Change version to 1.79.2-dev (#8903)782f2de
Change version to 1.79.1 (#8902)850eccb
Change version to 1.79.1-dev (#8851)765ff05
Change version to 1.79.0 (#8850)68804be
Cherry pick #8864 to
v1.79.x (#8896)Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.228.0
3.228.0 (2026-03-25)
Features
[cli] Don't apply the secrets filter to
trueandfalse(case-insensitive) #22269[cli] Add grpcs:// support and header authentication to OTLP exporter #22320
[cli] Read OTEL_RESOURCE_ATTRIBUTES #22329
[auto/nodejs] Add low-level "cancel" command to the auto-generated interface #22156
[cli/state] Allow
pulumi state deleteto accept multiple resource URNs and delete them in a dependency-safe orderBug Fixes
[cli] Allow relative file paths for --otel-traces #22300
[cli] Bridge opentracing spans from providers into OTel #22313
[cli] Correctly end spans for GRPC streams #22304
[cli/about] Do not include the access token in plain text #22347
[display] Fix detailed diff indentation so changed resources are not visually nested under unrelated visible resources when unchanged parents are hidden. #22317
[cli/import] Fix import codegen when generating references to non-standard names #22319
[engine] Update golang version #22277
[pcl] Typecheck component inputs in PCL programs #22292
[programgen/{nodejs,python}] Fix literal conversion when calling into local components #22306
... (truncated)
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.228.0 (2026-03-25)
Features
[cli] Don't apply the secrets filter to
trueandfalse(case-insensitive) #22269[cli] Add grpcs:// support and header authentication to OTLP exporter #22320
[cli] Read OTEL_RESOURCE_ATTRIBUTES #22329
[auto/nodejs] Add low-level "cancel" command to the auto-generated interface #22156
[cli/state] Allow
pulumi state deleteto accept multiple resource URNs and delete them in a dependency-safe orderBug Fixes
[cli] Allow relative file paths for --otel-traces #22300
[cli] Bridge opentracing spans from providers into OTel #22313
[cli] Correctly end spans for GRPC streams #22304
[cli/about] Do not include the access token in plain text #22347
[display] Fix detailed diff indentation so changed resources are not visually nested under unrelated visible resources when unchanged parents are hidden. #22317
[cli/import] Fix import codegen when generating references to non-standard names #22319
[engine] Update golang version #22277
[pcl] Typecheck component inputs in PCL programs #22292
[programgen/{nodejs,python}] Fix literal conversion when calling into local components #22306
... (truncated)
7551b7f
feat(cli/state): multiple URNs and substring match for pulumi
state delete ...6a1c2d2
env: mark AccessToken as Secret (#22347)9630cec
Deprecate legacy mode (#19625)3171ca6
Fix l2-component-call-simple (#22339)d5bf67e
Fix use of sanitised names in import codegen (#22319)6589fd4
Allow setting a GRPC endpoint for performance tests (#22330)fba98e9
Unskip l2-snake-names (#22337)469eb83
[display] Fix detailed diff indentation when hidden parents are
unchanged (#2...fe4a635
Update golang version to fix CVEs (#22277)cfb587b
fix(sdk/go/pulumi-language-go/goversion): handle non-standard toolchains
(#22...Sourced from github.com/danielgtaylor/huma/v2's releases.
v2.37.3
Overview
This bugfix release fixes a few minor bugs and typos from previous releases.
This also adjusts the HTTP status code returned by Huma if marshaling a response fails, from 200 to 500.
What's Changed
- Fix: add allow-popups to CSP sandbox for OAuth popups by
@Micasoin danielgtaylor/huma#987- Fix: use epsilon tolerance in multipleOf float validation by
@smazurovin danielgtaylor/huma#989- Fix typo in groups.md documentation by
@Its-Hazein danielgtaylor/huma#995- Fix relative schema urls by
@wolveixin danielgtaylor/huma#990- Return HTTP 500 if marshaling fails by
@wolveixin danielgtaylor/huma#997- Handle contentEncoding and contentMediaType keys by
@NPelletin danielgtaylor/huma#919- Chore(deps): bump github.com/gofiber/fiber/v2 from 2.52.11 to 2.52.12 by
@dependabot[bot] in danielgtaylor/huma#984New Contributors
@Micasomade their first contribution in danielgtaylor/huma#987@smazurovmade their first contribution in danielgtaylor/huma#989@Its-Hazemade their first contribution in danielgtaylor/huma#995@NPelletmade their first contribution in danielgtaylor/huma#919Full Changelog: https://github.com/danielgtaylor/huma/compare/v2.37.2...v2.37.3
a38b536
chore(deps): bump github.com/gofiber/fiber/v2 from 2.52.11 to 2.52.12
(#984)f4c5363
Handle contentEncoding and contentMediaType keys (#919)1678a04
Return HTTP 500 if marshaling fails (#997)1d5dddf
Fix relative schema urls (#990)1b8766d
fix typo in groups.md documentation (#995)99e60fd
fix: use epsilon tolerance in multipleOf float validation (#989)c6694fa
fix: add allow-popups to CSP sandbox for OAuth popups (#987)Sourced from github.com/go-git/go-git/v5's releases.
v5.17.1
What's Changed
- build: Update module github.com/cloudflare/circl to v1.6.3 [SECURITY] (releases/v5.x) by
@go-git-renovate[bot] in go-git/go-git#1930- [v5] plumbing: format/index, Improve v4 entry name validation by
@pjbgfin go-git/go-git#1935- [v5] plumbing: format/idxfile, Fix version and fanout checks by
@pjbgfin go-git/go-git#1937Full Changelog: https://github.com/go-git/go-git/compare/v5.17.0...v5.17.1
v5.17.0
What's Changed
- build: Update module github.com/go-git/go-git/v5 to v5.16.5 [SECURITY] (releases/v5.x) by
@go-git-renovate[bot] in go-git/go-git#1839- git: worktree, optimize infiles function for very large repos by
@k-anshulin go-git/go-git#1853- git: Add strict checks for supported extensions by
@pjbgfin go-git/go-git#1861- backport, git: Improve Status() speed with new index.ModTime check by
@cedric-appdirectin go-git/go-git#1862- storage: filesystem, Avoid overwriting loose obj files by
@pjbgfin go-git/go-git#1864Full Changelog: https://github.com/go-git/go-git/compare/v5.16.5...v5.17.0
5e23dfd
Merge pull request #1937
from pjbgf/idx-v56b38a32
Merge pull request #1935
from pjbgf/index-v5cd757fc
plumbing: format/idxfile, Fix version and fanout checks3ec0d70
plumbing: format/index, Fix tree extension invalidated entry
parsingdbe10b6
plumbing: format/index, Align V2/V3 long name and V4 prefix encoding
with Gite9b65df
plumbing: format/index, Improve v4 entry name validationadad18d
Merge pull request #1930
from go-git/renovate/releases/v5.x-go-github.com-clo...29470bd
build: Update module github.com/cloudflare/circl to v1.6.3
[SECURITY]bdf0688
Merge pull request #1864
from pjbgf/v5-issue-555290e52
storage: filesystem, Avoid overwriting loose obj files. Fixes #55Sourced from actions/setup-go's releases.
v6.4.0
What's Changed
Enhancement
- Add go-download-base-url input for custom Go distributions by
@gdamsin actions/setup-go#721Dependency update
- Upgrade minimatch from 3.1.2 to 3.1.5 by
@dependabotin actions/setup-go#727Documentation update
- Rearrange README.md, add advanced-usage.md by
@priyagupta108in actions/setup-go#724- Fix Microsoft build of Go link by
@gdamsin actions/setup-go#734New Contributors
@gdamsmade their first contribution in actions/setup-go#721Full Changelog: https://github.com/actions/setup-go/compare/v6...v6.4.0
Sourced from sigstore/cosign-installer's releases.
v4.1.1
What's Changed
- chore: update default cosign-release to v3.0.5 in sigstore/cosign-installer#223
Full Changelog: https://github.com/sigstore/cosign-installer/compare/v4.1.0...v4.1.1
cad07c2
chore: update default cosign-release to v3.0.5 (#223)Sourced from github.com/jackc/pgx/v5's changelog.
5.9.1 (March 22, 2026)
- Fix: batch result format corruption when using cached prepared statements (reported by Dirkjan Bussink)
5.9.0 (March 21, 2026)
This release includes a number of new features such as SCRAM-SHA-256-PLUS support, OAuth authentication support, and PostgreSQL protocol 3.2 support.
It significantly reduces the amount of network traffic when using prepared statements (which are used automatically by default) by avoiding unnecessary Describe Portal messages. This also reduces local memory usage.
It also includes multiple fixes for potential DoS due to panic or OOM if connected to a malicious server that sends deliberately malformed messages.
- Require Go 1.25+
- Add SCRAM-SHA-256-PLUS support (Adam Brightwell)
- Add OAuth authentication support for PostgreSQL 18 (David Schneider)
- Add PostgreSQL protocol 3.2 support (Dirkjan Bussink)
- Add tsvector type support (Adam Brightwell)
- Skip Describe Portal for cached prepared statements reducing network round trips
- Make LoadTypes query easier to support on "postgres-like" servers (Jelte Fennema-Nio)
- Default empty user to current OS user matching libpq behavior (ShivangSrivastava)
- Optimize LRU statement cache with custom linked list and node pooling (Mathias Bogaert)
- Optimize date scanning by replacing regex with manual parsing (Mathias Bogaert)
- Optimize pgio append/set functions with direct byte shifts (Mathias Bogaert)
- Make RowsAffected faster (Abhishek Chanda)
- Fix: Pipeline.Close panic when server sends multiple FATAL errors (Varun Chawla)
- Fix: ContextWatcher goroutine leak (Hank Donnay)
- Fix: stdlib discard connections with open transactions in ResetSession (Jeremy Schneider)
- Fix: pipelineBatchResults.Exec silently swallowing lastRows error
- Fix: ColumnTypeLength using BPCharArrayOID instead of BPCharOID
- Fix: TSVector text encoding returning nil for valid empty tsvector
- Fix: wrong error messages for Int2 and Int4 underflow
- Fix: Numeric nil Int pointer dereference with Valid: true
- Fix: reversed strings.ContainsAny arguments in Numeric.ScanScientific
- Fix: message length parsing on 32-bit platforms
- Fix: FunctionCallResponse.Decode mishandling of signed result size
- Fix: returning wrong error in configTLS when DecryptPEMBlock fails (Maxim Motyshen)
- Fix: misleading ParseConfig error when default_query_exec_mode is invalid (Skarm)
- Fix: missed Unwatch in Pipeline error paths
- Clarify too many failed acquire attempts error message
- Better error wrapping with context and SQL statement (Aneesh Makala)
- Enable govet and ineffassign linters (Federico Guerinoni)
- Guard against various malformed binary messages (arrays, hstore, multirange, protocol messages)
- Fix various godoc comments (ferhat elmas)
- Fix typos in comments (Oleksandr Redko)
4e4eaed
Release v5.9.16273188
Fix batch result format corruption when using cached prepared
statementsf7b90c2
Merge pull request #2524 from
dbussink/pipeline-result-format-reuse3ce6d75
Add failing test: batch scan corrupted in cache_statement modeb4d8e62
Release v5.9.0c227cd4
Bump minimum Go version from 1.24 to 1.25f492c14
Use reflect.TypeFor instead of reflect.TypeOf for static typesad8fb08
Use sync.WaitGroup.Go to simplify goroutine spawning3033773
Remove go1.26 build tag from synctest test83ffb3c
Validate multirange element count against source length before
allocatingSourced from github.com/google/go-containerregistry's releases.
v0.21.4
What's Changed
- go.mod: do not make a viral minimum go version by
@howardjohnin google/go-containerregistry#2237- Avoid pruning absolute links from extracted and flattened images by
@Subserialin google/go-containerregistry#2241- Bump the go-deps group across 3 directories with 5 updates by
@dependabot[bot] in google/go-containerregistry#2245- fix: update to go1.25.8, and use separate .go-version file by
@thaJeztahin google/go-containerregistry#2246- Bump CI go version to 1.26.1 by
@Subserialin google/go-containerregistry#2242- Bump codecov/codecov-action from 5.5.2 to 5.5.3 in the actions group by
@dependabot[bot] in google/go-containerregistry#2240- fork distribution client v3 auth-challenge as an internal package (squashed) by
@thaJeztahin google/go-containerregistry#2248- transport: validate Bearer realm URL to prevent SSRF by
@evilgensecin google/go-containerregistry#2243- revert path traversal and symlink escape from #2227 by
@Subserialin google/go-containerregistry#2250- Fix pkg/v1/google/auth tests for arm64 by
@Subserialin google/go-containerregistry#2085- goreleaser: Update goreleaser config and GH action by
@Subserialin google/go-containerregistry#2253New Contributors
@evilgensecmade their first contribution in google/go-containerregistry#2243Full Changelog: https://github.com/google/go-containerregistry/compare/v0.21.3...v0.21.4
e8813dd
goreleaser: Update goreleaser config and GH action for releases (#2253)e90447d
replace gcloud in binary calls in pkg/v1/google tests (#2085)0d0368c
revert path traversal and symlink escape changes (#2250)a2f47d4
transport: validate Bearer realm URL to prevent SSRF (#2243)19a36cd
fork distribution client v3 auth-challenge as an internal package
(squashed) ...c612a9b
Bump codecov/codecov-action from 5.5.2 to 5.5.3 in the actions group (#2240)8f92f59
Bump CI go version to 1.26.1 (#2242)c99e7cf
fix: update to go1.25.8, and use separate .go-version file (#2246)0794660
Bump the go-deps group across 3 directories with 5 updates (#2245)4cb93ae
Undo pruning absolute links from extracted and flattened images (#2241)Sourced from go.opentelemetry.io/contrib/instrumentation/runtime's releases.
v1.43.0 / v2.5.0 / v0.68.0 / v0.37.0 / v0.23.0 / v0.18.0 / v0.16.0 / v0.15.0
Added
- Add
Resourcemethod toSDKingo.opentelemetry.io/contrib/otelconf/v0.3.0to expose the resolved SDK resource from declarative configuration. (#8660)- Add support to set the configuration file via
OTEL_CONFIG_FILEingo.opentelemetry.io/contrib/otelconf. (#8639)- Add support for
serviceresource detector ingo.opentelemetry.io/contrib/otelconf. (#8674)- Add support for
attribute_count_limitandattribute_value_length_limitin tracer provider configuration ingo.opentelemetry.io/contrib/otelconf. (#8687)- Add support for
attribute_count_limitandattribute_value_length_limitin logger provider configuration ingo.opentelemetry.io/contrib/otelconf. (#8686)- Add support for
server.addressandserver.portattributes ingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc. (#8723)- Add support for
OTEL_SEMCONV_STABILITY_OPT_INingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc. Supported values arerpc(default),rpc/dupandrpc/old. (#8726)- Add the
http.routemetric attribute togo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp. (#8632)Changed
- Prepend
_to the normalized environment variable name when the key starts with a digit ingo.opentelemetry.io/contrib/propagators/envcar, ensuring POSIX compliance. (#8678)- Move experimental types from
go.opentelemetry.io/contrib/otelconftogo.opentelemetry.io/contrib/otelconf/x. (#8529)- Normalize cached environment variable names in
go.opentelemetry.io/contrib/propagators/envcar, aligningCarrier.Keysoutput with the carrier's normalized key format. (#8761)Fixed
- Fix
go.opentelemetry.io/contrib/otelconfPrometheus reader converting OTel dot-style label names (e.g.service.name) to underscore-style (service_name) intarget_infowhen bothwithout_type_suffixandwithout_unitsare set. UseNoTranslationinstead ofUnderscoreEscapingWithoutSuffixesto preserve dot-style label names while still suppressing metric name suffixes. (#8763)- Limit the request body size at 1MB in
go.opentelemetry.io/contrib/zpages. (#8656)- Fix server spans using the client's address and port for
server.addressandserver.portattributes ingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc. (#8723)Removed
- Host ID resource detector has been removed when configuring the
hostresource detector ingo.opentelemetry.io/contrib/otelconf. (#8581)Deprecated
- Deprecate
OTEL_EXPERIMENTAL_CONFIG_FILEin favour ofOTEL_CONFIG_FILEingo.opentelemetry.io/contrib/otelconf. (#8639)What's Changed
- chore(deps): update module github.com/jgautheron/goconst to v1.9.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8651- chore(deps): update module go.yaml.in/yaml/v2 to v2.4.4 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8652- chore(deps): update golang.org/x/telemetry digest to e526e8a by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8647- chore(deps): update module k8s.io/klog/v2 to v2.140.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8650- chore(deps): update module github.com/mgechev/revive to v1.14.0 by
@mmorel-35in open-telemetry/opentelemetry-go-contrib#8646- chore(deps): update module github.com/mgechev/revive to v1.15.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8539- chore: fix noctx issues by
@mmorel-35in open-telemetry/opentelemetry-go-contrib#8645- chore(deps): update golang.org/x by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8655- chore(deps): update module codeberg.org/chavacava/garif to v0.2.1 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8654- chore(deps): update module github.com/mattn/go-runewidth to v0.0.21 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8653- fix(deps): update module go.opentelemetry.io/proto/otlp to v1.10.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8657- Limit the number of bytes read from the zpages body by
@dmathieuin open-telemetry/opentelemetry-go-contrib#8656- fix(deps): update module github.com/golangci/golangci-lint/v2 to v2.11.2 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8648- fix(deps): update module github.com/golangci/golangci-lint/v2 to v2.11.3 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8661- chore(deps): update github.com/securego/gosec/v2 digest to 8895462 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8663- otelconf: support OTEL_CONFIG_FILE as it is no longer experimental by
@codebotenin open-telemetry/opentelemetry-go-contrib#8639- chore(deps): update module github.com/sonatard/noctx to v0.5.1 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8664
... (truncated)
Sourced from go.opentelemetry.io/contrib/instrumentation/runtime's changelog.
[1.43.0/2.5.0/0.68.0/0.37.0/0.23.0/0.18.0/0.16.0/0.15.0] - 2026-04-03
Added
- Add
Resourcemethod toSDKingo.opentelemetry.io/contrib/otelconf/v0.3.0to expose the resolved SDK resource from declarative configuration. (#8660)- Add support to set the configuration file via
OTEL_CONFIG_FILEingo.opentelemetry.io/contrib/otelconf. (#8639)- Add support for
serviceresource detector ingo.opentelemetry.io/contrib/otelconf. (#8674)- Add support for
attribute_count_limitandattribute_value_length_limitin tracer provider configuration ingo.opentelemetry.io/contrib/otelconf. (#8687)- Add support for
attribute_count_limitandattribute_value_length_limitin logger provider configuration ingo.opentelemetry.io/contrib/otelconf. (#8686)- Add support for
server.addressandserver.portattributes ingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc. (#8723)- Add support for
OTEL_SEMCONV_STABILITY_OPT_INingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc. Supported values arerpc(default),rpc/dupandrpc/old. (#8726)- Add the
http.routemetric attribute togo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp. (#8632)Changed
- Prepend
_to the normalized environment variable name when the key starts with a digit ingo.opentelemetry.io/contrib/propagators/envcar, ensuring POSIX compliance. (#8678)- Move experimental types from
go.opentelemetry.io/contrib/otelconftogo.opentelemetry.io/contrib/otelconf/x. (#8529)- Normalize cached environment variable names in
go.opentelemetry.io/contrib/propagators/envcar, aligningCarrier.Keysoutput with the carrier's normalized key format. (#8761)Fixed
- Fix
go.opentelemetry.io/contrib/otelconfPrometheus reader converting OTel dot-style label names (e.g.service.name) to underscore-style (service_name) intarget_infowhen bothwithout_type_suffixandwithout_unitsare set. UseNoTranslationinstead ofUnderscoreEscapingWithoutSuffixesto preserve dot-style label names while still suppressing metric name suffixes. (#8763)- Limit the request body size at 1MB in
go.opentelemetry.io/contrib/zpages. (#8656)- Fix server spans using the client's address and port for
server.addressandserver.portattributes ingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc. (#8723)Removed
- Host ID resource detector has been removed when configuring the
hostresource detector ingo.opentelemetry.io/contrib/otelconf. (#8581)Deprecated
- Deprecate
OTEL_EXPERIMENTAL_CONFIG_FILEin favour ofOTEL_CONFIG_FILEingo.opentelemetry.io/contrib/otelconf. (#8639)
45977a4
Release v1.43.0/v2.5.0/v0.68.0/v0.37.0/v0.23.0/v0.18.0/v0.16.0/v0.15.0
(#8769)0fcc152
fix(deps): update module
github.com/googlecloudplatform/opentelemetry-operati...eaba3cd
chore(deps): update googleapis to 6f92a3b (#8776)6df430c
chore(deps): update module github.com/jgautheron/goconst to v1.10.0 (#8771)ae90e32
Fix otelconf prometheus label escaping (#8763)f202c3f
otelconf: move experimental types to otelconf/x (#8529)8ddaece
fix(deps): update aws-sdk-go-v2 monorepo (#8764)c7c03a4
chore(deps): update module github.com/mattn/go-runewidth to v0.0.22 (#8766)717a85a
envcar: normalize cached environment variable names (#8761)ad990b6
fix(deps): update module github.com/aws/smithy-go to v1.24.3 (#8765)Sourced from go.opentelemetry.io/otel's changelog.
[1.43.0/0.65.0/0.19.0] 2026-04-02
Added
- Add
IsRandomandWithRandomonTraceFlags, andIsRandomonSpanContextingo.opentelemetry.io/otel/tracefor W3C Trace Context Level 2 Random Trace ID Flag support. (#8012)- Add service detection with
WithServiceingo.opentelemetry.io/otel/sdk/resource. (#7642)- Add
DefaultWithContextandEnvironmentWithContextingo.opentelemetry.io/otel/sdk/resourceto support plumbingcontext.Contextthrough default and environment detectors. (#8051)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8038)- Add support for per-series start time tracking for cumulative metrics in
go.opentelemetry.io/otel/sdk/metric. SetOTEL_GO_X_PER_SERIES_START_TIMESTAMPS=trueto enable. (#8060)- Add
WithCardinalityLimitSelectorfor metric reader for configuring cardinality limits specific to the instrument kind. (#7855)Changed
- Introduce the
EMPTYType ingo.opentelemetry.io/otel/attributeto reflect that an empty value is now a valid value, withINVALIDremaining as a deprecated alias ofEMPTY. (#8038)- Improve slice handling in
go.opentelemetry.io/otel/attributeto optimize short slice values with fixed-size fast paths. (#8039)- Improve performance of span metric recording in
go.opentelemetry.io/otel/sdk/traceby returning early if self-observability is not enabled. (#8067)- Improve formatting of metric data diffs in
go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8073)Deprecated
- Deprecate
INVALIDingo.opentelemetry.io/otel/attribute. UseEMPTYinstead. (#8038)Fixed
- Return spec-compliant
TraceIdRatioBaseddescription. This is a breaking behavioral change, but it is necessary to make the implementation spec-compliant. (#8027)- Fix a race condition in
go.opentelemetry.io/otel/sdk/metricwhere the lastvalue aggregation could collect the value 0 even when no zero-value measurements were recorded. (#8056)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)WithHostIDdetector ingo.opentelemetry.io/otel/sdk/resourceto use full path forkenvcommand on BSD. (#8113)- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto correctly handle HTTP2 GOAWAY frame. (#8096)
9276201
Release v1.43.0 / v0.65.0 / v0.19.0 (#8128)61b8c94
chore(deps): update module github.com/mattn/go-runewidth to v0.0.22 (#8131)97a086e
chore(deps): update github.com/golangci/dupl digest to c99c5cf (#8122)5e363de
limit response body size for OTLP HTTP exporters (#8108)35214b6
Use an absolute path when calling bsd kenv (#8113)290024c
fix(deps): update module google.golang.org/grpc to v1.80.0 (#8121)e70658e
fix: support getBody in otelploghttp (#8096)4afe468
fix(deps): update googleapis to 9d38bb4 (#8117)b9ca729
chore(deps): update module github.com/go-git/go-git/v5 to v5.17.2 (#8115)69472ec
chore(deps): update fossas/fossa-action action to v1.9.0 (#8118)Sourced from go.opentelemetry.io/otel/exporters/prometheus's releases.
v1.43.0/v0.65.0/v0.19.0
Added
- Add
IsRandomandWithRandomonTraceFlags, andIsRandomonSpanContextingo.opentelemetry.io/otel/tracefor W3C Trace Context Level 2 Random Trace ID Flag support. (#8012)- Add service detection with
WithServiceingo.opentelemetry.io/otel/sdk/resource. (#7642)- Add
DefaultWithContextandEnvironmentWithContextingo.opentelemetry.io/otel/sdk/resourceto support plumbingcontext.Contextthrough default and environment detectors. (#8051)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8038)- Add support for per-series start time tracking for cumulative metrics in
go.opentelemetry.io/otel/sdk/metric. SetOTEL_GO_X_PER_SERIES_START_TIMESTAMPS=trueto enable. (#8060)- Add
WithCardinalityLimitSelectorfor metric reader for configuring cardinality limits specific to the instrument kind. (#7855)Changed
- Introduce the
EMPTYType ingo.opentelemetry.io/otel/attributeto reflect that an empty value is now a valid value, withINVALIDremaining as a deprecated alias ofEMPTY. (#8038)- Refactor slice handling in
go.opentelemetry.io/otel/attributeto optimize short slice values with fixed-size fast paths. (#8039)- Improve performance of span metric recording in
go.opentelemetry.io/otel/sdk/traceby returning early if self-observability is not enabled. (#8067)- Improve formatting of metric data diffs in
go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8073)Deprecated
- Deprecate
INVALIDingo.opentelemetry.io/otel/attribute. UseEMPTYinstead. (#8038)Fixed
- Return spec-compliant
TraceIdRatioBaseddescription. This is a breaking behavioral change, but it is necessary to make the implementation spec-compliant. (#8027)- Fix a race condition in
go.opentelemetry.io/otel/sdk/metricwhere the lastvalue aggregation could collect the value 0 even when no zero-value measurements were recorded. (#8056)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)WithHostIDdetector ingo.opentelemetry.io/otel/sdk/resourceto use full path forkenvcommand on BSD. (#8113)- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto correctly handle HTTP2 GOAWAY frame. (#8096)What's Changed
- chore(deps): update module github.com/jgautheron/goconst to v1.9.0 by
@renovate[bot] in open-telemetry/opentelemetry-go#8014- fix(deps): update github.com/opentracing-contrib/go-grpc/test digest to 190d7d4 by
@renovate[bot] in open-telemetry/opentelemetry-go#8013- chore(deps): update module go.yaml.in/yaml/v2 to v2.4.4 by
@renovate[bot] in open-telemetry/opentelemetry-go#8016- fix(deps): update module github.com/golangci/golangci-lint/v2 to v2.11.1 by
@renovate[bot] in open-telemetry/opentelemetry-go#8011- fix(deps): update golang.org/x by
@renovate[bot] in open-telemetry/opentelemetry-go#8023- fix(deps): update module github.com/golangci/golangci-lint/v2 to v2.11.2 by
@renovate[bot] in open-telemetry/opentelemetry-go#8020
... (truncated)
Sourced from go.opentelemetry.io/otel/exporters/prometheus's changelog.
[1.43.0/0.65.0/0.19.0] 2026-04-02
Added
- Add
IsRandomandWithRandomonTraceFlags, andIsRandomonSpanContextingo.opentelemetry.io/otel/tracefor W3C Trace Context Level 2 Random Trace ID Flag support. (#8012)- Add service detection with
WithServiceingo.opentelemetry.io/otel/sdk/resource. (#7642)- Add
DefaultWithContextandEnvironmentWithContextingo.opentelemetry.io/otel/sdk/resourceto support plumbingcontext.Contextthrough default and environment detectors. (#8051)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8038)- Add support for per-series start time tracking for cumulative metrics in
go.opentelemetry.io/otel/sdk/metric. SetOTEL_GO_X_PER_SERIES_START_TIMESTAMPS=trueto enable. (#8060)- Add
WithCardinalityLimitSelectorfor metric reader for configuring cardinality limits specific to the instrument kind. (#7855)Changed
- Introduce the
EMPTYType ingo.opentelemetry.io/otel/attributeto reflect that an empty value is now a valid value, withINVALIDremaining as a deprecated alias ofEMPTY. (#8038)- Improve slice handling in
go.opentelemetry.io/otel/attributeto optimize short slice values with fixed-size fast paths. (#8039)- Improve performance of span metric recording in
go.opentelemetry.io/otel/sdk/traceby returning early if self-observability is not enabled. (#8067)- Improve formatting of metric data diffs in
go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8073)Deprecated
- Deprecate
INVALIDingo.opentelemetry.io/otel/attribute. UseEMPTYinstead. (#8038)Fixed
- Return spec-compliant
TraceIdRatioBaseddescription. This is a breaking behavioral change, but it is necessary to make the implementation spec-compliant. (#8027)- Fix a race condition in
go.opentelemetry.io/otel/sdk/metricwhere the lastvalue aggregation could collect the value 0 even when no zero-value measurements were recorded. (#8056)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)WithHostIDdetector ingo.opentelemetry.io/otel/sdk/resourceto use full path forkenvcommand on BSD. (#8113)- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto correctly handle HTTP2 GOAWAY frame. (#8096)
9276201
Release v1.43.0 / v0.65.0 / v0.19.0 (#8128)61b8c94
chore(deps): update module github.com/mattn/go-runewidth to v0.0.22 (#8131)97a086e
chore(deps): update github.com/golangci/dupl digest to c99c5cf (#8122)5e363de
limit response body size for OTLP HTTP exporters (#8108)35214b6
Use an absolute path when calling bsd kenv (#8113)290024c
fix(deps): update module google.golang.org/grpc to v1.80.0 (#8121)e70658e
fix: support getBody in otelploghttp (#8096)4afe468
fix(deps): update googleapis to 9d38bb4 (#8117)b9ca729
chore(deps): update module github.com/go-git/go-git/v5 to v5.17.2 (#8115)69472ec
chore(deps): update fossas/fossa-action action to v1.9.0 (#8118)Sourced from go.opentelemetry.io/otel/metric's changelog.
[1.43.0/0.65.0/0.19.0] 2026-04-02
Added
- Add
IsRandomandWithRandomonTraceFlags, andIsRandomonSpanContextingo.opentelemetry.io/otel/tracefor W3C Trace Context Level 2 Random Trace ID Flag support. (#8012)- Add service detection with
WithServiceingo.opentelemetry.io/otel/sdk/resource. (#7642)- Add
DefaultWithContextandEnvironmentWithContextingo.opentelemetry.io/otel/sdk/resourceto support plumbingcontext.Contextthrough default and environment detectors. (#8051)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8038)- Add support for per-series start time tracking for cumulative metrics in
go.opentelemetry.io/otel/sdk/metric. SetOTEL_GO_X_PER_SERIES_START_TIMESTAMPS=trueto enable. (#8060)- Add
WithCardinalityLimitSelectorfor metric reader for configuring cardinality limits specific to the instrument kind. (#7855)Changed
- Introduce the
EMPTYType ingo.opentelemetry.io/otel/attributeto reflect that an empty value is now a valid value, withINVALIDremaining as a deprecated alias ofEMPTY. (#8038)- Improve slice handling in
go.opentelemetry.io/otel/attributeto optimize short slice values with fixed-size fast paths. (#8039)- Improve performance of span metric recording in
go.opentelemetry.io/otel/sdk/traceby returning early if self-observability is not enabled. (#8067)- Improve formatting of metric data diffs in
go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8073)Deprecated
- Deprecate
INVALIDingo.opentelemetry.io/otel/attribute. UseEMPTYinstead. (#8038)Fixed
- Return spec-compliant
TraceIdRatioBaseddescription. This is a breaking behavioral change, but it is necessary to make the implementation spec-compliant. (#8027)- Fix a race condition in
go.opentelemetry.io/otel/sdk/metricwhere the lastvalue aggregation could collect the value 0 even when no zero-value measurements were recorded. (#8056)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)WithHostIDdetector ingo.opentelemetry.io/otel/sdk/resourceto use full path forkenvcommand on BSD. (#8113)- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto correctly handle HTTP2 GOAWAY frame. (#8096)
9276201
Release v1.43.0 / v0.65.0 / v0.19.0 (#8128)61b8c94
chore(deps): update module github.com/mattn/go-runewidth to v0.0.22 (#8131)97a086e
chore(deps): update github.com/golangci/dupl digest to c99c5cf (#8122)5e363de
limit response body size for OTLP HTTP exporters (#8108)35214b6
Use an absolute path when calling bsd kenv (#8113)290024c
fix(deps): update module google.golang.org/grpc to v1.80.0 (#8121)e70658e
fix: support getBody in otelploghttp (#8096)4afe468
fix(deps): update googleapis to 9d38bb4 (#8117)b9ca729
chore(deps): update module github.com/go-git/go-git/v5 to v5.17.2 (#8115)69472ec
chore(deps): update fossas/fossa-action action to v1.9.0 (#8118)Sourced from go.opentelemetry.io/otel/sdk's changelog.
[1.43.0/0.65.0/0.19.0] 2026-04-02
Added
- Add
IsRandomandWithRandomonTraceFlags, andIsRandomonSpanContextingo.opentelemetry.io/otel/tracefor W3C Trace Context Level 2 Random Trace ID Flag support. (#8012)- Add service detection with
WithServiceingo.opentelemetry.io/otel/sdk/resource. (#7642)- Add
DefaultWithContextandEnvironmentWithContextingo.opentelemetry.io/otel/sdk/resourceto support plumbingcontext.Contextthrough default and environment detectors. (#8051)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8038)- Add support for per-series start time tracking for cumulative metrics in
go.opentelemetry.io/otel/sdk/metric. SetOTEL_GO_X_PER_SERIES_START_TIMESTAMPS=trueto enable. (#8060)- Add
WithCardinalityLimitSelectorfor metric reader for configuring cardinality limits specific to the instrument kind. (#7855)Changed
- Introduce the
EMPTYType ingo.opentelemetry.io/otel/attributeto reflect that an empty value is now a valid value, withINVALIDremaining as a deprecated alias ofEMPTY. (#8038)- Improve slice handling in
go.opentelemetry.io/otel/attributeto optimize short slice values with fixed-size fast paths. (#8039)- Improve performance of span metric recording in
go.opentelemetry.io/otel/sdk/traceby returning early if self-observability is not enabled. (#8067)- Improve formatting of metric data diffs in
go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8073)Deprecated
- Deprecate
INVALIDingo.opentelemetry.io/otel/attribute. UseEMPTYinstead. (#8038)Fixed
- Return spec-compliant
TraceIdRatioBaseddescription. This is a breaking behavioral change, but it is necessary to make the implementation spec-compliant. (#8027)- Fix a race condition in
go.opentelemetry.io/otel/sdk/metricwhere the lastvalue aggregation could collect the value 0 even when no zero-value measurements were recorded. (#8056)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)WithHostIDdetector ingo.opentelemetry.io/otel/sdk/resourceto use full path forkenvcommand on BSD. ( Date: Wed, 8 Apr 2026 05:38:52 -0400 Subject: [PATCH 022/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.228.0 to 3.229.0 in /deploy (#1112) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.228.0 to 3.229.0.Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.229.0
3.229.0 (2026-04-02)
Features
[auto/python] Add org get-default and set-default commands to Automation API
[backend/diy] Avoid unnecessary S3 bucket HEAD calls to improve performance #22373
[cli] Allow TRACEPARENT to be set for CLI invocations, parenting the pulumi spans under an existing parent span #22369
[cli/display] Add
--urnsflag to display full resource URNs instead of short names in preview, up, destroy, refresh, import, and watch commands #22007[pcl] Type integer literals as integers rather than numbers in PCL #22268
[pcl] Support parameterized providers in PCL #22251
[protobuf] Add RunPlugin2 bidirectional streaming RPC to LanguageRuntime proto #22389
[yaml] Update YAML runtime to 1.30.2 #22426
[sdk/go] Add org get-default and set-default commands to Automation API
[sdk/nodejs] Modernize generated tsconfig.json to align with TypeScript defaults #22370
[cli/policy] Add a new
policy analyzecommand to run a policy pack against existing state #22250Bug Fixes
[backend/diy] Remove state lock for refresh --preview-only for diy backend #22385
[cli] Fix OTEL flushing on provider shutdown #22358
[cli/display] Fix deadlock in message renderer when cancelling an operation #22433
[engine] Fix
--includeand--excludenot working for program-based refresh (RefreshV2)... (truncated)
Changelog
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.229.0 (2026-04-02)
Features
[auto/python] Add org get-default and set-default commands to Automation API
[backend/diy] Avoid unnecessary S3 bucket HEAD calls to improve performance #22373
[cli] Allow TRACEPARENT to be set for CLI invocations, parenting the pulumi spans under an existing parent span #22369
[cli/display] Add
--urnsflag to display full resource URNs instead of short names in preview, up, destroy, refresh, import, and watch commands #22007[pcl] Type integer literals as integers rather than numbers in PCL #22268
[pcl] Support parameterized providers in PCL #22251
[protobuf] Add RunPlugin2 bidirectional streaming RPC to LanguageRuntime proto #22389
[yaml] Update YAML runtime to 1.30.2 #22426
[sdk/go] Add org get-default and set-default commands to Automation API
[sdk/nodejs] Modernize generated tsconfig.json to align with TypeScript defaults #22370
[cli/policy] Add a new
policy analyzecommand to run a policy pack against existing state #22250Bug Fixes
[backend/diy] Remove state lock for refresh --preview-only for diy backend #22385
[cli] Fix OTEL flushing on provider shutdown #22358
[cli/display] Fix deadlock in message renderer when cancelling an operation #22433
[engine] Fix
--includeand--excludenot working for program-based refresh (RefreshV2) #22404... (truncated)
Commits
4a1e067Addorgcommands to Python and Go Automation APIs (#22436)40fd963Fix var naming for hooks (#22445)5a26c3eFix flaky TestLanguageRuntimeCancellation (#22376)24ff624Cleanup some dotnet codegen from build scripts (#22444)1bf3962Addl1-builtin-sha1(#22443)dea48c6Fix deadlock in message renderer when cancelling an operation (#22433)0a0aff4Delete dead dotnet codegen code (#22435)f80af9eFix config tests to use int type (#22429)f94eb08Update java version (#22437)11ebea5Addproperty.Glob& implementencoding.(Unm|M)arshalTextfor `property.Pa...- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 0e4c7f5..199188d 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.25.8 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.28.0 - github.com/pulumi/pulumi/sdk/v3 v3.228.0 + github.com/pulumi/pulumi/sdk/v3 v3.229.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/deploy/go.sum b/deploy/go.sum index 766581d..be56fb7 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -185,8 +185,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.28.0 h1:muCE6cUJ4YmAaNLiOhbjEicxT+10i/EGsZrx2ZZQQ+o= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.28.0/go.mod h1:B998wofejDKAvvpLwsi4UMfWDFHHBnzYiM8mZ9e7OSo= -github.com/pulumi/pulumi/sdk/v3 v3.228.0 h1:+kV5pPM52MMFQsYiZ/deDi6egVb8JZsTpQhzv+CMB3A= -github.com/pulumi/pulumi/sdk/v3 v3.228.0/go.mod h1:PAqB2+8gnxqk+QrFdXL3fSjsLIjtlBIcy5KLZ//4WSk= +github.com/pulumi/pulumi/sdk/v3 v3.229.0 h1:jsAw5lXiHN22YQeo4bZHZBAG/DUlEnzsFWg5MuHnTSs= +github.com/pulumi/pulumi/sdk/v3 v3.229.0/go.mod h1:PAqB2+8gnxqk+QrFdXL3fSjsLIjtlBIcy5KLZ//4WSk= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From 9b32a5c1877b7a0f9683eb6d0497bfbe75ab4c47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Apr 2026 05:39:37 -0400 Subject: [PATCH 023/190] build(deps): bump docker/login-action from 4.0.0 to 4.1.0 in the actions group (#1113) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the actions group with 1 update: [docker/login-action](https://github.com/docker/login-action). Updates `docker/login-action` from 4.0.0 to 4.1.0 Release notes
Sourced from docker/login-action's releases.
v4.1.0
- Fix scoped Docker Hub cleanup path when registry is omitted by
@crazy-maxin docker/login-action#945- Bump
@aws-sdk/client-ecrand@aws-sdk/client-ecr-publicto 3.1020.0 in docker/login-action#930- Bump
@docker/actions-toolkitfrom 0.77.0 to 0.86.0 in docker/login-action#932 docker/login-action#936- Bump brace-expansion from 1.1.12 to 1.1.13 in docker/login-action#952
- Bump fast-xml-parser from 5.3.4 to 5.3.6 in docker/login-action#942
- Bump flatted from 3.3.3 to 3.4.2 in docker/login-action#944
- Bump glob from 10.3.12 to 10.5.0 in docker/login-action#940
- Bump handlebars from 4.7.8 to 4.7.9 in docker/login-action#949
- Bump http-proxy-agent and https-proxy-agent to 8.0.0 in docker/login-action#937
- Bump lodash from 4.17.23 to 4.18.1 in docker/login-action#958
- Bump minimatch from 3.1.2 to 3.1.5 in docker/login-action#941
- Bump picomatch from 4.0.3 to 4.0.4 in docker/login-action#948
- Bump undici from 6.23.0 to 6.24.1 in docker/login-action#938
Full Changelog: https://github.com/docker/login-action/compare/v4.0.0...v4.1.0
Commits
4907a6dMerge pull request #930 from docker/dependabot/npm_and_yarn/aws-sdk-dependenc...1e233e6chore: update generated content6c24eadbuild(deps): bump the aws-sdk-dependencies group with 2 updatesee034d7Merge pull request #958 from docker/dependabot/npm_and_yarn/lodash-4.18.11527209Merge pull request #937 from docker/dependabot/npm_and_yarn/proxy-agent-depen...d39362abuild(deps): bump lodash from 4.17.23 to 4.18.1a6f092bchore: update generated content60953f0build(deps): bump the proxy-agent-dependencies group with 2 updates62c6885Merge pull request #936 from docker/dependabot/npm_and_yarn/docker/actions-to...102c0e6chore: update generated content- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/deploy-staging.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index dd0589f..85f52df 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -34,7 +34,7 @@ jobs: uses: ko-build/setup-ko@v0.9 - name: Log in to Container Registry - uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ea606b7..d4c65c4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,7 +57,7 @@ jobs: uses: ko-build/setup-ko@v0.9 - name: Log in to Container Registry - uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 + uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 with: registry: ghcr.io username: ${{ github.actor }} From 0fc4606be26016b4c557770fd59ceb8922c7c346 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Thu, 9 Apr 2026 11:57:21 -0400 Subject: [PATCH 024/190] Stop pinning Go to patch versions, use stable in CI (#1137) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Motivation and Context We keep bumping `go 1.26.x` across the repo every time a new Go patch drops ## How Has This Been Tested? - **`go.mod` / `deploy/go.mod`**: `go 1.25.8` → `go 1.26` (minor only — "this module needs Go 1.26") - **All CI workflows**: `go-version-file: 'go.mod'` → `go-version: 'stable'` — CI always uses the latest stable Go, no more bump PRs - **govulncheck**: removed hardcoded `go-version-input: '1.26.1'` → `go-version-input: 'stable'` ## Breaking Changes ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist - [ ] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [ ] My code follows the repository's style guidelines - [ ] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed ## Additional context Signed-off-by: Radoslav Dimitrov --- .github/workflows/ci.yml | 10 ++++------ .github/workflows/deploy-production.yml | 2 +- .github/workflows/deploy-staging.yml | 4 ++-- .github/workflows/release.yml | 4 ++-- .golangci.yml | 5 +++++ cmd/publisher/auth/common.go | 4 ++-- cmd/publisher/auth/github-oidc.go | 4 ++-- deploy/go.mod | 2 +- go.mod | 2 +- internal/api/handlers/v0/auth/oidc_test.go | 2 +- internal/database/postgres.go | 1 - internal/database/testutil.go | 2 +- internal/validators/schema.go | 2 +- 13 files changed, 23 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1bc20d0..e24af7a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,13 +21,13 @@ jobs: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c with: - go-version-file: 'go.mod' + go-version: 'stable' cache: true - name: Run lint uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 with: - version: v2.4.0 + version: v2.11.4 - name: Validate schemas and examples run: make validate @@ -38,9 +38,7 @@ jobs: - name: Run govulncheck uses: golang/govulncheck-action@v1 with: - # Use Go 1.26.1 to pick up crypto/x509 vulnerability fixes (GO-2026-4600, GO-2026-4599). - # go.mod stays at go 1.25.8 for golangci-lint compatibility until it supports Go 1.26. - go-version-input: '1.26.1' + go-version-input: 'stable' go-package: ./... repo-checkout: false @@ -55,7 +53,7 @@ jobs: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c with: - go-version-file: 'go.mod' + go-version: 'stable' cache: true - name: Set up ko diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index 0ca5224..cd03772 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -28,7 +28,7 @@ jobs: - name: Setup Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c with: - go-version-file: 'deploy/go.mod' + go-version: 'stable' cache: true - name: Setup Pulumi diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index 85f52df..946aaaf 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -27,7 +27,7 @@ jobs: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c with: - go-version-file: 'go.mod' + go-version: 'stable' cache: true - name: Set up ko @@ -75,7 +75,7 @@ jobs: - name: Setup Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c with: - go-version-file: 'deploy/go.mod' + go-version: 'stable' cache: true - name: Setup Pulumi diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d4c65c4..b1f807f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,7 +21,7 @@ jobs: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c with: - go-version-file: 'go.mod' + go-version: 'stable' cache: true - name: Install cosign @@ -50,7 +50,7 @@ jobs: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c with: - go-version-file: 'go.mod' + go-version: 'stable' cache: true - name: Set up ko diff --git a/.golangci.yml b/.golangci.yml index dfb7587..5f3ad3c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -66,6 +66,11 @@ linters: - common-false-positives - legacy - std-error-handling + rules: + # httptest.NewRequest is idiomatic in tests; noctx is not useful there. + - path: _test\.go + linters: + - noctx paths: - third_party$ - builtin$ diff --git a/cmd/publisher/auth/common.go b/cmd/publisher/auth/common.go index 2ffdb7d..28829e8 100644 --- a/cmd/publisher/auth/common.go +++ b/cmd/publisher/auth/common.go @@ -160,7 +160,7 @@ func parseRawPrivateKey(curve elliptic.Curve, privateKeyBytes []byte) (*ecdsa.Pr return nil, fmt.Errorf("invalid private scalar") } - x, y := curve.ScalarBaseMult(d.Bytes()) + x, y := curve.ScalarBaseMult(d.Bytes()) //nolint:staticcheck // SA1019: needs crypto/ecdh refactor return &ecdsa.PrivateKey{ PublicKey: ecdsa.PublicKey{ Curve: curve, @@ -192,7 +192,7 @@ func PrintEcdsaP384KeyInfo(pubKey ecdsa.PublicKey) { } func printEcdsaKeyInfo(k string, pubKey ecdsa.PublicKey) { - compressed := elliptic.MarshalCompressed(pubKey.Curve, pubKey.X, pubKey.Y) + compressed := elliptic.MarshalCompressed(pubKey.Curve, pubKey.X, pubKey.Y) //nolint:staticcheck // SA1019: needs crypto/ecdh refactor pubKeyString := base64.StdEncoding.EncodeToString(compressed) fmt.Fprint(os.Stdout, "Expected proof record:\n") fmt.Fprintf(os.Stdout, "v=MCPv1; k=%s; p=%s\n", k, pubKeyString) diff --git a/cmd/publisher/auth/github-oidc.go b/cmd/publisher/auth/github-oidc.go index 7caebfe..55fa350 100644 --- a/cmd/publisher/auth/github-oidc.go +++ b/cmd/publisher/auth/github-oidc.go @@ -122,7 +122,7 @@ func (o *GitHubOIDCProvider) getOIDCTokenFromGitHub(ctx context.Context) (string fullURL := requestURL + "&audience=mcp-registry" // Create the request - req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullURL, nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullURL, nil) //nolint:gosec // G704: URL is from GitHub Actions ACTIONS_ID_TOKEN_REQUEST_URL env var if err != nil { return "", fmt.Errorf("failed to create request: %w", err) } @@ -133,7 +133,7 @@ func (o *GitHubOIDCProvider) getOIDCTokenFromGitHub(ctx context.Context) (string // Make the request client := &http.Client{} - resp, err := client.Do(req) + resp, err := client.Do(req) //nolint:gosec // G704: URL is from GitHub Actions env var if err != nil { return "", fmt.Errorf("failed to send request: %w", err) } diff --git a/deploy/go.mod b/deploy/go.mod index 199188d..8edac31 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -1,6 +1,6 @@ module github.com/modelcontextprotocol/registry/deploy/infra -go 1.25.8 +go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 diff --git a/go.mod b/go.mod index 5f1e76c..d08ff7b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/modelcontextprotocol/registry -go 1.25.8 +go 1.26 require ( cloud.google.com/go/kms v1.26.0 diff --git a/internal/api/handlers/v0/auth/oidc_test.go b/internal/api/handlers/v0/auth/oidc_test.go index 4ad8acb..d4e9500 100644 --- a/internal/api/handlers/v0/auth/oidc_test.go +++ b/internal/api/handlers/v0/auth/oidc_test.go @@ -31,7 +31,7 @@ func TestOIDCHandler_ExchangeToken(t *testing.T) { token string expectedError bool }{ - { + { //nolint:gosec // G101: test data, not real credentials name: "successful token exchange with publish permissions", config: &config.Config{ OIDCEnabled: true, diff --git a/internal/database/postgres.go b/internal/database/postgres.go index 70bfe43..a86e44b 100644 --- a/internal/database/postgres.go +++ b/internal/database/postgres.go @@ -764,7 +764,6 @@ func hashServerName(name string) int64 { hash ^= uint64(name[i]) hash *= prime64 } - //nolint:gosec // Intentional conversion with masking to 63 bits return int64(hash & 0x7FFFFFFFFFFFFFFF) } diff --git a/internal/database/testutil.go b/internal/database/testutil.go index c67e3a1..8fbdb60 100644 --- a/internal/database/testutil.go +++ b/internal/database/testutil.go @@ -64,7 +64,7 @@ func NewTestDB(t *testing.T) Database { defer cancel() // Connect to postgres database - adminURI := "postgres://mcpregistry:mcpregistry@localhost:5432/postgres?sslmode=disable" + adminURI := "postgres://mcpregistry:mcpregistry@localhost:5432/postgres?sslmode=disable" //nolint:gosec // G101: test database credentials adminConn, err := pgx.Connect(ctx, adminURI) require.NoError(t, err, "Failed to connect to PostgreSQL. Make sure PostgreSQL is running via: docker-compose up -d postgres") defer adminConn.Close(ctx) diff --git a/internal/validators/schema.go b/internal/validators/schema.go index 8a64b32..37d335e 100644 --- a/internal/validators/schema.go +++ b/internal/validators/schema.go @@ -284,7 +284,7 @@ func ConvertJSONPointerToBracketNotation(jsonPointer string) string { // Check if part is a pure number (array index) if _, err := strconv.Atoi(part); err == nil { // It's a numeric index - use bracket notation - result.WriteString(fmt.Sprintf("[%s]", part)) + fmt.Fprintf(&result, "[%s]", part) // Add dot after bracket if next part exists and is a field name (not a number) if i < len(parts)-1 { nextPart := parts[i+1] From 5f81cf3336c3d945c7889a5df1aae194434cc985 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:19:50 -0400 Subject: [PATCH 025/190] build(deps): bump cloud.google.com/go/kms from 1.26.0 to 1.27.0 (#1111) Bumps [cloud.google.com/go/kms](https://github.com/googleapis/google-cloud-go) from 1.26.0 to 1.27.0. Release notes
Sourced from cloud.google.com/go/kms's releases.
kms: v1.27.0
v1.27.0 (2026-04-02)
retail: v1.27.0
v1.27.0 (2026-04-02)
Changelog
Sourced from cloud.google.com/go/kms's changelog.
1.27.0 (2024-04-15)
Features
- documentai: Support a new Layout Processor in Document AI (2cdc40a)
1.26.1 (2024-03-14)
Bug Fixes
- documentai: Update protobuf dep to v1.33.0 (30b038d)
Documentation
- documentai: A comment for field
processor_version_sourcein message.google.cloud.documentai.v1beta3.ImportProcessorVersionRequestis changed (25c3f2d)Commits
b64e8dcchore: librarian release pull request: 20251013T184035Z (#13116)ddc086cfeat(aiplatform): Add JAILBREAK category to SafetySettings for prediction ser...c79db96chore: librarian generate pull request: 20251013T073656Z (#13101)b041315chore: migrate 18 modules to Librarian (#13112)a75de40chore: migrate advisorynotifications to Librarian (#13110)3cf5269chore: undo IAM semi-migration (#13109)7663fdcfix(internal/stategen): be more conservative about removing OwlBot lines (#13...8ebb896chore: librarian release pull request: 20251010T200657Z (#13107)befb302test(internal/postprocessor): skip test that expects certain live config (#13...1930511testing(internal/godocfx): convert equality check to a diff check (#13089)- Additional commits viewable in compare view
Signed-off-by: dependabot[bot]Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Radoslav Dimitrov --- go.mod | 26 +++++++++++++------------- go.sum | 52 ++++++++++++++++++++++++++-------------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/go.mod b/go.mod index d08ff7b..49c7fd1 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/modelcontextprotocol/registry go 1.26 require ( - cloud.google.com/go/kms v1.26.0 + cloud.google.com/go/kms v1.27.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 github.com/caarlos0/env/v11 v11.4.0 @@ -28,10 +28,10 @@ require ( require ( cloud.google.com/go v0.123.0 // indirect - cloud.google.com/go/auth v0.18.1 // indirect + cloud.google.com/go/auth v0.18.2 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect - cloud.google.com/go/iam v1.5.3 // indirect + cloud.google.com/go/iam v1.6.0 // indirect cloud.google.com/go/longrunning v0.8.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect @@ -49,8 +49,8 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.11 // indirect - github.com/googleapis/gax-go/v2 v2.17.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect + github.com/googleapis/gax-go/v2 v2.20.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 @@ -73,17 +73,17 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - golang.org/x/crypto v0.48.0 // indirect - golang.org/x/net v0.51.0 // indirect + golang.org/x/crypto v0.49.0 // indirect + golang.org/x/net v0.52.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.42.0 // indirect - golang.org/x/text v0.34.0 // indirect - golang.org/x/time v0.14.0 // indirect - google.golang.org/api v0.265.0 // indirect - google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 // indirect + golang.org/x/text v0.35.0 // indirect + golang.org/x/time v0.15.0 // indirect + google.golang.org/api v0.273.1 // indirect + google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260401001100-f93e5f3e9f0f // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/grpc v1.79.3 // indirect google.golang.org/protobuf v1.36.11 // indirect gotest.tools/v3 v3.5.2 // indirect diff --git a/go.sum b/go.sum index 6c4665b..56e727c 100644 --- a/go.sum +++ b/go.sum @@ -1,15 +1,15 @@ cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU= -cloud.google.com/go/auth v0.18.1 h1:IwTEx92GFUo2pJ6Qea0EU3zYvKnTAeRCODxfA/G5UWs= -cloud.google.com/go/auth v0.18.1/go.mod h1:GfTYoS9G3CWpRA3Va9doKN9mjPGRS+v41jmZAhBzbrA= +cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= +cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= -cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc= -cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU= -cloud.google.com/go/kms v1.26.0 h1:cK9mN2cf+9V63D3H1f6koxTatWy39aTI/hCjz1I+adU= -cloud.google.com/go/kms v1.26.0/go.mod h1:pHKOdFJm63hxBsiPkYtowZPltu9dW0MWvBa6IA4HM58= +cloud.google.com/go/iam v1.6.0 h1:JiSIcEi38dWBKhB3BtfKCW+dMvCZJEhBA2BsaGJgoxs= +cloud.google.com/go/iam v1.6.0/go.mod h1:ZS6zEy7QHmcNO18mjO2viYv/n+wOUkhJqGNkPPGueGU= +cloud.google.com/go/kms v1.27.0 h1:iYYgoD0HJIqz35A+He1G0dS5qTQzQsDXFsyXwzkUCXM= +cloud.google.com/go/kms v1.27.0/go.mod h1:KPxrdf61iYEOZ86uPwR86muBpSik2y4Ion6e83fVl1Q= cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8= cloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc= @@ -77,10 +77,10 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= 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/googleapis/enterprise-certificate-proxy v0.3.11 h1:vAe81Msw+8tKUxi2Dqh/NZMz7475yUvmRIkXr4oN2ao= -github.com/googleapis/enterprise-certificate-proxy v0.3.11/go.mod h1:RFV7MUdlb7AgEq2v7FmMCfeSMCllAzWxFgRdusoGks8= -github.com/googleapis/gax-go/v2 v2.17.0 h1:RksgfBpxqff0EZkDWYuz9q/uWsTVz+kf43LsZ1J6SMc= -github.com/googleapis/gax-go/v2 v2.17.0/go.mod h1:mzaqghpQp4JDh3HvADwrat+6M3MOIDp5YKHhb9PAgDY= +github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8= +github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= +github.com/googleapis/gax-go/v2 v2.20.0 h1:NIKVuLhDlIV74muWlsMM4CcQZqN6JJ20Qcxd9YMuYcs= +github.com/googleapis/gax-go/v2 v2.20.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= @@ -164,12 +164,12 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= -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.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= -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.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= @@ -177,20 +177,20 @@ golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= -golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.265.0 h1:FZvfUdI8nfmuNrE34aOWFPmLC+qRBEiNm3JdivTvAAU= -google.golang.org/api v0.265.0/go.mod h1:uAvfEl3SLUj/7n6k+lJutcswVojHPp2Sp08jWCu8hLY= -google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM= -google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM= -google.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20 h1:7ei4lp52gK1uSejlA8AZl5AJjeLUOHBQscRQZUgAcu0= -google.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20/go.mod h1:ZdbssH/1SOVnjnDlXzxDHK2MCidiqXtbYccJNzNYPEE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409 h1:H86B94AW+VfJWDqFeEbBPhEtHzJwJfTbgE2lZa54ZAQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260128011058-8636f8732409/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/api v0.273.1 h1:L7G/TmpAMz0nKx/ciAVssVmWQiOF6+pOuXeKrWVsquY= +google.golang.org/api v0.273.1/go.mod h1:JbAt7mF+XVmWu6xNP8/+CTiGH30ofmCmk9nM8d8fHew= +google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0= +google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= +google.golang.org/genproto/googleapis/api v0.0.0-20260401001100-f93e5f3e9f0f h1:K3zPU40OFjwD5YKADLMLoiL0L7JJpBgEdLqGuCNPfp0= +google.golang.org/genproto/googleapis/api v0.0.0-20260401001100-f93e5f3e9f0f/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:ndE4FoJqsIceKP2oYSnUZqhTdYufCYYkqwtFzfrhI7w= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/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/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= From 607d52ff20028db1949e6d0298f59784e2294754 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:20:12 -0400 Subject: [PATCH 026/190] build(deps): bump github.com/go-jose/go-jose/v4 from 4.1.3 to 4.1.4 (#1114) Bumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.1.3 to 4.1.4. Release notes
Sourced from github.com/go-jose/go-jose/v4's releases.
v4.1.4
What's Changed
Fixes Panic in JWE decryption. See https://github.com/go-jose/go-jose/security/advisories/GHSA-78h2-9frx-2jm8
Full Changelog: https://github.com/go-jose/go-jose/compare/v4.1.3...v4.1.4
Commits
0e59876Merge commit from forkddffdbcBump actions/checkout from 5 to 6 (#213)- See full diff in compare view
Signed-off-by: dependabot[bot]Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Radoslav Dimitrov --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 49c7fd1..3271c24 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/docker/cli v29.3.1+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/go-jose/go-jose/v4 v4.1.3 // indirect + github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/google/s2a-go v0.1.9 // indirect diff --git a/go.sum b/go.sum index 56e727c..0d029ae 100644 --- a/go.sum +++ b/go.sum @@ -58,8 +58,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= -github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= -github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= +github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= +github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= 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= From 83f8ea7cffcf6870c1c223cce0a5c148ae6b9acc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:20:33 -0400 Subject: [PATCH 027/190] build(deps): bump go.opentelemetry.io/otel/sdk from 1.41.0 to 1.43.0 in /deploy (#1139) Bumps [go.opentelemetry.io/otel/sdk](https://github.com/open-telemetry/opentelemetry-go) from 1.41.0 to 1.43.0. Changelog
Sourced from go.opentelemetry.io/otel/sdk's changelog.
[1.43.0/0.65.0/0.19.0] 2026-04-02
Added
- Add
IsRandomandWithRandomonTraceFlags, andIsRandomonSpanContextingo.opentelemetry.io/otel/tracefor W3C Trace Context Level 2 Random Trace ID Flag support. (#8012)- Add service detection with
WithServiceingo.opentelemetry.io/otel/sdk/resource. (#7642)- Add
DefaultWithContextandEnvironmentWithContextingo.opentelemetry.io/otel/sdk/resourceto support plumbingcontext.Contextthrough default and environment detectors. (#8051)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp. (#8038)- Support attributes with empty value (
attribute.EMPTY) ingo.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8038)- Add support for per-series start time tracking for cumulative metrics in
go.opentelemetry.io/otel/sdk/metric. SetOTEL_GO_X_PER_SERIES_START_TIMESTAMPS=trueto enable. (#8060)- Add
WithCardinalityLimitSelectorfor metric reader for configuring cardinality limits specific to the instrument kind. (#7855)Changed
- Introduce the
EMPTYType ingo.opentelemetry.io/otel/attributeto reflect that an empty value is now a valid value, withINVALIDremaining as a deprecated alias ofEMPTY. (#8038)- Improve slice handling in
go.opentelemetry.io/otel/attributeto optimize short slice values with fixed-size fast paths. (#8039)- Improve performance of span metric recording in
go.opentelemetry.io/otel/sdk/traceby returning early if self-observability is not enabled. (#8067)- Improve formatting of metric data diffs in
go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest. (#8073)Deprecated
- Deprecate
INVALIDingo.opentelemetry.io/otel/attribute. UseEMPTYinstead. (#8038)Fixed
- Return spec-compliant
TraceIdRatioBaseddescription. This is a breaking behavioral change, but it is necessary to make the implementation spec-compliant. (#8027)- Fix a race condition in
go.opentelemetry.io/otel/sdk/metricwhere the lastvalue aggregation could collect the value 0 even when no zero-value measurements were recorded. (#8056)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)- Limit HTTP response body to 4 MiB in
go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto mitigate excessive memory usage caused by a misconfigured or malicious server. Responses exceeding the limit are treated as non-retryable errors. (#8108)WithHostIDdetector ingo.opentelemetry.io/otel/sdk/resourceto use full path forkenvcommand on BSD. (#8113)- Fix missing
request.GetBodyingo.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttpto correctly handle HTTP2 GOAWAY frame. (#8096)[1.42.0/0.64.0/0.18.0/0.0.16] 2026-03-06
Added
- Add
go.opentelemetry.io/otel/semconv/v1.40.0package. The package contains semantic conventions from thev1.40.0version of the OpenTelemetry Semantic Conventions. See the migration documentation for information on how to upgrade fromgo.opentelemetry.io/otel/semconv/v1.39.0. (#7985)... (truncated)
Commits
9276201Release v1.43.0 / v0.65.0 / v0.19.0 (#8128)61b8c94chore(deps): update module github.com/mattn/go-runewidth to v0.0.22 (#8131)97a086echore(deps): update github.com/golangci/dupl digest to c99c5cf (#8122)5e363delimit response body size for OTLP HTTP exporters (#8108)35214b6Use an absolute path when calling bsd kenv (#8113)290024cfix(deps): update module google.golang.org/grpc to v1.80.0 (#8121)e70658efix: support getBody in otelploghttp (#8096)4afe468fix(deps): update googleapis to 9d38bb4 (#8117)b9ca729chore(deps): update module github.com/go-git/go-git/v5 to v5.17.2 (#8115)69472ecchore(deps): update fossas/fossa-action action to v1.9.0 (#8118)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/modelcontextprotocol/registry/network/alerts). Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Radoslav Dimitrov --- deploy/go.mod | 10 +++++----- deploy/go.sum | 24 ++++++++++++------------ 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 8edac31..860894b 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -93,12 +93,12 @@ require ( go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/featuregate v1.53.0 // indirect go.opentelemetry.io/collector/pdata v1.53.0 // indirect - go.opentelemetry.io/otel v1.41.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 // indirect - go.opentelemetry.io/otel/metric v1.41.0 // indirect - go.opentelemetry.io/otel/sdk v1.41.0 // indirect - go.opentelemetry.io/otel/trace v1.41.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/sdk v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect go.opentelemetry.io/proto/otlp v1.9.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect @@ -107,7 +107,7 @@ require ( golang.org/x/mod v0.32.0 // indirect golang.org/x/net v0.51.0 // indirect golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.41.0 // indirect + golang.org/x/sys v0.42.0 // indirect golang.org/x/term v0.40.0 // indirect golang.org/x/text v0.34.0 // indirect golang.org/x/tools v0.41.0 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index be56fb7..083fbf9 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -237,20 +237,20 @@ go.opentelemetry.io/collector/internal/testutil v0.147.0 h1:DFlRxBRp23/sZnpTITK2 go.opentelemetry.io/collector/internal/testutil v0.147.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= go.opentelemetry.io/collector/pdata v1.53.0 h1:DlYDbRwammEZaxDZHINx5v0n8SEOVNniPbi6FRTlVkA= go.opentelemetry.io/collector/pdata v1.53.0/go.mod h1:LRSYGNjKXaUrZEwZv3Yl+8/zV2HmRGKXW62zB2bysms= -go.opentelemetry.io/otel v1.41.0 h1:YlEwVsGAlCvczDILpUXpIpPSL/VPugt7zHThEMLce1c= -go.opentelemetry.io/otel v1.41.0/go.mod h1:Yt4UwgEKeT05QbLwbyHXEwhnjxNO6D8L5PQP51/46dE= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 h1:mq/Qcf28TWz719lE3/hMB4KkyDuLJIvgJnFGcd0kEUI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0/go.mod h1:yk5LXEYhsL2htyDNJbEq7fWzNEigeEdV5xBF/Y+kAv0= -go.opentelemetry.io/otel/metric v1.41.0 h1:rFnDcs4gRzBcsO9tS8LCpgR0dxg4aaxWlJxCno7JlTQ= -go.opentelemetry.io/otel/metric v1.41.0/go.mod h1:xPvCwd9pU0VN8tPZYzDZV/BMj9CM9vs00GuBjeKhJps= -go.opentelemetry.io/otel/sdk v1.41.0 h1:YPIEXKmiAwkGl3Gu1huk1aYWwtpRLeskpV+wPisxBp8= -go.opentelemetry.io/otel/sdk v1.41.0/go.mod h1:ahFdU0G5y8IxglBf0QBJXgSe7agzjE4GiTJ6HT9ud90= -go.opentelemetry.io/otel/sdk/metric v1.41.0 h1:siZQIYBAUd1rlIWQT2uCxWJxcCO7q3TriaMlf08rXw8= -go.opentelemetry.io/otel/sdk/metric v1.41.0/go.mod h1:HNBuSvT7ROaGtGI50ArdRLUnvRTRGniSUZbxiWxSO8Y= -go.opentelemetry.io/otel/trace v1.41.0 h1:Vbk2co6bhj8L59ZJ6/xFTskY+tGAbOnCtQGVVa9TIN0= -go.opentelemetry.io/otel/trace v1.41.0/go.mod h1:U1NU4ULCoxeDKc09yCWdWe+3QoyweJcISEVa1RBzOis= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= go.opentelemetry.io/proto/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= @@ -307,8 +307,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= From fbea08a3480c18fd350ac2bc5c1648250dfecd78 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:20:55 -0400 Subject: [PATCH 028/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.229.0 to 3.230.0 in /deploy (#1141) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.229.0 to 3.230.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.230.0
3.230.0 (2026-04-08)
Features
[cli] Detect AI agents and send in update metadata #22497
[auto/nodejs] Add "org" commands (get-default, set-default, search, search ai) to the auto-generated interface #22395
[auto/nodejs] Add "new" command to the auto-generated interface #22421
[sdk/{nodejs,python}] Add Cancel handler to Python & Node.js providers #22516
[cli/policy] Add ESC environment resolution for policy packs #22425
Bug Fixes
[auto/go] Insert --non-interactive flag before "--" positional separator to avoid misinterpretation as a positional argument #22462
[ci] Add code coverage collection for Node.js automation tools tests #22412
[pcl] Allow key indexing into a map of resources created by range #22498
[programgen/go] Fix an issue with formatted index modules not importing correctly
[cli/state] Check for Pulumi.yaml projects and
backendoption instate upgrade#22483[sdk/go] Fix Go program generation for ternary expressions inside apply callbacks, add Go predeclared identifiers to reserved words, handle optional list types in union type codegen, and fix unmarshalOutput for known outputs with null elements. #22460
[sdk/nodejs] Fix inherited input properties missing from component schema when args interface extends another interface #22446
[sdk/python] Fix inherited input properties missing from component schema when args class inherits from a base class #22484
Miscellaneous
... (truncated)
Commits
ae2e269Update dependency pulumi/pulumi-java to v1.23.0 (#22526)28d3f9cExtend module-format test to check index modules (#22505)dc6881aMark generated CLI docs files as auto-generated (#22528)cb231c1Update dependency pulumi/pulumi-dotnet to v3.102.1 (#22525)3809a4cAdd Cancel handler to Python & Node.js providers (#22516)b4e628bFix typos, grammar, and broken references in developer docs (#22493)f6ae330Add ESC environment resolution for policy packs (#22425)14b0963Use renovate to update the language runtimes (#22517)2e60a39Fix flaky TestFuzz (#22514)5da6fcb[Go] Fix l2-resource-optional (#22460)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Radoslav Dimitrov --- deploy/go.mod | 6 +++--- deploy/go.sum | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 860894b..07de0a8 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.28.0 - github.com/pulumi/pulumi/sdk/v3 v3.229.0 + github.com/pulumi/pulumi/sdk/v3 v3.230.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -38,7 +38,7 @@ require ( github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.8.0 // indirect - github.com/go-git/go-git/v5 v5.17.1 // indirect + github.com/go-git/go-git/v5 v5.17.2 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -113,7 +113,7 @@ require ( golang.org/x/tools v0.41.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect - google.golang.org/grpc v1.79.3 // indirect + google.golang.org/grpc v1.80.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index 083fbf9..418aa21 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -74,8 +74,8 @@ github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDz github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.17.1 h1:WnljyxIzSj9BRRUlnmAU35ohDsjRK0EKmL0evDqi5Jk= -github.com/go-git/go-git/v5 v5.17.1/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo= +github.com/go-git/go-git/v5 v5.17.2 h1:B+nkdlxdYrvyFK4GPXVU8w1U+YkbsgciIR7f2sZJ104= +github.com/go-git/go-git/v5 v5.17.2/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo= 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= @@ -185,8 +185,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.28.0 h1:muCE6cUJ4YmAaNLiOhbjEicxT+10i/EGsZrx2ZZQQ+o= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.28.0/go.mod h1:B998wofejDKAvvpLwsi4UMfWDFHHBnzYiM8mZ9e7OSo= -github.com/pulumi/pulumi/sdk/v3 v3.229.0 h1:jsAw5lXiHN22YQeo4bZHZBAG/DUlEnzsFWg5MuHnTSs= -github.com/pulumi/pulumi/sdk/v3 v3.229.0/go.mod h1:PAqB2+8gnxqk+QrFdXL3fSjsLIjtlBIcy5KLZ//4WSk= +github.com/pulumi/pulumi/sdk/v3 v3.230.0 h1:0TtF82Hlor39DLU0QtM7RZPwRaOmjn5UtQKPi1Mxo9M= +github.com/pulumi/pulumi/sdk/v3 v3.230.0/go.mod h1:u0fgmmPGwV5b4rmfuNABuYfRoqckuaTivufPn4EtfTk= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -329,14 +329,14 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -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= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= 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/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.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= 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 07fa85f68b4d23407e9807721ec113b87990f806 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Apr 2026 18:16:23 -0400 Subject: [PATCH 029/190] build(deps): bump github.com/coreos/go-oidc/v3 from 3.17.0 to 3.18.0 (#1140) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc) from 3.17.0 to 3.18.0. Release notes
Sourced from github.com/coreos/go-oidc/v3's releases.
v3.18.0
What's Changed
- .github: configure dependabot by
@ericchiangin coreos/go-oidc#477- .github: update go versions in CI by
@ericchiangin coreos/go-oidc#480- build(deps): bump golang.org/x/oauth2 from 0.28.0 to 0.36.0 by
@dependabot[bot] in coreos/go-oidc#478- build(deps): bump github.com/go-jose/go-jose/v4 from 4.1.3 to 4.1.4 by
@dependabot[bot] in coreos/go-oidc#479Full Changelog: https://github.com/coreos/go-oidc/compare/v3.17.0...v3.18.0
Commits
da6b3bfbuild(deps): bump github.com/go-jose/go-jose/v4 from 4.1.3 to 4.1.47f80694build(deps): bump golang.org/x/oauth2 from 0.28.0 to 0.36.07271de5.github: update go versions in CI3ccf20f.github: configure dependabot- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Radoslav Dimitrov --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3271c24..8619022 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 github.com/caarlos0/env/v11 v11.4.0 - github.com/coreos/go-oidc/v3 v3.17.0 + github.com/coreos/go-oidc/v3 v3.18.0 github.com/danielgtaylor/huma/v2 v2.37.3 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/go-containerregistry v0.21.4 diff --git a/go.sum b/go.sum index 0d029ae..71781bb 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,8 @@ github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/T github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= github.com/containerd/stargz-snapshotter/estargz v0.18.2 h1:yXkZFYIzz3eoLwlTUZKz2iQ4MrckBxJjkmD16ynUTrw= github.com/containerd/stargz-snapshotter/estargz v0.18.2/go.mod h1:XyVU5tcJ3PRpkA9XS2T5us6Eg35yM0214Y+wvrZTBrY= -github.com/coreos/go-oidc/v3 v3.17.0 h1:hWBGaQfbi0iVviX4ibC7bk8OKT5qNr4klBaCHVNvehc= -github.com/coreos/go-oidc/v3 v3.17.0/go.mod h1:wqPbKFrVnE90vty060SB40FCJ8fTHTxSwyXJqZH+sI8= +github.com/coreos/go-oidc/v3 v3.18.0 h1:V9orjXynvu5wiC9SemFTWnG4F45v403aIcjWo0d41+A= +github.com/coreos/go-oidc/v3 v3.18.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4= github.com/danielgtaylor/huma/v2 v2.37.3 h1:6Av0Vj45Vk5lDxRVfoO2iPlEdvCvwLc7pl5nbqGOkYM= github.com/danielgtaylor/huma/v2 v2.37.3/go.mod h1:OeHHtCEAaNiuVbAVdYu4IQ0UOmnb4x3yMUOShNlZ53g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From 1e83267610c9b6e17f8f5ecf055b060b24813207 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 05:19:09 -0400 Subject: [PATCH 030/190] build(deps): bump cloud.google.com/go/kms from 1.27.0 to 1.29.0 (#1163) --- go.mod | 16 ++++++++-------- go.sum | 36 ++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 8619022..21bab95 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/modelcontextprotocol/registry go 1.26 require ( - cloud.google.com/go/kms v1.27.0 + cloud.google.com/go/kms v1.29.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 github.com/caarlos0/env/v11 v11.4.0 @@ -31,8 +31,8 @@ require ( cloud.google.com/go/auth v0.18.2 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect - cloud.google.com/go/iam v1.6.0 // indirect - cloud.google.com/go/longrunning v0.8.0 // indirect + cloud.google.com/go/iam v1.7.0 // indirect + cloud.google.com/go/longrunning v0.9.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 // indirect @@ -50,7 +50,7 @@ require ( github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect - github.com/googleapis/gax-go/v2 v2.20.0 // indirect + github.com/googleapis/gax-go/v2 v2.21.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 @@ -80,11 +80,11 @@ require ( golang.org/x/sys v0.42.0 // indirect golang.org/x/text v0.35.0 // indirect golang.org/x/time v0.15.0 // indirect - google.golang.org/api v0.273.1 // indirect + google.golang.org/api v0.274.0 // indirect google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260401001100-f93e5f3e9f0f // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect - google.golang.org/grpc v1.79.3 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260401001100-f93e5f3e9f0f // indirect + google.golang.org/grpc v1.80.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gotest.tools/v3 v3.5.2 // indirect ) diff --git a/go.sum b/go.sum index 71781bb..d4ce0a3 100644 --- a/go.sum +++ b/go.sum @@ -6,12 +6,12 @@ cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIi cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= -cloud.google.com/go/iam v1.6.0 h1:JiSIcEi38dWBKhB3BtfKCW+dMvCZJEhBA2BsaGJgoxs= -cloud.google.com/go/iam v1.6.0/go.mod h1:ZS6zEy7QHmcNO18mjO2viYv/n+wOUkhJqGNkPPGueGU= -cloud.google.com/go/kms v1.27.0 h1:iYYgoD0HJIqz35A+He1G0dS5qTQzQsDXFsyXwzkUCXM= -cloud.google.com/go/kms v1.27.0/go.mod h1:KPxrdf61iYEOZ86uPwR86muBpSik2y4Ion6e83fVl1Q= -cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8= -cloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk= +cloud.google.com/go/iam v1.7.0 h1:JD3zh0C6LHl16aCn5Akff0+GELdp1+4hmh6ndoFLl8U= +cloud.google.com/go/iam v1.7.0/go.mod h1:tetWZW1PD/m6vcuY2Zj/aU0eCHNPuxedbnbRTyKXvdY= +cloud.google.com/go/kms v1.29.0 h1:bAW1C5FQf+6GhPkywQzPlsULALCG7c16qpXLFGV9ivY= +cloud.google.com/go/kms v1.29.0/go.mod h1:YIyXZym11R5uovJJt4oN5eUL3oPmirF3yKeIh6QAf4U= +cloud.google.com/go/longrunning v0.9.0 h1:0EzbDEGsAvOZNbqXopgniY0w0a1phvu5IdUFq8grmqY= +cloud.google.com/go/longrunning v0.9.0/go.mod h1:pkTz846W7bF4o2SzdWJ40Hu0Re+UoNT6Q5t+igIcb8E= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= @@ -79,8 +79,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/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8= github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= -github.com/googleapis/gax-go/v2 v2.20.0 h1:NIKVuLhDlIV74muWlsMM4CcQZqN6JJ20Qcxd9YMuYcs= -github.com/googleapis/gax-go/v2 v2.20.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4= +github.com/googleapis/gax-go/v2 v2.21.0 h1:h45NjjzEO3faG9Lg/cFrBh2PgegVVgzqKzuZl/wMbiI= +github.com/googleapis/gax-go/v2 v2.21.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= @@ -181,18 +181,18 @@ golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.273.1 h1:L7G/TmpAMz0nKx/ciAVssVmWQiOF6+pOuXeKrWVsquY= -google.golang.org/api v0.273.1/go.mod h1:JbAt7mF+XVmWu6xNP8/+CTiGH30ofmCmk9nM8d8fHew= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/api v0.274.0 h1:aYhycS5QQCwxHLwfEHRRLf9yNsfvp1JadKKWBE54RFA= +google.golang.org/api v0.274.0/go.mod h1:JbAt7mF+XVmWu6xNP8/+CTiGH30ofmCmk9nM8d8fHew= google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0= google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= -google.golang.org/genproto/googleapis/api v0.0.0-20260401001100-f93e5f3e9f0f h1:K3zPU40OFjwD5YKADLMLoiL0L7JJpBgEdLqGuCNPfp0= -google.golang.org/genproto/googleapis/api v0.0.0-20260401001100-f93e5f3e9f0f/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:ndE4FoJqsIceKP2oYSnUZqhTdYufCYYkqwtFzfrhI7w= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/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/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401001100-f93e5f3e9f0f h1:Rka45QInERYknkHYfJEPBQaoobXl+YpxTMjAKgWUq2A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401001100-f93e5f3e9f0f/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= 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 0c5dde243bf6b780be05fb6c0bb09e1df61008a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 05:19:36 -0400 Subject: [PATCH 031/190] build(deps): bump github.com/google/go-containerregistry from 0.21.4 to 0.21.5 (#1162) --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 21bab95..dccf238 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/coreos/go-oidc/v3 v3.18.0 github.com/danielgtaylor/huma/v2 v2.37.3 github.com/golang-jwt/jwt/v5 v5.3.1 - github.com/google/go-containerregistry v0.21.4 + github.com/google/go-containerregistry v0.21.5 github.com/jackc/pgx/v5 v5.9.1 github.com/prometheus/client_golang v1.23.2 github.com/rs/cors v1.11.1 @@ -22,7 +22,7 @@ require ( go.opentelemetry.io/otel/metric v1.43.0 go.opentelemetry.io/otel/sdk v1.43.0 go.opentelemetry.io/otel/sdk/metric v1.43.0 - golang.org/x/mod v0.34.0 + golang.org/x/mod v0.35.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -41,7 +41,7 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/docker/cli v29.3.1+incompatible // indirect + github.com/docker/cli v29.4.0+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-jose/go-jose/v4 v4.1.4 // indirect @@ -77,7 +77,7 @@ require ( golang.org/x/net v0.52.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.42.0 // indirect + golang.org/x/sys v0.43.0 // indirect golang.org/x/text v0.35.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/api v0.274.0 // indirect diff --git a/go.sum b/go.sum index d4ce0a3..0a61c79 100644 --- a/go.sum +++ b/go.sum @@ -45,8 +45,8 @@ github.com/danielgtaylor/huma/v2 v2.37.3/go.mod h1:OeHHtCEAaNiuVbAVdYu4IQ0UOmnb4 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/cli v29.3.1+incompatible h1:M04FDj2TRehDacrosh7Vlkgc7AuQoWloQkf1PA5hmoI= -github.com/docker/cli v29.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v29.4.0+incompatible h1:+IjXULMetlvWJiuSI0Nbor36lcJ5BTcVpUmB21KBoVM= +github.com/docker/cli v29.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= @@ -71,8 +71,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 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/go-containerregistry v0.21.4 h1:VrhlIQtdhE6riZW//MjPrcJ1snAjPoCCpPHqGOygrv8= -github.com/google/go-containerregistry v0.21.4/go.mod h1:kxgc23zQ2qMY/hAKt0wCbB/7tkeovAP2mE2ienynJUw= +github.com/google/go-containerregistry v0.21.5 h1:KTJG9Pn/jC0VdZR6ctV3/jcN+q6/Iqlx0sTVz3ywZlM= +github.com/google/go-containerregistry v0.21.5/go.mod h1:ySvMuiWg+dOsRW0Hw8GYwfMwBlNRTmpYBFJPlkco5zU= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -166,8 +166,8 @@ go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= @@ -175,8 +175,8 @@ golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7 golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= From 77bbd41fd37b824bb64a5c1bfe9cf49a3b7cd400 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Apr 2026 05:20:05 -0400 Subject: [PATCH 032/190] build(deps): bump actions/upload-artifact from 7.0.0 to 7.0.1 in the actions group (#1154) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e24af7a..e0dbb93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,7 +63,7 @@ jobs: run: make test-all - name: Upload coverage artifacts - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a with: name: coverage-report path: | From 90baa0528f75b01f8b5966c6cf1913484290087d Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Wed, 15 Apr 2026 03:23:07 -0400 Subject: [PATCH 033/190] fix: store tokens in ~/.config/mcp-publisher/ instead of cwd (#1166) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes #663 - **Security fix**: `mcp-publisher login` no longer writes `.mcpregistry_github_token` and `.mcpregistry_registry_token` to the current working directory. GitHub tokens are kept in memory during the login→exchange flow and cleared immediately after. - **Token location**: Unified token moved from `~/.mcp_publisher_token` to `~/.config/mcp-publisher/token.json` (dir 0700, file 0600), following the convention used by `gh`, `docker`, and `kubectl`. - **Dead code removed**: `NeedsLogin()` was on the `Provider` interface but never called — removed from interface and all 4 implementations. `forceLogin` field also removed. - **Auth tests added**: 11 new tests for `GitHubATProvider` (package previously had 0 tests). - **Test isolation**: `SetupTestToken` now uses `t.TempDir()` + `t.Setenv("HOME", ...)` instead of writing to real `$HOME`. ### Breaking change Users must re-login after upgrading (`mcp-publisher login `). Existing tokens at `~/.mcp_publisher_token` are not auto-migrated. `logout` cleans up both old and new locations. ## Test plan - [x] `make check` passes (lint, unit tests, integration tests) - [x] `mcp-publisher login none` stores token at `~/.config/mcp-publisher/token.json` - [x] No `.mcpregistry_*` files created in cwd after login (with `--token`, `MCP_GITHUB_TOKEN`, or device flow) - [x] `mcp-publisher publish` reads token from new location - [x] `mcp-publisher validate` reads registry URL from new location - [x] `mcp-publisher logout` cleans up new location, legacy `~/.mcp_publisher_token`, and cwd `.mcpregistry_*` files - [x] `mcp-publisher logout` when not logged in shows "Not logged in" - [x] File permissions: dir 0700, file 0600 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 (1M context) --- cmd/publisher/auth/common.go | 5 - cmd/publisher/auth/github-at.go | 129 ++------------- cmd/publisher/auth/github-oidc.go | 6 - cmd/publisher/auth/github_at_test.go | 203 ++++++++++++++++++++++++ cmd/publisher/auth/interface.go | 4 - cmd/publisher/auth/none.go | 4 - cmd/publisher/commands/login.go | 55 +++++-- cmd/publisher/commands/login_test.go | 97 +++++++++++ cmd/publisher/commands/logout.go | 48 ++++-- cmd/publisher/commands/logout_test.go | 123 ++++++++++++++ cmd/publisher/commands/publish.go | 9 +- cmd/publisher/commands/status.go | 8 +- cmd/publisher/commands/testutil_test.go | 18 +-- cmd/publisher/commands/validate.go | 19 +-- complete.md | 11 +- docs/reference/cli/commands.md | 11 +- tests/integration/main.go | 11 +- 17 files changed, 557 insertions(+), 204 deletions(-) create mode 100644 cmd/publisher/auth/github_at_test.go create mode 100644 cmd/publisher/commands/login_test.go create mode 100644 cmd/publisher/commands/logout_test.go diff --git a/cmd/publisher/auth/common.go b/cmd/publisher/auth/common.go index 28829e8..053b543 100644 --- a/cmd/publisher/auth/common.go +++ b/cmd/publisher/auth/common.go @@ -171,11 +171,6 @@ func parseRawPrivateKey(curve elliptic.Curve, privateKeyBytes []byte) (*ecdsa.Pr }, nil } -// NeedsLogin always returns false for cryptographic auth since no interactive login is needed -func (c *CryptoProvider) NeedsLogin() bool { - return false -} - // Login is not needed for cryptographic auth since authentication is cryptographic func (c *CryptoProvider) Login(_ context.Context) error { return nil diff --git a/cmd/publisher/auth/github-at.go b/cmd/publisher/auth/github-at.go index 602e116..3e53529 100644 --- a/cmd/publisher/auth/github-at.go +++ b/cmd/publisher/auth/github-at.go @@ -12,8 +12,6 @@ import ( ) const ( - gitHubTokenFilePath = ".mcpregistry_github_token" // #nosec:G101 - registryTokenFilePath = ".mcpregistry_registry_token" // #nosec:G101 // GitHub OAuth URLs GitHubDeviceCodeURL = "https://github.com/login/device/code" // #nosec:G101 GitHubAccessTokenURL = "https://github.com/login/oauth/access_token" // #nosec:G101 @@ -42,18 +40,12 @@ type RegistryTokenResponse struct { ExpiresAt int64 `json:"expires_at"` } -// StoredRegistryToken represents the registry token with expiration stored locally -type StoredRegistryToken struct { - Token string `json:"token"` - ExpiresAt int64 `json:"expires_at"` -} - // GitHubATProvider implements the Provider interface using GitHub's device flow type GitHubATProvider struct { clientID string - forceLogin bool registryURL string providedToken string // Token provided via --token flag or MCP_GITHUB_TOKEN env var + githubToken string // In-memory GitHub token set by Login() } // ServerHealthResponse represents the response from the health endpoint @@ -63,14 +55,13 @@ type ServerHealthResponse struct { } // NewGitHubATProvider creates a new GitHub OAuth provider -func NewGitHubATProvider(forceLogin bool, registryURL, token string) Provider { +func NewGitHubATProvider(registryURL, token string) Provider { // Check for token from flag or environment variable if token == "" { token = os.Getenv("MCP_GITHUB_TOKEN") } return &GitHubATProvider{ - forceLogin: forceLogin, registryURL: registryURL, providedToken: token, } @@ -78,69 +69,26 @@ func NewGitHubATProvider(forceLogin bool, registryURL, token string) Provider { // GetToken retrieves the registry JWT token (exchanges GitHub token if needed) func (g *GitHubATProvider) GetToken(ctx context.Context) (string, error) { - // Check if we have a valid registry token - registryToken, err := readRegistryToken() - if err == nil && registryToken != "" { - return registryToken, nil - } - - // If no valid registry token, exchange GitHub token for registry token - githubToken, err := readToken() - if err != nil { - return "", fmt.Errorf("failed to read GitHub token: %w", err) + if g.githubToken == "" { + return "", fmt.Errorf("no GitHub token available; run Login() first") } // Exchange GitHub token for registry token - registryToken, expiresAt, err := g.exchangeTokenForRegistry(ctx, githubToken) + registryToken, _, err := g.exchangeTokenForRegistry(ctx, g.githubToken) + // Clear the GitHub token from memory after exchange + g.githubToken = "" if err != nil { return "", fmt.Errorf("failed to exchange token: %w", err) } - // Store the registry token - err = saveRegistryToken(registryToken, expiresAt) - if err != nil { - return "", fmt.Errorf("failed to save registry token: %w", err) - } - return registryToken, nil } -// NeedsLogin checks if a new login is required -func (g *GitHubATProvider) NeedsLogin() bool { - // If a token was provided via --token or MCP_GITHUB_TOKEN, no login needed - if g.providedToken != "" { - return false - } - - if g.forceLogin { - return true - } - - // Check if GitHub token exists - _, statErr := os.Stat(gitHubTokenFilePath) - if os.IsNotExist(statErr) { - return true - } - - // Check if valid registry token exists - _, err := readRegistryToken() - if err != nil { - // No valid registry token, but we have GitHub token - // We don't need to login, just exchange tokens - return false - } - - return false -} - // Login performs the GitHub device flow authentication func (g *GitHubATProvider) Login(ctx context.Context) error { - // If a token was provided via --token or MCP_GITHUB_TOKEN, save it and skip device flow + // If a token was provided via --token or MCP_GITHUB_TOKEN, store it in memory and skip device flow if g.providedToken != "" { - err := saveToken(g.providedToken) - if err != nil { - return fmt.Errorf("error saving provided token: %w", err) - } + g.githubToken = g.providedToken return nil } @@ -173,11 +121,8 @@ func (g *GitHubATProvider) Login(ctx context.Context) error { return fmt.Errorf("error polling for token: %w", err) } - // Store the token locally - err = saveToken(token) - if err != nil { - return fmt.Errorf("error saving token: %w", err) - } + // Store the token in memory + g.githubToken = token _, _ = fmt.Fprintln(os.Stdout, "Successfully authenticated!") return nil @@ -305,20 +250,6 @@ func (g *GitHubATProvider) pollForToken(ctx context.Context, deviceCode string) return "", fmt.Errorf("device code authorization timed out") } -// saveToken saves the GitHub access token to a local file -func saveToken(token string) error { - return os.WriteFile(gitHubTokenFilePath, []byte(token), 0600) -} - -// readToken reads the GitHub access token from a local file -func readToken() (string, error) { - tokenData, err := os.ReadFile(gitHubTokenFilePath) - if err != nil { - return "", err - } - return string(tokenData), nil -} - func getClientID(ctx context.Context, registryURL string) (string, error) { // This function should retrieve the GitHub Client ID from the registry URL // For now, we will return a placeholder value @@ -407,41 +338,3 @@ func (g *GitHubATProvider) exchangeTokenForRegistry(ctx context.Context, githubT return tokenResp.RegistryToken, tokenResp.ExpiresAt, nil } - -// saveRegistryToken saves the registry JWT token to a local file with expiration -func saveRegistryToken(token string, expiresAt int64) error { - storedToken := StoredRegistryToken{ - Token: token, - ExpiresAt: expiresAt, - } - - data, err := json.Marshal(storedToken) - if err != nil { - return fmt.Errorf("failed to marshal token: %w", err) - } - - return os.WriteFile(registryTokenFilePath, data, 0600) -} - -// readRegistryToken reads the registry JWT token from a local file -func readRegistryToken() (string, error) { - data, err := os.ReadFile(registryTokenFilePath) - if err != nil { - return "", err - } - - var storedToken StoredRegistryToken - err = json.Unmarshal(data, &storedToken) - if err != nil { - return "", fmt.Errorf("failed to unmarshal token: %w", err) - } - - // Check if token has expired - if time.Now().Unix() >= storedToken.ExpiresAt { - // Token has expired, remove the file - os.Remove(registryTokenFilePath) - return "", fmt.Errorf("registry token has expired") - } - - return storedToken.Token, nil -} diff --git a/cmd/publisher/auth/github-oidc.go b/cmd/publisher/auth/github-oidc.go index 55fa350..e4b51ed 100644 --- a/cmd/publisher/auth/github-oidc.go +++ b/cmd/publisher/auth/github-oidc.go @@ -38,12 +38,6 @@ func (o *GitHubOIDCProvider) GetToken(ctx context.Context) (string, error) { return registryToken, nil } -// NeedsLogin always returns false for OIDC since the token is provided by GitHub Actions -func (o *GitHubOIDCProvider) NeedsLogin() bool { - // OIDC tokens are provided by GitHub Actions runtime, no interactive login needed - return false -} - // Login is not needed for OIDC since tokens are provided by GitHub Actions func (o *GitHubOIDCProvider) Login(_ context.Context) error { // No interactive login needed for OIDC diff --git a/cmd/publisher/auth/github_at_test.go b/cmd/publisher/auth/github_at_test.go new file mode 100644 index 0000000..06add95 --- /dev/null +++ b/cmd/publisher/auth/github_at_test.go @@ -0,0 +1,203 @@ +package auth_test + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "testing" + + "github.com/modelcontextprotocol/registry/cmd/publisher/auth" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewGitHubATProvider_Name(t *testing.T) { + p := auth.NewGitHubATProvider("https://registry.example.com", "") + assert.Equal(t, "github", p.Name()) +} + +func TestNewGitHubATProvider_WithEnvToken(t *testing.T) { + t.Setenv("MCP_GITHUB_TOKEN", "env-token") + + registry := newMockExchangeServer(t, "env-token") + + p := auth.NewGitHubATProvider(registry.URL, "") + + // Login should use the env var token + err := p.Login(context.Background()) + require.NoError(t, err) + + // GetToken should exchange it successfully + token, err := p.GetToken(context.Background()) + require.NoError(t, err) + assert.Equal(t, "registry-jwt", token) +} + +func TestNewGitHubATProvider_ExplicitTokenTakesPrecedence(t *testing.T) { + t.Setenv("MCP_GITHUB_TOKEN", "env-token") + + registry := newMockExchangeServer(t, "explicit-token") + + p := auth.NewGitHubATProvider(registry.URL, "explicit-token") + + err := p.Login(context.Background()) + require.NoError(t, err) + + token, err := p.GetToken(context.Background()) + require.NoError(t, err) + assert.Equal(t, "registry-jwt", token) +} + +func TestGitHubATProvider_LoginWithProvidedToken(t *testing.T) { + registry := newMockExchangeServer(t, "my-token") + + p := auth.NewGitHubATProvider(registry.URL, "my-token") + + err := p.Login(context.Background()) + require.NoError(t, err) + + // Verify the token exchange works (proves Login stored the token) + token, err := p.GetToken(context.Background()) + require.NoError(t, err) + assert.Equal(t, "registry-jwt", token) +} + +func TestGitHubATProvider_LoginDoesNotWriteFiles(t *testing.T) { + cwd, err := os.Getwd() + require.NoError(t, err) + + p := auth.NewGitHubATProvider("https://registry.example.com", "my-token") + + err = p.Login(context.Background()) + require.NoError(t, err) + + // Verify no .mcpregistry_* files were created in cwd + for _, name := range []string{".mcpregistry_github_token", ".mcpregistry_registry_token"} { + _, statErr := os.Stat(filepath.Join(cwd, name)) + assert.True(t, os.IsNotExist(statErr), "Login should not create %s in cwd", name) + } +} + +func TestGitHubATProvider_GetTokenWithoutLogin(t *testing.T) { + p := auth.NewGitHubATProvider("https://registry.example.com", "my-token") + + // GetToken without Login should fail + _, err := p.GetToken(context.Background()) + require.Error(t, err) + assert.Contains(t, err.Error(), "no GitHub token available") +} + +func TestGitHubATProvider_GetTokenClearsTokenAfterExchange(t *testing.T) { + registry := newMockExchangeServer(t, "my-token") + + p := auth.NewGitHubATProvider(registry.URL, "my-token") + + err := p.Login(context.Background()) + require.NoError(t, err) + + // First GetToken should succeed + token, err := p.GetToken(context.Background()) + require.NoError(t, err) + assert.Equal(t, "registry-jwt", token) + + // Second GetToken should fail (GitHub token was cleared after exchange) + _, err = p.GetToken(context.Background()) + require.Error(t, err) + assert.Contains(t, err.Error(), "no GitHub token available") +} + +func TestGitHubATProvider_GetTokenClearsTokenOnError(t *testing.T) { + // Mock registry that always returns an error + registry := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + http.Error(w, "server error", http.StatusInternalServerError) + })) + t.Cleanup(registry.Close) + + p := auth.NewGitHubATProvider(registry.URL, "my-token") + + err := p.Login(context.Background()) + require.NoError(t, err) + + // GetToken should fail + _, err = p.GetToken(context.Background()) + require.Error(t, err) + + // Token should be cleared — second call also fails with "no GitHub token" + _, err = p.GetToken(context.Background()) + require.Error(t, err) + assert.Contains(t, err.Error(), "no GitHub token available") +} + +func TestGitHubATProvider_GetTokenExchangeFailure_NoURL(t *testing.T) { + p := auth.NewGitHubATProvider("", "my-token") + + err := p.Login(context.Background()) + require.NoError(t, err) + + _, err = p.GetToken(context.Background()) + require.Error(t, err) + assert.Contains(t, err.Error(), "failed to exchange token") +} + +func TestGitHubATProvider_LoginDeviceFlow_FetchesClientID(t *testing.T) { + // Mock registry health endpoint + registry := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/v0/health" { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]string{ + "status": "ok", + "github_client_id": "test-client-id", + }) + return + } + http.Error(w, "not found", http.StatusNotFound) + })) + t.Cleanup(registry.Close) + + p := auth.NewGitHubATProvider(registry.URL, "") + + // Login without a provided token triggers device flow, which calls + // the real GitHub device code URL. This will fail, but only after + // fetching the client ID from our mock health endpoint. + err := p.Login(context.Background()) + require.Error(t, err) + assert.Contains(t, err.Error(), "error requesting device code") +} + +func TestGitHubATProvider_ImplementsProviderInterface(_ *testing.T) { + // Compile-time check + var _ = auth.NewGitHubATProvider("https://example.com", "token") +} + +// newMockExchangeServer creates an httptest.Server that mocks the registry's +// token exchange endpoint. It accepts a specific GitHub token and returns +// "registry-jwt" as the registry token. +func newMockExchangeServer(t *testing.T, expectedGitHubToken string) *httptest.Server { + t.Helper() + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.URL.Path == "/v0/auth/github-at" && r.Method == http.MethodPost { + var body map[string]string + if err := json.NewDecoder(r.Body).Decode(&body); err != nil { + http.Error(w, "bad request", http.StatusBadRequest) + return + } + if body["github_token"] == expectedGitHubToken { + w.Header().Set("Content-Type", "application/json") + resp := map[string]interface{}{ + "registry_token": "registry-jwt", + "expires_at": 9999999999, + } + _ = json.NewEncoder(w).Encode(resp) + return + } + http.Error(w, "unauthorized", http.StatusUnauthorized) + return + } + http.Error(w, "not found", http.StatusNotFound) + })) + t.Cleanup(server.Close) + return server +} diff --git a/cmd/publisher/auth/interface.go b/cmd/publisher/auth/interface.go index a230429..1e3561f 100644 --- a/cmd/publisher/auth/interface.go +++ b/cmd/publisher/auth/interface.go @@ -8,10 +8,6 @@ type Provider interface { // It returns the token string and any error encountered GetToken(ctx context.Context) (string, error) - // NeedsLogin checks if a new login is required - // This can check for existing tokens, expiry, etc. - NeedsLogin() bool - // Login performs the authentication flow // This might involve user interaction, device flows, etc. Login(ctx context.Context) error diff --git a/cmd/publisher/auth/none.go b/cmd/publisher/auth/none.go index a822cba..967db24 100644 --- a/cmd/publisher/auth/none.go +++ b/cmd/publisher/auth/none.go @@ -62,10 +62,6 @@ func (p *NoneProvider) GetToken(ctx context.Context) (string, error) { return p.token, nil } -func (p *NoneProvider) NeedsLogin() bool { - return false -} - func (p *NoneProvider) Login(_ context.Context) error { // No login needed for anonymous auth return nil diff --git a/cmd/publisher/commands/login.go b/cmd/publisher/commands/login.go index 091a700..3b97211 100644 --- a/cmd/publisher/commands/login.go +++ b/cmd/publisher/commands/login.go @@ -16,15 +16,45 @@ import ( ) const ( - DefaultRegistryURL = "https://registry.modelcontextprotocol.io" - TokenFileName = ".mcp_publisher_token" //nolint:gosec // Not a credential, just a filename - MethodGitHub = "github" - MethodGitHubOIDC = "github-oidc" - MethodDNS = "dns" - MethodHTTP = "http" - MethodNone = "none" + DefaultRegistryURL = "https://registry.modelcontextprotocol.io" + LegacyTokenFileName = ".mcp_publisher_token" //nolint:gosec // Not a credential, just a filename + MethodGitHub = "github" + MethodGitHubOIDC = "github-oidc" + MethodDNS = "dns" + MethodHTTP = "http" + MethodNone = "none" ) +// tokenFilePath returns the path to the token file in the user's config directory +// (~/.config/mcp-publisher/token.json). It does not create the directory. +func tokenFilePath() (string, error) { + homeDir, err := os.UserHomeDir() + if err != nil { + return "", fmt.Errorf("failed to get home directory: %w", err) + } + return filepath.Join(homeDir, ".config", "mcp-publisher", "token.json"), nil +} + +// notAuthenticatedError returns an error guiding the user to log in, +// with a hint about the token location change for users upgrading. +func notAuthenticatedError() error { + _, _ = fmt.Fprintln(os.Stderr, "hint: token storage moved to ~/.config/mcp-publisher/. If you recently upgraded, please re-login.") + return errors.New("not authenticated, run 'mcp-publisher login ' first") +} + +// ensureTokenDir creates the token directory (~/.config/mcp-publisher/) if needed. +func ensureTokenDir() error { + homeDir, err := os.UserHomeDir() + if err != nil { + return fmt.Errorf("failed to get home directory: %w", err) + } + dir := filepath.Join(homeDir, ".config", "mcp-publisher") + if err := os.MkdirAll(dir, 0700); err != nil { + return fmt.Errorf("failed to create config directory: %w", err) + } + return nil +} + type CryptoAlgorithm auth.CryptoAlgorithm type SignerType string @@ -130,7 +160,7 @@ func createSigner(flags LoginFlags) (auth.Signer, error) { func createAuthProvider(method, registryURL, domain string, token Token, signer auth.Signer) (auth.Provider, error) { switch method { case MethodGitHub: - return auth.NewGitHubATProvider(true, registryURL, string(token)), nil + return auth.NewGitHubATProvider(registryURL, string(token)), nil case MethodGitHubOIDC: return auth.NewGitHubOIDCProvider(registryURL), nil case MethodDNS: @@ -226,12 +256,15 @@ Examples: return fmt.Errorf("failed to get token: %w", err) } - homeDir, err := os.UserHomeDir() + if err := ensureTokenDir(); err != nil { + return err + } + + tokenPath, err := tokenFilePath() if err != nil { - return fmt.Errorf("failed to get home directory: %w", err) + return err } - tokenPath := filepath.Join(homeDir, TokenFileName) tokenData := map[string]string{ "token": token, "method": method, diff --git a/cmd/publisher/commands/login_test.go b/cmd/publisher/commands/login_test.go new file mode 100644 index 0000000..1f6a1b1 --- /dev/null +++ b/cmd/publisher/commands/login_test.go @@ -0,0 +1,97 @@ +package commands_test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "testing" + + "github.com/modelcontextprotocol/registry/cmd/publisher/commands" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLoginCommand_WritesTokenToConfigDir(t *testing.T) { + tempHome := t.TempDir() + t.Setenv("HOME", tempHome) + + // Mock registry that returns a token for "none" auth + server := setupNoneAuthServer(t) + + err := commands.LoginCommand([]string{"none", "--registry", server.URL}) + require.NoError(t, err) + + // Verify token written to new location + tokenPath := filepath.Join(tempHome, ".config", "mcp-publisher", "token.json") + data, err := os.ReadFile(tokenPath) + require.NoError(t, err) + + var tokenInfo map[string]string + require.NoError(t, json.Unmarshal(data, &tokenInfo)) + + assert.Equal(t, "none", tokenInfo["method"]) + assert.Equal(t, server.URL, tokenInfo["registry"]) + assert.NotEmpty(t, tokenInfo["token"]) +} + +func TestLoginCommand_CreatesDirectoryWithCorrectPerms(t *testing.T) { + tempHome := t.TempDir() + t.Setenv("HOME", tempHome) + + server := setupNoneAuthServer(t) + + err := commands.LoginCommand([]string{"none", "--registry", server.URL}) + require.NoError(t, err) + + // Verify directory permissions + dir := filepath.Join(tempHome, ".config", "mcp-publisher") + info, err := os.Stat(dir) + require.NoError(t, err) + assert.Equal(t, os.FileMode(0700), info.Mode().Perm()) + + // Verify file permissions + tokenPath := filepath.Join(dir, "token.json") + info, err = os.Stat(tokenPath) + require.NoError(t, err) + assert.Equal(t, os.FileMode(0600), info.Mode().Perm()) +} + +func TestLoginCommand_DoesNotWriteLegacyFiles(t *testing.T) { + tempHome := t.TempDir() + t.Setenv("HOME", tempHome) + + server := setupNoneAuthServer(t) + + err := commands.LoginCommand([]string{"none", "--registry", server.URL}) + require.NoError(t, err) + + // Verify no legacy file at $HOME + _, err = os.Stat(filepath.Join(tempHome, ".mcp_publisher_token")) + assert.True(t, os.IsNotExist(err), "should not create legacy ~/.mcp_publisher_token") + + // Verify no .mcpregistry_* files in cwd + cwd, err := os.Getwd() + require.NoError(t, err) + for _, name := range []string{".mcpregistry_github_token", ".mcpregistry_registry_token"} { + _, err := os.Stat(filepath.Join(cwd, name)) + assert.True(t, os.IsNotExist(err), "should not create %s in cwd", name) + } +} + +// setupNoneAuthServer creates a mock registry that handles the "none" auth flow. +func setupNoneAuthServer(t *testing.T) *httptest.Server { + t.Helper() + mux := http.NewServeMux() + mux.HandleFunc("/v0/auth/none", func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]interface{}{ + "registry_token": "test-registry-jwt", + "expires_at": 9999999999, + }) + }) + server := httptest.NewServer(mux) + t.Cleanup(server.Close) + return server +} diff --git a/cmd/publisher/commands/logout.go b/cmd/publisher/commands/logout.go index 3ac9abd..25adfd8 100644 --- a/cmd/publisher/commands/logout.go +++ b/cmd/publisher/commands/logout.go @@ -7,37 +7,57 @@ import ( ) func LogoutCommand() error { - homeDir, err := os.UserHomeDir() + tokenPath, err := tokenFilePath() if err != nil { - return fmt.Errorf("failed to get home directory: %w", err) + return err } - tokenPath := filepath.Join(homeDir, TokenFileName) + // Check if token file exists at new location or legacy location + homeDir, err := os.UserHomeDir() + if err != nil { + homeDir = "" // degrade gracefully for legacy cleanup + } + legacyTokenPath := "" + if homeDir != "" { + legacyTokenPath = filepath.Join(homeDir, LegacyTokenFileName) + } - // Check if token file exists - if _, err := os.Stat(tokenPath); os.IsNotExist(err) { + newExists := fileExists(tokenPath) + legacyExists := legacyTokenPath != "" && fileExists(legacyTokenPath) + + if !newExists && !legacyExists { _, _ = fmt.Fprintln(os.Stdout, "Not logged in") return nil } - // Remove token file - if err := os.Remove(tokenPath); err != nil { - return fmt.Errorf("failed to remove token: %w", err) + // Remove token file from new location + os.Remove(tokenPath) + + // Remove from legacy location + if legacyTokenPath != "" { + os.Remove(legacyTokenPath) } - // Also clean up legacy token files if they exist - legacyFiles := []string{ + // Clean up legacy intermediate token files from $HOME and cwd + legacyIntermediateFiles := []string{ ".mcpregistry_github_token", ".mcpregistry_registry_token", } - for _, file := range legacyFiles { - path := filepath.Join(homeDir, file) - if _, err := os.Stat(path); err == nil { - os.Remove(path) // Ignore errors for legacy files + for _, file := range legacyIntermediateFiles { + // Clean from $HOME + if homeDir != "" { + os.Remove(filepath.Join(homeDir, file)) } + // Clean from cwd (the original bug location) + os.Remove(file) } _, _ = fmt.Fprintln(os.Stdout, "✓ Successfully logged out") return nil } + +func fileExists(path string) bool { + _, err := os.Stat(path) + return err == nil +} diff --git a/cmd/publisher/commands/logout_test.go b/cmd/publisher/commands/logout_test.go new file mode 100644 index 0000000..ce0439f --- /dev/null +++ b/cmd/publisher/commands/logout_test.go @@ -0,0 +1,123 @@ +package commands_test + +import ( + "os" + "path/filepath" + "testing" + + "github.com/modelcontextprotocol/registry/cmd/publisher/commands" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLogoutCommand_RemovesNewToken(t *testing.T) { + tempHome := t.TempDir() + t.Setenv("HOME", tempHome) + + // Create token at new location + dir := filepath.Join(tempHome, ".config", "mcp-publisher") + require.NoError(t, os.MkdirAll(dir, 0700)) + require.NoError(t, os.WriteFile(filepath.Join(dir, "token.json"), []byte(`{"token":"t"}`), 0600)) + + err := commands.LogoutCommand() + require.NoError(t, err) + + _, err = os.Stat(filepath.Join(dir, "token.json")) + assert.True(t, os.IsNotExist(err)) +} + +func TestLogoutCommand_RemovesLegacyToken(t *testing.T) { + tempHome := t.TempDir() + t.Setenv("HOME", tempHome) + + // Create token at legacy location only + require.NoError(t, os.WriteFile(filepath.Join(tempHome, ".mcp_publisher_token"), []byte(`{"token":"t"}`), 0600)) + + err := commands.LogoutCommand() + require.NoError(t, err) + + _, err = os.Stat(filepath.Join(tempHome, ".mcp_publisher_token")) + assert.True(t, os.IsNotExist(err)) +} + +func TestLogoutCommand_RemovesBothOldAndNew(t *testing.T) { + tempHome := t.TempDir() + t.Setenv("HOME", tempHome) + + // Create tokens at both locations + dir := filepath.Join(tempHome, ".config", "mcp-publisher") + require.NoError(t, os.MkdirAll(dir, 0700)) + require.NoError(t, os.WriteFile(filepath.Join(dir, "token.json"), []byte(`{"token":"new"}`), 0600)) + require.NoError(t, os.WriteFile(filepath.Join(tempHome, ".mcp_publisher_token"), []byte(`{"token":"old"}`), 0600)) + + err := commands.LogoutCommand() + require.NoError(t, err) + + _, err = os.Stat(filepath.Join(dir, "token.json")) + assert.True(t, os.IsNotExist(err), "new token should be removed") + + _, err = os.Stat(filepath.Join(tempHome, ".mcp_publisher_token")) + assert.True(t, os.IsNotExist(err), "legacy token should be removed") +} + +func TestLogoutCommand_CleansUpCwdLegacyFiles(t *testing.T) { + tempHome := t.TempDir() + t.Setenv("HOME", tempHome) + + // Create a token so logout doesn't say "Not logged in" + dir := filepath.Join(tempHome, ".config", "mcp-publisher") + require.NoError(t, os.MkdirAll(dir, 0700)) + require.NoError(t, os.WriteFile(filepath.Join(dir, "token.json"), []byte(`{"token":"t"}`), 0600)) + + // Create legacy intermediate files in a temp cwd + tempCwd := t.TempDir() + origDir, err := os.Getwd() + require.NoError(t, err) + t.Cleanup(func() { _ = os.Chdir(origDir) }) + require.NoError(t, os.Chdir(tempCwd)) + + require.NoError(t, os.WriteFile(".mcpregistry_github_token", []byte("gh-token"), 0600)) + require.NoError(t, os.WriteFile(".mcpregistry_registry_token", []byte("reg-token"), 0600)) + + err = commands.LogoutCommand() + require.NoError(t, err) + + _, err = os.Stat(filepath.Join(tempCwd, ".mcpregistry_github_token")) + assert.True(t, os.IsNotExist(err), ".mcpregistry_github_token should be removed from cwd") + + _, err = os.Stat(filepath.Join(tempCwd, ".mcpregistry_registry_token")) + assert.True(t, os.IsNotExist(err), ".mcpregistry_registry_token should be removed from cwd") +} + +func TestLogoutCommand_CleansUpHomeLegacyFiles(t *testing.T) { + tempHome := t.TempDir() + t.Setenv("HOME", tempHome) + + // Create a token so logout doesn't say "Not logged in" + dir := filepath.Join(tempHome, ".config", "mcp-publisher") + require.NoError(t, os.MkdirAll(dir, 0700)) + require.NoError(t, os.WriteFile(filepath.Join(dir, "token.json"), []byte(`{"token":"t"}`), 0600)) + + // Create legacy intermediate files in $HOME + require.NoError(t, os.WriteFile(filepath.Join(tempHome, ".mcpregistry_github_token"), []byte("gh-token"), 0600)) + require.NoError(t, os.WriteFile(filepath.Join(tempHome, ".mcpregistry_registry_token"), []byte("reg-token"), 0600)) + + err := commands.LogoutCommand() + require.NoError(t, err) + + _, err = os.Stat(filepath.Join(tempHome, ".mcpregistry_github_token")) + assert.True(t, os.IsNotExist(err), ".mcpregistry_github_token should be removed from $HOME") + + _, err = os.Stat(filepath.Join(tempHome, ".mcpregistry_registry_token")) + assert.True(t, os.IsNotExist(err), ".mcpregistry_registry_token should be removed from $HOME") +} + +func TestLogoutCommand_NotLoggedIn(t *testing.T) { + tempHome := t.TempDir() + t.Setenv("HOME", tempHome) + + // No token files exist anywhere + err := commands.LogoutCommand() + // Should not error, just print "Not logged in" + require.NoError(t, err) +} diff --git a/cmd/publisher/commands/publish.go b/cmd/publisher/commands/publish.go index da7de7d..c93621a 100644 --- a/cmd/publisher/commands/publish.go +++ b/cmd/publisher/commands/publish.go @@ -4,12 +4,10 @@ import ( "bytes" "context" "encoding/json" - "errors" "fmt" "io" "net/http" "os" - "path/filepath" "strings" apiv0 "github.com/modelcontextprotocol/registry/pkg/api/v0" @@ -38,16 +36,15 @@ func PublishCommand(args []string) error { } // Load saved token - homeDir, err := os.UserHomeDir() + tokenPath, err := tokenFilePath() if err != nil { - return fmt.Errorf("failed to get home directory: %w", err) + return err } - tokenPath := filepath.Join(homeDir, TokenFileName) tokenData, err := os.ReadFile(tokenPath) if err != nil { if os.IsNotExist(err) { - return errors.New("not authenticated. Run 'mcp-publisher login ' first") + return notAuthenticatedError() } return fmt.Errorf("failed to read token: %w", err) } diff --git a/cmd/publisher/commands/status.go b/cmd/publisher/commands/status.go index bcfacf5..8132fa2 100644 --- a/cmd/publisher/commands/status.go +++ b/cmd/publisher/commands/status.go @@ -12,7 +12,6 @@ import ( "net/http" "net/url" "os" - "path/filepath" "strings" ) @@ -95,16 +94,15 @@ func StatusCommand(args []string) error { } // Load saved token - homeDir, err := os.UserHomeDir() + tokenPath, err := tokenFilePath() if err != nil { - return fmt.Errorf("failed to get home directory: %w", err) + return err } - tokenPath := filepath.Join(homeDir, TokenFileName) tokenData, err := os.ReadFile(tokenPath) if err != nil { if os.IsNotExist(err) { - return errors.New("not authenticated. Run 'mcp-publisher login ' first") + return notAuthenticatedError() } return fmt.Errorf("failed to read token: %w", err) } diff --git a/cmd/publisher/commands/testutil_test.go b/cmd/publisher/commands/testutil_test.go index 51c6687..e69027b 100644 --- a/cmd/publisher/commands/testutil_test.go +++ b/cmd/publisher/commands/testutil_test.go @@ -8,7 +8,6 @@ import ( "path/filepath" "testing" - "github.com/modelcontextprotocol/registry/cmd/publisher/commands" "github.com/modelcontextprotocol/registry/internal/validators" apiv0 "github.com/modelcontextprotocol/registry/pkg/api/v0" "github.com/stretchr/testify/require" @@ -64,14 +63,19 @@ func SetupMockRegistryServer(t *testing.T, publishHandler func(w http.ResponseWr return server } -// SetupTestToken creates a token file pointing to the test server +// SetupTestToken creates a token file pointing to the test server. +// It overrides $HOME to a temp directory so tests don't touch real credentials. func SetupTestToken(t *testing.T, registryURL, token string) string { t.Helper() - homeDir, err := os.UserHomeDir() - require.NoError(t, err) + // Override $HOME so tokenFilePath() resolves to a temp directory + tempHome := t.TempDir() + t.Setenv("HOME", tempHome) - tokenPath := filepath.Join(homeDir, commands.TokenFileName) + dir := filepath.Join(tempHome, ".config", "mcp-publisher") + require.NoError(t, os.MkdirAll(dir, 0700)) + + tokenPath := filepath.Join(dir, "token.json") tokenData := map[string]string{ "token": token, "registry": registryURL, @@ -83,10 +87,6 @@ func SetupTestToken(t *testing.T, registryURL, token string) string { err = os.WriteFile(tokenPath, data, 0600) require.NoError(t, err) - t.Cleanup(func() { - _ = os.Remove(tokenPath) - }) - return tokenPath } diff --git a/cmd/publisher/commands/validate.go b/cmd/publisher/commands/validate.go index b68c2b4..1e360ae 100644 --- a/cmd/publisher/commands/validate.go +++ b/cmd/publisher/commands/validate.go @@ -8,7 +8,6 @@ import ( "io" "net/http" "os" - "path/filepath" "strings" "github.com/modelcontextprotocol/registry/internal/validators" @@ -151,19 +150,15 @@ func ValidateCommand(args []string) error { } // Get registry URL (same pattern as publish) - homeDir, err := os.UserHomeDir() - if err != nil { - return fmt.Errorf("failed to get home directory: %w", err) - } - - tokenPath := filepath.Join(homeDir, TokenFileName) registryURL := DefaultRegistryURL // Try to read registry URL from token file (if it exists) - if tokenData, err := os.ReadFile(tokenPath); err == nil { - var tokenInfo map[string]string - if err := json.Unmarshal(tokenData, &tokenInfo); err == nil { - if url := tokenInfo["registry"]; url != "" { - registryURL = url + if tokenPath, err := tokenFilePath(); err == nil { + if tokenData, err := os.ReadFile(tokenPath); err == nil { + var tokenInfo map[string]string + if err := json.Unmarshal(tokenData, &tokenInfo); err == nil { + if url := tokenInfo["registry"]; url != "" { + registryURL = url + } } } } diff --git a/complete.md b/complete.md index 045e797..2355e4b 100644 --- a/complete.md +++ b/complete.md @@ -2027,21 +2027,24 @@ mcp-publisher logout ``` **Behavior:** -- Removes `~/.mcp_publisher_token` +- Removes `~/.config/mcp-publisher/token.json` +- Also cleans up legacy token files (`~/.mcp_publisher_token`, `.mcpregistry_*`) - Does not revoke tokens on server side ## Configuration ### Token Storage -Authentication tokens stored in `~/.mcp_publisher_token` as JSON: +Authentication tokens are stored in `~/.config/mcp-publisher/token.json` as JSON: ```json { "token": "jwt-token-here", - "registry_url": "https://registry.modelcontextprotocol.io", - "expires_at": "2024-12-31T23:59:59Z" + "method": "github", + "registry": "https://registry.modelcontextprotocol.io" } ``` +> **Note:** Tokens were previously stored in `~/.mcp_publisher_token`. If you are upgrading, run `mcp-publisher logout` followed by `mcp-publisher login` to migrate to the new location. + --- ## File: docs/reference/faq.md diff --git a/docs/reference/cli/commands.md b/docs/reference/cli/commands.md index 4d7d71a..0f44b7b 100644 --- a/docs/reference/cli/commands.md +++ b/docs/reference/cli/commands.md @@ -331,17 +331,20 @@ mcp-publisher logout ``` **Behavior:** -- Removes `~/.mcp_publisher_token` +- Removes `~/.config/mcp-publisher/token.json` +- Also cleans up legacy token files (`~/.mcp_publisher_token`, `.mcpregistry_*`) - Does not revoke tokens on server side ## Configuration ### Token Storage -Authentication tokens stored in `~/.mcp_publisher_token` as JSON: +Authentication tokens are stored in `~/.config/mcp-publisher/token.json` as JSON: ```json { "token": "jwt-token-here", - "registry_url": "https://registry.modelcontextprotocol.io", - "expires_at": "2024-12-31T23:59:59Z" + "method": "github", + "registry": "https://registry.modelcontextprotocol.io" } ``` + +> **Note:** Tokens were previously stored in `~/.mcp_publisher_token`. If you are upgrading, run `mcp-publisher logout` followed by `mcp-publisher login` to migrate to the new location. diff --git a/tests/integration/main.go b/tests/integration/main.go index 889780f..4187ccf 100644 --- a/tests/integration/main.go +++ b/tests/integration/main.go @@ -70,8 +70,15 @@ func cleanupPublisherAuth() { if err != nil { return } - tokenPath := filepath.Join(homeDir, ".mcp_publisher_token") - os.Remove(tokenPath) + // Remove from new config directory location + newTokenPath := filepath.Join(homeDir, ".config", "mcp-publisher", "token.json") + os.Remove(newTokenPath) + // Also remove from legacy location + legacyTokenPath := filepath.Join(homeDir, ".mcp_publisher_token") + os.Remove(legacyTokenPath) + // Clean up legacy intermediate token files from cwd + os.Remove(".mcpregistry_github_token") + os.Remove(".mcpregistry_registry_token") } func publish(examples []example) error { From 8df5a7711d8f4cac3385601181568a1cb608d73c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yusufhan=20Sa=C3=A7ak?= <67666222+JosephDoUrden@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:16:23 +0300 Subject: [PATCH 034/190] fix(publisher): omit repository when URL cannot be detected (#1149) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary When `detectRepoURL()` cannot determine the repository (no git remote, no package.json repository field), return an empty string instead of a placeholder URL (`https://github.com/YOUR_USERNAME/YOUR_REPO`). This causes `createServerJSON()` to omit the `repository` field entirely, preventing schema validation failures on publish. Fixes #613 ## Problem `mcp-publisher init` generated a `repository` object with a placeholder URL that fails the `uri` format validation on publish. 88 published servers in the official registry had this issue. ## Change - `cmd/publisher/commands/init.go`: `detectRepoURL()` returns `""` instead of placeholder when no repo is found - The existing guard in `createServerJSON()` (`if repoURL != "" && repoSource != ""`) already handles this correctly — it omits the repository when URL is empty ## Test plan - [x] `go build ./cmd/publisher/...` compiles - [x] `go test ./cmd/publisher/commands/...` passes - [ ] Manual: `mcp-publisher init` in a directory without git remote or package.json repo — verify no `repository` field in generated server.json - [ ] Manual: `mcp-publisher init` in a git repo — verify `repository` is populated correctly ## AI Disclosure AI assistance (Claude) was used for issue research. The implementation was written and reviewed by the author. --- cmd/publisher/commands/init.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/publisher/commands/init.go b/cmd/publisher/commands/init.go index 27cb664..8d0b505 100644 --- a/cmd/publisher/commands/init.go +++ b/cmd/publisher/commands/init.go @@ -246,7 +246,7 @@ func detectRepoURL() string { } } - return "https://github.com/YOUR_USERNAME/YOUR_REPO" + return "" } func detectPackageType() string { From 70b5f457c8866981e1a12a8e24acadf979e21529 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Wed, 15 Apr 2026 10:28:33 -0400 Subject: [PATCH 035/190] deploy: update prod to v1.6.0 (#1172) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Bumps production image tag from `1.5.0` to `1.6.0` in `deploy/Pulumi.gcpProd.yaml` - Corresponds to the [v1.6.0 release](https://github.com/modelcontextprotocol/registry/releases/tag/v1.6.0) ## Test plan - [ ] Verify Pulumi preview shows only the image tag change - [ ] Deploy and confirm the service is healthy 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index 0aac0d7..630f8a2 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.5.0 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.6.0 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From b6ab23cdea8e9dd918ad7486c042ce775f1464ea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 05:02:23 -0400 Subject: [PATCH 036/190] build(deps): bump goreleaser/goreleaser-action from 7.0.0 to 7.1.0 in the actions group (#1189) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the actions group with 1 update: [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action). Updates `goreleaser/goreleaser-action` from 7.0.0 to 7.1.0 Release notes
Sourced from goreleaser/goreleaser-action's releases.
v7.1.0
What's Changed
- feat: verify release checksum and cosign signature by
@caarlos0in goreleaser/goreleaser-action#550- docs: document cosign verification in README by
@caarlos0in goreleaser/goreleaser-action#553- docs: Upgrade import GPG action version by
@flecnoin goreleaser/goreleaser-action#547- ci: drop docker-bake in favor of plain npm by
@caarlos0in goreleaser/goreleaser-action#551- ci: add release-major-tag workflow by
@caarlos0in goreleaser/goreleaser-action#552- ci: drop pre-cosign-v3 goreleaser versions from tests by
@caarlos0in goreleaser/goreleaser-action#554- ci(deps): bump the actions group with 2 updates by
@dependabot[bot] in goreleaser/goreleaser-action#543- ci(deps): bump the actions group with 5 updates by
@dependabot[bot] in goreleaser/goreleaser-action#546- chore(deps): bump undici from 6.23.0 to 6.24.1 by
@dependabot[bot] in goreleaser/goreleaser-action#545New Contributors
@flecnomade their first contribution in goreleaser/goreleaser-action#547Full Changelog: https://github.com/goreleaser/goreleaser-action/compare/v7...v7.1.0
Commits
e24998bci: drop pre-cosign-v3 goreleaser versions from tests (#554)be2e8a3docs: document cosign verification in README (#553)5e53f8eci: add release-major-tag workflow (#552)4068afabuild: drop docker-bake in favor of plain npm (#551)213ec80docs: add CONTRIBUTING with pre-commit workflow4b462d3feat: verify release checksum and cosign signature (#550)01cbe07docs: Upgrade import GPG action version (#547)2a473d7ci(deps): bump the actions group with 5 updates (#546)fdcf0b9clean: leftover files from node 22(?)9881cc5fix: use new static URL- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b1f807f..b0e6c1f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: anchore/sbom-action/download-syft@v0.24.0 - name: Run GoReleaser - uses: goreleaser/goreleaser-action@ec59f474b9834571250b370d4735c50f8e2d1e29 + uses: goreleaser/goreleaser-action@e24998b8b67b290c2fa8b7c14fcfa7de2c5c9b8c with: distribution: goreleaser version: v2.12.0 From cc48844ebc49cc4d7b2633e21f07335716ca0044 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 05:02:43 -0400 Subject: [PATCH 037/190] build(deps): bump github.com/jackc/pgx/v5 from 5.9.1 to 5.9.2 (#1188) Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.9.1 to 5.9.2. Changelog
Sourced from github.com/jackc/pgx/v5's changelog.
5.9.2 (April 18, 2026)
Fix SQL Injection via placeholder confusion with dollar quoted string literals (GHSA-j88v-2chj-qfwx)
SQL injection can occur when:
- The non-default simple protocol is used.
- A dollar quoted string literal is used in the SQL query.
- That query contains text that would be would be interpreted outside as a placeholder outside of a string literal.
- The value of that placeholder is controllable by the attacker.
e.g.
attackValue := `$tag$; drop table canary; --` _, err = tx.Exec(ctx, `select $tag$ $1 $tag$, $1`, pgx.QueryExecModeSimpleProtocol, attackValue)This is unlikely to occur outside of a contrived scenario.
Commits
0aeabbcRelease v5.9.260644f8Fix SQL sanitizer bugs with dollar-quoted strings and placeholder overflowa5680bcMerge pull request #2531 from dolmen-go/godoc-add-linkse34e452doc: Add godoc links08c9bb1Fix Stringer types encoded as text instead of numeric value in composite fields96b4dbdRemove unstable testacf88e0Merge pull request #2526 from abrightwell/abrightwell-min-proto2f81f1fUpdatemax_protocol_versionandmin_protocol_versiondefaults- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dccf238..a6d5537 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/danielgtaylor/huma/v2 v2.37.3 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/go-containerregistry v0.21.5 - github.com/jackc/pgx/v5 v5.9.1 + github.com/jackc/pgx/v5 v5.9.2 github.com/prometheus/client_golang v1.23.2 github.com/rs/cors v1.11.1 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 diff --git a/go.sum b/go.sum index 0a61c79..18d07e2 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.9.1 h1:uwrxJXBnx76nyISkhr33kQLlUqjv7et7b9FjCen/tdc= -github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= +github.com/jackc/pgx/v5 v5.9.2 h1:3ZhOzMWnR4yJ+RW1XImIPsD1aNSz4T4fyP7zlQb56hw= +github.com/jackc/pgx/v5 v5.9.2/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/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= From 85c95569a756be3ebad6aff9df8567b6f1d2fc3f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 05:03:01 -0400 Subject: [PATCH 038/190] build(deps): bump github.com/go-git/go-git/v5 from 5.17.2 to 5.18.0 in /deploy (#1180) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.17.2 to 5.18.0. Release notes
Sourced from github.com/go-git/go-git/v5's releases.
v5.18.0
What's Changed
- plumbing: transport/http, Add support for followRedirects policy by
@pjbgfin go-git/go-git#2004Full Changelog: https://github.com/go-git/go-git/compare/v5.17.2...v5.18.0
Commits
ea3e7ecMerge pull request #2004 from go-git/v5-http-hardeningbcd20a9plumbing: transport/http, Add support for followRedirects policy- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/modelcontextprotocol/registry/network/alerts). Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 07de0a8..66bfb92 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -38,7 +38,7 @@ require ( github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.8.0 // indirect - github.com/go-git/go-git/v5 v5.17.2 // indirect + github.com/go-git/go-git/v5 v5.18.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index 418aa21..f6088ef 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -74,8 +74,8 @@ github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDz github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.17.2 h1:B+nkdlxdYrvyFK4GPXVU8w1U+YkbsgciIR7f2sZJ104= -github.com/go-git/go-git/v5 v5.17.2/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo= +github.com/go-git/go-git/v5 v5.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM= +github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo= 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= From 4be2234d3ffbb88f51c2be1d4987b64eb0405e24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 05:03:22 -0400 Subject: [PATCH 039/190] build(deps): bump github.com/pulumi/pulumi-kubernetes/sdk/v4 from 4.28.0 to 4.29.0 in /deploy (#1177) Bumps [github.com/pulumi/pulumi-kubernetes/sdk/v4](https://github.com/pulumi/pulumi-kubernetes) from 4.28.0 to 4.29.0. Release notes
Sourced from github.com/pulumi/pulumi-kubernetes/sdk/v4's releases.
v4.29.0
No release notes provided.
Changelog
Sourced from github.com/pulumi/pulumi-kubernetes/sdk/v4's changelog.
4.29.0 (April 15, 2026)
Fixed
#2926 Use client-side create for new resources instead of server-side apply.
Users may observe stricter errors on some Create operations. Please read carefully.
When a resource already exists in the cluster, the API server now returns an AlreadyExists error instead of silently updating the existing object. This prevents data loss from create-then-delete scenarios (e.g. renaming a Pulumi resource or replacing an explicitly-named resource). A new provider config option
upsertExistingObjects(defaultfalse) restores the previous upsert behavior for users who intentionally adopt existing cluster resources. To manage fields on existing objects without owning their lifecycle, use Patch resources (e.g.NamespacePatch).Added
- #2280 Add
enablePatchForceprovider config option to force SSA patch conflicts on a per-stack basis.Changed
- Upgrade Kubernetes schema and libraries to v1.35.3.
Commits
6a98f51Update GitHub Actions workflows. (#4283)677360aFix race condition in istio test (#4282)f3ebf58Prepare for v4.29.0 release (#4280)0d18fe4Use client-side create to prevent silent upsert of existing objects (#4278)8296942Update GitHub Actions workflows. (#4279)9d2f6f8Update module helm.sh/helm/v3 to v3.20.2 [SECURITY] (#4277)7d8fe4dMigrate Windows code signing to Azure Trusted Signing (#4274)374a2b2Update GitHub Actions workflows. (#4275)065ada9Update module go.opentelemetry.io/otel/sdk to v1.43.0 [SECURITY] (#4271)c2f6707Update module github.com/go-jose/go-jose/v3 to v3.0.5 [SECURITY] (#4268)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 31 ++++++++++++------------- deploy/go.sum | 64 +++++++++++++++++++++++++-------------------------- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 66bfb92..f473ce2 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -4,7 +4,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 - github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.28.0 + github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0 github.com/pulumi/pulumi/sdk/v3 v3.230.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -23,7 +23,7 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/charmbracelet/bubbles v1.0.0 // indirect github.com/charmbracelet/bubbletea v1.3.10 // indirect - github.com/charmbracelet/colorprofile v0.4.2 // indirect + github.com/charmbracelet/colorprofile v0.4.3 // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect github.com/charmbracelet/x/ansi v0.11.6 // indirect github.com/charmbracelet/x/cellbuf v0.0.15 // indirect @@ -59,7 +59,7 @@ require ( github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.21 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -83,7 +83,6 @@ require ( github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/stretchr/objx v0.2.0 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect @@ -94,25 +93,25 @@ require ( go.opentelemetry.io/collector/featuregate v1.53.0 // indirect go.opentelemetry.io/collector/pdata v1.53.0 // indirect go.opentelemetry.io/otel v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect go.opentelemetry.io/otel/metric v1.43.0 // indirect go.opentelemetry.io/otel/sdk v1.43.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect - go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.48.0 // indirect + golang.org/x/crypto v0.49.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.32.0 // indirect - golang.org/x/net v0.51.0 // indirect - golang.org/x/sync v0.19.0 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.42.0 // indirect - golang.org/x/term v0.40.0 // indirect - golang.org/x/text v0.34.0 // indirect - golang.org/x/tools v0.41.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect + golang.org/x/term v0.41.0 // indirect + golang.org/x/text v0.35.0 // indirect + golang.org/x/tools v0.42.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260311181403-84a4fc48630c // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c // indirect google.golang.org/grpc v1.80.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index f6088ef..341e958 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -31,8 +31,8 @@ github.com/charmbracelet/bubbles v1.0.0 h1:12J8/ak/uCZEMQ6KU7pcfwceyjLlWsDLAxB5f github.com/charmbracelet/bubbles v1.0.0/go.mod h1:9d/Zd5GdnauMI5ivUIVisuEm3ave1XwXtD1ckyV6r3E= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= -github.com/charmbracelet/colorprofile v0.4.2 h1:BdSNuMjRbotnxHSfxy+PCSa4xAmz7szw70ktAtWRYrY= -github.com/charmbracelet/colorprofile v0.4.2/go.mod h1:0rTi81QpwDElInthtrQ6Ni7cG0sDtwAd4C4le060fT8= +github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q= +github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= @@ -140,8 +140,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.20 h1:WcT52H91ZUAwy8+HUkdM3THM6gXqXuLJi9O3rjcQQaQ= -github.com/mattn/go-runewidth v0.0.20/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w= +github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= @@ -183,8 +183,8 @@ github.com/pulumi/esc v0.17.0 h1:oaVOIyFTENlYDuqc3pW75lQT9jb2cd6ie/4/Twxn66w= github.com/pulumi/esc v0.17.0/go.mod h1:XnSxlt5NkmuAj304l/gK4pRErFbtqq6XpfX1tYT9Jbc= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9FjWCUBCq6U= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= -github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.28.0 h1:muCE6cUJ4YmAaNLiOhbjEicxT+10i/EGsZrx2ZZQQ+o= -github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.28.0/go.mod h1:B998wofejDKAvvpLwsi4UMfWDFHHBnzYiM8mZ9e7OSo= +github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0 h1:NHikF7fXARV//HEwK8wW8kBq+8TGf1pzSV1O946AXDY= +github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= github.com/pulumi/pulumi/sdk/v3 v3.230.0 h1:0TtF82Hlor39DLU0QtM7RZPwRaOmjn5UtQKPi1Mxo9M= github.com/pulumi/pulumi/sdk/v3 v3.230.0/go.mod h1:u0fgmmPGwV5b4rmfuNABuYfRoqckuaTivufPn4EtfTk= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= @@ -207,8 +207,8 @@ github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -239,10 +239,10 @@ go.opentelemetry.io/collector/pdata v1.53.0 h1:DlYDbRwammEZaxDZHINx5v0n8SEOVNniP go.opentelemetry.io/collector/pdata v1.53.0/go.mod h1:LRSYGNjKXaUrZEwZv3Yl+8/zV2HmRGKXW62zB2bysms= go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 h1:mq/Qcf28TWz719lE3/hMB4KkyDuLJIvgJnFGcd0kEUI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0/go.mod h1:yk5LXEYhsL2htyDNJbEq7fWzNEigeEdV5xBF/Y+kAv0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= @@ -251,8 +251,8 @@ go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfC go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= -go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +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/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= @@ -270,29 +270,29 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -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.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -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.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -310,31 +310,31 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= +golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -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.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4= -google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng= -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/api v0.0.0-20260311181403-84a4fc48630c h1:OyQPd6I3pN/9gDxz6L13kYGJgqkpdrAohJRBeXyxlgI= +google.golang.org/genproto/googleapis/api v0.0.0-20260311181403-84a4fc48630c/go.mod h1:X2gu9Qwng7Nn009s/r3RUxqkzQNqOrAy79bluY7ojIg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c h1:xgCzyF2LFIO/0X2UAoVRiXKU5Xg6VjToG4i2/ecSswk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= From fa450110e47d2f6a1e789da6f7f87b928fbaa417 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Apr 2026 09:06:55 +0000 Subject: [PATCH 040/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.230.0 to 3.231.0 in /deploy (#1176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [//]: # (dependabot-start) ⚠️ **Dependabot is rebasing this PR** ⚠️ Rebasing might not happen immediately, so don't worry if this takes some time. Note: if you make any changes to this PR yourself, they will take precedence over the rebase. --- [//]: # (dependabot-end) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.230.0 to 3.231.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.231.0
3.231.0 (2026-04-16)
Features
[cli] Auto-detect Mercurial repository metadata for
pulumi up/pulumi previewupdates, mirroring existing Git support #22618[engine] Send Cancel RPC to plugins on host close for graceful shutdown #22569
[engine] Pass resource options to hooks through the engine #22582
[engine] Add GetDeploymentInfo to the resource monitor service
[auto/go] Add
Newcommand to Automation API #22439[auto/{go,nodejs,python}] Add --diff to automation api for destroy #22563
[auto/python] Add
newcommand to Automation API #22439[pcl] Support for resource hooks in PCL #22365
[sdk-nodejs] Warn when a non-ComponentResource class is passed in the explicit
componentslist tocomponentProviderHost#22619[sdk-python] Warn when a non-ComponentResource class is passed in the explicit
componentslist tocomponent_provider_host#22619[cli/import] Add support for providers to be defined in the same import file as their users #21671
[cli/policy] ESC environment support for local policy packs #22495
[sdk/nodejs] Support package.yaml when using pnpm #22491
[sdk/python] Add function decorator variants for resource and error hooks #22519
Bug Fixes
... (truncated)
Changelog
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.231.0 (2026-04-16)
Features
[cli] Auto-detect Mercurial repository metadata for
pulumi up/pulumi previewupdates, mirroring existing Git support #22618[engine] Send Cancel RPC to plugins on host close for graceful shutdown #22569
[engine] Pass resource options to hooks through the engine #22582
[engine] Add GetDeploymentInfo to the resource monitor service
[auto/go] Add
Newcommand to Automation API #22439[auto/{go,nodejs,python}] Add --diff to automation api for destroy #22563
[auto/python] Add
newcommand to Automation API #22439[pcl] Support for resource hooks in PCL #22365
[sdk-nodejs] Warn when a non-ComponentResource class is passed in the explicit
componentslist tocomponentProviderHost#22619[sdk-python] Warn when a non-ComponentResource class is passed in the explicit
componentslist tocomponent_provider_host#22619[cli/import] Add support for providers to be defined in the same import file as their users #21671
[cli/policy] ESC environment support for local policy packs #22495
[sdk/nodejs] Support package.yaml when using pnpm #22491
[sdk/python] Add function decorator variants for resource and error hooks #22519
Bug Fixes
- [auto/{nodejs,python}] Support --run-program for inline programs with preview_refresh/destroy
... (truncated)
Commits
5aaa649Add GetDeploymentInfo to resource monitor (#22595)e39b399Support --run-program with inline programs for preview_refresh/destroy (#22590)bd4b5dbGo Automation API Codegen #1B: Generating helpers (#22061)b5bb135Python Automation API Codegen: use TypedDict for option types (#22602)5cb5c1dsdk/python: fix 'occured' -> 'occurred' in rpc.py doc comment (#22620)b7c9d87try to stop pkg 7/7 from flaking (#22611)00f5eb9Auto-detect Mercurial VCS metadata for updates (#22618)eff41c5Warn when non-ComponentResource passed to component provider host (#22619)fdbd324Update dependency pulumi/pulumi-java to v1.24.0 (#22615)12c06b9Update dependency pulumi/pulumi-yaml to v1.31.1 (#22610)- Additional commits viewable in compare view
Signed-off-by: dependabot[bot]Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index f473ce2..59b5f95 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0 - github.com/pulumi/pulumi/sdk/v3 v3.230.0 + github.com/pulumi/pulumi/sdk/v3 v3.231.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/deploy/go.sum b/deploy/go.sum index 341e958..b656041 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -185,8 +185,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0 h1:NHikF7fXARV//HEwK8wW8kBq+8TGf1pzSV1O946AXDY= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.230.0 h1:0TtF82Hlor39DLU0QtM7RZPwRaOmjn5UtQKPi1Mxo9M= -github.com/pulumi/pulumi/sdk/v3 v3.230.0/go.mod h1:u0fgmmPGwV5b4rmfuNABuYfRoqckuaTivufPn4EtfTk= +github.com/pulumi/pulumi/sdk/v3 v3.231.0 h1:iAulagysgpFd3l2k3B2fsNtvcEy1ruOkyi++vwVQE2w= +github.com/pulumi/pulumi/sdk/v3 v3.231.0/go.mod h1:l5TYGBUlKrkq3z/SbmTGIUD6JrzyRtPWI3wKZA+IXeo= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From d8a1ea4e58a410a4c2e0f4a9150622b8b051699e Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 24 Apr 2026 00:15:43 +0200 Subject: [PATCH 041/190] fix: update openapi.yml to include statusChangedAt (#1187) Fixes #1169 Update the openapi.yml to add a missing field ## Motivation and Context openapi.yml was not in sync with live data ## How Has This Been Tested? Validated the openapi.yml file ## Breaking Changes No ## Types of changes - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed ## Additional context Signed-off-by: Jeff MAURY Co-authored-by: Radoslav Dimitrov --- docs/reference/api/openapi.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/reference/api/openapi.yaml b/docs/reference/api/openapi.yaml index 947ab24..faf8895 100644 --- a/docs/reference/api/openapi.yaml +++ b/docs/reference/api/openapi.yaml @@ -1039,6 +1039,11 @@ components: description: Optional message explaining the status (e.g., deprecation reason) example: "Please upgrade to version 2.0.0" maxLength: 500 + statusChangedAt: + type: string + format: date-time + description: Timestamp when the server status was last updated + example: "2023-12-01T10:30:00Z" publishedAt: type: string format: date-time From dac0982f6db8f391485d22f514e348cb8b86ea5a Mon Sep 17 00:00:00 2001 From: Ashwanthram K L <71945723+AshwanthramKL@users.noreply.github.com> Date: Fri, 24 Apr 2026 03:51:21 +0530 Subject: [PATCH 042/190] docs: signpost non-npm publishers to package-types from quickstart (#1192) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What Two targeted additions to `docs/modelcontextprotocol-io/quickstart.mdx`: 1. A ` ` immediately after the tutorial's intro, telling PyPI / NuGet / OCI / MCPB publishers that the Step 1 ownership-verification mechanism differs for their package type and pointing them to [Package Types](./package-types) before continuing. 2. The troubleshooting row for **"Registry validation failed for package"** previously named only npm's `mcpName` property in `package.json`. It now names all three current mechanisms (npm → `mcpName` in `package.json`; PyPI / NuGet → `mcp-name: ` line in the package README; other types → link to Package Types). +5 / -1 lines. ## Why The quickstart is the landing page for new publishers, but it's entirely TypeScript / npm-flavored — the Step 1 example shows npm's `mcpName` property and nothing else. The cross-reference to `./package-types` only appears in the "Next Steps" footer, by which point a PyPI publisher has already gone through every step and hit a `400 Bad Request` at `mcp-publisher publish`: > `registry validation failed for package 0 ( ): PyPI package ' ' ownership validation failed. The server name 'io.github. / ' must appear as 'mcp-name: io.github. / ' in the package README` That specific error has tripped at least one other publisher (#531) and was what motivated this change. The ownership mechanism is correctly documented at `./package-types` — the fix is purely to route people there before they publish, not to duplicate the content. ## What this change is **not** - It does not propose changing the validation logic. - It does not duplicate content from `package-types.mdx` into the quickstart. - It does not add a separate PyPI-specific tutorial. The existing npm-flavored tutorial remains the canonical one; the note just tells non-npm readers which step is different. ## Verification - Change is docs-only; no build or test impact. - Link target `./package-types` is the same shape as the one already used in "Next Steps" of the same file. - Anchor `#step-1-add-verification-information-to-the-package` matches the existing heading's slug. ## Related - #531 — same validation error hit by another PyPI publisher; closed with a workaround but the quickstart wasn't updated. --- docs/modelcontextprotocol-io/quickstart.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/modelcontextprotocol-io/quickstart.mdx b/docs/modelcontextprotocol-io/quickstart.mdx index b33fc17..41bc8fc 100644 --- a/docs/modelcontextprotocol-io/quickstart.mdx +++ b/docs/modelcontextprotocol-io/quickstart.mdx @@ -9,6 +9,10 @@ sidebarTitle: "Quickstart: Publish a Server" This tutorial will show you how to publish an MCP server written in TypeScript to the MCP Registry using the official `mcp-publisher` CLI tool. + + If you are publishing a non-npm package (PyPI, NuGet, OCI, MCPB), the overall flow is identical, but the ownership-verification step in [Step 1](#step-1-add-verification-information-to-the-package) is different per package type. See [Package Types](./package-types) for the verification mechanism that applies to your package, then return here and follow the remaining steps. + + ## Prerequisites - **Node.js** — This tutorial assumes the MCP server is written in TypeScript. @@ -279,7 +283,7 @@ You should see your server's metadata in the search results JSON: | Error Message | Action | | --- | --- | -|"Registry validation failed for package"|Ensure your package includes the required validation information (e.g, `mcpName` property in `package.json`).| +|"Registry validation failed for package"|Ensure your package includes the required ownership-verification marker for its package type. For npm this is `mcpName` in `package.json`; for PyPI and NuGet it is an `mcp-name:` line (or HTML comment) in the package README; for other types see [Package Types](./package-types).| |"Invalid or expired Registry JWT token"|Re-authenticate by running `mcp-publisher login github`.| |"You do not have permission to publish this server"|Your authentication method doesn't match your server's namespace format. With GitHub auth, your server name must start with `io.github.your-username/`.| From 35b124379b915a0a0d0ce6ca99019cdcbdd97e97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 04:54:09 -0400 Subject: [PATCH 043/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.231.0 to 3.232.0 in /deploy (#1194) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.231.0 to 3.232.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.232.0
3.232.0 (2026-04-22)
Features
[cli] Add an experimental
pulumi neocommand that creates a Pulumi Neo agent task in CLI tool-execution mode and runs the local tool loop. Filesystem and shell tool calls issued by the agent run on the user's machine in their working directory; the interactive chat continues to happen in the Pulumi Console at the URL the command prints. Hidden behind PULUMI_EXPERIMENTAL.[cli] Add support for handling user approval requests in the
pulumi neoterminal UI. When the agent requests confirmation for a sensitive action, the TUI prompts the user and forwards their response back to the Pulumi Console. Hidden behind PULUMI_EXPERIMENTAL.[cli] Add an interactive terminal UI for
pulumi neobuilt with bubbletea, rendering agent messages, tool calls, and streaming output in the terminal alongside the Pulumi Console session. Hidden behind PULUMI_EXPERIMENTAL.[cli] Switch logging library from glog to slog.
BREAKING: any
if logging.V(x) {need to be changed toif logging.V(x).Enabled()
[cli] Add a plan-mode toggle to the
pulumi neoTUI, bound to Shift+Tab. When plan mode is on, Neo explores and asks questions without writing files, runningpulumi up, or opening PRs, and surfaces an approved plan via a dedicated approval gate. The toggle must be set before the first message (plan mode is task-level on the wire); approving the proposed plan exits plan mode automatically.[cli] The
pulumi neoTUI now drives its "thinking" spinner off a single declarative rule (the spinner stays on until a final event — final assistant message, approval request, cancellation, or error — lands), so the indicator no longer flickers off when the agent hands off tool calls to the CLI or when streaming text arrives between tools. PressEscduring a turn to ask the agent to cancel; the label switches to "Cancelling..." until the backend acknowledges.... (truncated)
Changelog
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.232.0 (2026-04-22)
Features
[cli] Add an experimental
pulumi neocommand that creates a Pulumi Neo agent task in CLI tool-execution mode and runs the local tool loop. Filesystem and shell tool calls issued by the agent run on the user's machine in their working directory; the interactive chat continues to happen in the Pulumi Console at the URL the command prints. Hidden behind PULUMI_EXPERIMENTAL.[cli] Add support for handling user approval requests in the
pulumi neoterminal UI. When the agent requests confirmation for a sensitive action, the TUI prompts the user and forwards their response back to the Pulumi Console. Hidden behind PULUMI_EXPERIMENTAL.[cli] Add an interactive terminal UI for
pulumi neobuilt with bubbletea, rendering agent messages, tool calls, and streaming output in the terminal alongside the Pulumi Console session. Hidden behind PULUMI_EXPERIMENTAL.[cli] Switch logging library from glog to slog.
BREAKING: any
if logging.V(x) {need to be changed toif logging.V(x).Enabled()
[cli] Add a plan-mode toggle to the
pulumi neoTUI, bound to Shift+Tab. When plan mode is on, Neo explores and asks questions without writing files, runningpulumi up, or opening PRs, and surfaces an approved plan via a dedicated approval gate. The toggle must be set before the first message (plan mode is task-level on the wire); approving the proposed plan exits plan mode automatically.[cli] The
pulumi neoTUI now drives its "thinking" spinner off a single declarative rule (the spinner stays on until a final event — final assistant message, approval request, cancellation, or error — lands), so the indicator no longer flickers off when the agent hands off tool calls to the CLI or when streaming text arrives between tools. PressEscduring a turn to ask the agent to cancel; the label switches to "Cancelling..." until the backend acknowledges.... (truncated)
Commits
59d156aAddl2-plain-component& remove test dependencies on AWS (#22470)3efae3eCancel providers before closing them (#22692)448770eAdd l2-id-type test (#22681)cc8a16fgo/auto: use random stack names in TestNestedConfig (#22689)6b5ce00skip signal cancellation tests (#22684)923073cfix[codegen/go]: Use Context.GetOrRegisterPackageRef in generated code (#22170)2608e2cGitignore.claude/scheduled_tasks.lock(#22686)3e387c7chore: typosuccesful->successfulin nodejs run/index.ts (#22685)a850bcbUpdate dependency pulumi/pulumi-java to v1.25.0 (#22673)416fd51replace underlying logging library with slog (#22548)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 3 +-- deploy/go.sum | 10 ++++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 59b5f95..3c86c89 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0 - github.com/pulumi/pulumi/sdk/v3 v3.231.0 + github.com/pulumi/pulumi/sdk/v3 v3.232.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -42,7 +42,6 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.2.5 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index b656041..2c2628b 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -84,8 +84,6 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= -github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -167,8 +165,8 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pgavlin/fx v0.1.6 h1:r9jEg69DhNoCd3Xh0+5mIbdbS3PqWrVWujkY76MFRTU= github.com/pgavlin/fx v0.1.6/go.mod h1:KWZJ6fqBBSh8GxHYqwYCf3rYE7Gp2p0N8tJp8xv9u9M= -github.com/pgavlin/fx/v2 v2.0.10 h1:ggyQ6pB+lEQEbEae48Wh/X221eLOamMD7i01ISe88u4= -github.com/pgavlin/fx/v2 v2.0.10/go.mod h1:M/nF/ooAOy+NUBooYYXl2REARzJ/giPJxfMs8fINfKc= +github.com/pgavlin/fx/v2 v2.0.12 h1:SjjaJ68Dt8Z4zHwOpY/RPijd7lShs6xYupJbF9ra00M= +github.com/pgavlin/fx/v2 v2.0.12/go.mod h1:M/nF/ooAOy+NUBooYYXl2REARzJ/giPJxfMs8fINfKc= github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -185,8 +183,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0 h1:NHikF7fXARV//HEwK8wW8kBq+8TGf1pzSV1O946AXDY= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.231.0 h1:iAulagysgpFd3l2k3B2fsNtvcEy1ruOkyi++vwVQE2w= -github.com/pulumi/pulumi/sdk/v3 v3.231.0/go.mod h1:l5TYGBUlKrkq3z/SbmTGIUD6JrzyRtPWI3wKZA+IXeo= +github.com/pulumi/pulumi/sdk/v3 v3.232.0 h1:pU9j5qYHYtYZGaIKha1KFuB9ggp2obcMD1U523tpEnk= +github.com/pulumi/pulumi/sdk/v3 v3.232.0/go.mod h1:33NoTpvQXlTtAuaPbompgZNA3Ye4XEvxNydELFlWza8= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From a1a3303af92a666538f4525b7a3c7785aa53a37b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yusufhan=20Sa=C3=A7ak?= <67666222+JosephDoUrden@users.noreply.github.com> Date: Fri, 24 Apr 2026 12:47:24 +0300 Subject: [PATCH 044/190] feat(publisher): copy version from package.json and prefer mcpName in init (#1145) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Addresses two related enhancements to `mcp-publisher init`: - **Copy `version` from `package.json`** (#736): When `package.json` is present and contains a `version` field, it is now used for both the top-level `version` and `packages[].version` in the generated `server.json`. Falls back to `"1.0.0"` when unavailable. This aligns with the recommended best practice of keeping server version in sync with package version. - **Prefer `mcpName` over `name`** (#737): The init command now checks for `mcpName` in `package.json` first, falling back to `name` if `mcpName` is not defined. This ensures the generated server name matches the required `mcpName` property. Closes #736 Closes #737 ## Changes - `cmd/publisher/commands/init.go`: - Added `getVersionFromPackageJSON()` helper to read version from `package.json` - Modified `InitCommand()` to use detected version with `"1.0.0"` fallback - Modified `getNameFromPackageJSON()` to prefer `mcpName` over `name` ## Test plan - [x] `go build ./cmd/publisher/...` compiles without errors - [x] `go test ./cmd/publisher/commands/...` passes all existing tests - [ ] Manual: run `mcp-publisher init` in a directory with `package.json` containing `version` and `mcpName` — verify both are copied to `server.json` - [ ] Manual: run `mcp-publisher init` in a directory with `package.json` without `mcpName` — verify `name` is used as fallback - [ ] Manual: run `mcp-publisher init` in a directory without `package.json` — verify defaults (`"1.0.0"`, directory name) are used ## AI Disclosure AI assistance (Claude) was used for initial code exploration and issue research. The implementation was written and reviewed by the author. Co-authored-by: Radoslav Dimitrov --- cmd/publisher/commands/init.go | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/cmd/publisher/commands/init.go b/cmd/publisher/commands/init.go index 8d0b505..8e645f5 100644 --- a/cmd/publisher/commands/init.go +++ b/cmd/publisher/commands/init.go @@ -27,7 +27,10 @@ func InitCommand() error { // Try to detect values from environment name := detectServerName(subfolder) description := detectDescription() - version := "1.0.0" + version := getVersionFromPackageJSON() + if version == "" { + version = "1.0.0" + } repoURL := detectRepoURL() repoSource := MethodGitHub if repoURL != "" && !strings.Contains(repoURL, "github.com") { @@ -140,9 +143,13 @@ func getNameFromPackageJSON() string { return "" } - name, ok := pkg["name"].(string) + // Prefer mcpName over name, as the server name must match mcpName + name, ok := pkg["mcpName"].(string) if !ok || name == "" { - return "" + name, ok = pkg["name"].(string) + if !ok || name == "" { + return "" + } } // Convert npm package name to MCP server name @@ -156,6 +163,25 @@ func getNameFromPackageJSON() string { return fmt.Sprintf("io.github. /%s", name) } +func getVersionFromPackageJSON() string { + data, err := os.ReadFile("package.json") + if err != nil { + return "" + } + + var pkg map[string]any + if err := json.Unmarshal(data, &pkg); err != nil { + return "" + } + + version, ok := pkg["version"].(string) + if !ok || version == "" { + return "" + } + + return version +} + func detectServerName(subfolder string) string { // Try to get from git remote repoURL := detectRepoURL() From 7c446e75ad01b4c28746042539884e4109e4d21c Mon Sep 17 00:00:00 2001 From: Mikel Olasagasti Uranga Date: Fri, 24 Apr 2026 12:11:46 +0200 Subject: [PATCH 045/190] feat(oci): add support for Quay.io registry (#1150) Adds support for the Quay.io container registry to the OCI validator. This allows MCP servers hosted on Quay.io to be registered and validated by the official registry. ## Motivation and Context Quay.io is a major, trusted public OCI registry widely used by the cloud-native and open-source communities. Currently, attempting to publish a server using a Quay image results in an unsupported OCI registry error. This change enables developers to use Quay.io as a first-class hosting option for their MCP server images. ## How Has This Been Tested? - **Unit Tests:** Updated `internal/validators/registries/oci_test.go` to transition Quay.io from a rejected test case to an allowed one. - **Pattern Matching:** Verified that the allowlist correctly handles both specific image identifiers and general pattern matching for the `quay.io` host. - **Local Validation:** Ran `make check` to ensure no regressions in the existing OCI validation logic. ## Breaking Changes No. This is an additive change that expands the allowlist of supported registries. Existing configurations are unaffected. ## Types of changes - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [x] Documentation update ## Checklist - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [x] I have added appropriate error handling - [x] I have added or updated documentation as needed ## Additional context The implementation follows the existing pattern for OCI registries: 1. Added a `RegistryURLQuay` constant to `pkg/model` for consistency. 2. Hardcoded `quay.io` into the `allowedOCIRegistries` map in the validator to minimize architectural complexity. 3. Updated all relevant documentation files (`package-types.mdx`, `generic-server-json.md`, and `official-registry-requirements.md`) to ensure the source of truth is updated across the project. 4. Validation remains scoped to public images; no private registry authentication was added for this host. Signed-off-by: Mikel Olasagasti Uranga Co-authored-by: Radoslav Dimitrov --- .../modelcontextprotocol-io/package-types.mdx | 3 ++- .../server-json/generic-server-json.md | 20 ++++++++++++++++ .../official-registry-requirements.md | 1 + internal/validators/registries/oci.go | 3 +++ internal/validators/registries/oci_test.go | 24 ++++++++++++------- pkg/model/constants.go | 7 +++--- tools/validate-examples/main.go | 2 +- 7 files changed, 47 insertions(+), 13 deletions(-) diff --git a/docs/modelcontextprotocol-io/package-types.mdx b/docs/modelcontextprotocol-io/package-types.mdx index 9014302..b7a31b9 100644 --- a/docs/modelcontextprotocol-io/package-types.mdx +++ b/docs/modelcontextprotocol-io/package-types.mdx @@ -131,6 +131,7 @@ For Docker/OCI images, the MCP Registry currently supports: - Docker Hub (`docker.io`) - GitHub Container Registry (`ghcr.io`) +- Quay.io (`quay.io`) - Google Artifact Registry (any `*.pkg.dev` domain) - Azure Container Registry (`*.azurecr.io`) - Microsoft Container Registry (`mcr.microsoft.com`) @@ -156,7 +157,7 @@ Docker/OCI images use `"registryType": "oci"` in `server.json`. For example: } ``` -The format of `identifier` is `registry/namespace/repository:tag`. For example, `docker.io/user/app:1.0.0` or `ghcr.io/user/app:1.0.0`. The tag can also be specified as a digest. +The format of `identifier` is `registry/namespace/repository:tag`. For example, `docker.io/user/app:1.0.0`, `ghcr.io/user/app:1.0.0`, or `quay.io/myorg/my-mcp-server:1.0.0`. The tag can also be specified as a digest. ### Ownership Verification diff --git a/docs/reference/server-json/generic-server-json.md b/docs/reference/server-json/generic-server-json.md index 1b1aff1..bb5cc44 100644 --- a/docs/reference/server-json/generic-server-json.md +++ b/docs/reference/server-json/generic-server-json.md @@ -264,6 +264,26 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp } ``` +The same `registryType` / `identifier` pattern works for other supported OCI hosts. For example, an image on Quay.io: + +```json +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", + "name": "io.github.example/quay-sample-mcp", + "description": "Example MCP server distributed as an OCI image on Quay.io", + "version": "1.0.0", + "packages": [ + { + "registryType": "oci", + "identifier": "quay.io/myorg/my-mcp-server:1.0.0", + "transport": { + "type": "stdio" + } + } + ] +} +``` + ### Remote Server Example ```json diff --git a/docs/reference/server-json/official-registry-requirements.md b/docs/reference/server-json/official-registry-requirements.md index 494458f..ec456cc 100644 --- a/docs/reference/server-json/official-registry-requirements.md +++ b/docs/reference/server-json/official-registry-requirements.md @@ -36,6 +36,7 @@ Only trusted public registries are supported. Private registries and alternative - **Docker/OCI**: - Docker Hub (`docker.io`) - GitHub Container Registry (`ghcr.io`) + - Quay.io (`quay.io`) - Google Artifact Registry (`*.pkg.dev`) - Azure Container Registry (`*.azurecr.io`) - Microsoft Container Registry (`mcr.microsoft.com`) diff --git a/internal/validators/registries/oci.go b/internal/validators/registries/oci.go index 6932d7f..d4ab56c 100644 --- a/internal/validators/registries/oci.go +++ b/internal/validators/registries/oci.go @@ -33,6 +33,8 @@ var allowedOCIRegistries = map[string]bool{ "index.docker.io": true, // Docker Hub index // GitHub Container Registry "ghcr.io": true, + // Red Hat Quay + "quay.io": true, // Microsoft Container Registry "mcr.microsoft.com": true, // Google Artifact Registry (*.pkg.dev pattern handled in isAllowedRegistry) @@ -49,6 +51,7 @@ var allowedOCIRegistries = map[string]bool{ // Supported registries: // - Docker Hub (docker.io) // - GitHub Container Registry (ghcr.io) +// - Quay.io (quay.io) // - Google Artifact Registry (*.pkg.dev) // - Microsoft Container Registry (mcr.microsoft.com) func ValidateOCI(ctx context.Context, pkg model.Package, serverName string) error { diff --git a/internal/validators/registries/oci_test.go b/internal/validators/registries/oci_test.go index 634e2e5..fddf446 100644 --- a/internal/validators/registries/oci_test.go +++ b/internal/validators/registries/oci_test.go @@ -66,6 +66,13 @@ func TestValidateOCI_RegistryAllowlist(t *testing.T) { errorMsg: "missing required annotation", mustNotContainMsg: "unsupported OCI registry", }, + { + name: "Quay.io should be allowed", + identifier: "quay.io/prometheus/node-exporter:v1.7.0", + expectError: true, + errorMsg: "missing required annotation", + mustNotContainMsg: "unsupported OCI registry", + }, // Removed ACR test with non-existent host - ACR support is tested elsewhere // Disallowed registries @@ -75,12 +82,6 @@ func TestValidateOCI_RegistryAllowlist(t *testing.T) { expectError: true, errorMsg: "unsupported OCI registry", }, - { - name: "Quay.io should be rejected", - identifier: "quay.io/test/image:latest", - expectError: true, - errorMsg: "unsupported OCI registry", - }, { name: "ECR Public should be rejected", identifier: "public.ecr.aws/test/image:latest", @@ -134,8 +135,9 @@ func TestValidateOCI_RegistryAllowlist(t *testing.T) { } func TestValidateOCI_RegistryPatterns(t *testing.T) { - // This test verifies registry pattern matching (wildcards like *.azurecr.io and *.pkg.dev) - // without relying on external images that may not exist + // Verifies allowlist behavior: wildcard hosts (*.azurecr.io, *.pkg.dev) and fixed hosts + // like quay.io. shouldFail=false means the error must not be "unsupported OCI registry" + // (validation may still error later, for example missing annotation or image not found). tests := []struct { name string identifier string @@ -156,6 +158,12 @@ func TestValidateOCI_RegistryPatterns(t *testing.T) { identifier: "us-west1-docker.pkg.dev/project/repo/image:tag", shouldFail: false, }, + { + name: "Quay.io host should be allowed", + identifier: "quay.io/nonexistent/mcp-registry-fake-repo:v1", + // Past allowlist; fake repo typically yields "does not exist", not unsupported registry + shouldFail: false, + }, { name: "GCR should be rejected at registry check", identifier: "gcr.io/project/image:latest", diff --git a/pkg/model/constants.go b/pkg/model/constants.go index e817f2a..ead176d 100644 --- a/pkg/model/constants.go +++ b/pkg/model/constants.go @@ -11,11 +11,12 @@ const ( // Registry Base URLs - supported package registry base URLs const ( - RegistryURLNPM = "https://registry.npmjs.org" - RegistryURLPyPI = "https://pypi.org" - RegistryURLNuGet = "https://api.nuget.org/v3/index.json" RegistryURLGitHub = "https://github.com" RegistryURLGitLab = "https://gitlab.com" + RegistryURLNPM = "https://registry.npmjs.org" + RegistryURLNuGet = "https://api.nuget.org/v3/index.json" + RegistryURLPyPI = "https://pypi.org" + RegistryURLQuay = "https://quay.io" ) // Transport Types - supported remote transport protocols diff --git a/tools/validate-examples/main.go b/tools/validate-examples/main.go index 54a7e4b..2f8be56 100644 --- a/tools/validate-examples/main.go +++ b/tools/validate-examples/main.go @@ -33,7 +33,7 @@ func main() { func runValidation() error { // Define what we validate and how - expectedServerJSONCount := 15 + expectedServerJSONCount := 16 targets := []validationTarget{ { path: filepath.Join("docs", "reference", "server-json", "generic-server-json.md"), From aaa634ebb69ffd57643dd5efec6c2aa0575b9e4f Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sat, 25 Apr 2026 10:14:11 -0400 Subject: [PATCH 046/190] fix(publisher): honor mcpName as the authoritative server name in init (#1195) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Follow-up to #1145. When `mcpName` is set in `package.json`, it should be the server name used by `mcp-publisher init`. Two issues addressed: ### 1. `getNameFromPackageJSON` mangled `mcpName` through npm-name transformation `mcpName` values are already in MCP server name format (e.g. `io.github.foo/bar`). The existing code ran them through the `@scope/name → io.github.scope/name` transform and its `io.github. /*` fallback, producing a broken double-prefix result. Example with `"mcpName": "io.github.acme/weather"`: - Before: `io.github. /io.github.acme/weather` ❌ - After: `io.github.acme/weather` ✅ ### 2. `detectServerName` consulted git before `mcpName` Even with `mcpName` set in `package.json`, a github.com git remote (or a `repository` field) silently won — the function returned `io.github. / ` and never looked at `mcpName`. Per the [quickstart docs](https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/quickstart.mdx), *"The value of `mcpName` will be your server's name in the MCP Registry"*, so `mcpName` should take precedence. ## Changes - `cmd/publisher/commands/init.go`: - New `getMcpNameFromPackageJSON()` helper that returns `mcpName` or `""`. - `detectServerName` checks `mcpName` first, before git remote and the `name`-based fallback. - `getNameFromPackageJSON` simplified — the now-redundant `mcpName` branch was removed; it only handles the npm `name` transformation. - `cmd/publisher/commands/init_test.go` (new): 5 cases through the public `InitCommand` API covering `mcpName` as-is, fallback to scoped `name`, fallback to placeholder, version fallback, and `mcpName` winning over a GitHub `repository` URL. This completes the fix for #737. ## Test plan - [x] `go test ./cmd/publisher/commands/` passes (5 new subtests) - [x] `golangci-lint run ./cmd/publisher/commands/` clean - [ ] Manual: `mcp-publisher init` in a git-tracked directory with `package.json` containing `mcpName` produces a `server.json` whose `name` matches `mcpName`, not the repo slug 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- cmd/publisher/commands/init.go | 37 +++++++++--- cmd/publisher/commands/init_test.go | 92 +++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 7 deletions(-) create mode 100644 cmd/publisher/commands/init_test.go diff --git a/cmd/publisher/commands/init.go b/cmd/publisher/commands/init.go index 8e645f5..92d6c8a 100644 --- a/cmd/publisher/commands/init.go +++ b/cmd/publisher/commands/init.go @@ -132,6 +132,26 @@ func detectSubfolder() string { return filepath.ToSlash(relPath) } +// getMcpNameFromPackageJSON returns the `mcpName` field from package.json, or +// "" if not set. mcpName is the authoritative MCP server name when present — +// see docs/modelcontextprotocol-io/quickstart.mdx. +func getMcpNameFromPackageJSON() string { + data, err := os.ReadFile("package.json") + if err != nil { + return "" + } + + var pkg map[string]any + if err := json.Unmarshal(data, &pkg); err != nil { + return "" + } + + if mcpName, ok := pkg["mcpName"].(string); ok && mcpName != "" { + return mcpName + } + return "" +} + func getNameFromPackageJSON() string { data, err := os.ReadFile("package.json") if err != nil { @@ -143,17 +163,13 @@ func getNameFromPackageJSON() string { return "" } - // Prefer mcpName over name, as the server name must match mcpName - name, ok := pkg["mcpName"].(string) + name, ok := pkg["name"].(string) if !ok || name == "" { - name, ok = pkg["name"].(string) - if !ok || name == "" { - return "" - } + return "" } // Convert npm package name to MCP server name - // @org/package -> io.npm.org/package + // @org/package -> io.github.org/package if strings.HasPrefix(name, "@") { parts := strings.Split(name[1:], "/") if len(parts) == 2 { @@ -183,6 +199,13 @@ func getVersionFromPackageJSON() string { } func detectServerName(subfolder string) string { + // mcpName in package.json is the authoritative server name when set, so it + // takes precedence over names inferred from the git remote or the npm + // `name` field. + if name := getMcpNameFromPackageJSON(); name != "" { + return name + } + // Try to get from git remote repoURL := detectRepoURL() if repoURL != "" && strings.Contains(repoURL, "github.com") { diff --git a/cmd/publisher/commands/init_test.go b/cmd/publisher/commands/init_test.go new file mode 100644 index 0000000..e7f3fdb --- /dev/null +++ b/cmd/publisher/commands/init_test.go @@ -0,0 +1,92 @@ +package commands_test + +import ( + "encoding/json" + "os" + "path/filepath" + "testing" + + "github.com/modelcontextprotocol/registry/cmd/publisher/commands" + apiv0 "github.com/modelcontextprotocol/registry/pkg/api/v0" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestInitCommand_PackageJSON(t *testing.T) { + tests := []struct { + name string + pkgJSON string + expectedName string + expectedVersion string + }{ + { + name: "mcpName is returned as-is without transformation", + pkgJSON: `{"name": "@acme/weather", "mcpName": "io.github.acme/weather-mcp", "version": "2.3.4", "repository": "https://gitlab.com/acme/weather"}`, + expectedName: "io.github.acme/weather-mcp", + expectedVersion: "2.3.4", + }, + { + name: "empty mcpName falls back to scoped name transformation", + pkgJSON: `{"name": "@acme/weather", "mcpName": "", "version": "1.2.3", "repository": "https://gitlab.com/acme/weather"}`, + expectedName: "io.github.acme/weather", + expectedVersion: "1.2.3", + }, + { + name: "missing mcpName falls back to scoped name transformation", + pkgJSON: `{"name": "@acme/weather", "version": "1.2.3", "repository": "https://gitlab.com/acme/weather"}`, + expectedName: "io.github.acme/weather", + expectedVersion: "1.2.3", + }, + { + name: "missing version falls back to 1.0.0", + pkgJSON: `{"name": "@acme/weather", "mcpName": "io.github.acme/weather", "repository": "https://gitlab.com/acme/weather"}`, + expectedName: "io.github.acme/weather", + expectedVersion: "1.0.0", + }, + { + name: "mcpName takes precedence over GitHub repository URL", + pkgJSON: `{"name": "weather", "mcpName": "io.github.acme/weather-mcp", "version": "1.0.0", "repository": "https://github.com/someone-else/some-repo"}`, + expectedName: "io.github.acme/weather-mcp", + expectedVersion: "1.0.0", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + dir := withIsolatedPackageJSON(t, tt.pkgJSON) + + require.NoError(t, commands.InitCommand()) + + data, err := os.ReadFile(filepath.Join(dir, "server.json")) + require.NoError(t, err) + + var got apiv0.ServerJSON + require.NoError(t, json.Unmarshal(data, &got)) + + assert.Equal(t, tt.expectedName, got.Name) + assert.Equal(t, tt.expectedVersion, got.Version) + require.Len(t, got.Packages, 1) + assert.Equal(t, tt.expectedVersion, got.Packages[0].Version, + "package version should match server version") + }) + } +} + +// withIsolatedPackageJSON creates a temp dir outside any git repository, +// writes package.json with the given contents, chdirs into it, and returns +// the directory path. The HOME override prevents init from detecting the +// host repo's git state. +func withIsolatedPackageJSON(t *testing.T, contents string) string { + t.Helper() + + dir := t.TempDir() + require.NoError(t, os.WriteFile(filepath.Join(dir, "package.json"), []byte(contents), 0600)) + + originalDir, err := os.Getwd() + require.NoError(t, err) + t.Cleanup(func() { _ = os.Chdir(originalDir) }) + + require.NoError(t, os.Chdir(dir)) + + return dir +} From ccb7057c3314640718b71e813594c9ec28b712f5 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sat, 25 Apr 2026 10:15:00 -0400 Subject: [PATCH 047/190] docs: note PostgreSQL requirement for prebuilt Docker image (#1196) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Clarifies in the README that the prebuilt Docker image does not bundle PostgreSQL and needs an external instance reachable via \`MCP_REGISTRY_DATABASE_URL\` - Points readers to \`docker-compose.yml\` as a working multi-container example Closes #723 ## Test plan - [ ] Render the README on GitHub and verify the note appears in the "Alternative: Running a pre-built Docker image" section 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a456de..cbd9670 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ The setup can be configured with environment variables in [docker-compose.yml](. Alternative: Running a pre-built Docker image
-Pre-built Docker images are automatically published to GitHub Container Registry: +Pre-built Docker images are automatically published to GitHub Container Registry. Note that the image does not bundle PostgreSQL, so you need to run your own and point the registry at it via `MCP_REGISTRY_DATABASE_URL` (see [docker-compose.yml](./docker-compose.yml) for a working example): ```bash # Run latest stable release From 8b893ae1f1e029273b5c70857def8858a7b9852e Mon Sep 17 00:00:00 2001 From: Radoslav DimitrovDate: Sat, 25 Apr 2026 10:15:32 -0400 Subject: [PATCH 048/190] docs: recommend namespaced subkeys inside publisher-provided (#1197) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Adds a short "Recommended: Namespaced Subkeys" subsection to `official-registry-requirements.md`, documenting the reverse-DNS subkey convention for `publisher-provided` metadata with one worked example - Explicitly notes this is not enforced, to avoid churning the ~15 existing flat-key examples elsewhere in the docs Closes #477 ## Test plan - [ ] Render the file on GitHub and verify the new subsection appears right after the `Publisher-Provided Metadata` size-limit note 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- .../official-registry-requirements.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/reference/server-json/official-registry-requirements.md b/docs/reference/server-json/official-registry-requirements.md index ec456cc..e03b659 100644 --- a/docs/reference/server-json/official-registry-requirements.md +++ b/docs/reference/server-json/official-registry-requirements.md @@ -69,6 +69,28 @@ When publishing to the official registry, **only data under the specific key `io **Size limit:** The publisher-provided extension is limited to 4KB (4096 bytes) of JSON. If the marshaled JSON exceeds this limit, publishing will fail with an error indicating the actual size. +#### Recommended: Namespaced Subkeys + +When your `publisher-provided` metadata gets large or comes from multiple sources (e.g. GitHub-specific hints alongside your own CI tool's metadata), grouping keys under reverse-DNS subkeys is a useful convention to avoid accidental collisions: + +```jsonc +{ + "_meta": { + "io.modelcontextprotocol.registry/publisher-provided": { + "com.github": { + "serverDisplayName": "My Server" + }, + "io.example.ci-publisher": { + "tool": "ci-publisher", + "version": "1.0.0" + } + } + } +} +``` + +This is **not enforced**; flat keys work fine for simple cases, and existing examples in this repo use the flat form. Use the namespaced form when organizing metadata from more than one source. + ### Registry API Metadata vs server.json Metadata The `_meta` field in `server.json` is **different** from the `_meta` field returned in registry API responses: From c5f50e817b3dba2da74dd30533e196938e200348 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sat, 25 Apr 2026 11:22:06 -0400 Subject: [PATCH 049/190] fix(auth): better DNS verification errors and wrong-selector hint (#1202) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary DNS auth users have repeatedly hit two failure modes that both produce the same opaque "Ed25519 signature verification failed" error, making them indistinguishable to debug. This PR makes both diagnosable end-to-end without changing the auth protocol or any successful path. The two recurring failure modes: 1. **Wrong placement** — TXT record put under a selector (`_mcp-auth. ` or `_mcp-registry. `) instead of the apex. DKIM-style intuition, but MCP DNS auth uses SPF-style apex placement. See #385 (PR #388 fixed the docs but the failure recurred), #1103, #1126. 2. **Stale apex record** — old TXT record left behind after a key rotation, silently tried first and rejected. ## Changes **`internal/api/handlers/v0/auth/dns.go`** — when the apex has no `v=MCPv1` record, probe `_mcp-auth. ` and `_mcp-registry. ` in parallel (2s individual timeout). If a record is found there, return a targeted error pointing the user at the apex. Costs zero extra DNS work in the success path. **`internal/api/handlers/v0/auth/common.go`** — when verification fails against records that *are* present, include short fingerprints of every key the registry tried (`ed25519:YJLsHFhu`-style 8-char prefix). A new `ErrSignatureMismatch` sentinel keeps structural errors (wrong signature size, unsupported algorithm) passing through unchanged via `errors.Is`, so existing assertions on those messages still hold. **`docs/modelcontextprotocol-io/authentication.mdx`** — anti-pattern ` ` callout in the DNS section explicitly warning against selector placement and stale records. **Tests** — two new tests: - `TestDNSAuthHandler_WrongSelectorProbe` — verifies the probe surfaces records found at `_mcp-auth.` / `_mcp-registry.` and falls through to the standard error when nothing is found anywhere - `TestDNSAuthHandler_StaleKeyFingerprintInError` — verifies the fingerprint hint appears in the failure message for #1126's exact scenario One existing test assertion was updated from a generic `"signature verification failed"` substring to the more specific `"invalid signature size for ECDSA P-384"` it should always have been asserting; the new sentinel-based logic surfaces structural errors verbatim. ## Test plan - [x] `make lint` — clean - [x] `make test-unit` — all auth tests pass (existing + 2 new) - [x] Verified existing single-key and multi-key paths preserve their original (more specific) error messages where they were already specific - [ ] Reviewer to sanity-check the docs callout renders well in the Mintlify theme ## Out of scope The publisher-side preflight DNS check (cross-link in #845) is intentionally **not** in this PR — that belongs in the broader CLI UX work tracked by #845. Refs #845, #385, #1103 Fixes #1126 --------- Co-authored-by: Claude Opus 4.7 (1M context) --- .../authentication.mdx | 6 ++ internal/api/handlers/v0/auth/common.go | 83 ++++++++++++++-- internal/api/handlers/v0/auth/dns.go | 59 +++++++++++ internal/api/handlers/v0/auth/dns_test.go | 99 ++++++++++++++++++- 4 files changed, 236 insertions(+), 11 deletions(-) diff --git a/docs/modelcontextprotocol-io/authentication.mdx b/docs/modelcontextprotocol-io/authentication.mdx index c18268c..f5af3ad 100644 --- a/docs/modelcontextprotocol-io/authentication.mdx +++ b/docs/modelcontextprotocol-io/authentication.mdx @@ -51,6 +51,12 @@ Successfully authenticated! DNS authentication is a domain-based authentication method that relies on a DNS TXT record. + + The TXT record must be placed on the **apex** of your domain (e.g. `example.com`), **not** under a selector like `_mcp-auth.example.com` or `_mcp-registry.example.com`. MCP DNS auth follows SPF-style placement (apex), not DKIM-style (selector). If you put the record under a selector, the registry will not see it and authentication will fail with a generic signature error. + + If you rotate keys, also remember to remove the previous TXT record from the apex — a stale record left behind will be tried first and cause verification to fail. + + To perform DNS authentication using the `mcp-publisher` CLI tool, run the following commands in your server project directory to generate a TXT record based on a public/private key pair:diff --git a/internal/api/handlers/v0/auth/common.go b/internal/api/handlers/v0/auth/common.go index 40a6ba7..2f763d6 100644 --- a/internal/api/handlers/v0/auth/common.go +++ b/internal/api/handlers/v0/auth/common.go @@ -8,6 +8,7 @@ import ( "crypto/sha512" "encoding/base64" "encoding/hex" + "errors" "fmt" "math/big" "regexp" @@ -18,6 +19,17 @@ import ( "github.com/modelcontextprotocol/registry/internal/config" ) +// ErrSignatureMismatch is returned by VerifySignature when the signature is structurally +// valid but does not verify against the public key. Distinguishing this from structural +// failures (wrong size, bad key format) lets the caller add fingerprint hints only when +// the failure is actually a "wrong key" situation. +var ErrSignatureMismatch = errors.New("signature does not match public key") + +// MCPProofRecordPattern matches a well-formed MCPv1 DNS/HTTP proof record: +// "v=MCPv1; k= ; p= ". Shared so callers checking for the +// presence of a valid record see exactly what the parser will accept. +var MCPProofRecordPattern = regexp.MustCompile(`v=MCPv1;\s*k=([^;]+);\s*p=([A-Za-z0-9+/=]+)`) + // CryptoAlgorithm represents the cryptographic algorithm used for a public key type CryptoAlgorithm string @@ -90,18 +102,72 @@ func DecodeAndValidateSignature(signedTimestamp string) ([]byte, error) { } func VerifySignatureWithKeys(publicKeys []PublicKeyInfo, messageBytes []byte, signature []byte) error { + var lastErr error + allMismatch := true for _, publicKeyInfo := range publicKeys { err := publicKeyInfo.VerifySignature(messageBytes, signature) if err == nil { return nil } - - if len(publicKeys) == 1 { - return err + lastErr = err + if !errors.Is(err, ErrSignatureMismatch) { + allMismatch = false } } - return fmt.Errorf("signature verification failed") + // If at least one key failed for a structural reason (wrong size, unsupported algorithm), + // surface that error directly — it's more actionable than a generic "didn't match" message. + if !allMismatch { + return lastErr + } + + // Every key was tried and produced a clean cryptographic mismatch. Include short + // fingerprints of every key that was tried so users can tell which published keys the + // registry actually saw — the most common cause of this error is a stale record left + // behind after a key rotation, which is otherwise indistinguishable from a generic + // crypto failure. + fingerprints := make([]string, 0, len(publicKeys)) + for _, publicKeyInfo := range publicKeys { + fingerprints = append(fingerprints, publicKeyInfo.Fingerprint()) + } + if len(publicKeys) == 1 { + return fmt.Errorf( + "signature verification failed (tried published key %s); "+ + "if this is not the key you are signing with, the published record may be stale", + fingerprints[0], + ) + } + return fmt.Errorf( + "signature verification failed against all %d published keys (tried: %s); "+ + "if you recently rotated keys, remove any stale records from the apex domain", + len(publicKeys), strings.Join(fingerprints, ", "), + ) +} + +// Fingerprint returns a short, human-readable identifier for the public key. +// Format: " : ". Public keys are not secret, +// but truncating keeps error messages readable. +func (pki *PublicKeyInfo) Fingerprint() string { + const prefixLen = 8 + var raw []byte + switch pki.Algorithm { + case AlgorithmEd25519: + if k, ok := pki.Key.(ed25519.PublicKey); ok { + raw = k + } + case AlgorithmECDSAP384: + if k, ok := pki.Key.(ecdsa.PublicKey); ok { + raw = elliptic.MarshalCompressed(k.Curve, k.X, k.Y) //nolint:staticcheck // SA1019: matches the encoding used in DNS records + } + } + if len(raw) == 0 { + return fmt.Sprintf("%s:unknown", pki.Algorithm) + } + encoded := base64.StdEncoding.EncodeToString(raw) + if len(encoded) > prefixLen { + encoded = encoded[:prefixLen] + } + return fmt.Sprintf("%s:%s", pki.Algorithm, encoded) } // VerifySignature verifies a signature using the appropriate algorithm @@ -113,7 +179,7 @@ func (pki *PublicKeyInfo) VerifySignature(message, signature []byte) error { return fmt.Errorf("invalid signature size for Ed25519") } if !ed25519.Verify(ed25519Key, message, signature) { - return fmt.Errorf("Ed25519 signature verification failed") + return fmt.Errorf("Ed25519: %w", ErrSignatureMismatch) } return nil } @@ -126,7 +192,7 @@ func (pki *PublicKeyInfo) VerifySignature(message, signature []byte) error { s := new(big.Int).SetBytes(signature[48:]) digest := sha512.Sum384(message) if !ecdsa.Verify(&ecdsaKey, digest[:], r, s) { - return fmt.Errorf("ECDSA P-384 signature verification failed") + return fmt.Errorf("ECDSA P-384: %w", ErrSignatureMismatch) } return nil } @@ -246,11 +312,8 @@ func ParseMCPKeysFromStrings(inputs []string) []struct { error } - // proof record pattern: v=MCPv1; k= ; p= - cryptoPattern := regexp.MustCompile(`v=MCPv1;\s*k=([^;]+);\s*p=([A-Za-z0-9+/=]+)`) - for _, record := range inputs { - if matches := cryptoPattern.FindStringSubmatch(record); len(matches) == 3 { + if matches := MCPProofRecordPattern.FindStringSubmatch(record); len(matches) == 3 { publicKey, err := ParsePublicKey(matches[1], matches[2]) publicKeys = append(publicKeys, struct { *PublicKeyInfo diff --git a/internal/api/handlers/v0/auth/dns.go b/internal/api/handlers/v0/auth/dns.go index 5129486..cc18082 100644 --- a/internal/api/handlers/v0/auth/dns.go +++ b/internal/api/handlers/v0/auth/dns.go @@ -75,6 +75,11 @@ func RegisterDNSEndpoint(api huma.API, pathPrefix string, cfg *config.Config) { }) } +// commonWrongSelectors lists subdomain prefixes that users frequently mistake for the +// MCP DNS auth record location (DKIM-style intuition). MCP DNS auth uses the apex, +// like SPF — see #385, #1103, #1126 for the recurring confusion. +var commonWrongSelectors = []string{"_mcp-auth", "_mcp-registry"} + // ExchangeToken exchanges DNS signature for a Registry JWT token func (h *DNSAuthHandler) ExchangeToken(ctx context.Context, domain, timestamp, signedTimestamp string) (*auth.TokenResponse, error) { keyFetcher := func(ctx context.Context, domain string) ([]string, error) { @@ -90,9 +95,63 @@ func (h *DNSAuthHandler) ExchangeToken(ctx context.Context, domain, timestamp, s if err != nil { return nil, fmt.Errorf("failed to lookup DNS TXT records: %w", err) } + + if !hasMCPRecord(txtRecords) { + if found := h.findMisplacedSelector(timeoutCtx, domain); found != "" { + return nil, fmt.Errorf( + "no MCPv1 TXT record at %q, but one was found at %q — "+ + "MCP DNS auth requires the record at the apex domain, not under a selector", + domain, found, + ) + } + } + return txtRecords, nil } allowSubdomains := true return h.CoreAuthHandler.ExchangeToken(ctx, domain, timestamp, signedTimestamp, keyFetcher, allowSubdomains, auth.MethodDNS) } + +// hasMCPRecord reports whether any of the supplied TXT records contains a well-formed +// MCPv1 proof record. Uses the same strict pattern as the parser so a malformed +// "v=MCPv1" string at the apex doesn't suppress the misplaced-selector probe. +func hasMCPRecord(records []string) bool { + for _, r := range records { + if MCPProofRecordPattern.MatchString(r) { + return true + } + } + return false +} + +// findMisplacedSelector probes a small fixed set of common wrong selectors and returns the +// first one that holds an MCPv1 record, or "" if none do. Lookups run in parallel with a +// short individual timeout so a slow/missing zone never delays the response by much. +func (h *DNSAuthHandler) findMisplacedSelector(ctx context.Context, domain string) string { + type result struct { + name string + found bool + } + results := make(chan result, len(commonWrongSelectors)) + for _, selector := range commonWrongSelectors { + name := selector + "." + domain + go func(name string) { + lookupCtx, cancel := context.WithTimeout(ctx, 2*time.Second) + defer cancel() + records, err := h.resolver.LookupTXT(lookupCtx, name) + if err != nil { + results <- result{name: name, found: false} + return + } + results <- result{name: name, found: hasMCPRecord(records)} + }(name) + } + for range commonWrongSelectors { + r := <-results + if r.found { + return r.name + } + } + return "" +} diff --git a/internal/api/handlers/v0/auth/dns_test.go b/internal/api/handlers/v0/auth/dns_test.go index f0f3a56..b4895ab 100644 --- a/internal/api/handlers/v0/auth/dns_test.go +++ b/internal/api/handlers/v0/auth/dns_test.go @@ -546,7 +546,7 @@ func TestDNSAuthHandler_ExchangeToken_ECDSAP384(t *testing.T) { timestamp: time.Now().UTC().Format(time.RFC3339), signedTimestamp: "abcdef1234", // too short for ECDSA P-384 expectError: true, - errorContains: "signature verification failed", // general error when trying all keys + errorContains: "invalid signature size for ECDSA P-384", }, { name: "wrong ECDSA P-384 key for signature", @@ -990,3 +990,100 @@ func TestDNSAuthHandler_Mixed_Algorithm_Support(t *testing.T) { assert.NotNil(t, result) }) } + +// TestDNSAuthHandler_WrongSelectorProbe covers the case where the user mistakenly placed +// the MCPv1 TXT record under a selector (e.g. _mcp-auth. ) instead of the apex, +// which has been a recurring source of confusion (#385, #1103, #1126). +func TestDNSAuthHandler_WrongSelectorProbe(t *testing.T) { + cfg := &config.Config{ + JWTPrivateKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + } + + publicKey, _, err := ed25519.GenerateKey(nil) + require.NoError(t, err) + publicKeyB64 := base64.StdEncoding.EncodeToString(publicKey) + mcpRecord := fmt.Sprintf("v=MCPv1; k=ed25519; p=%s", publicKeyB64) + + tests := []struct { + name string + txtRecords map[string][]string + expectInError string + }{ + { + name: "record placed at _mcp-auth selector", + txtRecords: map[string][]string{ + "_mcp-auth." + testDomain: {mcpRecord}, + }, + expectInError: "_mcp-auth." + testDomain, + }, + { + name: "record placed at _mcp-registry selector", + txtRecords: map[string][]string{ + "_mcp-registry." + testDomain: {mcpRecord}, + }, + expectInError: "_mcp-registry." + testDomain, + }, + { + name: "no record anywhere falls through to standard error", + txtRecords: map[string][]string{ + testDomain: {"v=spf1 ~all"}, + }, + expectInError: "no MCP public key found in DNS TXT records", + }, + { + name: "malformed MCPv1 string at apex still triggers selector probe", + txtRecords: map[string][]string{ + // Looks like an MCPv1 record but missing the public key field. + testDomain: {"v=MCPv1; k=ed25519"}, + "_mcp-auth." + testDomain: {mcpRecord}, + }, + expectInError: "_mcp-auth." + testDomain, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + handler := auth.NewDNSAuthHandler(cfg) + handler.SetResolver(&MockDNSResolver{txtRecords: tt.txtRecords}) + + timestamp := time.Now().UTC().Format(time.RFC3339) + _, err := handler.ExchangeToken(context.Background(), testDomain, timestamp, hex.EncodeToString(make([]byte, 64))) + + require.Error(t, err) + assert.Contains(t, err.Error(), tt.expectInError) + }) + } +} + +// TestDNSAuthHandler_StaleKeyFingerprintInError covers #1126: when only one apex record is +// published and it doesn't match the key being signed with (the typical "rotated and forgot +// to update DNS" failure), the error message should include a fingerprint of the published +// key so the user can tell their CLI is signing with a different key than what's published. +func TestDNSAuthHandler_StaleKeyFingerprintInError(t *testing.T) { + cfg := &config.Config{ + JWTPrivateKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + } + + stalePublicKey, _, err := ed25519.GenerateKey(nil) + require.NoError(t, err) + stalePublicKeyB64 := base64.StdEncoding.EncodeToString(stalePublicKey) + + _, currentPrivateKey, err := ed25519.GenerateKey(nil) + require.NoError(t, err) + + handler := auth.NewDNSAuthHandler(cfg) + handler.SetResolver(&MockDNSResolver{ + txtRecords: map[string][]string{ + testDomain: {fmt.Sprintf("v=MCPv1; k=ed25519; p=%s", stalePublicKeyB64)}, + }, + }) + + timestamp := time.Now().UTC().Format(time.RFC3339) + signature := ed25519.Sign(currentPrivateKey, []byte(timestamp)) + _, err = handler.ExchangeToken(context.Background(), testDomain, timestamp, hex.EncodeToString(signature)) + + require.Error(t, err) + expectedFingerprint := "ed25519:" + stalePublicKeyB64[:8] + assert.Contains(t, err.Error(), expectedFingerprint, "error should expose the published key's fingerprint") + assert.Contains(t, err.Error(), "stale", "error should hint at the stale-record cause") +} From 0cb1f6bf521906eeccf84cf7d3faf4e05825b084 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sat, 25 Apr 2026 11:59:28 -0400 Subject: [PATCH 050/190] fix: recalculate isLatest after status changes (#1081) (#1201) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes #1081. When the version flagged `is_latest` was soft-deleted, no other version was promoted, and because `GetCurrentLatestVersion` didn't filter deleted rows, subsequent publishes with a lower semver never became latest — leaving `/v0/servers/{name}/versions/latest` permanently 404. This PR has two parts: ### 1. Code fix — recalculate `is_latest` on every status change - Recalculate `is_latest` after every status mutation (`UpdateServerStatus`, `UpdateAllVersionsStatus`, and the inline status change in `UpdateServer`), in the same transaction that already holds the per-server advisory lock. - Winner selection reuses the existing `CompareVersions` logic: highest non-deleted version gets the flag; if every version is deleted, the highest deleted version keeps it so admin lookups via `includeDeleted=true` still resolve the server (important for restore flows). - New `SetLatestVersion` DB primitive issues two statements (clear old, set new) — `idx_unique_latest_per_server` is a non-deferrable unique partial index, so a single `UPDATE` that flips two rows trips the constraint. ### 2. One-shot migration — heal servers already affected (no manual SQL needed) `014_heal_is_latest.sql` promotes the highest non-deleted version on every server whose `is_latest` flag is on a deleted row (or absent entirely). Picker parses `major.minor.patch` numerically and falls back to `published_at` for non-semver or as a tiebreaker. Heals `io.github.containers/kubernetes-mcp-server` to `0.0.61` automatically and catches any other servers silently affected by the original bug, without hardcoded version numbers. Picker behavior vs. `CompareVersions`: - Standard `M.m.p` semver: matches exactly, including the backport-after-delete case (e.g. published 1.0.1 then 1.0.0 hotfix after deleting 2.0.0 → picks 1.0.1, not 1.0.0). - Non-semver: falls through to `published_at DESC`. Reasonable. - Prereleases (`1.0.0-alpha` vs `1.0.0`): both parse to `(1,0,0)`, tiebreak by `published_at`. Diverges from `CompareVersions` (which always says `1.0.0 > 1.0.0-alpha`). Edge case requires (a) server hit by this bug AND (b) prereleases at the top of the version list. Acceptable; the publisher can flip it with one `mcp-publisher status` call (which now triggers proper recalc thanks to part 1). ## Verification End-to-end curl repro of the exact scenario from the issue, run against both `main` and this branch: **Before (main):** ``` publish 1.0.0 → 200 publish 0.0.59 → 200 PATCH .../1.0.0/status {deleted} → 200 GET /versions/latest → 404 ← bug publish 0.0.60 → 200 GET /versions/latest → 404 ← bug persists, 0.0.60 has isLatest=False ``` **After (this branch):** ``` publish 1.0.0 → 200 publish 0.0.59 → 200 PATCH .../1.0.0/status {deleted} → 200 GET /versions/latest → 200 (0.0.59, isLatest=true) publish 0.0.60 → 200 GET /versions/latest → 200 (0.0.60, isLatest=true) ``` ## Test plan - [x] Service tests covering: soft-delete latest → next highest active promoted; the exact #1081 repro end-to-end through the service; all-versions-deleted still keeps highest addressable for admin; restore-to-higher-version reclaims latest. - [x] Migration tests covering: kubernetes-mcp-server scenario (heals to highest semver); backport scenario (semver beats most-recent-published); no-is_latest-row defensive case; all-deleted server left untouched; healthy server left untouched; non-semver versions fall back to `published_at`. - [x] Full unit test suite (`./internal/... ./cmd/...`) passes against a real Postgres. - [x] `make lint` (0 issues) and `make validate` pass. - [x] Manual curl repro against a running registry confirms the fix resolves the failure mode and `main` still reproduces it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- internal/database/database.go | 4 + .../migrations/014_heal_is_latest.sql | 51 ++++++ internal/database/postgres.go | 34 ++++ internal/database/postgres_test.go | 147 +++++++++++++++++ internal/service/registry_service.go | 80 ++++++++- internal/service/registry_service_test.go | 154 ++++++++++++++++++ 6 files changed, 465 insertions(+), 5 deletions(-) create mode 100644 internal/database/migrations/014_heal_is_latest.sql diff --git a/internal/database/database.go b/internal/database/database.go index c9acf07..b4a797f 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -57,6 +57,10 @@ type Database interface { CheckVersionExists(ctx context.Context, tx pgx.Tx, serverName, version string) (bool, error) // UnmarkAsLatest marks the current latest version of a server as no longer latest UnmarkAsLatest(ctx context.Context, tx pgx.Tx, serverName string) error + // SetLatestVersion sets is_latest=true on the given version and false on all other + // versions of the same server. Passing an empty version clears is_latest for all rows. + // Callers must hold the per-server publish lock to avoid races. + SetLatestVersion(ctx context.Context, tx pgx.Tx, serverName, version string) error // AcquirePublishLock acquires an exclusive advisory lock for publishing a server // This prevents race conditions when multiple versions are published concurrently AcquirePublishLock(ctx context.Context, tx pgx.Tx, serverName string) error diff --git a/internal/database/migrations/014_heal_is_latest.sql b/internal/database/migrations/014_heal_is_latest.sql new file mode 100644 index 0000000..30e860c --- /dev/null +++ b/internal/database/migrations/014_heal_is_latest.sql @@ -0,0 +1,51 @@ +-- Heal servers whose is_latest flag is on a deleted version (or missing entirely) +-- by promoting the highest-semver non-deleted version. Falls back to published_at +-- for non-semver versions and as a tiebreaker for prereleases. +-- See https://github.com/modelcontextprotocol/registry/issues/1081. +-- +-- The migration framework wraps each migration in its own transaction, so no explicit +-- BEGIN/COMMIT here. + +-- Pre-compute the version to promote per affected server. A temp table is used +-- (rather than CTEs) because the two UPDATEs that follow run as separate statements: +-- the unique partial index idx_unique_latest_per_server is non-deferrable and Postgres +-- checks it row-by-row inside a single UPDATE, so the clear and the set must be split. +CREATE TEMP TABLE _heal_picks ON COMMIT DROP AS +WITH broken AS ( + -- Servers where no non-deleted version is flagged is_latest, but at least one + -- non-deleted version exists. Catches "is_latest is on a deleted row" and the + -- defensive case where no row has is_latest at all. + SELECT server_name + FROM servers + GROUP BY server_name + HAVING COUNT(*) FILTER (WHERE is_latest AND status <> 'deleted') = 0 + AND COUNT(*) FILTER (WHERE status <> 'deleted') > 0 +), +parsed AS ( + SELECT s.server_name, s.version, s.published_at, + (regexp_match(s.version, '^(\d+)\.(\d+)\.(\d+)'))[1]::int AS major, + (regexp_match(s.version, '^(\d+)\.(\d+)\.(\d+)'))[2]::int AS minor, + (regexp_match(s.version, '^(\d+)\.(\d+)\.(\d+)'))[3]::int AS patch + FROM servers s + JOIN broken b USING (server_name) + WHERE s.status <> 'deleted' +) +SELECT DISTINCT ON (server_name) server_name, version +FROM parsed +ORDER BY server_name, + major DESC NULLS LAST, + minor DESC NULLS LAST, + patch DESC NULLS LAST, + published_at DESC; + +-- Clear stale is_latest=true on rows of affected servers (typically the deleted row). +UPDATE servers s +SET is_latest = false +WHERE s.server_name IN (SELECT server_name FROM _heal_picks) + AND s.is_latest; + +-- Promote the chosen version. +UPDATE servers s +SET is_latest = true +FROM _heal_picks p +WHERE s.server_name = p.server_name AND s.version = p.version; diff --git a/internal/database/postgres.go b/internal/database/postgres.go index a86e44b..e40359a 100644 --- a/internal/database/postgres.go +++ b/internal/database/postgres.go @@ -877,6 +877,40 @@ func (db *PostgreSQL) UnmarkAsLatest(ctx context.Context, tx pgx.Tx, serverName return nil } +// SetLatestVersion sets is_latest=true on the given version and false on all other versions +// of the same server. Passing an empty version clears is_latest for all rows. +// +// The clear and set are issued as separate statements because the unique partial index +// idx_unique_latest_per_server is non-deferrable and Postgres checks it row-by-row within +// a single UPDATE, which would trip when flipping one row's flag off and another's on. +func (db *PostgreSQL) SetLatestVersion(ctx context.Context, tx pgx.Tx, serverName, version string) error { + if ctx.Err() != nil { + return ctx.Err() + } + + executor := db.getExecutor(tx) + + if _, err := executor.Exec(ctx, + `UPDATE servers SET is_latest = false WHERE server_name = $1 AND is_latest = true AND version <> $2`, + serverName, version, + ); err != nil { + return fmt.Errorf("failed to clear previous latest version: %w", err) + } + + if version == "" { + return nil + } + + if _, err := executor.Exec(ctx, + `UPDATE servers SET is_latest = true WHERE server_name = $1 AND version = $2 AND is_latest = false`, + serverName, version, + ); err != nil { + return fmt.Errorf("failed to set latest version: %w", err) + } + + return nil +} + // Close closes the database connection func (db *PostgreSQL) Close() error { db.pool.Close() diff --git a/internal/database/postgres_test.go b/internal/database/postgres_test.go index 9b6a5da..d0e4b97 100644 --- a/internal/database/postgres_test.go +++ b/internal/database/postgres_test.go @@ -3,6 +3,7 @@ package database_test import ( "context" "fmt" + "os" "testing" "time" @@ -1734,6 +1735,152 @@ func TestPostgreSQL_IncludeDeletedFilter(t *testing.T) { }) } +// TestMigration014_HealIsLatest exercises migrations/014_heal_is_latest.sql against +// synthetic broken states by re-running its SQL after seeding rows directly. The migration +// itself ran via the template DB; since it's idempotent (only matches servers with no +// non-deleted is_latest row), re-running it here only acts on the rows we just broke. +func TestMigration014_HealIsLatest(t *testing.T) { + db := database.NewTestDB(t) + ctx := context.Background() + + migrationSQL, err := os.ReadFile("migrations/014_heal_is_latest.sql") + require.NoError(t, err) + + createVersion := func(t *testing.T, name, version string, publishedAt time.Time, status model.Status, isLatest bool) { + t.Helper() + serverJSON := &apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, + Name: name, + Description: "test", + Version: version, + } + officialMeta := &apiv0.RegistryExtensions{ + Status: status, + StatusChangedAt: publishedAt, + PublishedAt: publishedAt, + UpdatedAt: publishedAt, + IsLatest: isLatest, + } + _, err := db.CreateServer(ctx, nil, serverJSON, officialMeta) + require.NoError(t, err) + } + + runHeal := func(t *testing.T) { + t.Helper() + err := db.InTransaction(ctx, func(ctx context.Context, tx pgx.Tx) error { + _, err := tx.Exec(ctx, string(migrationSQL)) + return err + }) + require.NoError(t, err) + } + + versionState := func(t *testing.T, name, version string) (model.Status, bool) { + t.Helper() + v, err := db.GetServerByNameAndVersion(ctx, nil, name, version, true) + require.NoError(t, err) + return v.Meta.Official.Status, v.Meta.Official.IsLatest + } + + t.Run("kubernetes-mcp-server scenario picks highest semver", func(t *testing.T) { + name := "io.test/k8s-scenario" + base := time.Now().Add(-10 * time.Hour) + // 1.0.0 published first, then 0.0.50, 0.0.51, 0.0.59, 0.0.60, 0.0.61. + // 1.0.0 was the original latest and got soft-deleted, leaving is_latest stranded. + createVersion(t, name, "1.0.0", base, model.StatusDeleted, true) + createVersion(t, name, "0.0.50", base.Add(1*time.Hour), model.StatusActive, false) + createVersion(t, name, "0.0.51", base.Add(2*time.Hour), model.StatusActive, false) + createVersion(t, name, "0.0.59", base.Add(3*time.Hour), model.StatusActive, false) + createVersion(t, name, "0.0.60", base.Add(4*time.Hour), model.StatusActive, false) + createVersion(t, name, "0.0.61", base.Add(5*time.Hour), model.StatusActive, false) + + runHeal(t) + + _, isLatest := versionState(t, name, "1.0.0") + assert.False(t, isLatest, "deleted 1.0.0 should no longer be latest") + _, isLatest = versionState(t, name, "0.0.61") + assert.True(t, isLatest, "highest active version should become latest") + for _, v := range []string{"0.0.50", "0.0.51", "0.0.59", "0.0.60"} { + _, isLatest := versionState(t, name, v) + assert.False(t, isLatest, "version %s should not be latest", v) + } + }) + + t.Run("backport scenario picks highest semver not most recent", func(t *testing.T) { + // Published 2.0.0 (deleted), then 1.0.1 hotfix, then 1.0.0 (older patch backported later). + // Most-recent-published would pick 1.0.0; semver-aware picks 1.0.1. + name := "io.test/backport-scenario" + base := time.Now().Add(-10 * time.Hour) + createVersion(t, name, "2.0.0", base, model.StatusDeleted, true) + createVersion(t, name, "1.0.1", base.Add(1*time.Hour), model.StatusActive, false) + createVersion(t, name, "1.0.0", base.Add(2*time.Hour), model.StatusActive, false) + + runHeal(t) + + _, isLatest := versionState(t, name, "1.0.1") + assert.True(t, isLatest, "1.0.1 should win on semver despite 1.0.0 being published more recently") + _, isLatest = versionState(t, name, "1.0.0") + assert.False(t, isLatest) + }) + + t.Run("no is_latest row at all gets healed", func(t *testing.T) { + // Defensive case: nothing flagged latest, but active versions exist. + name := "io.test/no-latest-flag" + base := time.Now().Add(-10 * time.Hour) + createVersion(t, name, "1.0.0", base, model.StatusActive, false) + createVersion(t, name, "1.1.0", base.Add(1*time.Hour), model.StatusActive, false) + + runHeal(t) + + _, isLatest := versionState(t, name, "1.1.0") + assert.True(t, isLatest) + _, isLatest = versionState(t, name, "1.0.0") + assert.False(t, isLatest) + }) + + t.Run("all-deleted server is left untouched", func(t *testing.T) { + // No non-deleted version → nothing to promote, leave existing flags alone so the + // server remains addressable via includeDeleted=true admin lookups. + name := "io.test/all-deleted" + base := time.Now().Add(-10 * time.Hour) + createVersion(t, name, "1.0.0", base, model.StatusDeleted, true) + createVersion(t, name, "2.0.0", base.Add(1*time.Hour), model.StatusDeleted, false) + + runHeal(t) + + _, isLatest := versionState(t, name, "1.0.0") + assert.True(t, isLatest, "all-deleted server should keep its existing latest flag") + _, isLatest = versionState(t, name, "2.0.0") + assert.False(t, isLatest) + }) + + t.Run("healthy server is left untouched", func(t *testing.T) { + name := "io.test/healthy" + base := time.Now().Add(-10 * time.Hour) + createVersion(t, name, "1.0.0", base, model.StatusActive, false) + createVersion(t, name, "2.0.0", base.Add(1*time.Hour), model.StatusActive, true) + + runHeal(t) + + _, isLatest := versionState(t, name, "2.0.0") + assert.True(t, isLatest) + _, isLatest = versionState(t, name, "1.0.0") + assert.False(t, isLatest) + }) + + t.Run("non-semver versions fall back to published_at", func(t *testing.T) { + name := "io.test/non-semver" + base := time.Now().Add(-10 * time.Hour) + createVersion(t, name, "rolling", base, model.StatusDeleted, true) + createVersion(t, name, "build-100", base.Add(1*time.Hour), model.StatusActive, false) + createVersion(t, name, "build-200", base.Add(2*time.Hour), model.StatusActive, false) + + runHeal(t) + + _, isLatest := versionState(t, name, "build-200") + assert.True(t, isLatest, "without semver, most recently published wins") + }) +} + // Helper functions for creating pointers to basic types func stringPtr(s string) *string { return &s diff --git a/internal/service/registry_service.go b/internal/service/registry_service.go index 05c4f16..4f4b8a0 100644 --- a/internal/service/registry_service.go +++ b/internal/service/registry_service.go @@ -164,6 +164,59 @@ func (s *registryServiceImpl) createServerInTransaction(ctx context.Context, tx return s.db.CreateServer(ctx, tx, &serverJSON, officialMeta) } +// recalculateLatest picks the highest non-deleted version of the given server and flags it +// as latest, clearing is_latest on every other row. If every version is deleted, the highest +// deleted version keeps the flag so admin lookups (GetServerByName with includeDeleted=true) +// still find the server. Caller must hold the per-server publish lock. +func (s *registryServiceImpl) recalculateLatest(ctx context.Context, tx pgx.Tx, serverName string) error { + versions, err := s.db.GetAllVersionsByServerName(ctx, tx, serverName, true) + if err != nil { + if errors.Is(err, database.ErrNotFound) { + return s.db.SetLatestVersion(ctx, tx, serverName, "") + } + return fmt.Errorf("failed to load versions for latest recalculation: %w", err) + } + + winner := pickLatestVersion(versions, false) + if winner == nil { + // No non-deleted versions — fall back to highest deleted so the server is still + // addressable via includeDeleted=true lookups. + winner = pickLatestVersion(versions, true) + } + + winnerVersion := "" + if winner != nil { + winnerVersion = winner.Server.Version + } + return s.db.SetLatestVersion(ctx, tx, serverName, winnerVersion) +} + +// pickLatestVersion returns the highest version from the given slice. If allowDeleted is +// false, deleted versions are skipped. +func pickLatestVersion(versions []*apiv0.ServerResponse, allowDeleted bool) *apiv0.ServerResponse { + var winner *apiv0.ServerResponse + for _, v := range versions { + if !allowDeleted && v.Meta.Official != nil && v.Meta.Official.Status == model.StatusDeleted { + continue + } + if winner == nil { + winner = v + continue + } + var winnerPublishedAt, candidatePublishedAt time.Time + if winner.Meta.Official != nil { + winnerPublishedAt = winner.Meta.Official.PublishedAt + } + if v.Meta.Official != nil { + candidatePublishedAt = v.Meta.Official.PublishedAt + } + if CompareVersions(v.Server.Version, winner.Server.Version, candidatePublishedAt, winnerPublishedAt) > 0 { + winner = v + } + } + return winner +} + // validateNoDuplicateRemoteURLs checks that no other server is using the same remote URLs func (s *registryServiceImpl) validateNoDuplicateRemoteURLs(ctx context.Context, tx pgx.Tx, serverDetail apiv0.ServerJSON) error { // Check each remote URL in the new server for conflicts @@ -237,11 +290,14 @@ func (s *registryServiceImpl) updateServerInTransaction(ctx context.Context, tx // Handle status change if provided if statusChange != nil { - updatedWithStatus, err := s.db.SetServerStatus(ctx, tx, serverName, version, statusChange.NewStatus, statusChange.StatusMessage) - if err != nil { + if _, err := s.db.SetServerStatus(ctx, tx, serverName, version, statusChange.NewStatus, statusChange.StatusMessage); err != nil { return nil, err } - return updatedWithStatus, nil + if err := s.recalculateLatest(ctx, tx, serverName); err != nil { + return nil, err + } + // Re-read to pick up the possibly updated is_latest flag. + return s.db.GetServerByNameAndVersion(ctx, tx, serverName, version, true) } return updatedServerResponse, nil @@ -279,7 +335,14 @@ func (s *registryServiceImpl) updateServerStatusInTransaction(ctx context.Contex } // Update only the status metadata - return s.db.SetServerStatus(ctx, tx, serverName, version, statusChange.NewStatus, statusChange.StatusMessage) + if _, err := s.db.SetServerStatus(ctx, tx, serverName, version, statusChange.NewStatus, statusChange.StatusMessage); err != nil { + return nil, err + } + if err := s.recalculateLatest(ctx, tx, serverName); err != nil { + return nil, err + } + // Re-read to pick up the possibly updated is_latest flag. + return s.db.GetServerByNameAndVersion(ctx, tx, serverName, version, true) } // UpdateAllVersionsStatus updates the status metadata of all versions of a server in a single transaction @@ -319,5 +382,12 @@ func (s *registryServiceImpl) updateAllVersionsStatusInTransaction(ctx context.C } // Update all versions' status in a single database call - return s.db.SetAllVersionsStatus(ctx, tx, serverName, statusChange.NewStatus, statusChange.StatusMessage) + if _, err := s.db.SetAllVersionsStatus(ctx, tx, serverName, statusChange.NewStatus, statusChange.StatusMessage); err != nil { + return nil, err + } + if err := s.recalculateLatest(ctx, tx, serverName); err != nil { + return nil, err + } + // Re-read to pick up the possibly updated is_latest flags. + return s.db.GetAllVersionsByServerName(ctx, tx, serverName, true) } diff --git a/internal/service/registry_service_test.go b/internal/service/registry_service_test.go index 63b6521..05ec847 100644 --- a/internal/service/registry_service_test.go +++ b/internal/service/registry_service_test.go @@ -982,6 +982,160 @@ func TestUpdateServerStatus_NoConflictWhenRestoringWithUniqueURLs(t *testing.T) assert.Equal(t, model.StatusActive, result.Meta.Official.Status) } +func TestRecalculateLatest_PromotesNextHighestWhenLatestSoftDeleted(t *testing.T) { + ctx := context.Background() + testDB := database.NewTestDB(t) + service := NewRegistryService(testDB, &config.Config{EnableRegistryValidation: false}) + + serverName := "com.example/delete-latest-server" + + // Publish 1.0.0, then 0.0.59. 1.0.0 is latest. + _, err := service.CreateServer(ctx, &apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, Name: serverName, Description: "v1", Version: "1.0.0", + }) + require.NoError(t, err) + _, err = service.CreateServer(ctx, &apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, Name: serverName, Description: "v0.0.59", Version: "0.0.59", + }) + require.NoError(t, err) + + // Soft-delete 1.0.0. + _, err = service.UpdateServerStatus(ctx, serverName, "1.0.0", &StatusChangeRequest{ + NewStatus: model.StatusDeleted, + }) + require.NoError(t, err) + + // 0.0.59 should now be latest. + latest, err := service.GetServerByName(ctx, serverName, false) + require.NoError(t, err) + assert.Equal(t, "0.0.59", latest.Server.Version) + assert.True(t, latest.Meta.Official.IsLatest) +} + +func TestRecalculateLatest_ReproFromIssue1081(t *testing.T) { + ctx := context.Background() + testDB := database.NewTestDB(t) + service := NewRegistryService(testDB, &config.Config{EnableRegistryValidation: false}) + + serverName := "com.example/issue-1081-repro" + + // 1. Publish 1.0.0. + _, err := service.CreateServer(ctx, &apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, Name: serverName, Description: "v1", Version: "1.0.0", + }) + require.NoError(t, err) + + // 2. Publish 0.0.59 — expected not latest at this point. + _, err = service.CreateServer(ctx, &apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, Name: serverName, Description: "v0.0.59", Version: "0.0.59", + }) + require.NoError(t, err) + + // 3. Delete 1.0.0. + _, err = service.UpdateServerStatus(ctx, serverName, "1.0.0", &StatusChangeRequest{ + NewStatus: model.StatusDeleted, + }) + require.NoError(t, err) + + // 4. /versions/latest must not 404. + latest, err := service.GetServerByName(ctx, serverName, false) + require.NoError(t, err) + assert.Equal(t, "0.0.59", latest.Server.Version) + + // 5. Publish 0.0.60 — should become latest because compare now excludes deleted 1.0.0. + _, err = service.CreateServer(ctx, &apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, Name: serverName, Description: "v0.0.60", Version: "0.0.60", + }) + require.NoError(t, err) + + latest, err = service.GetServerByName(ctx, serverName, false) + require.NoError(t, err) + assert.Equal(t, "0.0.60", latest.Server.Version) + assert.True(t, latest.Meta.Official.IsLatest) + + // Only one row should be flagged latest. + all, err := service.GetAllVersionsByServerName(ctx, serverName, true) + require.NoError(t, err) + latestCount := 0 + for _, v := range all { + if v.Meta.Official.IsLatest { + latestCount++ + } + } + assert.Equal(t, 1, latestCount) +} + +func TestRecalculateLatest_AllDeletedKeepsHighestAsLatest(t *testing.T) { + ctx := context.Background() + testDB := database.NewTestDB(t) + service := NewRegistryService(testDB, &config.Config{EnableRegistryValidation: false}) + + serverName := "com.example/all-deleted-server" + + _, err := service.CreateServer(ctx, &apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, Name: serverName, Description: "v1", Version: "1.0.0", + }) + require.NoError(t, err) + _, err = service.CreateServer(ctx, &apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, Name: serverName, Description: "v2", Version: "2.0.0", + }) + require.NoError(t, err) + + // Delete all versions in one call. + _, err = service.UpdateAllVersionsStatus(ctx, serverName, &StatusChangeRequest{ + NewStatus: model.StatusDeleted, + }) + require.NoError(t, err) + + // Public lookup (includeDeleted=false) must now 404. + _, err = service.GetServerByName(ctx, serverName, false) + require.ErrorIs(t, err, database.ErrNotFound) + + // Admin lookup (includeDeleted=true) must still find the server: the highest deleted + // version keeps is_latest=true so the server remains addressable for restore flows. + latest, err := service.GetServerByName(ctx, serverName, true) + require.NoError(t, err) + assert.Equal(t, "2.0.0", latest.Server.Version) + assert.True(t, latest.Meta.Official.IsLatest) +} + +func TestRecalculateLatest_RestoringHigherVersionPromotesIt(t *testing.T) { + ctx := context.Background() + testDB := database.NewTestDB(t) + service := NewRegistryService(testDB, &config.Config{EnableRegistryValidation: false}) + + serverName := "com.example/restore-server" + + // Publish 2.0.0 and 1.0.0 — 2.0.0 is latest. + _, err := service.CreateServer(ctx, &apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, Name: serverName, Description: "v2", Version: "2.0.0", + }) + require.NoError(t, err) + _, err = service.CreateServer(ctx, &apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, Name: serverName, Description: "v1", Version: "1.0.0", + }) + require.NoError(t, err) + + // Delete 2.0.0 — 1.0.0 gets promoted. + _, err = service.UpdateServerStatus(ctx, serverName, "2.0.0", &StatusChangeRequest{ + NewStatus: model.StatusDeleted, + }) + require.NoError(t, err) + latest, err := service.GetServerByName(ctx, serverName, false) + require.NoError(t, err) + require.Equal(t, "1.0.0", latest.Server.Version) + + // Restore 2.0.0 — it should reclaim latest. + _, err = service.UpdateServerStatus(ctx, serverName, "2.0.0", &StatusChangeRequest{ + NewStatus: model.StatusActive, + }) + require.NoError(t, err) + latest, err = service.GetServerByName(ctx, serverName, false) + require.NoError(t, err) + assert.Equal(t, "2.0.0", latest.Server.Version) + assert.True(t, latest.Meta.Official.IsLatest) +} + // Helper functions func stringPtr(s string) *string { return &s From 7722031739ad2d4e09ee6027dc51943888606795 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Sat, 25 Apr 2026 13:01:08 -0400 Subject: [PATCH 051/190] deploy: update prod to v1.7.0 (#1205) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Bumps production image tag from `1.6.0` to `1.7.0` in `deploy/Pulumi.gcpProd.yaml` - Corresponds to the [v1.7.0 release](https://github.com/modelcontextprotocol/registry/releases/tag/v1.7.0) - Notable change: includes #1201 — fixes #1081 (`isLatest` no longer stranded after soft-delete) and ships migration `014_heal_is_latest` that auto-heals affected servers (e.g. `io.github.containers/kubernetes-mcp-server`) on deploy ## Test plan - [ ] Verify Pulumi preview shows only the image tag change - [ ] After deploy, confirm migration 014 ran and `io.github.containers/kubernetes-mcp-server`'s `/versions/latest` returns `0.0.61` (or whichever is highest non-deleted) - [ ] Sample a few unaffected servers and confirm `isLatest` is unchanged - [ ] Confirm overall service health 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index 630f8a2..a1ad178 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.6.0 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.7.0 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From b24d6c7657786d4474f2ab0fd067deb85be1de33 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 27 Apr 2026 09:09:50 -0400 Subject: [PATCH 052/190] fix: harden registry availability and add publish phase timings (#1211) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Daily ~17:00 UTC `Publish Endpoint Latency` and `Availability < 95%` alerts are caused by both registry pods exit-0'ing within seconds of each other and racing with the still-recovering `registry-pg-rw` endpoint on restart. Separately, the default compute SA had no project IAM roles, so `fluentbit-gke` and the GMP collector were silently dropping every log line and time series — which is why none of this was visible in Cloud Logging. All Kubernetes/IAM changes apply uniformly to staging and prod. ## Changes - **GCP IAM** (`deploy/pkg/providers/gcp/provider.go`) — grant the default compute SA `logging.logWriter`, `monitoring.metricWriter`, `monitoring.viewer`, and `stackdriver.resourceMetadata.writer`. Already applied live; this just encodes it in Pulumi. - **Pod resilience** (`deploy/pkg/k8s/registry.go`) — - `PodDisruptionBudget` (`minAvailable: 1`) prevents a synchronized voluntary disruption. - `TopologySpreadConstraints` (`ScheduleAnyway`, hostname) keeps the PDB from deadlocking node drains when both pods co-locate. - `StartupProbe` (30 × 5s = 150s) protects the DB-retry budget from the liveness probe. - Memory bump 128→256Mi request, 256→512Mi limit. - **Startup retry** (`cmd/registry/main.go`) — replace silent `return` on initial DB-ping failure with bounded retry-with-backoff (8 attempts, 1→8s capped, 10s per-attempt). A brief endpoint flap no longer cascades into a restart loop. - **Diagnostic log** (`internal/service/registry_service.go`) — emit `validate_ms` on each publish (success and failure). Validate fans out to npm/PyPI/OCI with 10s per-host timeouts and is the most likely contributor to publish latency. Total request duration is already covered by the existing `http.request.duration` histogram. ## Calibration The IAM, PDB, topology-spread, startup-probe, and DB-retry pieces are mitigations — they reduce blast radius regardless of root cause. The `validate_ms` log is the diagnostic for identifying the trigger when the alert fires next. Single-PG SPOF (`deploy/pkg/k8s/postgres.go:57`) remains a follow-up; today's evidence shows PG was a victim, not the cause. ## Test plan - [x] `go build ./...` and `go vet ./...` clean for both modules - [x] `make lint` clean (12 pre-existing issues under `deploy/` are not in `make lint`) - [x] `go test -race -count=1 ./internal/... ./cmd/...` green - [x] IAM applied live; `fluentbit-gke` and GMP no longer hitting `IAM_PERMISSION_DENIED` - [ ] After deploy, verify the next 17:00 UTC firing surfaces `validate_ms` in Cloud Logging 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- cmd/registry/main.go | 34 +++++++++++----- deploy/pkg/k8s/registry.go | 58 +++++++++++++++++++++++++++- deploy/pkg/providers/gcp/provider.go | 53 +++++++++++++++++++++++++ internal/service/registry_service.go | 37 +++++++++++++++--- 4 files changed, 165 insertions(+), 17 deletions(-) diff --git a/cmd/registry/main.go b/cmd/registry/main.go index 3eee551..ed68abf 100644 --- a/cmd/registry/main.go +++ b/cmd/registry/main.go @@ -57,15 +57,31 @@ func main() { // Initialize configuration cfg := config.NewConfig() - // Create a context with timeout for PostgreSQL connection - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - // Connect to PostgreSQL - db, err = database.NewPostgreSQL(ctx, cfg.DatabaseURL) - if err != nil { - log.Printf("Failed to connect to PostgreSQL: %v", err) - return + // Connect to PostgreSQL with bounded retry. The DB endpoint can flap briefly + // during voluntary disruptions (node drains, rollouts) and without retry the + // pod exits cleanly, restarts, then races with the still-recovering service + // — turning a transient blip into a multi-minute outage. + const ( + maxStartupAttempts = 8 + perAttemptTimeout = 10 * time.Second + initialBackoff = 1 * time.Second + maxBackoff = 8 * time.Second + ) + backoff := initialBackoff + for attempt := 1; ; attempt++ { + attemptCtx, attemptCancel := context.WithTimeout(context.Background(), perAttemptTimeout) + db, err = database.NewPostgreSQL(attemptCtx, cfg.DatabaseURL) + attemptCancel() + if err == nil { + break + } + if attempt >= maxStartupAttempts { + log.Printf("Failed to connect to PostgreSQL after %d attempts: %v", attempt, err) + return + } + log.Printf("PostgreSQL not reachable (attempt %d/%d): %v, retrying in %s", attempt, maxStartupAttempts, err, backoff) + time.Sleep(backoff) + backoff = min(backoff*2, maxBackoff) } // Store the PostgreSQL instance for later cleanup diff --git a/deploy/pkg/k8s/registry.go b/deploy/pkg/k8s/registry.go index 4655203..579f740 100644 --- a/deploy/pkg/k8s/registry.go +++ b/deploy/pkg/k8s/registry.go @@ -10,6 +10,7 @@ import ( "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/helm/v3" metav1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/meta/v1" networkingv1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/networking/v1" + policyv1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/policy/v1" "github.com/pulumi/pulumi/sdk/v3/go/pulumi" "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config" @@ -95,6 +96,22 @@ func DeployMCPRegistry(ctx *pulumi.Context, cluster *providers.ProviderInfo, env }, }, Spec: &corev1.PodSpecArgs{ + // Soft-spread pods across nodes so the PodDisruptionBudget below can't + // deadlock a node drain when both pods happen to co-locate. + // `ScheduleAnyway` keeps single-node clusters (e.g. constrained dev + // envs) schedulable while still preferring spread under normal load. + TopologySpreadConstraints: corev1.TopologySpreadConstraintArray{ + &corev1.TopologySpreadConstraintArgs{ + MaxSkew: pulumi.Int(1), + TopologyKey: pulumi.String("kubernetes.io/hostname"), + WhenUnsatisfiable: pulumi.String("ScheduleAnyway"), + LabelSelector: &metav1.LabelSelectorArgs{ + MatchLabels: pulumi.StringMap{ + "app": pulumi.String("mcp-registry"), + }, + }, + }, + }, Containers: corev1.ContainerArray{ &corev1.ContainerArgs{ Name: pulumi.String("mcp-registry"), @@ -169,6 +186,18 @@ func DeployMCPRegistry(ctx *pulumi.Context, cluster *providers.ProviderInfo, env Value: pulumi.String("*"), }, }, + // StartupProbe protects the DB-retry budget in cmd/registry/main.go: + // 30 × 5s = 150s allowed before liveness/readiness take over, which + // covers the worst-case retry budget (8 attempts × 10s + ~40s sleep). + StartupProbe: &corev1.ProbeArgs{ + HttpGet: &corev1.HTTPGetActionArgs{ + Path: pulumi.String("/v0/health"), + Port: pulumi.Int(8080), + }, + PeriodSeconds: pulumi.Int(5), + FailureThreshold: pulumi.Int(30), + TimeoutSeconds: pulumi.Int(3), + }, LivenessProbe: &corev1.ProbeArgs{ HttpGet: &corev1.HTTPGetActionArgs{ Path: pulumi.String("/v0/health"), @@ -187,11 +216,11 @@ func DeployMCPRegistry(ctx *pulumi.Context, cluster *providers.ProviderInfo, env }, Resources: &corev1.ResourceRequirementsArgs{ Requests: pulumi.StringMap{ - "memory": pulumi.String("128Mi"), + "memory": pulumi.String("256Mi"), "cpu": pulumi.String("100m"), }, Limits: pulumi.StringMap{ - "memory": pulumi.String("256Mi"), + "memory": pulumi.String("512Mi"), }, }, }, @@ -204,6 +233,31 @@ func DeployMCPRegistry(ctx *pulumi.Context, cluster *providers.ProviderInfo, env return nil, err } + // Keep at least one registry pod available during voluntary disruptions + // (node drains, evictions, etc.) so a synchronized eviction can't take both + // pods down at once. + _, err = policyv1.NewPodDisruptionBudget(ctx, "mcp-registry", &policyv1.PodDisruptionBudgetArgs{ + Metadata: &metav1.ObjectMetaArgs{ + Name: pulumi.String("mcp-registry"), + Namespace: pulumi.String("default"), + Labels: pulumi.StringMap{ + "app": pulumi.String("mcp-registry"), + "environment": pulumi.String(environment), + }, + }, + Spec: &policyv1.PodDisruptionBudgetSpecArgs{ + MinAvailable: pulumi.Int(1), + Selector: &metav1.LabelSelectorArgs{ + MatchLabels: pulumi.StringMap{ + "app": pulumi.String("mcp-registry"), + }, + }, + }, + }, pulumi.Provider(cluster.Provider)) + if err != nil { + return nil, err + } + // Create Service service, err := corev1.NewService(ctx, "mcp-registry", &corev1.ServiceArgs{ Metadata: &metav1.ObjectMetaArgs{ diff --git a/deploy/pkg/providers/gcp/provider.go b/deploy/pkg/providers/gcp/provider.go index 108a209..6a51e27 100644 --- a/deploy/pkg/providers/gcp/provider.go +++ b/deploy/pkg/providers/gcp/provider.go @@ -3,9 +3,12 @@ package gcp import ( "encoding/base64" "fmt" + "strings" "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp" "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp/container" + "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp/organizations" + "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp/projects" "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp/storage" "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes" corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/core/v1" @@ -58,6 +61,49 @@ func createGCPProvider(ctx *pulumi.Context, name string) (*gcp.Provider, error) return nil, nil } +// grantNodeServiceAccountRoles grants the default compute service account the standard +// GKE node roles required for log shipping (fluentbit-gke) and metrics scraping +// (managed Prometheus). New GCP projects no longer auto-grant Editor to the default +// compute SA, so these have to be set explicitly or every pod log/metric is dropped. +func grantNodeServiceAccountRoles(ctx *pulumi.Context, projectID string, gcpProvider *gcp.Provider) error { + invokeOpts := []pulumi.InvokeOption{} + resourceOpts := []pulumi.ResourceOption{} + if gcpProvider != nil { + invokeOpts = append(invokeOpts, pulumi.Provider(gcpProvider)) + resourceOpts = append(resourceOpts, pulumi.Provider(gcpProvider)) + } + + project, err := organizations.LookupProject(ctx, &organizations.LookupProjectArgs{ + ProjectId: pulumi.StringRef(projectID), + }, invokeOpts...) + if err != nil { + return fmt.Errorf("failed to look up project number for node SA bindings: %w", err) + } + + nodeSA := fmt.Sprintf("serviceAccount:%s-compute@developer.gserviceaccount.com", project.Number) + + roles := []string{ + "roles/logging.logWriter", + "roles/monitoring.metricWriter", + "roles/monitoring.viewer", + "roles/stackdriver.resourceMetadata.writer", + } + + for _, role := range roles { + name := fmt.Sprintf("node-sa-%s", strings.ReplaceAll(strings.TrimPrefix(role, "roles/"), ".", "-")) + _, err := projects.NewIAMMember(ctx, name, &projects.IAMMemberArgs{ + Project: pulumi.String(projectID), + Role: pulumi.String(role), + Member: pulumi.String(nodeSA), + }, resourceOpts...) + if err != nil { + return fmt.Errorf("failed to grant %s to node SA: %w", role, err) + } + } + + return nil +} + // CreateCluster creates a Google Kubernetes Engine cluster func (p *Provider) CreateCluster(ctx *pulumi.Context, environment string) (*providers.ProviderInfo, error) { // Get configuration @@ -152,6 +198,13 @@ func (p *Provider) CreateCluster(ctx *pulumi.Context, environment string) (*prov return nil, fmt.Errorf("failed to create node pool: %w", err) } + // Grant the default compute service account the standard GKE node roles so the + // fluentbit-gke and managed Prometheus collectors can ship logs and metrics. + // Without these, every pod log line and time series fails with IAM_PERMISSION_DENIED. + if err := grantNodeServiceAccountRoles(ctx, projectID, gcpProvider); err != nil { + return nil, err + } + // Create Kubernetes provider using the cluster directly k8sProvider, err := kubernetes.NewProvider(ctx, "k8s-provider", &kubernetes.ProviderArgs{ Kubeconfig: pulumi.All(cluster.Endpoint, cluster.MasterAuth).ApplyT(func(args []any) (string, error) { diff --git a/internal/service/registry_service.go b/internal/service/registry_service.go index 4f4b8a0..4403136 100644 --- a/internal/service/registry_service.go +++ b/internal/service/registry_service.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "log/slog" "time" "github.com/jackc/pgx/v5" @@ -85,15 +86,29 @@ func (s *registryServiceImpl) CreateServer(ctx context.Context, req *apiv0.Serve }) } -// createServerInTransaction contains the actual CreateServer logic within a transaction +// createServerInTransaction contains the actual CreateServer logic within a transaction. func (s *registryServiceImpl) createServerInTransaction(ctx context.Context, tx pgx.Tx, req *apiv0.ServerJSON) (*apiv0.ServerResponse, error) { - // Validate the request - if err := validators.ValidatePublishRequest(ctx, *req, s.cfg); err != nil { - return nil, err + serverJSON := *req + + // Validate the request. ValidatePublishRequest fans out to npm/PyPI/OCI for + // registry-ownership checks with 10s per-host timeouts, so it's the most likely + // contributor to publish latency. Log validate_ms on both success and failure + // so the next /v0/publish latency alert is diagnostic — a slow upstream that + // times out into a validation error is exactly the case we need to see. + validateStart := time.Now() + validateErr := validators.ValidatePublishRequest(ctx, serverJSON, s.cfg) + validateMs := time.Since(validateStart).Milliseconds() + if validateErr != nil { + slog.WarnContext(ctx, "publish validate failed", + "server_name", serverJSON.Name, + "version", serverJSON.Version, + "validate_ms", validateMs, + "error", validateErr.Error(), + ) + return nil, validateErr } publishTime := time.Now() - serverJSON := *req // Acquire advisory lock to prevent concurrent publishes of the same server if err := s.db.AcquirePublishLock(ctx, tx, serverJSON.Name); err != nil { @@ -161,7 +176,17 @@ func (s *registryServiceImpl) createServerInTransaction(ctx context.Context, tx } // Insert new server version - return s.db.CreateServer(ctx, tx, &serverJSON, officialMeta) + resp, err := s.db.CreateServer(ctx, tx, &serverJSON, officialMeta) + if err != nil { + return nil, err + } + + slog.InfoContext(ctx, "publish complete", + "server_name", serverJSON.Name, + "version", serverJSON.Version, + "validate_ms", validateMs, + ) + return resp, nil } // recalculateLatest picks the highest non-deleted version of the given server and flags it From c6d3096d1b029278ed03891d08a20a0029b101ed Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 27 Apr 2026 12:32:22 -0400 Subject: [PATCH 053/190] fix(deploy): manage Cloud Resource Manager API enablement in Pulumi (#1213) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Follow-up to #1211 to encode the GCP API and IAM dependencies its node-SA bindings rely on. After #1211 merged, the staging deploy hit two undocumented prereqs in sequence — Cloud Resource Manager API not enabled (because `projects.NewIAMMember` calls SetIamPolicy through CRM), then the Pulumi service account missing `roles/resourcemanager.projectIamAdmin`. Both fixed manually to unblock; this PR makes them explicit so they don't bite again. ## Changes **`ensureRequiredAPIs` adopts five GCP APIs** as Pulumi-managed `projects.Service` resources, all with `DisableOnDestroy: false` and `DisableDependentServices: false` so a Pulumi destroy/refactor can never disable a shared API: | API | Why | |-----|-----| | `cloudresourcemanager` | `projects.NewIAMMember` → SetIamPolicy | | `compute` | `compute.GetDefaultServiceAccount` invoke + GKE | | `container` | GKE cluster | | `logging` | fluentbit-gke ships container logs | | `monitoring` | managed Prometheus collector ships metrics | CRM is created explicitly (not in the loop) so callers get a direct reference for `pulumi.DependsOn`. Storage is intentionally **not** Pulumi-managed — Pulumi state itself lives in a GCS bucket, chicken-and-egg. **`grantNodeServiceAccountRoles`** now `DependsOn` the CRM `projects.Service` for the four IAM bindings, and uses `compute.GetDefaultServiceAccount` to derive the SA email (Compute API was already required for GKE — avoids a CRM-dependent project-number lookup). **`deploy/README.md`** — adds `roles/resourcemanager.projectIamAdmin` to the Pulumi SA's required roles and clarifies which APIs must be enabled before the first `pulumi up` (storage, cloudresourcemanager, container) vs. which `ensureRequiredAPIs` adopts. ## Notes `projects.Service` is idempotent against already-enabled APIs — on existing projects (staging/prod), Pulumi adopts the live enablement into state without re-enabling. This was confirmed live: staging deploy went green after the manual unblocks above, validating the runtime model. ## Test plan - [x] `go build ./...` clean for `deploy/` - [x] `golangci-lint run` clean for `deploy/pkg/providers/gcp/...` (one pre-existing `nilnil` at line 61, unrelated) - [x] Manual unblock + green staging deploy verified the runtime behavior this PR encodes - [ ] On merge: staging deploy adopts the existing API enablements without churn, then proceeds normally - [ ] Prod deploy via #1212 (image promotion) inherits the same setup 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/README.md | 17 +++++- deploy/pkg/providers/gcp/provider.go | 90 +++++++++++++++++++++++++--- 2 files changed, 98 insertions(+), 9 deletions(-) diff --git a/deploy/README.md b/deploy/README.md index 3125d61..392b244 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -65,8 +65,20 @@ Pre-requisites: 1. Create a project: `gcloud projects create mcp-registry-prod` 2. Set the project: `gcloud config set project mcp-registry-prod` -3. Enable required APIs: `gcloud services enable storage.googleapis.com && gcloud services enable container.googleapis.com` -4. Create a service account with necessary permissions, and get the key: +3. Enable the bootstrap APIs needed before Pulumi can run. The remaining APIs + (`cloudresourcemanager`, `compute`, `container`, `logging`, `monitoring`) are + adopted as Pulumi-managed `projects.Service` resources by `ensureRequiredAPIs` + in `pkg/providers/gcp/provider.go`, so they self-heal against drift but still + need to be reachable on the very first deploy: + ```bash + gcloud services enable storage.googleapis.com # for the Pulumi state bucket below + gcloud services enable cloudresourcemanager.googleapis.com # for the IAM bindings Pulumi creates + gcloud services enable container.googleapis.com # for the GKE cluster + ``` +4. Create the Pulumi service account and grant it the roles required to manage + the deploy. `projectIamAdmin` is needed because the deploy creates IAM bindings + on the project (for the default compute SA). The other four are general + resource management: ```bash gcloud iam service-accounts create pulumi-svc sleep 10 @@ -74,6 +86,7 @@ Pre-requisites: gcloud projects add-iam-policy-binding mcp-registry-prod --member="serviceAccount:pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com" --role="roles/compute.admin" gcloud projects add-iam-policy-binding mcp-registry-prod --member="serviceAccount:pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com" --role="roles/storage.admin" gcloud projects add-iam-policy-binding mcp-registry-prod --member="serviceAccount:pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com" --role="roles/storage.hmacKeyAdmin" + gcloud projects add-iam-policy-binding mcp-registry-prod --member="serviceAccount:pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com" --role="roles/resourcemanager.projectIamAdmin" gcloud iam service-accounts add-iam-policy-binding $(gcloud projects describe mcp-registry-prod --format="value(projectNumber)")-compute@developer.gserviceaccount.com --member="serviceAccount:pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com" --role="roles/iam.serviceAccountUser" gcloud iam service-accounts keys create sa-key.json --iam-account=pulumi-svc@mcp-registry-prod.iam.gserviceaccount.com ``` diff --git a/deploy/pkg/providers/gcp/provider.go b/deploy/pkg/providers/gcp/provider.go index 6a51e27..e4f1e76 100644 --- a/deploy/pkg/providers/gcp/provider.go +++ b/deploy/pkg/providers/gcp/provider.go @@ -6,8 +6,8 @@ import ( "strings" "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp" + "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp/compute" "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp/container" - "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp/organizations" "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp/projects" "github.com/pulumi/pulumi-gcp/sdk/v8/go/gcp/storage" "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes" @@ -61,10 +61,75 @@ func createGCPProvider(ctx *pulumi.Context, name string) (*gcp.Provider, error) return nil, nil } +// ensureRequiredAPIs adopts the GCP APIs the deploy depends on as Pulumi-managed +// services. Encoding them as Pulumi resources makes the dependency explicit and +// protects against drift (an org policy reset or accidental disable). +// +// Note: bootstrap APIs (storage, cloudresourcemanager, container — see +// deploy/README.md) must already be enabled before this runs, because the +// resources that need them are created earlier in the stack. For those, this +// function adopts them into Pulumi state after the fact. For the rest (logging, +// monitoring), the adoption happens before any consumer runs. +// +// DisableOnDestroy and DisableDependentServices are both false — a Pulumi destroy +// or refactor must never disable a shared API that other resources (and humans) +// rely on. Enable-only. +// +// Returns the Cloud Resource Manager API resource specifically, since the node-SA +// IAM bindings need to DependsOn it (SetIamPolicy is gated on CRM). +func ensureRequiredAPIs(ctx *pulumi.Context, projectID string, resourceOpts []pulumi.ResourceOption) (*projects.Service, error) { + // Service Usage API (which projects.NewService itself uses) is enabled by default + // on GCP projects, so we don't need to manage it here. + + // CRM is created explicitly (not in the loop below) because callers need a + // direct reference to it for DependsOn — projects.NewIAMMember calls + // SetIamPolicy under the hood, which is gated on CRM. + crm, err := projects.NewService(ctx, "crm-api", &projects.ServiceArgs{ + Project: pulumi.String(projectID), + Service: pulumi.String("cloudresourcemanager.googleapis.com"), + DisableOnDestroy: pulumi.Bool(false), + DisableDependentServices: pulumi.Bool(false), + }, resourceOpts...) + if err != nil { + return nil, fmt.Errorf("failed to ensure cloudresourcemanager.googleapis.com is enabled: %w", err) + } + + otherAPIs := []struct { + resourceName string + serviceName string + }{ + // Required for compute.GetDefaultServiceAccount and the GKE cluster. + {"compute-api", "compute.googleapis.com"}, + // Required for the GKE cluster. + {"container-api", "container.googleapis.com"}, + // Required for fluentbit-gke to ship container logs. + {"logging-api", "logging.googleapis.com"}, + // Required for the managed Prometheus collector to ship metrics. + {"monitoring-api", "monitoring.googleapis.com"}, + } + + for _, api := range otherAPIs { + _, err := projects.NewService(ctx, api.resourceName, &projects.ServiceArgs{ + Project: pulumi.String(projectID), + Service: pulumi.String(api.serviceName), + DisableOnDestroy: pulumi.Bool(false), + DisableDependentServices: pulumi.Bool(false), + }, resourceOpts...) + if err != nil { + return nil, fmt.Errorf("failed to ensure %s is enabled: %w", api.serviceName, err) + } + } + return crm, nil +} + // grantNodeServiceAccountRoles grants the default compute service account the standard // GKE node roles required for log shipping (fluentbit-gke) and metrics scraping // (managed Prometheus). New GCP projects no longer auto-grant Editor to the default // compute SA, so these have to be set explicitly or every pod log/metric is dropped. +// +// The IAM bindings depend on Cloud Resource Manager API being enabled (managed by +// ensureRequiredAPIs above) — without it, projects.NewIAMMember fails because +// SetIamPolicy lives behind that API. func grantNodeServiceAccountRoles(ctx *pulumi.Context, projectID string, gcpProvider *gcp.Provider) error { invokeOpts := []pulumi.InvokeOption{} resourceOpts := []pulumi.ResourceOption{} @@ -73,14 +138,22 @@ func grantNodeServiceAccountRoles(ctx *pulumi.Context, projectID string, gcpProv resourceOpts = append(resourceOpts, pulumi.Provider(gcpProvider)) } - project, err := organizations.LookupProject(ctx, &organizations.LookupProjectArgs{ - ProjectId: pulumi.StringRef(projectID), - }, invokeOpts...) + crmAPI, err := ensureRequiredAPIs(ctx, projectID, resourceOpts) if err != nil { - return fmt.Errorf("failed to look up project number for node SA bindings: %w", err) + return err } - nodeSA := fmt.Sprintf("serviceAccount:%s-compute@developer.gserviceaccount.com", project.Number) + // Get the default compute SA email directly from the Compute API instead of + // constructing it from the project number — avoids needing CRM API just for + // the project lookup, and matches whatever GCP actually returns. + defaultSA, err := compute.GetDefaultServiceAccount(ctx, &compute.GetDefaultServiceAccountArgs{ + Project: pulumi.StringRef(projectID), + }, invokeOpts...) + if err != nil { + return fmt.Errorf("failed to look up default compute service account: %w", err) + } + + nodeSA := "serviceAccount:" + defaultSA.Email roles := []string{ "roles/logging.logWriter", @@ -89,13 +162,16 @@ func grantNodeServiceAccountRoles(ctx *pulumi.Context, projectID string, gcpProv "roles/stackdriver.resourceMetadata.writer", } + bindingOpts := make([]pulumi.ResourceOption, 0, len(resourceOpts)+1) + bindingOpts = append(bindingOpts, resourceOpts...) + bindingOpts = append(bindingOpts, pulumi.DependsOn([]pulumi.Resource{crmAPI})) for _, role := range roles { name := fmt.Sprintf("node-sa-%s", strings.ReplaceAll(strings.TrimPrefix(role, "roles/"), ".", "-")) _, err := projects.NewIAMMember(ctx, name, &projects.IAMMemberArgs{ Project: pulumi.String(projectID), Role: pulumi.String(role), Member: pulumi.String(nodeSA), - }, resourceOpts...) + }, bindingOpts...) if err != nil { return fmt.Errorf("failed to grant %s to node SA: %w", role, err) } From 762a4849a65557e1c0c3be2753b7fabab26d7645 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 27 Apr 2026 12:44:10 -0400 Subject: [PATCH 054/190] deploy: update prod to v1.7.1 (#1212) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Promotes [v1.7.1](https://github.com/modelcontextprotocol/registry/releases/tag/v1.7.1) to production. Contents: the hardening + diagnostics from #1211. What's in v1.7.1 (vs v1.7.0): - Pulumi-managed IAM bindings for the default compute SA so fluentbit-gke and the GMP collector can ship logs/metrics (already applied to live cluster manually) - `PodDisruptionBudget` with `minAvailable: 1` + `TopologySpreadConstraints` to keep pods spread across nodes - `StartupProbe` (30 × 5s) covering the new DB-retry budget - Bounded retry-with-backoff on initial DB connect in `cmd/registry/main.go` - Memory request 128→256Mi, limit 256→512Mi - `slog` `validate_ms` timing on the publish path so the next slow `/v0/publish` is self-diagnostic ## Test plan - [x] v1.7.1 release workflow built and pushed image successfully (`ghcr.io/modelcontextprotocol/registry:1.7.1`) - [x] Pulumi.gcpProd.yaml diff is the single-line image bump - [ ] On merge, `deploy-production.yml` rolls out v1.7.1 — watch for clean rolling update (`maxSurge: 1`, `maxUnavailable: 0`) and confirm both pods reach Ready - [ ] After rollout, confirm `Starting MCP Registry Application v1.7.1` shows up in Cloud Logging from the new pods 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index a1ad178..1dd623b 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.7.0 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.7.1 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From 27af672c5ee355e88d8329f51ce20f0e4d08db39 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 27 Apr 2026 15:35:59 -0400 Subject: [PATCH 055/190] fix(list): use row-constructor cursor + restore per-phase publish timings + enable pg_stat_statements (#1215) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Three changes from the 2026-04-27 incident: 1. **Cursor SQL fix** — `addCursorCondition` rewritten to use a row-constructor comparison `(server_name, version) > ($1, $2)` instead of the OR-decomposed form. Postgres can index-seek on the row constructor; it can't on the OR form, which scanned from the start of the index and filtered rows before the cursor. Cost grew linearly with cursor depth. 2. **Per-phase publish timings restored** — `createServerInTransaction` was simplified during #1211 review to log only `validate_ms`. The incident showed publishes spending 50+ s in `acquire_lock` / `version_checks` / `db_create` while `validate_ms` reported a few hundred ms — the diagnostic signal was hidden. Restored timings for every phase, refactored into a small `runPhase` helper. 3. **`pg_stat_statements` enabled** in the CNPG cluster spec. We had no aggregate query visibility during the incident — could only EXPLAIN queries we happened to suspect. ## Cursor fix evidence Local benchmark, 100K rows, cold cache: | Form | Rows filtered | Buffer reads | Time | |------|--------------:|-------------:|-----:| | OLD | 80,001 | 7,679 | 31.6 ms | | NEW | 2 | 1 | **0.05 ms** | Maps to prod's measured 8,911 buffer hits → 760 ms. End-to-end API: `/v0/servers?limit=100&cursor=…` returns in 4–7 ms regardless of depth. Risk check: confirmed `(server_name, version)` index exists in that column order (both `servers_pkey` and `idx_servers_name_version`), and both columns are `NOT NULL` so row-constructor comparison can't silently drop rows. ## Tests - New `TestPostgreSQL_PerformanceScenarios/compound_cursor_across_versions_of_same_server` pins multi-version pagination semantics. The existing cursor tests only exercised the fallback (single-component cursor) and degenerate (one version per server) cases. - `make lint` clean, `go test -race ./internal/... ./cmd/...` green. ## Deployment The cursor + slog changes are zero-downtime. The CNPG spec change triggers a brief PG restart (single-instance cluster). After the restart, run once on prod: ```bash kubectl exec -i registry-pg-1 -c postgres \ --context gke_mcp-registry-prod_us-central1-b_mcp-registry-prod \ -- psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements" ``` Time the merge for a low-traffic UTC window. v1.7.1's DB retry-with-backoff covers the brief PG restart. ## Out of scope `MaxConns` bump, per-IP rate limiting at nginx, response caching, the pre-existing `superfluous WriteHeader` warnings — separate follow-ups. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/pkg/k8s/postgres.go | 20 ++++ internal/database/postgres.go | 16 ++- internal/database/postgres_test.go | 98 ++++++++++++++++++ internal/service/registry_service.go | 148 ++++++++++++++++++--------- 4 files changed, 232 insertions(+), 50 deletions(-) diff --git a/deploy/pkg/k8s/postgres.go b/deploy/pkg/k8s/postgres.go index 57a28aa..7a119fd 100644 --- a/deploy/pkg/k8s/postgres.go +++ b/deploy/pkg/k8s/postgres.go @@ -59,6 +59,26 @@ func DeployPostgresDatabases(ctx *pulumi.Context, cluster *providers.ProviderInf "storage": map[string]any{ "size": "50Gi", }, + // Enable pg_stat_statements so we can attribute slow time to specific + // queries (the 2026-04-27 incident took an EXPLAIN-the-one-query-I-saw + // approach because we had no aggregate visibility). CNPG triggers a PG + // restart on shared_preload_libraries change — with instances: 1 this + // is brief downtime. CREATE EXTENSION still needs to run once as a + // superuser on existing clusters; new clusters get it via the + // postInitApplicationSQL hook below. + "postgresql": map[string]any{ + "shared_preload_libraries": []any{"pg_stat_statements"}, + "parameters": map[string]any{ + "pg_stat_statements.track": "all", + }, + }, + "bootstrap": map[string]any{ + "initdb": map[string]any{ + "postInitApplicationSQL": []any{ + "CREATE EXTENSION IF NOT EXISTS pg_stat_statements", + }, + }, + }, }, }, }, pulumi.Provider(cluster.Provider), pulumi.DependsOnInputs(cloudNativePG.Ready), pulumi.RetainOnDelete(true)) diff --git a/internal/database/postgres.go b/internal/database/postgres.go index e40359a..ff139e2 100644 --- a/internal/database/postgres.go +++ b/internal/database/postgres.go @@ -127,7 +127,16 @@ func buildFilterConditions(filter *ServerFilter, argIndex int) ([]string, []any, return conditions, args, argIndex } -// addCursorCondition adds pagination cursor condition to WHERE clause +// addCursorCondition adds pagination cursor condition to WHERE clause. +// +// The compound cursor uses a row-constructor comparison so PostgreSQL can seek +// directly into the (server_name, version) B-tree index. The OR-decomposed form +// `server_name > X OR (server_name = X AND version > Y)` is logically equivalent +// but PostgreSQL's planner cannot use it for an index seek — it scans the index +// from the start and filters everything before the cursor, making cost grow +// linearly with cursor depth (a 20K-row table at a deep cursor took ~760ms in +// prod). The row-constructor form `(server_name, version) > (X, Y)` is special- +// cased and stays constant-time regardless of cursor depth. func addCursorCondition(cursor string, argIndex int) (string, []any, int) { if cursor == "" { return "", nil, argIndex @@ -138,9 +147,8 @@ func addCursorCondition(cursor string, argIndex int) (string, []any, int) { if len(parts) == 2 { cursorServerName := parts[0] cursorVersion := parts[1] - // Use compound condition: (server_name > cursor_name) OR (server_name = cursor_name AND version > cursor_version) - condition := fmt.Sprintf("(server_name > $%d OR (server_name = $%d AND version > $%d))", argIndex, argIndex+1, argIndex+2) - return condition, []any{cursorServerName, cursorServerName, cursorVersion}, argIndex + 3 + condition := fmt.Sprintf("(server_name, version) > ($%d, $%d)", argIndex, argIndex+1) + return condition, []any{cursorServerName, cursorVersion}, argIndex + 2 } // Fallback for malformed cursor - treat as server name only for backwards compatibility diff --git a/internal/database/postgres_test.go b/internal/database/postgres_test.go index d0e4b97..6784ae5 100644 --- a/internal/database/postgres_test.go +++ b/internal/database/postgres_test.go @@ -1150,6 +1150,104 @@ func TestPostgreSQL_PerformanceScenarios(t *testing.T) { // Should have retrieved all servers including the ones we just created assert.GreaterOrEqual(t, len(allResults), serverCount) }) + + t.Run("compound cursor across versions of same server", func(t *testing.T) { + // Insert multiple versions of two servers so cursor pagination has to + // correctly seek across the (server_name, version) boundary. This is the + // case that the row-constructor cursor predicate `(server_name, version) > ($1, $2)` + // has to handle — the OR-decomposed form had the same semantics but a + // linear-scan plan; this test pins the semantic behaviour so a future + // rewrite can't silently break it. + serverA := "com.example/cursor-test-a" + serverB := "com.example/cursor-test-b" + versionsA := []string{"1.0.0", "2.0.0", "3.0.0"} + versionsB := []string{"1.0.0", "2.0.0"} + + // First mark the latest version of each as latest=true; older ones false + // so the pkey + uniqueness constraints are satisfied. + mkServer := func(name, version string, isLatest bool) { + _, err := db.CreateServer(ctx, nil, &apiv0.ServerJSON{ + Name: name, Description: "compound cursor test", Version: version, + }, &apiv0.RegistryExtensions{ + Status: model.StatusActive, + StatusChangedAt: timeNow, PublishedAt: timeNow, UpdatedAt: timeNow, + IsLatest: isLatest, + }) + require.NoError(t, err) + } + for i, v := range versionsA { + mkServer(serverA, v, i == len(versionsA)-1) + } + for i, v := range versionsB { + mkServer(serverB, v, i == len(versionsB)-1) + } + + // Filter to just the two servers we just created so unrelated rows in the + // shared test DB don't bleed in. + filterTo := func(rs []*apiv0.ServerResponse) []*apiv0.ServerResponse { + out := make([]*apiv0.ServerResponse, 0, len(rs)) + for _, r := range rs { + if r.Server.Name == serverA || r.Server.Name == serverB { + out = append(out, r) + } + } + return out + } + + // Cursor at (serverA, "1.0.0") must skip 1.0.0 and return 2.0.0, 3.0.0, + // then both versions of serverB. Specifically tests the compound predicate: + // without it, the OR form would still skip 1.0.0 correctly but the version + // boundary of (serverA, "3.0.0") → (serverB, "1.0.0") is what depends on + // the second-column comparison. + results, _, err := db.ListServers(ctx, nil, nil, serverA+":1.0.0", 100) + require.NoError(t, err) + got := filterTo(results) + require.Len(t, got, 4, "expected 4 rows after cursor at A:1.0.0") + assert.Equal(t, serverA, got[0].Server.Name) + assert.Equal(t, "2.0.0", got[0].Server.Version) + assert.Equal(t, serverA, got[1].Server.Name) + assert.Equal(t, "3.0.0", got[1].Server.Version) + assert.Equal(t, serverB, got[2].Server.Name) + assert.Equal(t, "1.0.0", got[2].Server.Version) + assert.Equal(t, serverB, got[3].Server.Name) + assert.Equal(t, "2.0.0", got[3].Server.Version) + + // Cursor at the *last* version of serverA must cross the server boundary + // and return serverB rows only. + results, _, err = db.ListServers(ctx, nil, nil, serverA+":3.0.0", 100) + require.NoError(t, err) + got = filterTo(results) + require.Len(t, got, 2, "expected 2 rows after cursor at A:3.0.0") + assert.Equal(t, serverB, got[0].Server.Name) + assert.Equal(t, "1.0.0", got[0].Server.Version) + assert.Equal(t, serverB, got[1].Server.Name) + assert.Equal(t, "2.0.0", got[1].Server.Version) + + // Page-by-page traversal with size=2 must produce the same global ordering + // (A 1.0.0, A 2.0.0, A 3.0.0, B 1.0.0, B 2.0.0). + var paged []*apiv0.ServerResponse + cursor := "" + for { + rs, next, err := db.ListServers(ctx, nil, + &database.ServerFilter{SubstringName: stringPtr("cursor-test-")}, + cursor, 2) + require.NoError(t, err) + paged = append(paged, rs...) + if next == "" || len(rs) < 2 { + break + } + cursor = next + } + require.Len(t, paged, 5) + want := []struct{ name, version string }{ + {serverA, "1.0.0"}, {serverA, "2.0.0"}, {serverA, "3.0.0"}, + {serverB, "1.0.0"}, {serverB, "2.0.0"}, + } + for i, w := range want { + assert.Equal(t, w.name, paged[i].Server.Name, "row %d name", i) + assert.Equal(t, w.version, paged[i].Server.Version, "row %d version", i) + } + }) } func TestPostgreSQL_NewStatusFields(t *testing.T) { diff --git a/internal/service/registry_service.go b/internal/service/registry_service.go index 4403136..16a9100 100644 --- a/internal/service/registry_service.go +++ b/internal/service/registry_service.go @@ -18,6 +18,18 @@ import ( const maxServerVersionsPerServer = 10000 +// Publish phase names emitted on the structured "publish complete"/"publish failed" +// log from createServerInTransaction. Constants because version_checks is reported +// from multiple branches. +const ( + phaseValidate = "validate" + phaseAcquireLock = "acquire_lock" + phaseValidateRemoteURLs = "validate_remote_urls" + phaseVersionChecks = "version_checks" + phaseUnmarkLatest = "unmark_latest" + phaseDBCreate = "db_create" +) + // registryServiceImpl implements the RegistryService interface using our Database type registryServiceImpl struct { db database.Database @@ -87,60 +99,105 @@ func (s *registryServiceImpl) CreateServer(ctx context.Context, req *apiv0.Serve } // createServerInTransaction contains the actual CreateServer logic within a transaction. -func (s *registryServiceImpl) createServerInTransaction(ctx context.Context, tx pgx.Tx, req *apiv0.ServerJSON) (*apiv0.ServerResponse, error) { +// +// Phases are individually timed and emitted as a single structured log event per call. +// During the 2026-04-27 incident the validate-only timing (the previous shape) hid +// pool-exhaustion stalls in acquire_lock / version_checks / db_create — we saw 50s+ +// total publish times even though validate_ms was a few hundred ms. With every phase +// reported the next slow publish tells us which step to blame. +func (s *registryServiceImpl) createServerInTransaction(ctx context.Context, tx pgx.Tx, req *apiv0.ServerJSON) (resp *apiv0.ServerResponse, err error) { + start := time.Now() serverJSON := *req + var ( + validateMs, lockMs, remotesMs, versionChecksMs, unmarkMs, createMs int64 + failedPhase string + ) - // Validate the request. ValidatePublishRequest fans out to npm/PyPI/OCI for - // registry-ownership checks with 10s per-host timeouts, so it's the most likely - // contributor to publish latency. Log validate_ms on both success and failure - // so the next /v0/publish latency alert is diagnostic — a slow upstream that - // times out into a validation error is exactly the case we need to see. - validateStart := time.Now() - validateErr := validators.ValidatePublishRequest(ctx, serverJSON, s.cfg) - validateMs := time.Since(validateStart).Milliseconds() - if validateErr != nil { - slog.WarnContext(ctx, "publish validate failed", + defer func() { + attrs := []any{ "server_name", serverJSON.Name, "version", serverJSON.Version, + "total_ms", time.Since(start).Milliseconds(), "validate_ms", validateMs, - "error", validateErr.Error(), - ) - return nil, validateErr + "lock_ms", lockMs, + "remotes_ms", remotesMs, + "version_checks_ms", versionChecksMs, + "unmark_ms", unmarkMs, + "create_ms", createMs, + } + if err != nil { + attrs = append(attrs, "failed_phase", failedPhase, "error", err.Error()) + slog.WarnContext(ctx, "publish failed", attrs...) + } else { + slog.InfoContext(ctx, "publish complete", attrs...) + } + }() + + // runPhase times fn into *ms and, on error, stashes the phase name + error + // onto the closed-over failedPhase / err. Returns true on success so callers + // can `if !runPhase(...) { return nil, err }`. + runPhase := func(name string, ms *int64, fn func() error) bool { + t := time.Now() + e := fn() + *ms = time.Since(t).Milliseconds() + if e != nil { + failedPhase = name + err = e + return false + } + return true + } + + // Validate the request — registry-ownership checks fan out to npm/PyPI/OCI with + // 10s per-host timeouts. Was historically the most likely slow phase; now any + // phase can be the slow one when the connection pool is starved. + if !runPhase(phaseValidate, &validateMs, func() error { + return validators.ValidatePublishRequest(ctx, serverJSON, s.cfg) + }) { + return nil, err } publishTime := time.Now() // Acquire advisory lock to prevent concurrent publishes of the same server - if err := s.db.AcquirePublishLock(ctx, tx, serverJSON.Name); err != nil { + if !runPhase(phaseAcquireLock, &lockMs, func() error { + return s.db.AcquirePublishLock(ctx, tx, serverJSON.Name) + }) { return nil, err } // Check for duplicate remote URLs - if err := s.validateNoDuplicateRemoteURLs(ctx, tx, serverJSON); err != nil { + if !runPhase(phaseValidateRemoteURLs, &remotesMs, func() error { + return s.validateNoDuplicateRemoteURLs(ctx, tx, serverJSON) + }) { return nil, err } - // Check we haven't exceeded the maximum versions allowed for a server - versionCount, err := s.db.CountServerVersions(ctx, tx, serverJSON.Name) - if err != nil && !errors.Is(err, database.ErrNotFound) { - return nil, err - } - if versionCount >= maxServerVersionsPerServer { - return nil, database.ErrMaxServersReached - } - - // Check this isn't a duplicate version - versionExists, err := s.db.CheckVersionExists(ctx, tx, serverJSON.Name, serverJSON.Version) - if err != nil { - return nil, err - } - if versionExists { - return nil, database.ErrInvalidVersion - } - - // Get current latest version to determine if new version should be latest - currentLatest, err := s.db.GetCurrentLatestVersion(ctx, tx, serverJSON.Name) - if err != nil && !errors.Is(err, database.ErrNotFound) { + // Version checks: count, exists, current-latest (small DB lookups, but on a + // starved pool any of them stalls until a connection is free). Bundled under + // one phase since they share a logical step. + var currentLatest *apiv0.ServerResponse + if !runPhase(phaseVersionChecks, &versionChecksMs, func() error { + versionCount, e := s.db.CountServerVersions(ctx, tx, serverJSON.Name) + if e != nil && !errors.Is(e, database.ErrNotFound) { + return e + } + if versionCount >= maxServerVersionsPerServer { + return database.ErrMaxServersReached + } + versionExists, e := s.db.CheckVersionExists(ctx, tx, serverJSON.Name, serverJSON.Version) + if e != nil { + return e + } + if versionExists { + return database.ErrInvalidVersion + } + currentLatest, e = s.db.GetCurrentLatestVersion(ctx, tx, serverJSON.Name) + if e != nil && !errors.Is(e, database.ErrNotFound) { + return e + } + return nil + }) { return nil, err } @@ -161,7 +218,9 @@ func (s *registryServiceImpl) createServerInTransaction(ctx context.Context, tx // Unmark old latest version if needed if isNewLatest && currentLatest != nil { - if err := s.db.UnmarkAsLatest(ctx, tx, serverJSON.Name); err != nil { + if !runPhase(phaseUnmarkLatest, &unmarkMs, func() error { + return s.db.UnmarkAsLatest(ctx, tx, serverJSON.Name) + }) { return nil, err } } @@ -176,16 +235,13 @@ func (s *registryServiceImpl) createServerInTransaction(ctx context.Context, tx } // Insert new server version - resp, err := s.db.CreateServer(ctx, tx, &serverJSON, officialMeta) - if err != nil { + if !runPhase(phaseDBCreate, &createMs, func() error { + var e error + resp, e = s.db.CreateServer(ctx, tx, &serverJSON, officialMeta) + return e + }) { return nil, err } - - slog.InfoContext(ctx, "publish complete", - "server_name", serverJSON.Name, - "version", serverJSON.Version, - "validate_ms", validateMs, - ) return resp, nil } From a4d9d829205ad1982c4bc345763e870c79643235 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 27 Apr 2026 15:58:11 -0400 Subject: [PATCH 056/190] deploy: update prod to v1.7.2 (#1216) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Promotes [v1.7.2](https://github.com/modelcontextprotocol/registry/releases/tag/v1.7.2) (PR #1215) to production: - **Row-constructor cursor pagination** — fixes the 760ms list query that was the root cause of today's pool-exhaustion alerts. Local benchmark shows /v0/servers paginated requests dropping from ~30ms (cold cache, 100K rows) to ~0.05ms. - **Per-phase publish slog** — `publish complete` events now include validate / lock / remotes / version_checks / unmark / db_create timings so the next slow publish is self-diagnostic. - **pg_stat_statements** — aggregate query visibility we didn't have during today's incident. ## Deployment caveat The CNPG cluster spec change for `pg_stat_statements` triggers an in-pod postgres restart on the next prod Pulumi run. Staging took **~45–70s of registry unavailability** during the equivalent restart. The DB retry-with-backoff in v1.7.1 covers most of it, but registry pods may bounce once before they reconnect (one staging pod hit `Failed to connect after 8 attempts` then recovered on its next restart). **Time the merge for a low-traffic UTC window** — the alert history suggests very early UTC is quietest. ## Post-merge action Once the prod Pulumi run completes, run once on the existing cluster: ```bash PATH=/opt/homebrew/share/google-cloud-sdk/bin:$PATH kubectl exec -i registry-pg-1 -c postgres \ --context gke_mcp-registry-prod_us-central1-b_mcp-registry-prod \ -- psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements" ``` Verify: ```bash kubectl exec -i registry-pg-1 -c postgres \ --context gke_mcp-registry-prod_us-central1-b_mcp-registry-prod \ -- psql -U postgres -d app -c " SELECT round(mean_exec_time::numeric, 2) AS mean_ms, calls, substring(query, 1, 80) AS q FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;" ``` ## Test plan - [x] v1.7.2 release built and pushed (`ghcr.io/modelcontextprotocol/registry:1.7.2`) - [x] Staging deployed cleanly; `pg_stat_statements` is collecting on staging - [ ] Prod Pulumi run applies cleanly; brief PG restart - [ ] Run `CREATE EXTENSION` on prod - [ ] Confirm `publish complete` events contain per-phase timings on the next publish 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index 1dd623b..46c12c2 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.7.1 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.7.2 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From 3764acad404e3d145117c781c70d18bdc3137c60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 03:23:14 -0400 Subject: [PATCH 057/190] build(deps): bump github.com/pulumi/pulumi-kubernetes/sdk/v4 from 4.29.0 to 4.30.0 in /deploy (#1217) Bumps [github.com/pulumi/pulumi-kubernetes/sdk/v4](https://github.com/pulumi/pulumi-kubernetes) from 4.29.0 to 4.30.0. Release notes
Sourced from github.com/pulumi/pulumi-kubernetes/sdk/v4's releases.
v4.30.0
No release notes provided.
Changelog
Sourced from github.com/pulumi/pulumi-kubernetes/sdk/v4's changelog.
4.30.0 (April 24, 2026)
Fixed
- #4295Fix kustomize.v2.Directory resource output type in the schema to properly support array outputs. Previously, the resources field was incorrectly typed as a
stringin the schema. This fix updates the type to an array ofAny, aligning the schema with the provider's Go implementation (pulumi.ArrayOutput). This resolves a regression that caused the Kustomize v2 resource to fail in the Python SDK.- #2997 Stop stripping null values when unmarshaling, fixing Helm chart default deletion and
valueYamlFilesnull handling. DeprecateallowNullValues(no longer needed).Changed
- Upgrade Kubernetes schema and libraries to v1.35.4.
- Upgrade Kubernetes schema and libraries to v1.36.0.
Commits
55e3b2dAutomated upgrade: bump Kubernetes to v1.36.0 (#4304)437be67Update GitHub Actions workflows. (#4308)7e10bf3Don't skip nulls when unmarshaling (#4293)f4379dfUpdate GitHub Actions workflows. (#4301)da7a987Update GitHub Actions workflows. (#4297)d1122d1fix: correctkustomize.v2.Directoryschema types to fix Python SDK (#4295)ec3b5cbAutomated upgrade: bump Kubernetes to v1.35.4 (#4286)779d4c8Update GitHub Actions workflows. (#4294)fcfebd1Update GitHub Actions workflows. (#4292)8b58167Update GitHub Actions workflows. (#4291)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 3c86c89..79fbc0e 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -4,7 +4,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 - github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0 + github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 github.com/pulumi/pulumi/sdk/v3 v3.232.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/deploy/go.sum b/deploy/go.sum index 2c2628b..e3c85c8 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -181,8 +181,8 @@ github.com/pulumi/esc v0.17.0 h1:oaVOIyFTENlYDuqc3pW75lQT9jb2cd6ie/4/Twxn66w= github.com/pulumi/esc v0.17.0/go.mod h1:XnSxlt5NkmuAj304l/gK4pRErFbtqq6XpfX1tYT9Jbc= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9FjWCUBCq6U= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= -github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0 h1:NHikF7fXARV//HEwK8wW8kBq+8TGf1pzSV1O946AXDY= -github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.29.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= +github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 h1:nF0Y1F7fUGL6RYD9EAtHTdDbNFmDaA3xcEiRlvCDV5E= +github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= github.com/pulumi/pulumi/sdk/v3 v3.232.0 h1:pU9j5qYHYtYZGaIKha1KFuB9ggp2obcMD1U523tpEnk= github.com/pulumi/pulumi/sdk/v3 v3.232.0/go.mod h1:33NoTpvQXlTtAuaPbompgZNA3Ye4XEvxNydELFlWza8= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= From a490b6f1ecc171ce7235bb29560cb2a56e950fa6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Apr 2026 03:23:31 -0400 Subject: [PATCH 058/190] build(deps): bump goreleaser/goreleaser-action from 7.1.0 to 7.2.1 in the actions group (#1218) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the actions group with 1 update: [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action). Updates `goreleaser/goreleaser-action` from 7.1.0 to 7.2.1 Release notes
Sourced from goreleaser/goreleaser-action's releases.
v7.2.1
This fully removes the usage of the old
nightlymoving tag.Full Changelog: https://github.com/goreleaser/goreleaser-action/compare/v7.2.0...v7.2.1
v7.2.0
What's Changed
- test: cover install across release eras by
@caarlos0in goreleaser/goreleaser-action#555- feat: add
version-fileinput by@caarlos0in goreleaser/goreleaser-action#556- feat: resolve nightly to latest vX.Y.Z--nightly release by
@caarlos0in goreleaser/goreleaser-action#558Full Changelog: https://github.com/goreleaser/goreleaser-action/compare/v7...v7.2.0
Commits
1a80836ci(nightly): pass GITHUB_TOKEN to nightly integration joba71152erefactor: drop legacy 'nightly' tag fallback4c6ab56feat: resolve nightly to latest vX.Y.Z-<sha>-nightly release (#558)4f96abffeat: addversion-fileinput (#556)15fa2a9test: cover install across release eras (#555)- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b0e6c1f..7b248f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: anchore/sbom-action/download-syft@v0.24.0 - name: Run GoReleaser - uses: goreleaser/goreleaser-action@e24998b8b67b290c2fa8b7c14fcfa7de2c5c9b8c + uses: goreleaser/goreleaser-action@1a80836c5c9d9e5755a25cb59ec6f45a3b5f41a8 with: distribution: goreleaser version: v2.12.0 From 54cbe2473cf37fabee22aeea56968b4448f84371 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Tue, 28 Apr 2026 15:03:21 -0400 Subject: [PATCH 059/190] fix(list): use JSONB containment for RemoteURL filter (GIN-indexable) (#1220) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Same shape of bug as #1215's cursor fix, different filter. The RemoteURL filter built its WHERE predicate using `jsonb_array_elements` + `->>` extraction, which the planner can't translate into a GIN search. Replaced with a JSONB containment predicate `@>` that uses `idx_servers_json_remotes`. ## Diagnosis (from the per-phase publish slog #1215 added) Today's first publish-latency alert at 17:08 UTC pointed straight at this: ``` publish complete server_name=dev.storage/mcp version=1.10.1 total_ms=14822 validate_ms=0 lock_ms=238 remotes_ms=10980 version_checks_ms=535 unmark_ms=3014 create_ms=53 ``` `remotes_ms=10,980` on a server with **one** remote URL pointed at `validateNoDuplicateRemoteURLs`, which runs the RemoteURL filter against the database. EXPLAIN ANALYZE on prod confirmed: ``` Filter: (status != 'deleted') AND EXISTS(SubPlan 1) Rows Removed by Filter: 21,092 ← scans the whole table Buffers: shared hit=20,028 Execution Time: 10,005 ms ``` ## Fix `internal/database/postgres.go:99` rewritten: ```sql -- before (planner can't use GIN index for this) EXISTS (SELECT 1 FROM jsonb_array_elements(value->'remotes') AS remote WHERE remote->>'url' = $1) -- after (GIN-indexable) value -> 'remotes' @> jsonb_build_array(jsonb_build_object('url', $1::text)) ``` Semantically equivalent for our schema (`url` is always a string, NOT NULL). ## Local benchmark — 20K rows, prod-shaped JSONB (~1KB/row) | Form | Buffer hits | Index used | Time | |------|------------:|------------|-----:| | OLD | 40,398 | none — full scan | 17.0 ms | | NEW | **294** | **`idx_servers_json_remotes` GIN bitmap** | **1.6 ms** | Maps to prod's 10,005 ms cold-cache observation — same shape of speedup we got from the cursor fix. ## Scope honesty This PR addresses the **publish slowness path** (`validateNoDuplicateRemoteURLs` in the publish transaction). It directly resolves today's 17:08 UTC `Publish Endpoint Latency` alert. It does **not** address: - Today's 17:35–17:40 UTC `Availability dropped below 95%` alert. Per-investigation: only 4 publishes happened in the entire 17:00–17:50 window and zero during the burst minutes — so my initial "concurrent slow publishes starved the pool" hypothesis was wrong. The actual cause was scraper-driven concurrency (4,500+ requests in 5 min) on plain cursor pagination + ILIKE substring search, where individual queries are fast (mean 42 ms) but tail latency under concurrency reaches 10 s server-side and 20–35 s nginx-level due to pool queueing. - The 18:17 UTC `Publish Endpoint Latency` re-fire (same scraper-driven concurrency). A follow-up PR will raise pool size + PG `max_connections` + add explicit PG resource limits to absorb concurrency without queue blowup. That fix has a different shape (config) and a different risk profile (PG restart for `max_connections`); kept separate so this surgical SQL change can ship cleanly. ## Test plan - [x] `go build ./...` clean - [x] `make lint` clean - [x] `go test -race ./internal/database/... ./internal/service/...` green — existing `TestPostgreSQL_ListServers/filter by remote URL` covers semantic correctness - [x] EXPLAIN ANALYZE comparison locally on 20K rows + prod-shaped JSONB - [ ] After merge + deploy: verify on prod via `EXPLAIN ANALYZE`; confirm `remotes_ms` in `publish complete` slog drops to single-digit ms ## Out of scope (separate follow-ups) - pgxpool `MaxConns` / `MinConns` bump + PG `max_connections` raise + PG `resources` limits — addresses the cursor-tail and ILIKE-search concurrency that this PR doesn't touch - Per-IP rate limiting at nginx — defends against scraper retry storms regardless of query speed - `Cache-Control` headers on `/v0/servers` — let nginx absorb scraper repeats - Pre-existing `superfluous WriteHeader` warnings — separate Huma framework issue - ILIKE substring search on `server_name` is unindexable — could be replaced with `pg_trgm` GIN index or full-text search 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- internal/database/postgres.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/internal/database/postgres.go b/internal/database/postgres.go index ff139e2..105c570 100644 --- a/internal/database/postgres.go +++ b/internal/database/postgres.go @@ -96,7 +96,15 @@ func buildFilterConditions(filter *ServerFilter, argIndex int) ([]string, []any, argIndex++ } if filter.RemoteURL != nil { - conditions = append(conditions, fmt.Sprintf("EXISTS (SELECT 1 FROM jsonb_array_elements(value->'remotes') AS remote WHERE remote->>'url' = $%d)", argIndex)) + // Use a JSONB containment predicate so the planner can use the GIN index + // idx_servers_json_remotes on (value -> 'remotes'). The previously-used + // EXISTS / jsonb_array_elements / ->> form is logically equivalent but + // the planner can't translate the per-row array unfolding into a GIN + // search — it falls back to scanning every row. validateNoDuplicateRemoteURLs + // in the publish path ran this filter and was measured at ~10s on prod's + // 21K-row table on 2026-04-28; the containment form is GIN-indexable and + // completes in low single-digit ms. + conditions = append(conditions, fmt.Sprintf("value -> 'remotes' @> jsonb_build_array(jsonb_build_object('url', $%d::text))", argIndex)) args = append(args, *filter.RemoteURL) argIndex++ } From 736d37685808225a4fed0efaf39e2049920e06bb Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Tue, 28 Apr 2026 15:21:24 -0400 Subject: [PATCH 060/190] fix(db): raise pgxpool MaxConns + PG max_connections + set PG resources (#1221) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Follow-up to #1215 and #1220. Both of those addressed *individual* slow queries; this PR addresses *concurrency* — under today's scraper load the cursor query is fast on average (mean 42ms) but the connection pool saturates and queue depth blows up at the Go HTTP layer. ## Diagnosis `pg_stat_statements` (added in #1215) made this possible to see: ``` max_ms mean_ms calls template 10,755 41.8 94,009 plain cursor pagination, no filter 7,277 214.7 14,770 ILIKE substring filter 7,638 330.8 7,656 ILIKE substring + is_latest filter ``` Mean times are healthy. But `max_exec_time` of 7–10s on the cursor query, combined with sustained ~15 req/s from scrapers (ServiceNow's 148.139.x.x range, anonymous `node` user-agent, etc) saturates `MaxConns=30 × 2 pods = 60`. New requests queue at the Go HTTP layer; nginx-side p99 hits 35s; eventually scrapers time out at 60s, retry, and amplify the queue. Today's two ongoing alerts are both this pattern: - 17:35–17:40 UTC `Availability dropped below 95%` — 4,526 GET requests in 5 min, hundreds of 504s - 18:17 UTC `Publish Endpoint Latency` re-fire — same scraper concurrency dragging the publish path Critically, the symptoms today were also visible during yesterday's incident, but yesterday's broken cursor (#1215) was the dominant cause. After #1215 the cursor is fast individually; concurrency now becomes the next bottleneck. ## Changes ### pgxpool (`internal/database/postgres.go`) | Setting | Before | After | |---------|-------:|------:| | `MaxConns` | 30 | **60** per pod | | `MinConns` | 5 | **10** per pod | | `MaxConnIdleTime` | 30 min | (unchanged) | | `MaxConnLifetime` | 2 h | (unchanged) | 2 pods × 60 = 120 total app connections. Cuts queue depth roughly in half at current scraper load. ### PG cluster (`deploy/pkg/k8s/postgres.go`) - `max_connections: 100 → 200` — required to support the larger pool. 120 (app) + ~10 (PG internals: autovacuum, replication, admin) + 70 headroom. - Added explicit `resources:` block — previously the pod had no resource limits, making node-level OOM behaviour unpredictable. | | Request | Limit | |---|--------:|------:| | memory | 512Mi | **4Gi** | | cpu | 200m | 1500m | ## Resource budget | Node | Now | After | |------|----:|------:| | dy89 (PG node) | 39% mem (~2.4 GiB / 6 GiB) | ~65% mem worst-case (~3.9 GiB) | | 2yxm | 36% mem | unchanged | Both nodes well within capacity. CPU usage <50% on both, plenty of headroom. PG worst-case memory math: - 200 conns × ~15 MB per backend = 3 GiB - + `shared_buffers` 128 MiB - + `maintenance_work_mem`, OS overhead, etc. - ≈ 3–4 GiB total ## Deployment caveat `max_connections` is a postmaster-level setting → CNPG triggers a PG restart on the change. Same in-pod restart shape as the pg_stat_statements deploy yesterday — registry pods see ~30s of DB unavailability, covered by v1.7.1's retry-with-backoff (8 attempts, 1→8s capped). One registry pod may bounce once before recovering, like yesterday. **Time the merge for a low-traffic UTC window.** Order of operations matters within the deploy itself: 1. Pulumi applies the new CNPG spec → PG restarts with `max_connections=200` 2. Rolling deploy of registry pods picks up `MaxConns=60` config 3. New conns are accepted up to 200 limit Pulumi's standard ordering does step 1 before step 2 in this scenario (Pulumi resource graph: CNPG cluster precedes Deployment). If for any reason it doesn't, the worst case is `too many connections` errors during a small window — Self-correcting once the rollout completes. ## Test plan - [x] `go build ./...` clean for app + deploy - [x] `make lint` clean - [x] `go test -race ./internal/database/...` green - [ ] On merge: staging deploy applies the spec change cleanly; PG restarts; pool reaches 60 max - [ ] On prod deploy: same; verify no `too many connections` errors during the rollout window - [ ] After deploy: query `SHOW max_connections` returns 200; query pg_stat_statements after a scraper burst, confirm `max_exec_time` for cursor query no longer hits 10s ## Out of scope - **ILIKE substring search** (`server_name ILIKE '%foo%'`) is unindexable. Three pg_stat_statements variants run with means 141–333ms and max 4–7s. Worth replacing with a `pg_trgm` GIN index or full-text search in a separate PR. - **Per-IP nginx rate limiting** — defends against scraper retry storms regardless of pool size. - **`Cache-Control` on `/v0/servers`** — let nginx absorb scraper-repeated cursors. - **Pre-existing `superfluous WriteHeader` warnings** — separate Huma framework issue. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/pkg/k8s/postgres.go | 21 +++++++++++++++++++++ internal/database/postgres.go | 10 +++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/deploy/pkg/k8s/postgres.go b/deploy/pkg/k8s/postgres.go index 7a119fd..0b5e407 100644 --- a/deploy/pkg/k8s/postgres.go +++ b/deploy/pkg/k8s/postgres.go @@ -59,6 +59,21 @@ func DeployPostgresDatabases(ctx *pulumi.Context, cluster *providers.ProviderInf "storage": map[string]any{ "size": "50Gi", }, + // Explicit resource budget. PG was previously unlimited which made + // node-level OOM behaviour unpredictable. With max_connections=200 + // the worst-case per-connection memory (~10–15MB each) plus + // shared_buffers and overhead lands around 3–4GiB; 4Gi limit gives + // headroom for query workspaces (work_mem) and OS-level effects. + "resources": map[string]any{ + "requests": map[string]any{ + "memory": "512Mi", + "cpu": "200m", + }, + "limits": map[string]any{ + "memory": "4Gi", + "cpu": "1500m", + }, + }, // Enable pg_stat_statements so we can attribute slow time to specific // queries (the 2026-04-27 incident took an EXPLAIN-the-one-query-I-saw // approach because we had no aggregate visibility). CNPG triggers a PG @@ -66,10 +81,16 @@ func DeployPostgresDatabases(ctx *pulumi.Context, cluster *providers.ProviderInf // is brief downtime. CREATE EXTENSION still needs to run once as a // superuser on existing clusters; new clusters get it via the // postInitApplicationSQL hook below. + // + // max_connections raised from default 100 to 200 because the registry + // pgxpool was bumped from 30 to 60 per pod (120 total across 2 pods) + // + ~10 reserved for PG internals and ad-hoc admin = 130, with 70 + // headroom for future scale or burst. "postgresql": map[string]any{ "shared_preload_libraries": []any{"pg_stat_statements"}, "parameters": map[string]any{ "pg_stat_statements.track": "all", + "max_connections": "200", }, }, "bootstrap": map[string]any{ diff --git a/internal/database/postgres.go b/internal/database/postgres.go index 105c570..1b0abdb 100644 --- a/internal/database/postgres.go +++ b/internal/database/postgres.go @@ -45,9 +45,13 @@ func NewPostgreSQL(ctx context.Context, connectionURI string) (*PostgreSQL, erro return nil, fmt.Errorf("failed to parse PostgreSQL config: %w", err) } - // Configure pool for stability-focused defaults - config.MaxConns = 30 // Handle good concurrent load - config.MinConns = 5 // Keep connections warm for fast response + // Configure pool for stability-focused defaults. + // MaxConns was 30 per pod (60 total across 2 replicas) which saturated under + // the 2026-04-28 scraper bursts (15 req/s on /v0/servers caused queue blowup + // even though individual queries were fast). 60 per pod gives 120 total, + // leaving 80 of PG max_connections=200 for autovacuum/admin/headroom. + config.MaxConns = 60 // Handle scraper-burst concurrent load + config.MinConns = 10 // Keep connections warm for fast response config.MaxConnIdleTime = 30 * time.Minute // Keep connections available for bursts config.MaxConnLifetime = 2 * time.Hour // Refresh connections regularly for stability From 0a97e59ecb937a59b880d20a8a2f47579ba5d9ea Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Tue, 28 Apr 2026 17:50:38 -0400 Subject: [PATCH 061/190] deploy: update prod to v1.7.3 (#1223) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Promotes [v1.7.3](https://github.com/modelcontextprotocol/registry/releases/tag/v1.7.3) to production. Contents: - **#1220** — `RemoteURL` filter SQL rewritten to use JSONB containment (`@>`) instead of `EXISTS jsonb_array_elements`. The new form is GIN-indexable; the old form forced a full table scan. Local benchmark: 40,398 → 294 buffer reads, 17 ms → 1.6 ms. Maps to prod's 10,005 ms cold-cache observation. - **#1221** — pgxpool `MaxConns 30→60`, `MinConns 5→10`. PG `max_connections 100→200`. Explicit PG `resources:` block (was unset). ## What this addresses - **#1220**: yesterday's 17:08 UTC `Publish Endpoint Latency` alert (`dev.storage/mcp` publish took 14.8s with `remotes_ms=10980` — pinpointed by the per-phase slog from #1215). - **#1221**: yesterday's 17:35–17:40 UTC `Availability dropped below 95%` alert and 18:17 UTC `Publish Endpoint Latency` re-fire. Both were scraper-driven concurrency on `/v0/servers` (~15 req/s sustained from ServiceNow + others). With the bumped pool, the queue at the Go HTTP layer should clear faster instead of blowing up to 20–35s nginx-level latencies. ## Deployment caveat The PG `max_connections` change is a postmaster-level setting → CNPG triggers a PG restart on the next prod Pulumi run. With `instances: 1` this is brief downtime — staging took **~30s** during the equivalent restart, with **one registry pod bouncing once** on its 8-attempt DB-retry budget before recovering on the next kubelet restart. **Time the merge for a low-traffic UTC window.** Alert history suggests very early UTC (02:00–04:00) is quietest. ## Resource impact PG node memory is currently 39% (~2.4 GiB / 6 GiB allocatable). Worst-case PG memory growth with `max_connections=200` lands around 3–4 GiB, putting the node at ~65% — fits with headroom. Empirically, prod PG has peaked at **413 MiB** in the last 30h of incident data, so the proposed 4 GiB limit is ~10× the historical max — guardrail not constraint. ## Post-merge CNPG handles `pg_stat_statements` extension creation automatically (no manual `CREATE EXTENSION` step needed — it was already done in v1.7.2's deploy). Verify after deploy: ```bash PATH=/opt/homebrew/share/google-cloud-sdk/bin:$PATH # max_connections actually changed kubectl exec -i registry-pg-1 -c postgres \ --context gke_mcp-registry-prod_us-central1-b_mcp-registry-prod \ -- psql -U postgres -tAc "SHOW max_connections" # expect: 200 # resources block applied kubectl get pod registry-pg-1 \ --context gke_mcp-registry-prod_us-central1-b_mcp-registry-prod \ -o jsonpath='{.spec.containers[?(@.name=="postgres")].resources}{"\n"}' # pgxpool MaxConns reflected (registry app uses 60 per pod after restart) kubectl exec -i registry-pg-1 -c postgres \ --context gke_mcp-registry-prod_us-central1-b_mcp-registry-prod \ -- psql -U postgres -tAc "SELECT count(*) FROM pg_stat_activity WHERE datname='app'" ``` ## Test plan - [x] v1.7.3 release built and pushed (`ghcr.io/modelcontextprotocol/registry:1.7.3`) - [x] Staging deployed cleanly; PG restarted and came back with `max_connections=200`; one staging pod bounced as expected - [ ] Prod Pulumi run applies cleanly; brief PG restart - [ ] Confirm `SHOW max_connections` returns 200 on prod - [ ] Confirm `publish complete` events show `remotes_ms` < 10ms - [ ] Watch for any "too many connections" errors during the rollout window (none expected — Pulumi orders CNPG cluster before Deployment, so PG accepts the new conn limit before pgxpool tries to use it) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index 46c12c2..d071b8f 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.7.2 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.7.3 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From 5dcae5b3cee0f5ebfcc3c65c196bc5f89c6a1a68 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Wed, 29 Apr 2026 14:05:09 -0400 Subject: [PATCH 062/190] fix(deploy): bump registry pod memory to match doubled pgxpool size (#1225) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Follow-up to #1221. That PR doubled pgxpool `MaxConns` from 30 to 60 per pod without bumping the registry pod memory limit. pgxpool keeps per-connection state in the Go process (prepared statement cache, scratch buffers, row iteration state), so memory grew roughly proportionally — peak per-pod usage shifted from ~330 MB to ~450 MB against a 512 MiB limit. ## What surfaced it Pod `tx49f` was OOMKilled at 17:01 UTC on 2026-04-29 (`exitCode 137`, `reason: OOMKilled`). Memory history from Cloud Monitoring confirms the regression: | Pods | Peak 30-min memory | |------|-------------------:| | Pre-#1221 (`MaxConns=30`) | 178–333 MB | | **Post-#1221** (`MaxConns=60`) | **437–449 MB** | | Old limit | **512 MiB** ← right at the edge | Other pod was at 394 MB at the time of inspection — could OOM again. ## Fix `deploy/pkg/k8s/registry.go:217-225`: | | Before | After | |---|-------:|------:| | `requests.memory` | 256 MiB | **512 MiB** | | `limits.memory` | 512 MiB | **1 GiB** | 1 GiB is ~2× the current peak under load — gives room for traffic spikes without immediate OOM risk. Either node has 4–5 GiB free allocatable memory, so the new request fits comfortably. ## Test plan - [x] `go build ./...` clean - [x] `golangci-lint run` clean - [ ] After release + prod promotion: pod memory stabilises around 450 MB peak with no OOMKills - [ ] After release + prod promotion: tx49f restartCount stops climbing (currently at 5) ## Deployment Zero downtime — Deployment template change only, rolling update with `maxSurge: 1, maxUnavailable: 0`. **No PG involvement** (no `max_connections` change, no shared_preload_libraries change). Same shape as a normal v1.7.x image promotion. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/pkg/k8s/registry.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/deploy/pkg/k8s/registry.go b/deploy/pkg/k8s/registry.go index 579f740..48e9124 100644 --- a/deploy/pkg/k8s/registry.go +++ b/deploy/pkg/k8s/registry.go @@ -215,12 +215,20 @@ func DeployMCPRegistry(ctx *pulumi.Context, cluster *providers.ProviderInfo, env TimeoutSeconds: pulumi.Int(3), }, Resources: &corev1.ResourceRequirementsArgs{ + // Memory was 256Mi/512Mi when pgxpool MaxConns was 30. After + // #1221 doubled MaxConns to 60 per pod, peak per-pod memory + // shifted from ~330MB to ~450MB under scraper load and one + // pod was OOMKilled at 17:01 UTC on 2026-04-29. pgxpool keeps + // per-connection state (prepared statement cache, scratch + // buffers, row iteration state) so memory scales roughly + // linearly with the connection count. Doubled both request + // and limit to match. Requests: pulumi.StringMap{ - "memory": pulumi.String("256Mi"), + "memory": pulumi.String("512Mi"), "cpu": pulumi.String("100m"), }, Limits: pulumi.StringMap{ - "memory": pulumi.String("512Mi"), + "memory": pulumi.String("1Gi"), }, }, }, From f7663fe91a2d39153a9bc262ce8055a1727ce065 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Wed, 29 Apr 2026 14:43:18 -0400 Subject: [PATCH 063/190] deploy: update prod to v1.7.4 (#1226) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Promotes [v1.7.4](https://github.com/modelcontextprotocol/registry/releases/tag/v1.7.4) (#1225) to production: registry pod memory request `256Mi → 512Mi`, limit `512Mi → 1Gi`. ## Why #1221 doubled pgxpool `MaxConns` 30→60 per pod without bumping the registry pod memory limit. pgxpool keeps per-connection state in the Go process (prepared statement cache, scratch buffers, row iteration state) so peak per-pod memory shifted from ~330 MB to ~450 MB against the 512 MiB limit. Pod `tx49f` was OOMKilled at 17:01 UTC on 2026-04-29. ## Validation so far - Staging deployed cleanly via `deploy-staging.yml` after #1225 merged - Both staging pods running with `req=512Mi limit=1Gi` ✓ - Rolling update was clean — no failed health checks during the transition - Both pods spread across nodes (q716 + 7exo) ## Deployment **Zero downtime** — Deployment template change only, rolling update with `maxSurge: 1, maxUnavailable: 0`. No PG involvement (no `max_connections` change, no shared_preload_libraries change). ## Test plan - [x] v1.7.4 release built and pushed (`ghcr.io/modelcontextprotocol/registry:1.7.4`) - [x] Staging deployed cleanly with new limits - [ ] Prod Pulumi run applies cleanly; rolling update completes - [ ] Prod pods come up with `req=512Mi limit=1Gi` - [ ] After 24h: no OOMKills on either pod, peak memory stays under ~600 MB 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index d071b8f..3859f13 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.7.3 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.7.4 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From 1201cbd82b2cf6d4b56edfc05c763059a12f9fdb Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Wed, 29 Apr 2026 19:14:00 -0400 Subject: [PATCH 064/190] security: fix open redirect and add small hardening (#1227) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What this does Fixes an open redirect plus a handful of small, mostly-invisible hardening changes around it. ## What's in it - **The fix**: trailing-slash redirects no longer let `//evil.com/` redirect off-host. - **SSRF block** on the DNS/HTTP namespace verification — refuses to dial loopback, RFC1918, link-local, multicast, CGNAT, or IP-literal/single-label \"domains\". - **Slow-client guard**: `ReadTimeout` and `IdleTimeout` on the HTTP server (no `WriteTimeout` — would risk cutting off legitimate multi-package publishes). - **Defence-in-depth headers** on the UI (`/`) and 404 responses. - **5xx responses** stop leaking raw DB error text to clients (logged server-side instead). - **Search filter** stops treating `%` and `_` as wildcards. - **Validators**: PyPI/NuGet identifiers URL-escaped before fetching; MCPB no longer follows redirects. - **Misc**: `Version` field bounded to 255 chars; logs quote user input; `BlockedNamespaces` denylist now catches subdomain claimants. Each change is its own commit so they can be reviewed (or reverted) independently. ## Test plan - [ ] CI green - [ ] Synthetic publish in staging for each package type (npm, pypi, nuget, oci, mcpb) — confirms validator changes don't regress - [ ] Quick browser check of `/` after deploy to confirm UI still loads with the new CSP - [ ] `curl https:// //evil.com/` — confirm the open redirect is closed 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- docs/reference/api/openapi.yaml | 1 + .../server-json/draft/server.schema.json | 1 + internal/api/handlers/v0/auth/common.go | 13 +++ internal/api/handlers/v0/auth/common_test.go | 49 +++++++++++ internal/api/handlers/v0/auth/dns_test.go | 11 --- internal/api/handlers/v0/auth/http.go | 86 +++++++++++++++++++ .../handlers/v0/auth/http_internal_test.go | 52 +++++++++++ internal/api/handlers/v0/auth/http_test.go | 11 --- internal/api/handlers/v0/edit.go | 4 +- internal/api/handlers/v0/servers.go | 10 ++- internal/api/handlers/v0/status.go | 10 ++- internal/api/router/router.go | 23 ++++- internal/api/server.go | 18 +++- internal/api/server_test.go | 16 ++++ internal/auth/jwt.go | 11 ++- internal/database/postgres.go | 9 +- internal/validators/registries/mcpb.go | 23 ++++- internal/validators/registries/nuget.go | 15 ++-- internal/validators/registries/pypi.go | 10 ++- internal/validators/schemas/2025-12-11.json | 1 + pkg/api/v0/types.go | 2 +- pkg/model/types.go | 2 +- 22 files changed, 330 insertions(+), 48 deletions(-) create mode 100644 internal/api/handlers/v0/auth/common_test.go create mode 100644 internal/api/handlers/v0/auth/http_internal_test.go diff --git a/docs/reference/api/openapi.yaml b/docs/reference/api/openapi.yaml index faf8895..108e2fb 100644 --- a/docs/reference/api/openapi.yaml +++ b/docs/reference/api/openapi.yaml @@ -688,6 +688,7 @@ components: description: "Package version. Must be a specific version. Version ranges are rejected (e.g., '^1.2.3', '~1.2.3', '>=1.2.3', '1.x', '1.*')." example: "1.0.2" minLength: 1 + maxLength: 255 not: const: "latest" fileSha256: diff --git a/docs/reference/server-json/draft/server.schema.json b/docs/reference/server-json/draft/server.schema.json index 5c59335..95539fe 100644 --- a/docs/reference/server-json/draft/server.schema.json +++ b/docs/reference/server-json/draft/server.schema.json @@ -282,6 +282,7 @@ "version": { "description": "Package version. Must be a specific version. Version ranges are rejected (e.g., '^1.2.3', '~1.2.3', '\u003e=1.2.3', '1.x', '1.*').", "example": "1.0.2", + "maxLength": 255, "minLength": 1, "not": { "const": "latest" diff --git a/internal/api/handlers/v0/auth/common.go b/internal/api/handlers/v0/auth/common.go index 2f763d6..c283655 100644 --- a/internal/api/handlers/v0/auth/common.go +++ b/internal/api/handlers/v0/auth/common.go @@ -11,6 +11,7 @@ import ( "errors" "fmt" "math/big" + "net" "regexp" "strings" "time" @@ -376,6 +377,18 @@ func IsValidDomain(domain string) bool { return false } + // Reject IP literals — this auth method proves domain ownership, not IP + // ownership, and IP literals are an SSRF vector into internal networks. + if net.ParseIP(domain) != nil { + return false + } + + // Require at least one dot — rejects single-label names like "localhost" + // or "kubernetes" that resolve only inside private networks. + if !strings.Contains(domain, ".") { + return false + } + // Check for valid characters and structure domainPattern := regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$`) return domainPattern.MatchString(domain) diff --git a/internal/api/handlers/v0/auth/common_test.go b/internal/api/handlers/v0/auth/common_test.go new file mode 100644 index 0000000..7662116 --- /dev/null +++ b/internal/api/handlers/v0/auth/common_test.go @@ -0,0 +1,49 @@ +package auth_test + +import ( + "testing" + + "github.com/modelcontextprotocol/registry/internal/api/handlers/v0/auth" +) + +func TestIsValidDomain(t *testing.T) { + tests := []struct { + domain string + want bool + }{ + // Valid + {"example.com", true}, + {"sub.example.com", true}, + {"a.b.c.d.example.com", true}, + {"foo-bar.example.com", true}, + {"123.example.com", true}, + + // Invalid — empty / oversize + {"", false}, + + // Invalid — IP literals (SSRF vector) + {"127.0.0.1", false}, + {"10.0.0.1", false}, + {"169.254.169.254", false}, + {"::1", false}, + {"fe80::1", false}, + + // Invalid — single-label internal names (SSRF vector) + {"localhost", false}, + {"kubernetes", false}, + {"internal", false}, + + // Invalid — bad characters / structure + {"-example.com", false}, + {"example.com-", false}, + {"exa mple.com", false}, + {"example..com", false}, + } + for _, tc := range tests { + t.Run(tc.domain, func(t *testing.T) { + if got := auth.IsValidDomain(tc.domain); got != tc.want { + t.Errorf("IsValidDomain(%q) = %v, want %v", tc.domain, got, tc.want) + } + }) + } +} diff --git a/internal/api/handlers/v0/auth/dns_test.go b/internal/api/handlers/v0/auth/dns_test.go index b4895ab..7ffda75 100644 --- a/internal/api/handlers/v0/auth/dns_test.go +++ b/internal/api/handlers/v0/auth/dns_test.go @@ -280,17 +280,6 @@ func TestDNSAuthHandler_Permissions(t *testing.T) { "v1.api.example.com/*", // should be reversed }, }, - { - name: "single part domain", - domain: "localhost", - expectedPatterns: []string{ - "localhost/*", // exact pattern (no reversal needed) - "localhost.*", // subdomain pattern - }, - unexpectedPatterns: []string{ - "*.localhost", // wrong wildcard position - }, - }, { name: "hyphenated domain", domain: "my-app.example-site.com", diff --git a/internal/api/handlers/v0/auth/http.go b/internal/api/handlers/v0/auth/http.go index e917f85..7d73d52 100644 --- a/internal/api/handlers/v0/auth/http.go +++ b/internal/api/handlers/v0/auth/http.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "net" "net/http" "strings" "time" @@ -34,6 +35,9 @@ type DefaultHTTPKeyFetcher struct { // NewDefaultHTTPKeyFetcher creates a new HTTP key fetcher with timeout func NewDefaultHTTPKeyFetcher() *DefaultHTTPKeyFetcher { + transport := http.DefaultTransport.(*http.Transport).Clone() + transport.DialContext = safeDialContext + return &DefaultHTTPKeyFetcher{ client: &http.Client{ Timeout: 10 * time.Second, @@ -42,10 +46,92 @@ func NewDefaultHTTPKeyFetcher() *DefaultHTTPKeyFetcher { CheckRedirect: func(_ *http.Request, _ []*http.Request) error { return http.ErrUseLastResponse }, + Transport: transport, }, } } +// safeDialContext resolves the target hostname and refuses to dial loopback, +// private (RFC1918, ULA), link-local, or unspecified addresses. Combined with +// IsValidDomain rejecting IP literals, this neutralises SSRF abuse of the +// well-known fetcher: an attacker cannot reach internal HTTPS services +// (Kubernetes API server, internal admin panels, internal DNS-resolved hosts) +// even if they control DNS for an attacker domain. +// +// The hostname is resolved once here; we then dial the resolved IP directly, +// which pins the connection against DNS rebinding (a TOCTOU where the resolver +// returns a public IP to a pre-flight check and an internal IP to the actual +// dial). TLS SNI and the Host header continue to use the original hostname +// since they are set by http.Transport from the request URL, not the dial +// address. +func safeDialContext(ctx context.Context, network, addr string) (net.Conn, error) { + host, port, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + + var resolver net.Resolver + ips, err := resolver.LookupIPAddr(ctx, host) + if err != nil { + return nil, err + } + + // Try each non-blocked address in order, falling through on dial failure. + // Without this, a stale public AAAA record that no longer routes (or any + // individually-unreachable IP) breaks auth where the default transport + // would have recovered by trying the next answer. + // + // Each attempt is bounded by perIPDialTimeout so that a single hanging + // address can't consume the whole http.Client budget. This is a + // simpler substitute for Happy Eyeballs (parallel A/AAAA racing) — we + // fail fast and try the next answer instead of racing them. + const perIPDialTimeout = 3 * time.Second + + var lastErr error + allBlocked := true + for _, ip := range ips { + if isBlockedIP(ip.IP) { + continue + } + allBlocked = false + dialCtx, cancel := context.WithTimeout(ctx, perIPDialTimeout) + var d net.Dialer + conn, dialErr := d.DialContext(dialCtx, network, net.JoinHostPort(ip.IP.String(), port)) + cancel() + if dialErr == nil { + return conn, nil + } + lastErr = dialErr + } + if allBlocked { + return nil, fmt.Errorf("dial %s: refusing to connect to private or loopback address", host) + } + return nil, fmt.Errorf("dial %s: all resolved public addresses failed: %w", host, lastErr) +} + +// cgnatRange covers RFC 6598 Carrier-Grade NAT (100.64.0.0/10), which the +// stdlib does not classify via any Is* helper but is reachable on some +// cloud / mobile networks where it shadows internal infrastructure. +var cgnatRange = func() *net.IPNet { + _, n, _ := net.ParseCIDR("100.64.0.0/10") + return n +}() + +// isBlockedIP reports whether an IP must not be dialled by the namespace +// verification fetcher. Covers loopback (127/8, ::1), RFC1918 + ULA via +// IsPrivate, link-local (169.254/16, fe80::/10 — includes cloud metadata +// 169.254.169.254), unspecified (0.0.0.0, ::), all multicast (admin-scoped +// 239/8 and ff00::/8 in addition to link-local-multicast), and CGNAT. +func isBlockedIP(ip net.IP) bool { + if ip == nil { + return true + } + return ip.IsLoopback() || ip.IsPrivate() || + ip.IsLinkLocalUnicast() || ip.IsMulticast() || + ip.IsUnspecified() || + cgnatRange.Contains(ip) +} + // NewDefaultHTTPKeyFetcherWithClient creates a new HTTP key fetcher with a custom HTTP client. // This is primarily useful in tests to inject transports or TLS settings. func NewDefaultHTTPKeyFetcherWithClient(client *http.Client) *DefaultHTTPKeyFetcher { diff --git a/internal/api/handlers/v0/auth/http_internal_test.go b/internal/api/handlers/v0/auth/http_internal_test.go new file mode 100644 index 0000000..5b2ce37 --- /dev/null +++ b/internal/api/handlers/v0/auth/http_internal_test.go @@ -0,0 +1,52 @@ +package auth + +import ( + "net" + "testing" +) + +func TestIsBlockedIP(t *testing.T) { + tests := []struct { + ip string + blocked bool + }{ + // Blocked — loopback + {"127.0.0.1", true}, + {"::1", true}, + // Blocked — RFC1918 / ULA (IsPrivate) + {"10.0.0.1", true}, + {"172.16.0.1", true}, + {"192.168.1.1", true}, + {"fc00::1", true}, + // Blocked — link-local (includes cloud metadata 169.254.169.254) + {"169.254.169.254", true}, + {"fe80::1", true}, + // Blocked — unspecified + {"0.0.0.0", true}, + {"::", true}, + // Blocked — admin-scoped and broader multicast + {"239.0.0.1", true}, + {"ff00::1", true}, + // Blocked — Carrier-Grade NAT (RFC 6598) + {"100.64.0.1", true}, + {"100.127.255.254", true}, + // Allowed — public + {"1.1.1.1", false}, + {"8.8.8.8", false}, + {"2606:4700:4700::1111", false}, + // Allowed — outside CGNAT range + {"100.63.255.255", false}, + {"100.128.0.1", false}, + } + for _, tc := range tests { + t.Run(tc.ip, func(t *testing.T) { + ip := net.ParseIP(tc.ip) + if ip == nil { + t.Fatalf("ParseIP(%q) returned nil", tc.ip) + } + if got := isBlockedIP(ip); got != tc.blocked { + t.Errorf("isBlockedIP(%q) = %v, want %v", tc.ip, got, tc.blocked) + } + }) + } +} diff --git a/internal/api/handlers/v0/auth/http_test.go b/internal/api/handlers/v0/auth/http_test.go index d3781ba..d0aa0ed 100644 --- a/internal/api/handlers/v0/auth/http_test.go +++ b/internal/api/handlers/v0/auth/http_test.go @@ -472,17 +472,6 @@ func TestHTTPAuthHandler_Permissions(t *testing.T) { "v1.api.example.com/*", // should be reversed }, }, - { - name: "single part domain", - domain: "localhost", - expectedPatterns: []string{ - "localhost/*", // exact pattern only (no reversal needed) - }, - unexpectedPatterns: []string{ - "localhost.*", // HTTP should not grant subdomain permissions - "*.localhost", // wrong wildcard position - }, - }, { name: "hyphenated domain", domain: "my-app.example-site.com", diff --git a/internal/api/handlers/v0/edit.go b/internal/api/handlers/v0/edit.go index 2862350..a927e7b 100644 --- a/internal/api/handlers/v0/edit.go +++ b/internal/api/handlers/v0/edit.go @@ -3,6 +3,7 @@ package v0 import ( "context" "errors" + "log" "net/http" "net/url" "strings" @@ -74,7 +75,8 @@ func RegisterEditEndpoints(api huma.API, pathPrefix string, registry service.Reg if errors.Is(err, database.ErrNotFound) { return nil, huma.Error404NotFound("Server not found") } - return nil, huma.Error500InternalServerError("Failed to get current server", err) + log.Printf("edit: get current server (%q/%q) failed: %v", serverName, version, err) + return nil, huma.Error500InternalServerError("Failed to get current server") } // Verify edit permissions for this server using the existing server name diff --git a/internal/api/handlers/v0/servers.go b/internal/api/handlers/v0/servers.go index d187fc0..bc7c618 100644 --- a/internal/api/handlers/v0/servers.go +++ b/internal/api/handlers/v0/servers.go @@ -3,6 +3,7 @@ package v0 import ( "context" "errors" + "log" "net/http" "net/url" "reflect" @@ -131,7 +132,8 @@ func RegisterServersEndpoints(api huma.API, pathPrefix string, registry service. // Get paginated results with filtering servers, nextCursor, err := registry.ListServers(ctx, filter, input.Cursor, input.Limit) if err != nil { - return nil, huma.Error500InternalServerError("Failed to get registry list", err) + log.Printf("list servers failed: %v", err) + return nil, huma.Error500InternalServerError("Failed to get registry list") } // Convert []*ServerResponse to []ServerResponse @@ -184,7 +186,8 @@ func RegisterServersEndpoints(api huma.API, pathPrefix string, registry service. if err.Error() == errRecordNotFound || errors.Is(err, database.ErrNotFound) { return nil, huma.Error404NotFound("Server not found") } - return nil, huma.Error500InternalServerError("Failed to get server details", err) + log.Printf("get server details (%q/%q) failed: %v", serverName, version, err) + return nil, huma.Error500InternalServerError("Failed to get server details") } return &Response[apiv0.ServerResponse]{ @@ -213,7 +216,8 @@ func RegisterServersEndpoints(api huma.API, pathPrefix string, registry service. if err.Error() == errRecordNotFound || errors.Is(err, database.ErrNotFound) { return nil, huma.Error404NotFound("Server not found") } - return nil, huma.Error500InternalServerError("Failed to get server versions", err) + log.Printf("get server versions (%q) failed: %v", serverName, err) + return nil, huma.Error500InternalServerError("Failed to get server versions") } // Convert []*ServerResponse to []ServerResponse diff --git a/internal/api/handlers/v0/status.go b/internal/api/handlers/v0/status.go index 627e884..3f03fc2 100644 --- a/internal/api/handlers/v0/status.go +++ b/internal/api/handlers/v0/status.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "log" "net/http" "net/url" "strings" @@ -122,7 +123,8 @@ func RegisterStatusEndpoints(api huma.API, pathPrefix string, registry service.R if errors.Is(err, database.ErrNotFound) { return nil, huma.Error404NotFound("Server version not found") } - return nil, huma.Error500InternalServerError("Failed to get server", err) + log.Printf("status: get server (%q/%q) failed: %v", serverName, version, err) + return nil, huma.Error500InternalServerError("Failed to get server") } // Verify publish or edit permissions for this server @@ -228,7 +230,8 @@ func RegisterAllVersionsStatusEndpoints(api huma.API, pathPrefix string, registr if errors.Is(err, database.ErrNotFound) { return nil, huma.Error404NotFound("Server not found") } - return nil, huma.Error500InternalServerError("Failed to get server", err) + log.Printf("status: get server (%q) failed: %v", serverName, err) + return nil, huma.Error500InternalServerError("Failed to get server") } // Verify publish or edit permissions for this server @@ -243,7 +246,8 @@ func RegisterAllVersionsStatusEndpoints(api huma.API, pathPrefix string, registr // Fetch all versions to validate the bulk status transition allVersions, err := registry.GetAllVersionsByServerName(ctx, serverName, true) if err != nil { - return nil, huma.Error500InternalServerError("Failed to get server versions", err) + log.Printf("status: get all versions (%q) failed: %v", serverName, err) + return nil, huma.Error500InternalServerError("Failed to get server versions") } // Validate bulk status transition - reject if no changes would occur diff --git a/internal/api/router/router.go b/internal/api/router/router.go index d951e60..46b975b 100644 --- a/internal/api/router/router.go +++ b/internal/api/router/router.go @@ -97,6 +97,7 @@ func WithSkipPaths(paths ...string) MiddlewareOption { // handle404 returns a helpful 404 error with suggestions for common mistakes func handle404(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/problem+json") + w.Header().Set("X-Content-Type-Options", "nosniff") w.WriteHeader(http.StatusNotFound) path := r.URL.Path @@ -187,8 +188,28 @@ func NewHumaAPI(cfg *config.Config, registry service.RegistryService, mux *http. // Add UI and 404 handler for all other routes mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/" { - // Serve UI at root + // Serve UI at root. The page renders publisher-controlled content + // (server names, descriptions, repository URLs) — server-side + // validation plus a JS escape function are the primary XSS + // defences; these headers are defence-in-depth in case any of + // those slip. w.Header().Set("Content-Type", "text/html; charset=utf-8") + w.Header().Set("X-Content-Type-Options", "nosniff") + w.Header().Set("X-Frame-Options", "DENY") + // connect-src is unrestricted because the UI exposes a base-URL + // selector (prod / staging / custom) that issues cross-origin + // XHRs to whichever target the operator picks. Constraining + // connect-src would silently break that affordance. The other + // directives still meaningfully limit the page's attack surface. + w.Header().Set("Content-Security-Policy", + "default-src 'self'; "+ + "script-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com; "+ + "style-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com; "+ + "img-src 'self' data:; "+ + "connect-src *; "+ + "frame-ancestors 'none'; "+ + "base-uri 'self'; "+ + "form-action 'self'") _, err := w.Write([]byte(v0.GetUIHTML())) if err != nil { http.Error(w, "Failed to write response", http.StatusInternalServerError) diff --git a/internal/api/server.go b/internal/api/server.go index e795a1e..9114067 100644 --- a/internal/api/server.go +++ b/internal/api/server.go @@ -5,6 +5,7 @@ import ( "encoding/json" "log" "net/http" + "path" "strings" "time" @@ -71,9 +72,11 @@ func TrailingSlashMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Only redirect if the path is not "/" and ends with a "/" if r.URL.Path != "/" && strings.HasSuffix(r.URL.Path, "/") { - // Create a copy of the URL and remove the trailing slash + // path.Clean both removes the trailing slash and collapses any + // leading "//" to "/", which prevents an open-redirect via a + // protocol-relative path like "//evil.com/" (GHSA-v8vw-gw5j-w7m6). newURL := *r.URL - newURL.Path = strings.TrimSuffix(r.URL.Path, "/") + newURL.Path = path.Clean(r.URL.Path) // Use 308 Permanent Redirect to preserve the request method http.Redirect(w, r, newURL.String(), http.StatusPermanentRedirect) @@ -127,6 +130,17 @@ func NewServer(cfg *config.Config, registryService service.RegistryService, metr Addr: cfg.ServerAddress, Handler: handler, ReadHeaderTimeout: 10 * time.Second, + ReadTimeout: 30 * time.Second, + // WriteTimeout intentionally not set: the publish path runs + // outbound package validators sequentially (npm/pypi/nuget up to + // 10s each, OCI up to 30s), so any tight cap could cut off a + // legitimate multi-package publish mid-response — surfacing as a + // truncated read to the publisher even when the DB commit + // succeeded. Slow-response-read DoS is bounded upstream by + // NGINX ingress timeouts and the per-IP rate limit. Revisit once + // validators are parallelised or per-request package counts are + // bounded. + IdleTimeout: 120 * time.Second, }, } diff --git a/internal/api/server_test.go b/internal/api/server_test.go index dc313b0..9094c36 100644 --- a/internal/api/server_test.go +++ b/internal/api/server_test.go @@ -232,6 +232,22 @@ func TestTrailingSlashMiddleware(t *testing.T) { expectedLocation: "/v0/servers?limit=10", expectRedirect: true, }, + { + // Regression test for GHSA-v8vw-gw5j-w7m6: a protocol-relative + // path like "//evil.com/" must not redirect off-host. + name: "protocol-relative path should not redirect off-host", + path: "//evil.com/", + expectedStatus: http.StatusPermanentRedirect, + expectedLocation: "/evil.com", + expectRedirect: true, + }, + { + name: "path with multiple leading slashes should be collapsed", + path: "///evil.com/foo/", + expectedStatus: http.StatusPermanentRedirect, + expectedLocation: "/evil.com/foo", + expectRedirect: true, + }, } for _, tt := range tests { diff --git a/internal/auth/jwt.go b/internal/auth/jwt.go index b1935e5..88c8f76 100644 --- a/internal/auth/jwt.go +++ b/internal/auth/jwt.go @@ -81,10 +81,17 @@ func (j *JWTManager) GenerateTokenResponse(_ context.Context, claims JWTClaims) } } - // Check permissions against denylist, provided they are not an admin + // Check permissions against denylist, provided they are not an admin. + // Probe two synthetic resources per blocked namespace so that both the + // slash-suffix patterns (e.g. com.evil/*) and the dot-wildcard patterns + // (e.g. com.evil.mailer.* — granted to a subdomain claimant) are + // detected. Probing only " /test" misses the dot-wildcard form + // because the prefix match against "com.evil.mailer." does not start + // with "com.evil/test". if !hasGlobalPermissions { for _, blockedNamespace := range BlockedNamespaces { - if j.HasPermission(blockedNamespace+"/test", PermissionActionPublish, claims.Permissions) { + if j.HasPermission(blockedNamespace+"/test", PermissionActionPublish, claims.Permissions) || + j.HasPermission(blockedNamespace+".test/x", PermissionActionPublish, claims.Permissions) { return nil, fmt.Errorf("your namespace is blocked. raise an issue at https://github.com/modelcontextprotocol/registry/ if you think this is a mistake") } } diff --git a/internal/database/postgres.go b/internal/database/postgres.go index 1b0abdb..2749ad8 100644 --- a/internal/database/postgres.go +++ b/internal/database/postgres.go @@ -118,8 +118,13 @@ func buildFilterConditions(filter *ServerFilter, argIndex int) ([]string, []any, argIndex++ } if filter.SubstringName != nil { - conditions = append(conditions, fmt.Sprintf("server_name ILIKE $%d", argIndex)) - args = append(args, "%"+*filter.SubstringName+"%") + // Escape LIKE metacharacters so that user input cannot expand into + // wildcard matches (e.g. `?search=_` matching every single-char name, + // `?search=%` matching everything). Order matters: backslashes must be + // escaped first so subsequent escape backslashes are not double-escaped. + escaped := strings.NewReplacer(`\`, `\\`, `%`, `\%`, `_`, `\_`).Replace(*filter.SubstringName) + conditions = append(conditions, fmt.Sprintf("server_name ILIKE $%d ESCAPE '\\'", argIndex)) + args = append(args, "%"+escaped+"%") argIndex++ } if filter.Version != nil { diff --git a/internal/validators/registries/mcpb.go b/internal/validators/registries/mcpb.go index d42059b..82ba4d9 100644 --- a/internal/validators/registries/mcpb.go +++ b/internal/validators/registries/mcpb.go @@ -54,8 +54,17 @@ func ValidateMCPB(ctx context.Context, pkg model.Package, _ string) error { return fmt.Errorf("MCPB package URL must contain 'mcp': %s", pkg.Identifier) } - // Verify the file exists and is publicly accessible - client := &http.Client{Timeout: 10 * time.Second} + // Verify the file exists and is publicly accessible. Refuse to follow + // redirects: the URL allowlist (github.com / gitlab.com) only constrains + // the FIRST hop, and a 30x bouncing through CDN/release-asset hosts + // could otherwise be steered toward attacker infrastructure or + // internal-only endpoints reached via DNS quirks. + client := &http.Client{ + Timeout: 10 * time.Second, + CheckRedirect: func(_ *http.Request, _ []*http.Request) error { + return http.ErrUseLastResponse + }, + } req, err := http.NewRequestWithContext(ctx, http.MethodHead, pkg.Identifier, nil) if err != nil { return fmt.Errorf("failed to create request: %w", err) @@ -69,7 +78,15 @@ func ValidateMCPB(ctx context.Context, pkg model.Package, _ string) error { } defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { + // GitHub serves release assets via a 302 to a signed S3 URL; a HEAD that + // returns 200 directly OR a 302 with a Location header is acceptable. + // Any other 3xx without a usable Location is treated as inaccessible. + switch { + case resp.StatusCode == http.StatusOK: + // fine + case resp.StatusCode >= 300 && resp.StatusCode < 400 && resp.Header.Get("Location") != "": + // fine — first-hop allowlist + we don't actually need the body + default: return fmt.Errorf("MCPB package '%s' is not publicly accessible (status: %d)", pkg.Identifier, resp.StatusCode) } diff --git a/internal/validators/registries/nuget.go b/internal/validators/registries/nuget.go index c3b95a0..0c6d4c5 100644 --- a/internal/validators/registries/nuget.go +++ b/internal/validators/registries/nuget.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "net/http" + "net/url" "strings" "sync" "time" @@ -209,9 +210,11 @@ func validateReadme(ctx context.Context, serverName, lowerID, lowerVersion strin return NoReadme, fmt.Errorf("failed to get README URL template: %w", err) } - // Replace placeholders in the template - readmeURL := strings.ReplaceAll(readmeURLTemplate, "{lower_id}", lowerID) - readmeURL = strings.ReplaceAll(readmeURL, "{lower_version}", lowerVersion) + // Replace placeholders in the template. PathEscape both the id and version + // so a publisher cannot smuggle "/" / ".." through the template into a + // fetch against an unrelated package's README. + readmeURL := strings.ReplaceAll(readmeURLTemplate, "{lower_id}", url.PathEscape(lowerID)) + readmeURL = strings.ReplaceAll(readmeURL, "{lower_version}", url.PathEscape(lowerVersion)) req, err := http.NewRequestWithContext(ctx, http.MethodGet, readmeURL, nil) if err != nil { return NoReadme, fmt.Errorf("failed to create NuGet README request: %w", err) @@ -266,8 +269,10 @@ func validatePackageExists(ctx context.Context, lowerID, lowerVersion string, cl return PackageIDNotFound, fmt.Errorf("failed to get Package Base URL: %w", err) } - // Fetch the package content index to check if package ID and version exist - indexURL := fmt.Sprintf("%s/%s/index.json", strings.TrimRight(packageBaseURL, "/"), lowerID) + // Fetch the package content index to check if package ID and version exist. + // PathEscape so an identifier that smuggles "/" or ".." cannot redirect + // the metadata fetch to a different package than the one being claimed. + indexURL := fmt.Sprintf("%s/%s/index.json", strings.TrimRight(packageBaseURL, "/"), url.PathEscape(lowerID)) req, err := http.NewRequestWithContext(ctx, http.MethodGet, indexURL, nil) if err != nil { diff --git a/internal/validators/registries/pypi.go b/internal/validators/registries/pypi.go index 62ce22e..2bac843 100644 --- a/internal/validators/registries/pypi.go +++ b/internal/validators/registries/pypi.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "net/http" + "net/url" "strings" "time" @@ -52,8 +53,13 @@ func ValidatePyPI(ctx context.Context, pkg model.Package, serverName string) err client := &http.Client{Timeout: 10 * time.Second} - url := fmt.Sprintf("%s/pypi/%s/%s/json", pkg.RegistryBaseURL, pkg.Identifier, pkg.Version) - req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + // PathEscape so an identifier that smuggles "/" or ".." cannot redirect + // the metadata fetch to a different package than the one being claimed. + fetchURL := fmt.Sprintf("%s/pypi/%s/%s/json", + pkg.RegistryBaseURL, + url.PathEscape(pkg.Identifier), + url.PathEscape(pkg.Version)) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, fetchURL, nil) if err != nil { return fmt.Errorf("failed to create request: %w", err) } diff --git a/internal/validators/schemas/2025-12-11.json b/internal/validators/schemas/2025-12-11.json index 9f6469b..70902ed 100644 --- a/internal/validators/schemas/2025-12-11.json +++ b/internal/validators/schemas/2025-12-11.json @@ -283,6 +283,7 @@ "description": "Package version. Must be a specific version. Version ranges are rejected (e.g., '^1.2.3', '~1.2.3', '\u003e=1.2.3', '1.x', '1.*').", "example": "1.0.2", "minLength": 1, + "maxLength": 255, "not": { "const": "latest" }, diff --git a/pkg/api/v0/types.go b/pkg/api/v0/types.go index de78a91..67fe094 100644 --- a/pkg/api/v0/types.go +++ b/pkg/api/v0/types.go @@ -39,7 +39,7 @@ type ServerJSON struct { Description string `json:"description" minLength:"1" maxLength:"100" doc:"Clear human-readable explanation of server functionality." example:"MCP server providing weather data and forecasts via OpenWeatherMap API"` Title string `json:"title,omitempty" minLength:"1" maxLength:"100" doc:"Optional human-readable title or display name for the MCP server." example:"Weather API"` Repository *model.Repository `json:"repository,omitempty" doc:"Optional repository metadata for the MCP server source code."` - Version string `json:"version" doc:"Version string for this server. SHOULD follow semantic versioning." example:"1.0.2"` + Version string `json:"version" minLength:"1" maxLength:"255" doc:"Version string for this server. SHOULD follow semantic versioning." example:"1.0.2"` WebsiteURL string `json:"websiteUrl,omitempty" format:"uri" doc:"Optional URL to the server's homepage, documentation, or project website." example:"https://modelcontextprotocol.io/examples"` Icons []model.Icon `json:"icons,omitempty" doc:"Optional set of sized icons that the client can display in a user interface."` Packages []model.Package `json:"packages,omitempty" doc:"Array of package configurations"` diff --git a/pkg/model/types.go b/pkg/model/types.go index 03d2841..b0bf8e4 100644 --- a/pkg/model/types.go +++ b/pkg/model/types.go @@ -35,7 +35,7 @@ type Package struct { // - For MCPB: direct download URL Identifier string `json:"identifier" minLength:"1" doc:"Package identifier - either a package name (for registries) or URL (for direct downloads)" example:"@modelcontextprotocol/server-brave-search"` // Version is the package version (required for npm, pypi, nuget; optional for mcpb; not used by oci where version is in the identifier) - Version string `json:"version,omitempty" minLength:"1" doc:"Package version. Must be a specific version. Version ranges are rejected (e.g., '^1.2.3', '~1.2.3', '>=1.2.3', '1.x', '1.*')." example:"1.0.2"` + Version string `json:"version,omitempty" minLength:"1" maxLength:"255" doc:"Package version. Must be a specific version. Version ranges are rejected (e.g., '^1.2.3', '~1.2.3', '>=1.2.3', '1.x', '1.*')." example:"1.0.2"` // FileSHA256 is the SHA-256 hash for integrity verification (required for mcpb, optional for others) FileSHA256 string `json:"fileSha256,omitempty" pattern:"^[a-f0-9]{64}$" doc:"SHA-256 hash of the package file for integrity verification. Required for MCPB packages and optional for other package types. Authors are responsible for generating correct SHA-256 hashes when creating server.json. If present, MCP clients must validate the downloaded file matches the hash before running packages to ensure file integrity." example:"fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce"` // RunTimeHint suggests the appropriate runtime for the package From 88bbb851ad2fd7ee8ca660398fb5d9d23a337cc9 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Wed, 29 Apr 2026 19:32:54 -0400 Subject: [PATCH 065/190] deploy: update prod to v1.7.5 (#1228) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Bumps prod imageTag from `1.7.4` to `1.7.5`. - Promotes the security release tagged at v1.7.5 (#1227 merged at 1201cbd). ## Test plan - [ ] Smoke staging at https://staging.registry.modelcontextprotocol.io — already done, all checks green - [ ] Roll out via Pulumi - [ ] Confirm prod health post-rollout: `curl https://registry.modelcontextprotocol.io/v0/health` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index 3859f13..25cd2fd 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.7.4 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.7.5 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From 3f89fc2b1fb34fd49f3c0e1b39e964a5c67b613f Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Wed, 29 Apr 2026 20:27:26 -0400 Subject: [PATCH 066/190] auth: bind GitHub OIDC token exchange to a per-deployment audience (#1229) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What this does The publisher CLI now derives the OIDC audience to request from the `--registry` URL instead of using a fixed constant, and the server validates the token's `aud` claim against a new per-deployment env var (`MCP_REGISTRY_GITHUB_OIDC_AUDIENCE`). Production sets this env var to `https://registry.modelcontextprotocol.io` (and per-environment URL elsewhere), so the deployment only accepts tokens that were requested for it. ## Compatibility This is a breaking change for older `mcp-publisher` binaries that still request the legacy hardcoded audience. After this rolls to a deployment, users on old `mcp-publisher` will see a clear `invalid audience: expected …, got […]` error and need to upgrade. Users following the documented `releases/latest` install pattern get the new binary automatically. ## Test plan - [ ] CI green - [ ] Run a synthetic publish from a real GitHub Actions workflow against staging after deploy - [ ] Confirm an older `mcp-publisher` against the same staging deploy returns the expected `invalid audience` error 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- cmd/publisher/auth/github-oidc.go | 31 +++++++- .../auth/github-oidc_internal_test.go | 48 ++++++++++++ deploy/pkg/k8s/registry.go | 9 +++ internal/api/handlers/v0/auth/github_oidc.go | 6 +- .../api/handlers/v0/auth/github_oidc_test.go | 78 ++++++++++++++++++- internal/config/config.go | 2 + 6 files changed, 166 insertions(+), 8 deletions(-) create mode 100644 cmd/publisher/auth/github-oidc_internal_test.go diff --git a/cmd/publisher/auth/github-oidc.go b/cmd/publisher/auth/github-oidc.go index e4b51ed..9b32e44 100644 --- a/cmd/publisher/auth/github-oidc.go +++ b/cmd/publisher/auth/github-oidc.go @@ -7,7 +7,9 @@ import ( "fmt" "io" "net/http" + "net/url" "os" + "strings" ) type GitHubOIDCProvider struct { @@ -23,8 +25,13 @@ func NewGitHubOIDCProvider(registryURL string) Provider { // GetToken retrieves the registry JWT token using GitHub Actions OIDC token func (o *GitHubOIDCProvider) GetToken(ctx context.Context) (string, error) { + audience, err := audienceFromRegistryURL(o.registryURL) + if err != nil { + return "", fmt.Errorf("invalid --registry URL: %w", err) + } + // Get OIDC token from GitHub Actions endpoint - oidcToken, err := o.getOIDCTokenFromGitHub(ctx) + oidcToken, err := o.getOIDCTokenFromGitHub(ctx, audience) if err != nil { return "", fmt.Errorf("failed to get OIDC token from GitHub: %w", err) } @@ -99,8 +106,8 @@ func (o *GitHubOIDCProvider) exchangeOIDCTokenForRegistry(ctx context.Context, o return tokenResp.RegistryToken, nil } -// getOIDCTokenFromGitHub fetches the OIDC token from GitHub Actions endpoint -func (o *GitHubOIDCProvider) getOIDCTokenFromGitHub(ctx context.Context) (string, error) { +// getOIDCTokenFromGitHub fetches the OIDC token from GitHub Actions endpoint. +func (o *GitHubOIDCProvider) getOIDCTokenFromGitHub(ctx context.Context, audience string) (string, error) { // Check for required environment variables requestToken := os.Getenv("ACTIONS_ID_TOKEN_REQUEST_TOKEN") if requestToken == "" { @@ -113,7 +120,7 @@ func (o *GitHubOIDCProvider) getOIDCTokenFromGitHub(ctx context.Context) (string } // Build the full URL with audience parameter - fullURL := requestURL + "&audience=mcp-registry" + fullURL := requestURL + "&audience=" + url.QueryEscape(audience) // Create the request req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullURL, nil) //nolint:gosec // G704: URL is from GitHub Actions ACTIONS_ID_TOKEN_REQUEST_URL env var @@ -158,3 +165,19 @@ func (o *GitHubOIDCProvider) getOIDCTokenFromGitHub(ctx context.Context) (string return tokenResp.Value, nil } + +// audienceFromRegistryURL returns scheme + lowercased host for the given URL. +func audienceFromRegistryURL(registryURL string) (string, error) { + registryURL = strings.TrimSpace(registryURL) + if registryURL == "" { + return "", fmt.Errorf("registry URL is empty") + } + u, err := url.Parse(registryURL) + if err != nil { + return "", fmt.Errorf("parse %q: %w", registryURL, err) + } + if u.Scheme == "" || u.Host == "" { + return "", fmt.Errorf("registry URL must include scheme and host: %q", registryURL) + } + return u.Scheme + "://" + strings.ToLower(u.Host), nil +} diff --git a/cmd/publisher/auth/github-oidc_internal_test.go b/cmd/publisher/auth/github-oidc_internal_test.go new file mode 100644 index 0000000..e8a5068 --- /dev/null +++ b/cmd/publisher/auth/github-oidc_internal_test.go @@ -0,0 +1,48 @@ +package auth + +import "testing" + +func TestAudienceFromRegistryURL(t *testing.T) { + tests := []struct { + input string + want string + wantErr bool + }{ + // Canonical forms + {"https://registry.modelcontextprotocol.io", "https://registry.modelcontextprotocol.io", false}, + {"https://staging.registry.modelcontextprotocol.io", "https://staging.registry.modelcontextprotocol.io", false}, + + // Trailing slash and path are stripped + {"https://registry.modelcontextprotocol.io/", "https://registry.modelcontextprotocol.io", false}, + {"https://registry.modelcontextprotocol.io/api/v0", "https://registry.modelcontextprotocol.io", false}, + + // Host is lowercased + {"https://Registry.Example.COM", "https://registry.example.com", false}, + + // Whitespace is tolerated + {" https://registry.example ", "https://registry.example", false}, + + // Invalid inputs + {"", "", true}, + {"registry.example", "", true}, // missing scheme + {"https://", "", true}, // missing host + {"://nothing", "", true}, // missing scheme + } + for _, tc := range tests { + t.Run(tc.input, func(t *testing.T) { + got, err := audienceFromRegistryURL(tc.input) + if tc.wantErr { + if err == nil { + t.Fatalf("expected error for %q, got %q", tc.input, got) + } + return + } + if err != nil { + t.Fatalf("unexpected error for %q: %v", tc.input, err) + } + if got != tc.want { + t.Errorf("audienceFromRegistryURL(%q) = %q, want %q", tc.input, got, tc.want) + } + }) + } +} diff --git a/deploy/pkg/k8s/registry.go b/deploy/pkg/k8s/registry.go index 48e9124..53f2d85 100644 --- a/deploy/pkg/k8s/registry.go +++ b/deploy/pkg/k8s/registry.go @@ -185,6 +185,15 @@ func DeployMCPRegistry(ctx *pulumi.Context, cluster *providers.ProviderInfo, env Name: pulumi.String("MCP_REGISTRY_OIDC_PUBLISH_PERMISSIONS"), Value: pulumi.String("*"), }, + &corev1.EnvVarArgs{ + Name: pulumi.String("MCP_REGISTRY_GITHUB_OIDC_AUDIENCE"), + Value: pulumi.String(func() string { + if environment == "prod" { + return "https://registry.modelcontextprotocol.io" + } + return "https://" + environment + ".registry.modelcontextprotocol.io" + }()), + }, }, // StartupProbe protects the DB-retry budget in cmd/registry/main.go: // 30 × 5s = 150s allowed before liveness/readiness take over, which diff --git a/internal/api/handlers/v0/auth/github_oidc.go b/internal/api/handlers/v0/auth/github_oidc.go index e925fb5..4170640 100644 --- a/internal/api/handlers/v0/auth/github_oidc.go +++ b/internal/api/handlers/v0/auth/github_oidc.go @@ -252,8 +252,10 @@ func RegisterGitHubOIDCEndpoint(api huma.API, pathPrefix string, cfg *config.Con // ExchangeToken exchanges a GitHub OIDC token for a Registry JWT token func (h *GitHubOIDCHandler) ExchangeToken(ctx context.Context, oidcToken string) (*auth.TokenResponse, error) { - // Validate OIDC token with audience "mcp-registry" - claims, err := h.validator.ValidateToken(ctx, oidcToken, "mcp-registry") + if h.config.GitHubOIDCAudience == "" { + return nil, fmt.Errorf("GitHub OIDC exchange disabled: this deployment has no audience configured") + } + claims, err := h.validator.ValidateToken(ctx, oidcToken, h.config.GitHubOIDCAudience) if err != nil { return nil, fmt.Errorf("failed to validate OIDC token: %w", err) } diff --git a/internal/api/handlers/v0/auth/github_oidc_test.go b/internal/api/handlers/v0/auth/github_oidc_test.go index a65ab95..37d07e8 100644 --- a/internal/api/handlers/v0/auth/github_oidc_test.go +++ b/internal/api/handlers/v0/auth/github_oidc_test.go @@ -26,7 +26,8 @@ func (m *MockOIDCValidator) ValidateToken(ctx context.Context, token string, aud func TestGitHubOIDCHandler_ExchangeToken(t *testing.T) { cfg := &config.Config{ - JWTPrivateKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", // 32 bytes hex + JWTPrivateKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", // 32 bytes hex + GitHubOIDCAudience: "https://registry.test", } handler := auth.NewGitHubOIDCHandler(cfg) @@ -118,9 +119,82 @@ func TestGitHubOIDCHandler_ExchangeToken(t *testing.T) { } } +func TestGitHubOIDCHandler_AudienceBinding(t *testing.T) { + t.Run("empty audience config fails closed", func(t *testing.T) { + cfg := &config.Config{ + JWTPrivateKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + GitHubOIDCAudience: "", + } + handler := auth.NewGitHubOIDCHandler(cfg) + // Validator should never be called — the audience precondition rejects first. + handler.SetValidator(&MockOIDCValidator{ + validateFunc: func(_ context.Context, _ string, _ string) (*auth.GitHubOIDCClaims, error) { + t.Fatal("validator must not be called when audience is unconfigured") + return nil, fmt.Errorf("unreachable") + }, + }) + + _, err := handler.ExchangeToken(context.Background(), "any-token") + require.Error(t, err) + assert.Contains(t, err.Error(), "no audience configured") + }) + + t.Run("configured audience is what the validator sees", func(t *testing.T) { + cfg := &config.Config{ + JWTPrivateKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + GitHubOIDCAudience: "https://registry.example.com", + } + handler := auth.NewGitHubOIDCHandler(cfg) + + var seenAudience string + handler.SetValidator(&MockOIDCValidator{ + validateFunc: func(_ context.Context, _ string, audience string) (*auth.GitHubOIDCClaims, error) { + seenAudience = audience + return &auth.GitHubOIDCClaims{ + RegisteredClaims: jwt.RegisteredClaims{ + Subject: "repo:octo-org/octo-repo:environment:prod", + ExpiresAt: jwt.NewNumericDate(time.Now().Add(1 * time.Hour)), + Audience: jwt.ClaimStrings{audience}, + }, + RepositoryOwner: "octo-org", + }, nil + }, + }) + + _, err := handler.ExchangeToken(context.Background(), "any-token") + require.NoError(t, err) + assert.Equal(t, "https://registry.example.com", seenAudience) + }) + + t.Run("token issued for another deployment is rejected", func(t *testing.T) { + cfg := &config.Config{ + JWTPrivateKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + GitHubOIDCAudience: "https://registry.modelcontextprotocol.io", + } + handler := auth.NewGitHubOIDCHandler(cfg) + + // The mock validator does what the real one does: reject if the + // expected audience is not present in the token's aud claim. + handler.SetValidator(&MockOIDCValidator{ + validateFunc: func(_ context.Context, _ string, expected string) (*auth.GitHubOIDCClaims, error) { + tokenAudience := "https://attacker-registry.example" //nolint:gosec // G101 false positive: URL string, not a credential + if expected != tokenAudience { + return nil, fmt.Errorf("invalid audience: expected %s, got [%s]", expected, tokenAudience) + } + return &auth.GitHubOIDCClaims{RepositoryOwner: "octo-org"}, nil + }, + }) + + _, err := handler.ExchangeToken(context.Background(), "captured-token") + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid audience") + }) +} + func TestBuildPermissionsFromOIDC(t *testing.T) { cfg := &config.Config{ - JWTPrivateKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + JWTPrivateKey: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + GitHubOIDCAudience: "https://registry.test", } handler := auth.NewGitHubOIDCHandler(cfg) diff --git a/internal/config/config.go b/internal/config/config.go index 60e9a06..a15a67a 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -17,6 +17,8 @@ type Config struct { EnableAnonymousAuth bool `env:"ENABLE_ANONYMOUS_AUTH" envDefault:"false"` EnableRegistryValidation bool `env:"ENABLE_REGISTRY_VALIDATION" envDefault:"true"` + GitHubOIDCAudience string `env:"GITHUB_OIDC_AUDIENCE" envDefault:""` + // OIDC Configuration OIDCEnabled bool `env:"OIDC_ENABLED" envDefault:"false"` OIDCIssuer string `env:"OIDC_ISSUER" envDefault:""` From db438962092c444d3b734b70644bc7a2694418a5 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Wed, 29 Apr 2026 20:56:53 -0400 Subject: [PATCH 067/190] docs: document GitHub OIDC audience binding for self-hosters and CI users (#1230) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Follow-up to #1229. Three small doc additions so the new audience requirement is discoverable without reading the source: - `.env.example` lists `MCP_REGISTRY_GITHUB_OIDC_AUDIENCE` alongside the other registry env vars, with a note that the value must match the scheme+host that publishers pass via `--registry`. - The publisher CLI reference (`docs/reference/cli/commands.md`) explains that the CLI derives the audience from `--registry` and that self-hosters must set the matching env var on the registry side. - The GitHub Actions troubleshooting table (`docs/modelcontextprotocol-io/github-actions.mdx`) maps the new `invalid audience` error to the user-facing fix (upgrade `mcp-publisher`). No code changes — docs only. ## Test plan - [ ] CI green (markdown lint / link checks if any) - [ ] Eyeball-render the troubleshooting table on the modelcontextprotocol.io preview to confirm the new row formats correctly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- .env.example | 8 ++++++++ docs/modelcontextprotocol-io/github-actions.mdx | 1 + docs/reference/cli/commands.md | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/.env.example b/.env.example index bfadfd4..786fc1b 100644 --- a/.env.example +++ b/.env.example @@ -27,6 +27,14 @@ MCP_REGISTRY_JWT_PRIVATE_KEY=bb2c6b424005acd5df47a9e2c87f446def86dd740c888ea3efb # This should be disabled in prod MCP_REGISTRY_ENABLE_ANONYMOUS_AUTH=false +# GitHub OIDC token exchange (for `mcp-publisher login github-oidc`) +# Expected `aud` claim on incoming GitHub Actions OIDC tokens. Must equal the +# scheme + host that publishers pass via `--registry` (e.g. `https://registry.example.com`). +# The publisher CLI derives the audience from `--registry` automatically; the server +# rejects all OIDC exchanges if this is unset, so set it on every deployment that +# accepts GitHub Actions publishes. +MCP_REGISTRY_GITHUB_OIDC_AUDIENCE= + # Google Cloud Identity OIDC configuration for admin access # Enable OIDC authentication for @modelcontextprotocol.io admin accounts MCP_REGISTRY_OIDC_ENABLED=false diff --git a/docs/modelcontextprotocol-io/github-actions.mdx b/docs/modelcontextprotocol-io/github-actions.mdx index 311b28f..0da50cd 100644 --- a/docs/modelcontextprotocol-io/github-actions.mdx +++ b/docs/modelcontextprotocol-io/github-actions.mdx @@ -220,6 +220,7 @@ The workflow will run tests, build the package, publish the package to npm, and | Error Message | Action | | --- | --- | | "Authentication failed" | Ensure `id-token: write` permission is set for OIDC, or check secrets. | +| "invalid audience" | Your `mcp-publisher` binary is too old for this registry deployment. Re-run the install step shown above so you pick up the latest release. | | "Package validation failed" | Verify your package successfully published to the package registry (e.g., npm, PyPI), and that your package has the [necessary verification information](./package-types). | {/* prettier-ignore-end */} diff --git a/docs/reference/cli/commands.md b/docs/reference/cli/commands.md index 0f44b7b..e077019 100644 --- a/docs/reference/cli/commands.md +++ b/docs/reference/cli/commands.md @@ -72,6 +72,13 @@ mcp-publisher login github-oidc [--registry=URL] - Requires `id-token: write` permission in workflow - No browser interaction needed +The CLI derives the OIDC `aud` claim from `--registry` (scheme + host, e.g. +`https://registry.modelcontextprotocol.io`) so tokens are bound to the specific +deployment they were minted for. Self-hosters must set +`MCP_REGISTRY_GITHUB_OIDC_AUDIENCE` on the registry to the matching value; +publishers running an older `mcp-publisher` will fail with `invalid audience` +and need to upgrade. + Also see [the guide to publishing from GitHub Actions](../../modelcontextprotocol-io/github-actions.mdx). #### DNS Verification From 42092742ce941af281b32a1c53b1436b7f1d34bc Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Wed, 29 Apr 2026 21:08:54 -0400 Subject: [PATCH 068/190] deploy: update prod to v1.7.6 (#1232) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Bumps prod imageTag from \`1.7.5\` to \`1.7.6\`. ## Test plan - [ ] Smoke staging at https://staging.registry.modelcontextprotocol.io - [ ] Roll out via Pulumi - [ ] Confirm prod health post-rollout: \`curl https://registry.modelcontextprotocol.io/v0/version\` shows \`1.7.6\` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index 25cd2fd..034330b 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.7.5 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.7.6 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From 46bbe0dba3882dba42320ac311f4dbfdeea012f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 03:19:24 -0400 Subject: [PATCH 069/190] build(deps): bump cloud.google.com/go/kms from 1.29.0 to 1.30.0 (#1233) Bumps [cloud.google.com/go/kms](https://github.com/googleapis/google-cloud-go) from 1.29.0 to 1.30.0. Release notes
Sourced from cloud.google.com/go/kms's releases.
kms: v1.30.0
v1.30.0 (2026-04-30)
retail: v1.30.0
v1.30.0 (2026-04-30)
Commits
54d941achore: librarian release pull request: 20260402T153541Z (#14330)22d0749docs(storage): UpdateEnableParallelUploaddocumentation (#14328)751febdfeat(spanner): Switch to using builtin open telemetry for EEF (#14193)a70f04fchore: add a config check (#14327)9e2b3f5chore: update sources and regenerate (#14325)e0760b5fix(spanner): set gauge metric start time to match end time (#14289)71df27fdocs(pubsub/v2): revamp package docs (#14317)a6efdbfchore: update librarian version (#14323)22cda56chore: update librariangen image SHA (#14315)1720392chore(all): update deps (main) (#14231)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a6d5537..dac7d01 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/modelcontextprotocol/registry go 1.26 require ( - cloud.google.com/go/kms v1.29.0 + cloud.google.com/go/kms v1.30.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 github.com/caarlos0/env/v11 v11.4.0 diff --git a/go.sum b/go.sum index 18d07e2..c7cf970 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdB cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/iam v1.7.0 h1:JD3zh0C6LHl16aCn5Akff0+GELdp1+4hmh6ndoFLl8U= cloud.google.com/go/iam v1.7.0/go.mod h1:tetWZW1PD/m6vcuY2Zj/aU0eCHNPuxedbnbRTyKXvdY= -cloud.google.com/go/kms v1.29.0 h1:bAW1C5FQf+6GhPkywQzPlsULALCG7c16qpXLFGV9ivY= -cloud.google.com/go/kms v1.29.0/go.mod h1:YIyXZym11R5uovJJt4oN5eUL3oPmirF3yKeIh6QAf4U= +cloud.google.com/go/kms v1.30.0 h1:TSEZopy/OXojbVCQS9Rrx0jFqdKWvO31+N8ncXbxG/s= +cloud.google.com/go/kms v1.30.0/go.mod h1:YIyXZym11R5uovJJt4oN5eUL3oPmirF3yKeIh6QAf4U= cloud.google.com/go/longrunning v0.9.0 h1:0EzbDEGsAvOZNbqXopgniY0w0a1phvu5IdUFq8grmqY= cloud.google.com/go/longrunning v0.9.0/go.mod h1:pkTz846W7bF4o2SzdWJ40Hu0Re+UoNT6Q5t+igIcb8E= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc= From 23f4fda297cef56ee2b340c5b7d8b43a743eb695 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 May 2026 03:19:42 -0400 Subject: [PATCH 070/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.232.0 to 3.233.0 in /deploy (#1234) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.232.0 to 3.233.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.233.0
3.233.0 (2026-04-30)
Features
[auto/python] Expose the auto-generated Pulumi CLI interface as
workspace.cli_api#22638[cli] Add encrypted logging to ~/.pulumi/logs; use the PULUMI_ENABLE_AUTOMATIC_LOGGING feature flag to turn it on #22494
[cli] Implement the
filesystem__grepandfilesystem__content_replacelocal tools forpulumi neo.grepruns a regex search across files in the project root with an optionalincludeglob filter and returns results inpath:lineno: lineform.content_replaceperforms a literal multi-file search-and-replace with afile_patternglob anddry_runpreview mode. Both tools skip binary files, hidden directories, andnode_modules, and reject paths outside the project root. Their input schemas match the cloud-side tool definitions.[cli] Add
pulumi_previewandpulumi_upas local tools for the experimentalpulumi neoagent. The Neo TUI renders a persistent bordered block for each operation that streams changed resources and diagnostics as the engine runs and finalizes with a summary of the op counts. Hidden behind PULUMI_EXPERIMENTAL.[engine] Add
Listto the provider protocol and schema #22693Bug Fixes
[engine] Return a clear error when two installed plugins claim the same default provider package name (for example, a native
scalewayprovider alongside aterraform-providerbridge parameterized asscaleway) instead of panicking with "Should not have seen an older plugin if sorting is correct!" #22679[programgen] Do not wrap a
call(...)on a method whose return type is marked plain in an Output. Previously PCL bound every method call's return type asOutput<T>, which caused downstream program-gen to emit broken.apply(...)/.ApplyT(...)traversals against plain struct returns (e.g. methods withliftSingleValueMethodReturns=trueorReturnTypePlain=true).[backend/diy] When using a backend url containing creds (e.g. PostgreSQL conn string), mask user:pass as in lock-related error messages #22701
[codegen/go] Generate unqualified
Providerreferences for the package's own provider resource. Previously the Go codegen always emitted<pkg>.Providereven when the reference appeared inside<pkg>... (truncated)
Changelog
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.233.0 (2026-04-30)
Features
[auto/python] Expose the auto-generated Pulumi CLI interface as
workspace.cli_api#22638[cli] Add encrypted logging to ~/.pulumi/logs; use the PULUMI_ENABLE_AUTOMATIC_LOGGING feature flag to turn it on #22494
[cli] Implement the
filesystem__grepandfilesystem__content_replacelocal tools forpulumi neo.grepruns a regex search across files in the project root with an optionalincludeglob filter and returns results inpath:lineno: lineform.content_replaceperforms a literal multi-file search-and-replace with afile_patternglob anddry_runpreview mode. Both tools skip binary files, hidden directories, andnode_modules, and reject paths outside the project root. Their input schemas match the cloud-side tool definitions.[cli] Add
pulumi_previewandpulumi_upas local tools for the experimentalpulumi neoagent. The Neo TUI renders a persistent bordered block for each operation that streams changed resources and diagnostics as the engine runs and finalizes with a summary of the op counts. Hidden behind PULUMI_EXPERIMENTAL.[engine] Add
Listto the provider protocol and schema #22693Bug Fixes
[engine] Return a clear error when two installed plugins claim the same default provider package name (for example, a native
scalewayprovider alongside aterraform-providerbridge parameterized asscaleway) instead of panicking with "Should not have seen an older plugin if sorting is correct!" #22679[programgen] Do not wrap a
call(...)on a method whose return type is marked plain in an Output. Previously PCL bound every method call's return type asOutput<T>, which caused downstream program-gen to emit broken.apply(...)/.ApplyT(...)traversals against plain struct returns (e.g. methods withliftSingleValueMethodReturns=trueorReturnTypePlain=true).[backend/diy] When using a backend url containing creds (e.g. PostgreSQL conn string), mask user:pass as in lock-related error messages #22701
[codegen/go] Generate unqualified
Providerreferences for the package's own provider resource. Previously the Go codegen always emitted<pkg>.Providereven when the reference appeared inside<pkg>itself, producing identifiers that would not compile. Affects generated code for method return... (truncated)
Commits
fa31301don't stamp vcs information into binaries (#22788)17fd404double timeout in "does not hang" test (#22789)eb6e31dsplit tests module on macos further (#22790)94dbe64Remove runInStack from run-policy-pack (#22783)a35ec7eretry pip install a few times (#22785)7a4beeaReject schemas with duplicate tokens after applyingmoduleFormat(#22765)0b914ceunflake TestNodejsComponentProviderRun (#22782)5cd1646start logging encrypted logs for all pulumi commands (#22494)a81ef07pin more plugin versions in integration tests (#22758)0d2b8bfUpdate list doc comment (#22777)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 2 +- deploy/go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 79fbc0e..50d59a8 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 - github.com/pulumi/pulumi/sdk/v3 v3.232.0 + github.com/pulumi/pulumi/sdk/v3 v3.233.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/deploy/go.sum b/deploy/go.sum index e3c85c8..8f015d6 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -183,8 +183,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 h1:nF0Y1F7fUGL6RYD9EAtHTdDbNFmDaA3xcEiRlvCDV5E= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.232.0 h1:pU9j5qYHYtYZGaIKha1KFuB9ggp2obcMD1U523tpEnk= -github.com/pulumi/pulumi/sdk/v3 v3.232.0/go.mod h1:33NoTpvQXlTtAuaPbompgZNA3Ye4XEvxNydELFlWza8= +github.com/pulumi/pulumi/sdk/v3 v3.233.0 h1:r2Z1GtGZUM7olY+vF5Av2nqH1iAvSMKx5DJZxDnqrcY= +github.com/pulumi/pulumi/sdk/v3 v3.233.0/go.mod h1:Eu9QVad1cSPymhTboINPqK6WZMaW7I0NHQcWOmxLYek= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -350,5 +350,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= lukechampine.com/frand v1.5.1 h1:fg0eRtdmGFIxhP5zQJzM1lFDbD6CUfu/f+7WgAZd5/w= lukechampine.com/frand v1.5.1/go.mod h1:4VstaWc2plN4Mjr10chUD46RAVGWhpkZ5Nja8+Azp0Q= -pgregory.net/rapid v0.6.1 h1:4eyrDxyht86tT4Ztm+kvlyNBLIk071gR+ZQdhphc9dQ= -pgregory.net/rapid v0.6.1/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= From 648da259b02c0398e9fa6dc9432790a196885e15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 06:12:19 -0400 Subject: [PATCH 071/190] build(deps): bump github.com/caarlos0/env/v11 from 11.4.0 to 11.4.1 (#1236) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/caarlos0/env/v11](https://github.com/caarlos0/env) from 11.4.0 to 11.4.1. Release notes
Sourced from github.com/caarlos0/env/v11's releases.
v11.4.1
Changelog
Bug fixes
- 6daeb06ac7e3c9532a7eaa5768d45917393b7480: fix: use Key instead of OwnKey in rawEnvVars to properly reference existing defaults in complex structs (#412) (
@AndrewChubatiuk)Documentation updates
- 1ff55e6c9733833ce75d62b345916a407dbe4158: docs: adaptive starchart (#416) (
@alexandear)Other work
- cf4a9682420b025e44b4773fd7ee0be48bb68b2f: ci(deps): bump the actions group with 3 updates (#411) (
@dependabot[bot])- 33faf6f333c2c3dacef2991825f8e03960a2c0cb: ci(deps): bump the actions group with 3 updates (#417) (
@dependabot[bot])- 0cb635b62488f4d310809a82a8832cedc9aa94eb: ci(deps): bump the actions group with 6 updates (#415) (
@dependabot[bot])- a72d89a8930fc800372a6a338a1acf33e5cc3a56: ci: update release config (
@caarlos0)
Released with GoReleaser Pro!
Commits
a72d89aci: update release config6daeb06fix: use Key instead of OwnKey in rawEnvVars to properly reference existing d...33faf6fci(deps): bump the actions group with 3 updates (#417)1ff55e6docs: adaptive starchart (#416)0cb635bci(deps): bump the actions group with 6 updates (#415)cf4a968ci(deps): bump the actions group with 3 updates (#411)- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dac7d01..9294010 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( cloud.google.com/go/kms v1.30.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 - github.com/caarlos0/env/v11 v11.4.0 + github.com/caarlos0/env/v11 v11.4.1 github.com/coreos/go-oidc/v3 v3.18.0 github.com/danielgtaylor/huma/v2 v2.37.3 github.com/golang-jwt/jwt/v5 v5.3.1 diff --git a/go.sum b/go.sum index c7cf970..cb4f347 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgv github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/caarlos0/env/v11 v11.4.0 h1:Kcb6t5kIIr4XkoQC9AF2j+8E1Jsrl3Wz/hhm1LtoGAc= -github.com/caarlos0/env/v11 v11.4.0/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= +github.com/caarlos0/env/v11 v11.4.1 h1:fYwH0sWEsBSMPG7t4e/PEfTFzrWrpjyygXyUnWiSwEw= +github.com/caarlos0/env/v11 v11.4.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= 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/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= From f3308d16f51d3a9cb3d7b2d3f05e0634095fa60c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 06:12:32 -0400 Subject: [PATCH 072/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.233.0 to 3.234.0 in /deploy (#1237) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.233.0 to 3.234.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.234.0
3.234.0 (2026-05-01)
Features
[cli/cloud] Add
pulumi cloud api describefor inspecting the parameters, request body, and response schema of any Pulumi Cloud API operation, with text, markdown, and JSON output[cli/cloud] Add
pulumi cloud api listfor browsing every endpoint exposed by the Pulumi Cloud OpenAPI spec, with table and JSON outputBug Fixes
- [engine] Revert changes to property path parsing that resulted in errors for currently valid paths
Changelog
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.234.0 (2026-05-01)
Features
[cli/cloud] Add
pulumi cloud api describefor inspecting the parameters, request body, and response schema of any Pulumi Cloud API operation, with text, markdown, and JSON output[cli/cloud] Add
pulumi cloud api listfor browsing every endpoint exposed by the Pulumi Cloud OpenAPI spec, with table and JSON outputBug Fixes
- [engine] Revert changes to property path parsing that resulted in errors for currently valid paths
Commits
e802ef2Revert "Tighten parsing on new property paths (#22695)" (#22801)f5deaa1cli/cloud: addpulumi cloud api describe(#22770)bccf53dcli/cloud: addpulumi cloud api list(#22769)5575172Changelog and go.mod updates for v3.233.0 (#22795)caf13d6Cancel in-flight fuzz iterations when the 20s cap fires (#22725)324811cFreeze v2.233.0 (#22793)- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 50d59a8..d64615f 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 - github.com/pulumi/pulumi/sdk/v3 v3.233.0 + github.com/pulumi/pulumi/sdk/v3 v3.234.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/deploy/go.sum b/deploy/go.sum index 8f015d6..54c892c 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -183,8 +183,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 h1:nF0Y1F7fUGL6RYD9EAtHTdDbNFmDaA3xcEiRlvCDV5E= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.233.0 h1:r2Z1GtGZUM7olY+vF5Av2nqH1iAvSMKx5DJZxDnqrcY= -github.com/pulumi/pulumi/sdk/v3 v3.233.0/go.mod h1:Eu9QVad1cSPymhTboINPqK6WZMaW7I0NHQcWOmxLYek= +github.com/pulumi/pulumi/sdk/v3 v3.234.0 h1:PoXVM2lJoyqavwPQlVQC6KzhGKNOJpz9OFxyojm8RjA= +github.com/pulumi/pulumi/sdk/v3 v3.234.0/go.mod h1:Eu9QVad1cSPymhTboINPqK6WZMaW7I0NHQcWOmxLYek= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From 811046c4ce305444b9bc9b3c2e3dfb527e10f7e5 Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Mon, 4 May 2026 03:24:34 -0700 Subject: [PATCH 073/190] auth/oidc: support slice-typed extra claims via overlap match (#1238) Closes #988. Direct `actualValue != expectedValue` fails when the token claim is an array (groups, roles, scp, aud). Switch to a slice-aware any-of overlap so OIDC list claims are validated correctly. --- internal/api/handlers/v0/auth/oidc.go | 34 ++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/internal/api/handlers/v0/auth/oidc.go b/internal/api/handlers/v0/auth/oidc.go index 0cef699..98526e1 100644 --- a/internal/api/handlers/v0/auth/oidc.go +++ b/internal/api/handlers/v0/auth/oidc.go @@ -224,7 +224,7 @@ func (h *OIDCHandler) validateExtraClaims(claims *OIDCClaims) error { return fmt.Errorf("claim validation failed: required claim %s not found", key) } - if actualValue != expectedValue { + if !claimMatches(actualValue, expectedValue) { return fmt.Errorf("claim validation failed: %s expected %v, got %v", key, expectedValue, actualValue) } } @@ -233,6 +233,38 @@ func (h *OIDCHandler) validateExtraClaims(claims *OIDCClaims) error { return nil } +// claimMatches reports whether a claim value satisfies the expected configuration. +// Both sides may be a scalar or a slice; for slice-typed claims (groups, roles, scp, +// aud, etc.) any single overlap is treated as a match, mirroring how OIDC consumers +// normally interpret list claims. +func claimMatches(actual, expected any) bool { + actualList := toAnySlice(actual) + expectedList := toAnySlice(expected) + for _, e := range expectedList { + for _, a := range actualList { + if a == e { + return true + } + } + } + return false +} + +func toAnySlice(v any) []any { + switch s := v.(type) { + case []any: + return s + case []string: + out := make([]any, len(s)) + for i, x := range s { + out[i] = x + } + return out + default: + return []any{v} + } +} + // buildPermissions builds permissions based on OIDC claims and configuration func (h *OIDCHandler) buildPermissions(_ *OIDCClaims) []auth.Permission { var permissions []auth.Permission From dfaa8f3b82c33e2bce0821fc968f95251be47fca Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 4 May 2026 06:52:12 -0400 Subject: [PATCH 074/190] auth/oidc: test slice-typed extra claims comparison (#1245) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Follow-up to #1238 (closes #988). Adds direct unit-test coverage for the `claimMatches` helper, which was the actual change in #1238. `claimMatches` and `toAnySlice` are unexported, so the tests live in `oidc_internal_test.go` (`package auth`) — same pattern as `http_internal_test.go`. Cases covered: - scalar/scalar match and mismatch - scalar actual against array expected (both directions of overlap) - array actual against scalar expected - **array/array** — pre-#1238 this combination panicked with `comparing uncomparable type []interface {}` - `[]string` typed slice (exercises the typed-slice branch of `toAnySlice`, which `[]any` skips) - non-string scalars (int, bool) - empty actual array Test values use single letters (`x`, `y`, `p`, `q`) rather than role labels — only the relationships matter, and short tokens keep `goconst` quiet. ## Test plan - [x] `go test ./internal/api/handlers/v0/auth/...` — all 13 subtests pass - [x] `golangci-lint run ./internal/api/handlers/v0/auth/...` — no new issues vs main --- .../handlers/v0/auth/oidc_internal_test.go | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 internal/api/handlers/v0/auth/oidc_internal_test.go diff --git a/internal/api/handlers/v0/auth/oidc_internal_test.go b/internal/api/handlers/v0/auth/oidc_internal_test.go new file mode 100644 index 0000000..cc3e472 --- /dev/null +++ b/internal/api/handlers/v0/auth/oidc_internal_test.go @@ -0,0 +1,41 @@ +package auth + +import "testing" + +func TestClaimMatches(t *testing.T) { + tests := []struct { + name string + actual any + expected any + want bool + }{ + {"scalar/scalar match", "x", "x", true}, + {"scalar/scalar mismatch", "x", "y", false}, + + {"scalar actual in array expected", "x", []any{"x", "y"}, true}, + {"scalar actual not in array expected", "z", []any{"x", "y"}, false}, + + {"array actual contains scalar expected", []any{"x", "y"}, "x", true}, + {"array actual missing scalar expected", []any{"y", "z"}, "x", false}, + + // Pre-#1238 array/array comparison panicked with "comparing uncomparable type []interface {}". + {"array/array overlap", []any{"a", "b"}, []any{"b", "c"}, true}, + {"array/array disjoint", []any{"a", "b"}, []any{"c", "d"}, false}, + + // Exercises the []string branch of toAnySlice (concrete typed slice, not []any). + {"[]string actual matches scalar", []string{"p", "q"}, "p", true}, + {"scalar matches []string expected", "p", []string{"p", "q"}, true}, + + {"non-string scalar match", 42, 42, true}, + {"bool scalar match", true, true, true}, + {"empty actual array", []any{}, "x", false}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := claimMatches(tt.actual, tt.expected); got != tt.want { + t.Errorf("claimMatches(%v, %v) = %v, want %v", tt.actual, tt.expected, got, tt.want) + } + }) + } +} From 6f9bd6661c45ee477dee15b21b57c171352473ca Mon Sep 17 00:00:00 2001 From: Mesut Oezdil <114185853+mesutoezdil@users.noreply.github.com> Date: Mon, 4 May 2026 12:57:02 +0200 Subject: [PATCH 075/190] refactor: extract readBody helper to remove duplicate io.ReadAll calls (#1241) The same pattern for reading an error response body appeared in three places across the auth handlers: - `internal/api/handlers/v0/auth/github_at.go` (twice) - `internal/api/handlers/v0/auth/github_oidc.go` (once) A shared `readBody` helper function added to `common.go` now handles this in one place. The `io` import is removed from both files since it is no longer used directly there. --------- Co-authored-by: Radoslav Dimitrov --- internal/api/handlers/v0/auth/common.go | 6 ++++++ internal/api/handlers/v0/auth/github_at.go | 7 ++----- internal/api/handlers/v0/auth/github_oidc.go | 4 +--- internal/database/postgres.go | 1 - 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/internal/api/handlers/v0/auth/common.go b/internal/api/handlers/v0/auth/common.go index c283655..2c81303 100644 --- a/internal/api/handlers/v0/auth/common.go +++ b/internal/api/handlers/v0/auth/common.go @@ -10,6 +10,7 @@ import ( "encoding/hex" "errors" "fmt" + "io" "math/big" "net" "regexp" @@ -20,6 +21,11 @@ import ( "github.com/modelcontextprotocol/registry/internal/config" ) +func readBody(r io.Reader) string { + b, _ := io.ReadAll(r) + return string(b) +} + // ErrSignatureMismatch is returned by VerifySignature when the signature is structurally // valid but does not verify against the public key. Distinguishing this from structural // failures (wrong size, bad key format) lets the caller add fingerprint hints only when diff --git a/internal/api/handlers/v0/auth/github_at.go b/internal/api/handlers/v0/auth/github_at.go index fbb950c..b495f4d 100644 --- a/internal/api/handlers/v0/auth/github_at.go +++ b/internal/api/handlers/v0/auth/github_at.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "io" "net/http" "regexp" "strings" @@ -123,8 +122,7 @@ func (h *GitHubHandler) getGitHubUser(ctx context.Context, token string) (*GitHu defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - body, _ := io.ReadAll(resp.Body) - return nil, fmt.Errorf("GitHub API error (status %d): %s", resp.StatusCode, body) + return nil, fmt.Errorf("GitHub API error (status %d): %s", resp.StatusCode, readBody(resp.Body)) } var user GitHubUserOrOrg @@ -152,8 +150,7 @@ func (h *GitHubHandler) getGitHubUserOrgs(ctx context.Context, username string, defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - body, _ := io.ReadAll(resp.Body) - return nil, fmt.Errorf("GitHub API error (status %d): %s", resp.StatusCode, body) + return nil, fmt.Errorf("GitHub API error (status %d): %s", resp.StatusCode, readBody(resp.Body)) } var orgs []GitHubUserOrOrg diff --git a/internal/api/handlers/v0/auth/github_oidc.go b/internal/api/handlers/v0/auth/github_oidc.go index 4170640..6a6761b 100644 --- a/internal/api/handlers/v0/auth/github_oidc.go +++ b/internal/api/handlers/v0/auth/github_oidc.go @@ -6,7 +6,6 @@ import ( "encoding/base64" "encoding/json" "fmt" - "io" "math/big" "net/http" "strings" @@ -149,8 +148,7 @@ func (v *GitHubOIDCValidator) fetchJWKS(ctx context.Context) (*JWKS, error) { defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - body, _ := io.ReadAll(resp.Body) - return nil, fmt.Errorf("JWKS endpoint returned status %d: %s", resp.StatusCode, body) + return nil, fmt.Errorf("JWKS endpoint returned status %d: %s", resp.StatusCode, readBody(resp.Body)) } var jwks JWKS diff --git a/internal/database/postgres.go b/internal/database/postgres.go index 2749ad8..b0b2d98 100644 --- a/internal/database/postgres.go +++ b/internal/database/postgres.go @@ -198,7 +198,6 @@ func (db *PostgreSQL) ListServers( whereConditions = append(whereConditions, cursorCondition) args = append(args, cursorArgs...) } - _ = argIndex // Silence unused variable warning // Build the WHERE clause whereClause := "" From 7a4216c52823fe1b64b40608ec84e4745684a2c7 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 4 May 2026 07:09:57 -0400 Subject: [PATCH 076/190] refactor: rename readBody to readErrorBody and cap body size (#1246) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Follow-up to #1241. Two small tweaks to the `readBody` helper: - **Rename `readBody` → `readErrorBody`.** The helper is only ever called on the error path (after a non-2xx status check), where we want a small string for diagnostics. The generic name made it look reusable on the success path, where streaming JSON decoding is the right approach. The new name pins the intended use down. - **Cap the read with `io.LimitReader` (8 KiB).** Defense in depth — error diagnostics never need more than a few KB, and we shouldn't buffer an arbitrarily large body from an upstream just to format an error message. 8 KiB is well above any realistic GitHub API or JWKS error response. No behavior change on the happy path. On the unhappy path, error messages are now bounded. ## Test plan - [x] `go build ./...` - [x] `go test ./internal/api/handlers/v0/auth/...` 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- internal/api/handlers/v0/auth/common.go | 8 ++++++-- internal/api/handlers/v0/auth/github_at.go | 4 ++-- internal/api/handlers/v0/auth/github_oidc.go | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/internal/api/handlers/v0/auth/common.go b/internal/api/handlers/v0/auth/common.go index 2c81303..5d91047 100644 --- a/internal/api/handlers/v0/auth/common.go +++ b/internal/api/handlers/v0/auth/common.go @@ -21,8 +21,12 @@ import ( "github.com/modelcontextprotocol/registry/internal/config" ) -func readBody(r io.Reader) string { - b, _ := io.ReadAll(r) +// readErrorBody reads an upstream error response body for inclusion in an +// error message. The cap protects against a misbehaving upstream returning a +// huge body — error diagnostics never need more than a few KB. +func readErrorBody(r io.Reader) string { + const maxErrorBodySize = 8 * 1024 + b, _ := io.ReadAll(io.LimitReader(r, maxErrorBodySize)) return string(b) } diff --git a/internal/api/handlers/v0/auth/github_at.go b/internal/api/handlers/v0/auth/github_at.go index b495f4d..af5e793 100644 --- a/internal/api/handlers/v0/auth/github_at.go +++ b/internal/api/handlers/v0/auth/github_at.go @@ -122,7 +122,7 @@ func (h *GitHubHandler) getGitHubUser(ctx context.Context, token string) (*GitHu defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("GitHub API error (status %d): %s", resp.StatusCode, readBody(resp.Body)) + return nil, fmt.Errorf("GitHub API error (status %d): %s", resp.StatusCode, readErrorBody(resp.Body)) } var user GitHubUserOrOrg @@ -150,7 +150,7 @@ func (h *GitHubHandler) getGitHubUserOrgs(ctx context.Context, username string, defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("GitHub API error (status %d): %s", resp.StatusCode, readBody(resp.Body)) + return nil, fmt.Errorf("GitHub API error (status %d): %s", resp.StatusCode, readErrorBody(resp.Body)) } var orgs []GitHubUserOrOrg diff --git a/internal/api/handlers/v0/auth/github_oidc.go b/internal/api/handlers/v0/auth/github_oidc.go index 6a6761b..5ce38ac 100644 --- a/internal/api/handlers/v0/auth/github_oidc.go +++ b/internal/api/handlers/v0/auth/github_oidc.go @@ -148,7 +148,7 @@ func (v *GitHubOIDCValidator) fetchJWKS(ctx context.Context) (*JWKS, error) { defer resp.Body.Close() if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("JWKS endpoint returned status %d: %s", resp.StatusCode, readBody(resp.Body)) + return nil, fmt.Errorf("JWKS endpoint returned status %d: %s", resp.StatusCode, readErrorBody(resp.Body)) } var jwks JWKS From fbfd63ced8e1f6bee9ccd0dd93f1b8fe087f9f22 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 4 May 2026 09:25:41 -0400 Subject: [PATCH 077/190] fix(ui): encode publisher-controlled URLs for href attribute context (#1248) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The catalogue page interpolates publisher-supplied URL fields (`server.repository.url`, `server.websiteUrl`) inside `href="..."` attributes via `innerHTML`, escaping them with a `textContent`→`innerHTML` helper. Per the HTML5 fragment-serialisation algorithm, that round-trip encodes only `&`, `<`, `>`, and U+00A0 inside text nodes — it does not encode `"` or `'`. The helper is therefore safe in element-text contexts (where it is used for `name`, `version`, `description`, etc.) but unsafe inside an attribute value. Add an attribute-safe `escapeAttr` helper that follows the OWASP attribute-encoding rule (also encodes `"` and `'`) and use it for the two `href` interpolations. Element-text usages keep the existing `escapeHtml` and remain unchanged. A short comment on each helper documents the contexts they cover so future fields are wired up correctly. Co-Authored-By: Claude Opus 4.7 (1M context) Co-authored-by: Claude Opus 4.7 (1M context) --- internal/api/handlers/v0/ui_index.html | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/internal/api/handlers/v0/ui_index.html b/internal/api/handlers/v0/ui_index.html index 38bac7f..dc437ff 100644 --- a/internal/api/handlers/v0/ui_index.html +++ b/internal/api/handlers/v0/ui_index.html @@ -423,13 +423,13 @@ ${server.repository?.url ? ` ` : ''} ${server.websiteUrl ? ` ` : ''} @@ -491,12 +491,26 @@ }); // Utility functions + // Safe for element-text contexts only: encodes `&`, `<`, `>`. Does NOT + // encode `"` or `'`, so it is unsafe inside attribute values — use + // escapeAttr there. function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } + // Safe for HTML attribute values per OWASP attribute-encoding rule. + function escapeAttr(text) { + if (text == null) return ''; + return String(text) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + function formatDate(dateStr) { if (!dateStr) return '-'; const date = new Date(dateStr); From 78b7bbde07948049b916d76b4769faee461ff930 Mon Sep 17 00:00:00 2001 From: Radoslav DimitrovDate: Mon, 4 May 2026 09:26:50 -0400 Subject: [PATCH 078/190] fix(validators): reject HTML metacharacters and whitespace in websiteUrl (#1249) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `validateWebsiteURL` only checked that the URL parses, is absolute, and uses the `https` scheme. It accepted literal `"`, `'`, `<`, `>`, and ASCII space — none of which are valid in a URI per RFC 3986, and all of which broke rendering when the value flowed into the catalogue UI's `` template. Add a `strings.IndexAny` check after the scheme check that rejects any of these characters with a clear `website-url-invalid-characters` issue that points at the offending byte position. Control characters (`\t`, `\n`, `\r`) are also covered: they're caught one step earlier by Go's `url.Parse`, but the bytes are listed in the rejection set so the behaviour is explicit and survives any future relaxation of `url.Parse`. Already-percent-encoded URLs (e.g. `?q=hello%20world`) continue to validate cleanly. Adds table-driven cases for `"`, `'`, `<>`, space, newline, and a positive case for percent-encoded special characters. Co-Authored-By: Claude Opus 4.7 (1M context) Co-authored-by: Claude Opus 4.7 (1M context) --- internal/validators/validators.go | 14 ++++ internal/validators/validators_test.go | 94 ++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/internal/validators/validators.go b/internal/validators/validators.go index 4da756d..114ed3c 100644 --- a/internal/validators/validators.go +++ b/internal/validators/validators.go @@ -195,6 +195,20 @@ func validateWebsiteURL(ctx *ValidationContext, websiteURL string) *ValidationRe result.AddIssue(issue) } + // Reject characters that aren't valid in a URI per RFC 3986 and that have + // caused rendering issues when websiteUrl flows into the catalogue UI's + // href attributes. Publishers should percent-encode these in the source URL. + if i := strings.IndexAny(websiteURL, "\"'<> \t\n\r"); i >= 0 { + issue := NewValidationIssue( + ValidationIssueTypeSemantic, + ctx.String(), + fmt.Sprintf("websiteUrl contains an invalid character %q at position %d: %s", websiteURL[i], i, websiteURL), + ValidationIssueSeverityError, + "website-url-invalid-characters", + ) + result.AddIssue(issue) + } + return result } diff --git a/internal/validators/validators_test.go b/internal/validators/validators_test.go index d4ff5c1..c3e5585 100644 --- a/internal/validators/validators_test.go +++ b/internal/validators/validators_test.go @@ -13,6 +13,8 @@ import ( "github.com/modelcontextprotocol/registry/pkg/model" ) +const websiteURLInvalidCharErrSubstr = "websiteUrl contains an invalid character" + func TestValidate(t *testing.T) { tests := []struct { name string @@ -486,6 +488,98 @@ func TestValidate(t *testing.T) { }, expectedError: "invalid websiteUrl:", }, + { + name: "server with websiteUrl containing double quote", + serverDetail: apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, + Name: "com.example/test-server", + Description: "A test server", + Repository: &model.Repository{ + URL: "https://github.com/owner/repo", + Source: "github", + }, + Version: "1.0.0", + WebsiteURL: `https://example.com/"oops`, + }, + expectedError: websiteURLInvalidCharErrSubstr, + }, + { + name: "server with websiteUrl containing single quote", + serverDetail: apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, + Name: "com.example/test-server", + Description: "A test server", + Repository: &model.Repository{ + URL: "https://github.com/owner/repo", + Source: "github", + }, + Version: "1.0.0", + WebsiteURL: "https://example.com/it's", + }, + expectedError: websiteURLInvalidCharErrSubstr, + }, + { + name: "server with websiteUrl containing angle brackets", + serverDetail: apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, + Name: "com.example/test-server", + Description: "A test server", + Repository: &model.Repository{ + URL: "https://github.com/owner/repo", + Source: "github", + }, + Version: "1.0.0", + WebsiteURL: "https://example.com/ ", + }, + expectedError: websiteURLInvalidCharErrSubstr, + }, + { + name: "server with websiteUrl containing space", + serverDetail: apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, + Name: "com.example/test-server", + Description: "A test server", + Repository: &model.Repository{ + URL: "https://github.com/owner/repo", + Source: "github", + }, + Version: "1.0.0", + WebsiteURL: "https://example.com/has space", + }, + expectedError: websiteURLInvalidCharErrSubstr, + }, + { + name: "server with websiteUrl containing newline", + serverDetail: apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, + Name: "com.example/test-server", + Description: "A test server", + Repository: &model.Repository{ + URL: "https://github.com/owner/repo", + Source: "github", + }, + Version: "1.0.0", + WebsiteURL: "https://example.com/has\nnewline", + }, + // url.Parse rejects ASCII control chars before our character-set + // check runs; either path produces a validation error. + expectedError: "invalid websiteUrl:", + }, + { + name: "server with websiteUrl with percent-encoded special chars is accepted", + serverDetail: apiv0.ServerJSON{ + Schema: model.CurrentSchemaURL, + Name: "com.example/test-server", + Description: "A test server", + Repository: &model.Repository{ + URL: "https://github.com/owner/repo", + Source: "github", + }, + Version: "1.0.0", + WebsiteURL: "https://example.com/path/?q=hello%20world&r=a%22b", + }, + expectedError: "", + }, { name: "server with websiteUrl that matches namespace domain", serverDetail: apiv0.ServerJSON{ From f5f40bd98084466eaf18fe48ea62a0d534caa774 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 4 May 2026 09:41:23 -0400 Subject: [PATCH 079/190] fix(auth/http): extend SSRF blocklist to IPv6 6to4/NAT64/site-local prefixes (#1250) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HTTP namespace-verification fetcher's `isBlockedIP` composed its blocklist from Go stdlib's `Is*` helpers plus a manual CGNAT range. That covers IPv4 cloud metadata, RFC1918, ULA, and link-local — but Go's classification helpers don't recognise IPv6 prefix families that embed or tunnel to arbitrary IPv4: - 2002::/16 RFC 3056 6to4 — bits 16-47 are an arbitrary IPv4 - 64:ff9b::/96 RFC 6052 NAT64 well-known — low 32 bits are IPv4 - 64:ff9b:1::/48 RFC 8215 NAT64 local-use — same IPv4-embedding shape - fec0::/10 RFC 3879 site-local (deprecated, still routed by some stacks) On hosts with 6to4 routing or a NAT64 next-hop (the default on IPv6-only GKE node pools, AWS IPv6-only EC2, Azure IPv6 VMs with NAT64, and many corporate DNS64/NAT64 networks), an attacker who controls DNS for a publisher domain can cause the registry to dial `169.254.169.254`, `10.0.0.0/8`, etc. via the IPv6 wrapper. Same SSRF class as GHSA-56c3-vfp2-5qqj on n8n-mcp. Define the four prefixes via a new `mustCIDR` helper (panic on malformed CIDR at init so a typo can't fail-open silently) and iterate them in `isBlockedIP` after the stdlib gates. Refactor the existing CGNAT IIFE to use the same helper for consistency. IPv4-mapped IPv6 (::ffff:0:0/96) needs no special-casing: Go's `Is*` helpers honour the `To4()` fast-path, so e.g. `::ffff:10.0.0.1` is already classified as `IsPrivate`. Adds 17 test cases to `TestIsBlockedIP` covering each new prefix family, IPv4-mapped IPv6 sanity checks, and just-outside-the-range positive controls (`2001::1`, `2003::1`, `64:ff9c::1`). Co-Authored-By: Claude Opus 4.7 (1M context) Co-authored-by: Claude Opus 4.7 (1M context) --- internal/api/handlers/v0/auth/http.go | 52 ++++++++++++++++--- .../handlers/v0/auth/http_internal_test.go | 28 ++++++++++ 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/internal/api/handlers/v0/auth/http.go b/internal/api/handlers/v0/auth/http.go index 7d73d52..8f438b7 100644 --- a/internal/api/handlers/v0/auth/http.go +++ b/internal/api/handlers/v0/auth/http.go @@ -109,27 +109,65 @@ func safeDialContext(ctx context.Context, network, addr string) (net.Conn, error return nil, fmt.Errorf("dial %s: all resolved public addresses failed: %w", host, lastErr) } +// mustCIDR parses a CIDR literal at init; panics on malformed input so a +// typo surfaces at startup rather than letting a nil *IPNet through to the +// blocklist check (which would silently fail-open). +func mustCIDR(s string) *net.IPNet { + _, n, err := net.ParseCIDR(s) + if err != nil { + panic(fmt.Sprintf("auth: invalid CIDR %q: %v", s, err)) + } + return n +} + // cgnatRange covers RFC 6598 Carrier-Grade NAT (100.64.0.0/10), which the // stdlib does not classify via any Is* helper but is reachable on some // cloud / mobile networks where it shadows internal infrastructure. -var cgnatRange = func() *net.IPNet { - _, n, _ := net.ParseCIDR("100.64.0.0/10") - return n -}() +var cgnatRange = mustCIDR("100.64.0.0/10") + +// blockedIPv6Prefixes are IPv6 ranges that either embed an arbitrary IPv4 +// address (and therefore tunnel into RFC1918 / cloud-metadata space on +// hosts with the corresponding routing) or are routed into site-local +// internal networks. None of these are caught by Go's per-class Is* +// helpers. +// +// 2002::/16 RFC 3056 6to4 — bits 16-47 are an IPv4 address +// 64:ff9b::/96 RFC 6052 NAT64 well-known — low 32 bits are IPv4 +// 64:ff9b:1::/48 RFC 8215 NAT64 local-use — same IPv4-embedding shape +// fec0::/10 RFC 3879 site-local (deprecated, still routed by some +// stacks) +var blockedIPv6Prefixes = []*net.IPNet{ + mustCIDR("2002::/16"), + mustCIDR("64:ff9b::/96"), + mustCIDR("64:ff9b:1::/48"), + mustCIDR("fec0::/10"), +} // isBlockedIP reports whether an IP must not be dialled by the namespace // verification fetcher. Covers loopback (127/8, ::1), RFC1918 + ULA via // IsPrivate, link-local (169.254/16, fe80::/10 — includes cloud metadata // 169.254.169.254), unspecified (0.0.0.0, ::), all multicast (admin-scoped -// 239/8 and ff00::/8 in addition to link-local-multicast), and CGNAT. +// 239/8 and ff00::/8 in addition to link-local-multicast), CGNAT, and +// IPv6 prefix families that tunnel to or embed arbitrary IPv4 addresses +// (see blockedIPv6Prefixes). IPv4-mapped IPv6 (::ffff:0:0/96) is handled +// implicitly: the stdlib Is* helpers honour the To4() fast-path, so e.g. +// ::ffff:10.0.0.1 is correctly classified as IsPrivate. func isBlockedIP(ip net.IP) bool { if ip == nil { return true } - return ip.IsLoopback() || ip.IsPrivate() || + if ip.IsLoopback() || ip.IsPrivate() || ip.IsLinkLocalUnicast() || ip.IsMulticast() || ip.IsUnspecified() || - cgnatRange.Contains(ip) + cgnatRange.Contains(ip) { + return true + } + for _, p := range blockedIPv6Prefixes { + if p.Contains(ip) { + return true + } + } + return false } // NewDefaultHTTPKeyFetcherWithClient creates a new HTTP key fetcher with a custom HTTP client. diff --git a/internal/api/handlers/v0/auth/http_internal_test.go b/internal/api/handlers/v0/auth/http_internal_test.go index 5b2ce37..998c8c8 100644 --- a/internal/api/handlers/v0/auth/http_internal_test.go +++ b/internal/api/handlers/v0/auth/http_internal_test.go @@ -30,10 +30,38 @@ func TestIsBlockedIP(t *testing.T) { // Blocked — Carrier-Grade NAT (RFC 6598) {"100.64.0.1", true}, {"100.127.255.254", true}, + // Blocked — IPv6 6to4 (RFC 3056 2002::/16); bits 16-47 are an + // arbitrary IPv4 address, so 2002:a9fe:a9fe:: tunnels to + // 169.254.169.254 and 2002:0a00:0001:: tunnels to 10.0.0.1. + {"2002:a9fe:a9fe::", true}, + {"2002:0a00:0001::", true}, + {"2002::1", true}, + // Blocked — IPv6 NAT64 well-known prefix (RFC 6052 64:ff9b::/96); + // low 32 bits embed an IPv4 address. + {"64:ff9b::a9fe:a9fe", true}, + {"64:ff9b::a00:1", true}, + // Blocked — IPv6 NAT64 local-use prefix (RFC 8215 64:ff9b:1::/48). + {"64:ff9b:1::1", true}, + {"64:ff9b:1:abcd::", true}, + // Blocked — IPv6 deprecated site-local (RFC 3879 fec0::/10); + // still routed into internal networks by some stacks. + {"fec0::1", true}, + {"feff::1", true}, + // Blocked — IPv4-mapped IPv6 (::ffff:0:0/96) inherits the + // classification of the wrapped IPv4 via To4() fast-path; covered + // here as an explicit regression guard. + {"::ffff:127.0.0.1", true}, + {"::ffff:10.0.0.1", true}, + {"::ffff:169.254.169.254", true}, // Allowed — public {"1.1.1.1", false}, {"8.8.8.8", false}, {"2606:4700:4700::1111", false}, + {"2001:4860:4860::8888", false}, + // Allowed — just outside the new IPv6 blocks + {"2001::1", false}, // outside 2002::/16 + {"2003::1", false}, // outside 2002::/16 on the other side + {"64:ff9c::1", false}, // outside 64:ff9b::/96 // Allowed — outside CGNAT range {"100.63.255.255", false}, {"100.128.0.1", false}, From 1b9f69e81b27bc2e3dc73c2c986c890c3af7173a Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 4 May 2026 10:07:32 -0400 Subject: [PATCH 080/190] deploy: update prod to v1.7.7 (#1251) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Bump `mcp-registry:imageTag` from `1.7.6` → `1.7.7` in `deploy/Pulumi.gcpProd.yaml` - v1.7.7 is a security patch covering three findings (validator hardening, attribute-context UI escaping, IPv6 SSRF blocklist extension); see the v1.7.7 release notes - Staging is on `f5f40bd` (the v1.7.7 commit) and verified end-to-end: - `/v0.1/version` reports the new commit - `/v0.1/validate` rejects a poisoned `websiteUrl` with `website-url-invalid-characters` - `/` HTML serves the `escapeAttr` helper ## Test plan - [ ] Confirm release workflow's `ko-push` job has finished publishing `ghcr.io/modelcontextprotocol/registry:1.7.7` before merging - [ ] Watch deploy-production workflow rolls the registry pods to `1.7.7` - [ ] Hit `https://registry.modelcontextprotocol.io/v0.1/version` and confirm `git_commit` matches `f5f40bd...` - [ ] Spot-check the catalogue UI loads cleanly 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index 034330b..44e5839 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.7.6 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.7.7 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From 6d6a8871749abf152d8f8173c1b61ac1ace14866 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 03:50:20 -0400 Subject: [PATCH 081/190] build(deps): bump pulumi/actions from 6.6.1 to 7.0.0 in the actions group (#1254) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the actions group with 1 update: [pulumi/actions](https://github.com/pulumi/actions). Updates `pulumi/actions` from 6.6.1 to 7.0.0 Release notes
Sourced from pulumi/actions's releases.
v7.0.0
What's Changed
- minor style fixups for CONTRIBUTING.md by
@tgummererin pulumi/actions#1396- Allow downloading PR artifacts by
@iwahbein pulumi/actions#1397- Bump Node runtime from 20 to 24 by
@nelsonfigueroain pulumi/actions#1404- Bump TypeScript and jest toolchain by
@nelsonfigueroain pulumi/actions#1405- chore: update ESLint stack and migrate to flat config by
@nelsonfigueroain pulumi/actions#1406New Contributors
@iwahbemade their first contribution in pulumi/actions#1397@nelsonfigueroamade their first contribution in pulumi/actions#1404Full Changelog: https://github.com/pulumi/actions/compare/v6...v7.0.0
Changelog
Sourced from pulumi/actions's changelog.
CHANGELOG
HEAD (Unreleased)
(none)
7.0.0 (2026-05-01)
- chore: update Action runtime to node 24 (#1404)
- chore: bump
typescript,jest,ts-jest,@types/jest,@types/node(#1405)- chore: update ESLint stack and migrate to flat config (#1406)
6.6.1 (2025-11-12)
- chore: Update pulumi/pulumi dependency (#1394)
6.6.0 (2025-09-29)
- feat: Strip ansi control characters from GitHub step Summary and PR comment (#1312)
6.4.0 (2025-07-16)
- feat: Add
run-programflag support for refresh, destroy, preview, and up/update commands (#1376)6.3.0 (2025-05-08)
feat: support
--excludeand--exclude-dependentsflags (#1363)feat: verbosity and debug inputs to enable debug options (#1046)
fix: update "user agent" string to pulumi/actions@v6 (#1357)
6.2.0 (2025-03-05)
- feat: support continue on error flag (--continue-on-error) (#1357)
6.1.0 (2025-02-27)
... (truncated)
Commits
8e5e406prepare v7.0.0 release (#1407)22d32eechore: update ESLint stack and migrate to flat config (#1406)bee3070Bump TypeScript and jest toolchain (#1405)eec25feBump Node runtime from 20 to 24 (#1404)85a185bchore(dist): Update dist [automated commit]7bf44bfAllow downloading PR buildsba42386minor style fixups for CONTRIBUTING.md (#1396)- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cancel-pulumi-lock.yml | 2 +- .github/workflows/deploy-production.yml | 2 +- .github/workflows/deploy-staging.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cancel-pulumi-lock.yml b/.github/workflows/cancel-pulumi-lock.yml index 345c0be..06f1305 100644 --- a/.github/workflows/cancel-pulumi-lock.yml +++ b/.github/workflows/cancel-pulumi-lock.yml @@ -27,7 +27,7 @@ jobs: uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 - name: Setup Pulumi - uses: pulumi/actions@8582a9e8cc630786854029b4e09281acd6794b58 + uses: pulumi/actions@8e5e406f4007fca908480587cb9893c07090f58d with: pulumi-version: ${{ env.PULUMI_VERSION }} diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index cd03772..bf8f4f2 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -32,7 +32,7 @@ jobs: cache: true - name: Setup Pulumi - uses: pulumi/actions@8582a9e8cc630786854029b4e09281acd6794b58 + uses: pulumi/actions@8e5e406f4007fca908480587cb9893c07090f58d with: pulumi-version: ${{ env.PULUMI_VERSION }} diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index 946aaaf..074bb4a 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -79,7 +79,7 @@ jobs: cache: true - name: Setup Pulumi - uses: pulumi/actions@8582a9e8cc630786854029b4e09281acd6794b58 + uses: pulumi/actions@8e5e406f4007fca908480587cb9893c07090f58d with: pulumi-version: ${{ env.PULUMI_VERSION }} From 4e147072f03aeacfe8456c7f24407e0ea65d92c0 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Tue, 5 May 2026 05:58:05 -0400 Subject: [PATCH 082/190] metrics: stop counting client-cancelled requests as server errors (#1255) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Remap recorded status to `499` (NGINX-style "client closed") when `ctx.Context().Err()` is `context.Canceled` after the handler returns - Skip the `http_errors_total` increment for `499`s so the availability metric reflects server-visible errors only ## Why Under scraper-driven load, clients with short timeouts paginate `/v0.1/servers`, give up while PG is busy, and close the TCP connection. The handler's DB iteration returns `context canceled`, the handler converts that to `huma.Error500InternalServerError`, and tries to write a response to the now-closed socket. NGINX records `499` (client closed) and never delivers anything to the client — but the registry's middleware records `status_code=500` and bumps `mcp_registry_http_errors_total`. That's what's been firing the `Availability dropped below 95%` alert during the daily 17:00 UTC bursts. Recent prod numbers from one pod (~19h uptime): ``` mcp_registry_http_errors_total{path="/v0.1/servers", status_code="500"} 7396 mcp_registry_http_errors_total{path="/v0.1/servers/{serverName}/versions", status_code="500"} 283 mcp_registry_http_errors_total{path="/v0/servers", status_code="500"} 352 ``` …against zero 5xx in NGINX ingress logs over the same window. The alert was correct *given the data it had*; the data was misclassifying client cancellations as server errors. ## What this does In `internal/api/router/router.go` (the metric middleware): after `next(ctx)`, check `ctx.Context().Err()`. If it's `context.Canceled`, override `statusCode` to `499` and skip the error counter. Requests counter and duration histogram still record so the cancellation rate stays visible. `context.DeadlineExceeded` is intentionally **not** remapped — that would indicate a server-side timeout if we ever add per-request deadlines, and should still count as a server error. ## What this does *not* do - Doesn't reduce the underlying load (ServiceNow + notion catalog scrapers driving the daily peak — separate work, see the `updated_since` outreach we're doing). - Doesn't change handler behaviour — handlers still call `huma.Error500…` on `context.Canceled`. We could short-circuit earlier (return without writing) to save the work, but that's a bigger refactor and the metric fix unblocks the alert immediately. ## Companion change (no code, just a Grafana annotation tweak) The `Availability dropped below 95%` alert (UID `bexrc60etvhmoa`) currently has the annotation: > No. of 5xx are increased from acceptable limit i.e. 5% of total throughput The query is on `mcp_registry_http_errors_total`, not 5xx specifically. After this change the count is meaningful again, but the wording is still misleading. Suggest updating to: > Internal error rate exceeded 5% of total throughput (no PromQL change required.) ## Test plan - [x] `go test ./internal/api/router/...` — new test passes - [x] `golangci-lint run ./internal/...` — clean - [ ] After merge, watch a daily 17:00 UTC burst — `mcp_registry_http_errors_total{status_code="500", path="/v0.1/servers"}` should stay flat while `mcp_registry_http_requests_total{status_code="499", path="/v0.1/servers"}` grows. Availability alert should not fire on cancellation-only bursts. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- internal/api/router/router.go | 28 ++++++- internal/api/router/router_test.go | 119 +++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 internal/api/router/router_test.go diff --git a/internal/api/router/router.go b/internal/api/router/router.go index 46b975b..7d64258 100644 --- a/internal/api/router/router.go +++ b/internal/api/router/router.go @@ -2,7 +2,9 @@ package router import ( + "context" "encoding/json" + "errors" "fmt" "net/http" "strings" @@ -19,6 +21,12 @@ import ( "github.com/modelcontextprotocol/registry/internal/telemetry" ) +// statusClientClosed mirrors NGINX's non-standard 499 — used for requests +// where the client disconnected before we finished. Distinguishing these from +// real server errors keeps the availability metric meaningful under bursts of +// scraper traffic that time out and reconnect. +const statusClientClosed = 499 + // Middleware configuration options type middlewareConfig struct { skipPaths map[string]bool @@ -67,6 +75,22 @@ func MetricTelemetryMiddleware(metrics *telemetry.Metrics, options ...Middleware duration := time.Since(start).Seconds() statusCode := ctx.Status() + // If the client disconnected before the handler finished, the handler + // likely converted the resulting context.Canceled into a huma 5xx and + // tried to write a response to a closed socket. NGINX records that + // case as a 499 (client closed). Without this remap we count it as a + // server error: a single ServiceNow-style burst that times out a + // few thousand list-servers requests inflates http_errors_total even + // though no client ever saw a 5xx, and the availability alert fires + // on what is effectively just slow responses. + // + // Only context.Canceled is remapped — context.DeadlineExceeded would + // indicate a server-side timeout we set ourselves and should still + // count as a server error if/when we add per-request deadlines. + if reqErr := ctx.Context().Err(); reqErr != nil && errors.Is(reqErr, context.Canceled) { + statusCode = statusClientClosed + } + // Combine common and custom attributes attrs := []attribute.KeyValue{ attribute.String("method", method), @@ -77,7 +101,9 @@ func MetricTelemetryMiddleware(metrics *telemetry.Metrics, options ...Middleware // Record metrics metrics.Requests.Add(ctx.Context(), 1, metric.WithAttributes(attrs...)) - if statusCode >= 400 { + // Skip the error counter for client-closed requests so the availability + // metric reflects server-visible errors only. + if statusCode >= 400 && statusCode != statusClientClosed { metrics.ErrorCount.Add(ctx.Context(), 1, metric.WithAttributes(attrs...)) } diff --git a/internal/api/router/router_test.go b/internal/api/router/router_test.go new file mode 100644 index 0000000..f61b1de --- /dev/null +++ b/internal/api/router/router_test.go @@ -0,0 +1,119 @@ +package router_test + +import ( + "context" + "errors" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/danielgtaylor/huma/v2" + "github.com/danielgtaylor/huma/v2/adapters/humago" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/modelcontextprotocol/registry/internal/api/router" + "github.com/modelcontextprotocol/registry/internal/telemetry" +) + +// TestMetricMiddleware_ClientCancelledNotCountedAsError verifies that a request +// the client gave up on (request-context Canceled) is recorded as 499 in +// http_requests_total and is NOT incremented in http_errors_total — even when +// the handler returned huma.Error500InternalServerError because its DB call +// surfaced context.Canceled. +// +// Regression test for the case where a ServiceNow-style scraper burst +// generated thousands of internal 500s for cancelled requests, tripping the +// "Availability dropped below 95%" alert despite zero 5xx reaching clients. +func TestMetricMiddleware_ClientCancelledNotCountedAsError(t *testing.T) { + shutdown, metrics, err := telemetry.InitMetrics("test") + require.NoError(t, err) + defer func() { _ = shutdown(context.Background()) }() + + mux := http.NewServeMux() + api := humago.New(mux, huma.DefaultConfig("Test API", "1.0.0")) + api.UseMiddleware(router.MetricTelemetryMiddleware(metrics)) + + // Handler that simulates: DB returns context.Canceled because the client + // disconnected, handler converts to huma 500. + huma.Register(api, huma.Operation{ + OperationID: "cancelled-list", + Method: http.MethodGet, + Path: "/v0/servers", + }, func(_ context.Context, _ *struct{}) (*struct{}, error) { + return nil, huma.Error500InternalServerError("Failed to get registry list", + errors.New("error iterating rows: context canceled")) + }) + + mux.Handle("/metrics", metrics.PrometheusHandler()) + + cancelledCtx, cancel := context.WithCancel(context.Background()) + cancel() + + req := httptest.NewRequest(http.MethodGet, "/v0/servers", nil).WithContext(cancelledCtx) + rec := httptest.NewRecorder() + mux.ServeHTTP(rec, req) + + scrapeReq := httptest.NewRequest(http.MethodGet, "/metrics", nil) + scrapeRec := httptest.NewRecorder() + mux.ServeHTTP(scrapeRec, scrapeReq) + assert.Equal(t, http.StatusOK, scrapeRec.Code) + + body := scrapeRec.Body.String() + + // The request is recorded — but as 499, not 500. + assert.True(t, + containsMetric(body, `mcp_registry_http_requests_total`, `status_code="499"`, `path="/v0/servers"`), + "expected requests_total to record status_code=499 for the cancelled request; got:\n%s", + filterMetricLines(body, "mcp_registry_http_requests_total"), + ) + assert.False(t, + containsMetric(body, `mcp_registry_http_requests_total`, `status_code="500"`, `path="/v0/servers"`), + "did not expect requests_total to record status_code=500 for a client-cancelled request; got:\n%s", + filterMetricLines(body, "mcp_registry_http_requests_total"), + ) + + // The error counter is NOT bumped for 499s — that is the point of this fix. + assert.False(t, + containsMetric(body, `mcp_registry_http_errors_total`, `status_code="499"`), + "errors_total must not be incremented for client-cancelled requests; got:\n%s", + filterMetricLines(body, "mcp_registry_http_errors_total"), + ) + assert.False(t, + containsMetric(body, `mcp_registry_http_errors_total`, `status_code="500"`, `path="/v0/servers"`), + "errors_total must not record a 500 for a request the client already gave up on; got:\n%s", + filterMetricLines(body, "mcp_registry_http_errors_total"), + ) +} + +// containsMetric returns true iff some line in body starts with `metric{...}` +// and that label set contains every requested label fragment. +func containsMetric(body, metric string, labels ...string) bool { + for _, line := range strings.Split(body, "\n") { + if !strings.HasPrefix(line, metric+"{") { + continue + } + ok := true + for _, l := range labels { + if !strings.Contains(line, l) { + ok = false + break + } + } + if ok { + return true + } + } + return false +} + +func filterMetricLines(body, metric string) string { + var lines []string + for _, line := range strings.Split(body, "\n") { + if strings.HasPrefix(line, metric) { + lines = append(lines, line) + } + } + return strings.Join(lines, "\n") +} From 2b90d93712fe7bd8ce1db1c0129dcca35df2e0a2 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Tue, 5 May 2026 06:14:49 -0400 Subject: [PATCH 083/190] deploy: update prod to v1.7.8 (#1256) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Bump `mcp-registry:imageTag` from `1.7.7` → `1.7.8` in `deploy/Pulumi.gcpProd.yaml` - v1.7.8 ships the metrics fix that stops counting client-cancelled requests as server errors (#1255). Under scraper-driven load, clients with short timeouts close the socket while PG is still iterating; the handler converts `context.Canceled` to a 500 and the metric middleware was bumping `mcp_registry_http_errors_total` even though NGINX recorded 499 and never delivered a response. This is what's been firing the daily ~17:00 UTC `Availability dropped below 95%` alert. - Also includes a CI-only `pulumi/actions` 6.6.1 → 7.0.0 bump (#1254). No registry runtime impact. - Staging is on `4e14707` (the v1.7.8 commit) and `staging.registry.modelcontextprotocol.io/v0.1/version` reports it. ## Test plan - [ ] Confirm release workflow's `ko-push` job has published `ghcr.io/modelcontextprotocol/registry:1.7.8` before merging - [ ] Watch deploy-production roll the registry pods to `1.7.8` - [ ] Hit `https://registry.modelcontextprotocol.io/v0.1/version` and confirm `git_commit` matches `4e147072f03aeacfe8456c7f24407e0ea65d92c0` - [ ] Through the next ~17:00 UTC scraper burst, watch in Prometheus: - `mcp_registry_http_errors_total{status_code="500", path="/v0.1/servers"}` should stay flat - `mcp_registry_http_requests_total{status_code="499", path="/v0.1/servers"}` should grow during the burst - The `Availability dropped below 95%` alert should not fire on cancellation-only bursts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index 44e5839..f4ce516 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.7.7 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.7.8 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From 6ae2d54e737d9c1d7d6e3e8805df96a79eada6ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 17:34:08 -0400 Subject: [PATCH 084/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.234.0 to 3.235.0 in /deploy (#1259) --- deploy/go.mod | 3 ++- deploy/go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index d64615f..9ca00fe 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 - github.com/pulumi/pulumi/sdk/v3 v3.234.0 + github.com/pulumi/pulumi/sdk/v3 v3.235.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -42,6 +42,7 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v1.2.5 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index 54c892c..fe7076d 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -84,6 +84,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= +github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -183,8 +185,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 h1:nF0Y1F7fUGL6RYD9EAtHTdDbNFmDaA3xcEiRlvCDV5E= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.234.0 h1:PoXVM2lJoyqavwPQlVQC6KzhGKNOJpz9OFxyojm8RjA= -github.com/pulumi/pulumi/sdk/v3 v3.234.0/go.mod h1:Eu9QVad1cSPymhTboINPqK6WZMaW7I0NHQcWOmxLYek= +github.com/pulumi/pulumi/sdk/v3 v3.235.0 h1:GoFZGHA2QHf+sX4x7Nok8ngremykvWC9sIvfQvLO/wM= +github.com/pulumi/pulumi/sdk/v3 v3.235.0/go.mod h1:ybUihqUfVF1ZXBH3JNunYsAMz2P6i+7v5gzoJ60sVp0= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From 321337c8107580526da934ca46df29d1344ca6ca Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Thu, 7 May 2026 10:36:03 -0400 Subject: [PATCH 085/190] docs: add ToolHive Registry Server to community projects (#1261) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Add a new **Registry Implementations** section to `docs/community-projects.md` for self-hostable servers that implement the MCP Registry API spec. - Move existing **ToolSDK MCP Registry** entry from "Other" into the new section. - Add **ToolHive Registry Server** (https://github.com/stacklok/toolhive-registry-server) to the new section. ## Test plan - [x] `docs/community-projects.md` renders correctly (markdown only, no build step). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- docs/community-projects.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/community-projects.md b/docs/community-projects.md index ef59bf5..b61c247 100644 --- a/docs/community-projects.md +++ b/docs/community-projects.md @@ -20,6 +20,13 @@ Browse the official MCP Registry in your browser! - [mcp-registry-spec-sdk](https://www.npmjs.com/package/mcp-registry-spec-sdk) - TypeScript client for the MCP Registry - [LangChain4j MCP Registry Java client](https://docs.langchain4j.dev/tutorials/mcp/#mcp-registry-client) - Java API +### Registry Implementations + +Self-hostable servers that implement the MCP Registry API specification. + +- [ToolSDK MCP Registry](https://github.com/toolsdk-ai/toolsdk-mcp-registry) - Extends the MCP Registry with **API-based MCP execution, private deployment**, and **secure sandbox isolation**. +- [ToolHive Registry Server](https://github.com/stacklok/toolhive-registry-server) - Enterprise-grade MCP Registry API implementation with Kubernetes-native CRD discovery, OIDC/JWT claim-based access control, multi-source aggregation (Git, K8s, upstream registries), SIEM-compliant audit logging, and OpenTelemetry observability. + ### Other - [MCP Registry Cheat Sheet](https://github.com/subbyte/mcp-registry-cheatsheet) - MCP Registry Cheat Sheet for MCP server developers, client developers, and registry admin @@ -28,7 +35,6 @@ Browse the official MCP Registry in your browser! - [mcp-insights](https://github.com/joelverhagen/mcp-insights/) - Analytics and insights for the MCP Registry - [mcp-registry-cli](https://pypi.org/project/mcp-registry-cli/) - CLI tool to navigate the MCP registry servers - [OtherVibes/mcp-publish-action](https://github.com/OtherVibes/mcp-publish-action) - GitHub Action for publishing MCP servers to the official registry -- [ToolSDK MCP Registry](https://github.com/toolsdk-ai/toolsdk-mcp-registry) - Extends the MCP Registry with **API-based MCP execution, private deployment**, and **secure sandbox isolation**. ## Adding Your Project From 718735cfbb1d9f998ce33e1a3d6e0c8a2e6dc58b Mon Sep 17 00:00:00 2001 From: Andrew Cunliffe Date: Thu, 7 May 2026 07:42:37 -0700 Subject: [PATCH 086/190] docs(authentication): note OpenSSL 3.x requirement for Ed25519 (#1253) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary The DNS and HTTP authentication guides currently run `openssl genpkey -algorithm Ed25519 -out key.pem` without caveat. macOS ships LibreSSL as the system `openssl` binary, and LibreSSL doesn't implement Ed25519 in `genpkey` — so the very first command in the Ed25519 codepath errors out with: ``` Algorithm Ed25519 not found ``` A first-time integrator on macOS hits this immediately, with no path to a fix from the docs alone. Cost me ~5 minutes earlier today before I figured out I needed `brew install openssl@3` and an explicit binary path. This PR adds a ` ` callout to the **DNS Authentication** section right above the Ed25519 codepath, and a shorter cross-reference Note in the **HTTP Authentication** section since the same `openssl genpkey -algorithm Ed25519` commands appear there. The ECDSA P-384 codepath works on LibreSSL, so it's untouched. ## Test plan - [x] Verified locally that `/opt/homebrew/opt/openssl@3/bin/openssl genpkey -algorithm Ed25519 -out key.pem` works on macOS Darwin 25.4.0 - [x] Verified the system `/usr/bin/openssl genpkey -algorithm Ed25519 -out key.pem` fails with `Algorithm Ed25519 not found` on the same machine (LibreSSL 3.3.6) - [x] Verified the published `ai.ravenmcp/raven-mcp` flow end-to-end with the OpenSSL 3 binary - [ ] Markdown rendering of the ` ` callouts — relying on the existing ` ` pattern in this file (line 6) to validate the syntax Co-authored-by: Radoslav Dimitrov --- docs/modelcontextprotocol-io/authentication.mdx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/modelcontextprotocol-io/authentication.mdx b/docs/modelcontextprotocol-io/authentication.mdx index f5af3ad..78bf23a 100644 --- a/docs/modelcontextprotocol-io/authentication.mdx +++ b/docs/modelcontextprotocol-io/authentication.mdx @@ -59,6 +59,10 @@ DNS authentication is a domain-based authentication method that relies on a DNS To perform DNS authentication using the `mcp-publisher` CLI tool, run the following commands in your server project directory to generate a TXT record based on a public/private key pair: + + The Ed25519 codepath requires **OpenSSL 3.0 or later**. macOS ships with LibreSSL by default (the system `openssl` binary), which does not implement Ed25519 in `genpkey` and fails with `Algorithm Ed25519 not found`. On macOS, install OpenSSL 3 (`brew install openssl@3`) and invoke it explicitly — for example, replace `openssl` with `/opt/homebrew/opt/openssl@3/bin/openssl` (Apple Silicon) or `/usr/local/opt/openssl@3/bin/openssl` (Intel) in the commands below. The ECDSA P-384 codepath works on LibreSSL. + +```bash Ed25519 @@ -185,6 +189,10 @@ HTTP authentication is a domain-based authentication method that relies on a `/. To perform HTTP authentication using the `mcp-publisher` CLI tool, run the following commands in your server project directory to generate an `mcp-registry-auth` file based on a public/private key pair: + + As with DNS authentication, the Ed25519 codepath requires **OpenSSL 3.0 or later**. macOS's system LibreSSL does not support Ed25519 in `genpkey`. See the note in the [DNS Authentication](#dns-authentication) section for the macOS workaround. + +```bash Ed25519 From f5fe2e97f65d5fa26997be7e567293f834f162fc Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Fri, 8 May 2026 07:33:10 -0400 Subject: [PATCH 087/190] build(deps): bump golang.org/x/net from v0.52.0 to v0.53.0 (#1269) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Bumps `golang.org/x/net` from `v0.52.0` to `v0.53.0` to address `GO-2026-4918` (HTTP/2 transport infinite loop on bad `SETTINGS_MAX_FRAME_SIZE`). `go mod tidy` also pulls `golang.org/x/crypto` to v0.50.0 and `golang.org/x/text` to v0.36.0. ## Why now `govulncheck` is failing on `main` and every open Dependabot PR (#1263, #1264, #1265) after the 2026-05 Go security release. The findings split into: - **One we control** — `golang.org/x/net@v0.52.0` → fixed in `v0.53.0`. Addressed here. - **Six stdlib findings** (`GO-2026-4986`, `4982`, `4980`, `4977`, `4971`, and the stdlib half of `4918`) — all fixed in `go1.26.3`. We deliberately do **not** pin a Go patch in the workflow: `go-version: 'stable'` will pick up `1.26.3` automatically once the `actions/go-versions` manifest catches up, with no workflow maintenance. ## Test plan - [x] `go build ./...` - [x] `go vet ./...` - [x] `GOTOOLCHAIN=go1.26.3 govulncheck ./...` → "No vulnerabilities found." 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 9294010..7f97768 100644 --- a/go.mod +++ b/go.mod @@ -73,12 +73,12 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - golang.org/x/crypto v0.49.0 // indirect - golang.org/x/net v0.52.0 // indirect + golang.org/x/crypto v0.50.0 // indirect + golang.org/x/net v0.53.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.43.0 // indirect - golang.org/x/text v0.35.0 // indirect + golang.org/x/text v0.36.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/api v0.274.0 // indirect google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect diff --git a/go.sum b/go.sum index cb4f347..e7cb100 100644 --- a/go.sum +++ b/go.sum @@ -164,12 +164,12 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= @@ -177,8 +177,8 @@ golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= From d93f8f78a0d78439ed433d1053982fa100c50632 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 07:56:59 -0400 Subject: [PATCH 088/190] build(deps): bump cloud.google.com/go/kms from 1.30.0 to 1.31.0 (#1263) Bumps [cloud.google.com/go/kms](https://github.com/googleapis/google-cloud-go) from 1.30.0 to 1.31.0. Release notes
Sourced from cloud.google.com/go/kms's releases.
kms: v1.31.0
v1.31.0 (2026-05-07)
retail: v1.31.0
v1.31.0 (2026-05-07)
Changelog
Sourced from cloud.google.com/go/kms's changelog.
1.31.0 (2024-08-01)
Features
- documentai: A new field
imageless_modeis added to message.google.cloud.documentai.v1.ProcessRequest(#10615) (97fa560)Documentation
- documentai: Keep the API doc up-to-date with recent changes (97fa560)
1.30.5 (2024-07-24)
Bug Fixes
- documentai: Update dependencies (257c40b)
1.30.4 (2024-07-10)
Bug Fixes
- documentai: Bump google.golang.org/grpc@v1.64.1 (8ecc4e9)
1.30.3 (2024-07-01)
Bug Fixes
- documentai: Bump google.golang.org/api@v0.187.0 (8fa9e39)
1.30.2 (2024-06-26)
Bug Fixes
- documentai: Enable new auth lib (b95805f)
1.30.1 (2024-06-20)
Documentation
- documentai: Update the comment to add a note about
documentai.processors.createpermission (4fa4308)Commits
9a44b31chore: librarian release pull request: 20260409T070606Z (#14406)18a3318feat: Make AgentEngine APIs publicdb45f2dfeat(bigtable): enable bigtable conn pool by default (#14319)124ffd3feat(vertexai): Add AgentEngine Memories Revisions modulee247d48chore: onboard new library appoptimize (#14393)ece84abchore: update librarian to v0.10.1-0.20260408193841-095ea7e727aa (#14392)ecf9783chore: librarian release pull request: 20260408T191440Z (#14390)70b47d2chore: librarian release pull request: 20260408T190447Z (#14389)95c53a6chore(bigquery): bumpapito v0.275.0 and unskip bq tracing tests (#14333)df22e9efix(storage): add retry logic for "http2: client connection lost" (#14385)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Radoslav Dimitrov --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 7f97768..558ebd8 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/modelcontextprotocol/registry go 1.26 require ( - cloud.google.com/go/kms v1.30.0 + cloud.google.com/go/kms v1.31.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 github.com/caarlos0/env/v11 v11.4.1 diff --git a/go.sum b/go.sum index e7cb100..cc6c8e6 100644 --- a/go.sum +++ b/go.sum @@ -8,8 +8,8 @@ cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdB cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/iam v1.7.0 h1:JD3zh0C6LHl16aCn5Akff0+GELdp1+4hmh6ndoFLl8U= cloud.google.com/go/iam v1.7.0/go.mod h1:tetWZW1PD/m6vcuY2Zj/aU0eCHNPuxedbnbRTyKXvdY= -cloud.google.com/go/kms v1.30.0 h1:TSEZopy/OXojbVCQS9Rrx0jFqdKWvO31+N8ncXbxG/s= -cloud.google.com/go/kms v1.30.0/go.mod h1:YIyXZym11R5uovJJt4oN5eUL3oPmirF3yKeIh6QAf4U= +cloud.google.com/go/kms v1.31.0 h1:LS8N92OxFDgOLg5NCo3OmbvjtQAIVT5gUHVLKIDHaFE= +cloud.google.com/go/kms v1.31.0/go.mod h1:YIyXZym11R5uovJJt4oN5eUL3oPmirF3yKeIh6QAf4U= cloud.google.com/go/longrunning v0.9.0 h1:0EzbDEGsAvOZNbqXopgniY0w0a1phvu5IdUFq8grmqY= cloud.google.com/go/longrunning v0.9.0/go.mod h1:pkTz846W7bF4o2SzdWJ40Hu0Re+UoNT6Q5t+igIcb8E= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc= From 8af641cf1cc0449557769c6f7b987523fe09049d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 07:57:18 -0400 Subject: [PATCH 089/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.235.0 to 3.236.0 in /deploy (#1264) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.235.0 to 3.236.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.236.0
3.236.0 (2026-05-06)
Commits
7db0778exclude another nodejs language test for bun (#22861)3a74cfbBump the version of pulumi-hcl to v0.2.0 (#22867)8437bfeExpandl1-output-mapto handle adversarial strings (#22854)a9b310fcli/neo: support typing quit/exit to leave the TUI (#22859)f499abfcli/neo: show CLI version in the welcome banner (#22860)cec8b90fix integration test (#22857)060f73fAdd changelog message guidance to AGENTS.md (#22848)a9f6c19skip more signal cancellation tests (#22844)b0b94faChange PluginInfo timestamps to be cached like size (#22839)1e4e2f0freeze 3.235.0 (#22850)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Radoslav Dimitrov --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 9ca00fe..64f31cf 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 - github.com/pulumi/pulumi/sdk/v3 v3.235.0 + github.com/pulumi/pulumi/sdk/v3 v3.236.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/deploy/go.sum b/deploy/go.sum index fe7076d..150ed1a 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -185,8 +185,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 h1:nF0Y1F7fUGL6RYD9EAtHTdDbNFmDaA3xcEiRlvCDV5E= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.235.0 h1:GoFZGHA2QHf+sX4x7Nok8ngremykvWC9sIvfQvLO/wM= -github.com/pulumi/pulumi/sdk/v3 v3.235.0/go.mod h1:ybUihqUfVF1ZXBH3JNunYsAMz2P6i+7v5gzoJ60sVp0= +github.com/pulumi/pulumi/sdk/v3 v3.236.0 h1:vX+0ZCmylokASSKRqvx8ryRnLeFl87xqh3l5cKAI4Ko= +github.com/pulumi/pulumi/sdk/v3 v3.236.0/go.mod h1:ybUihqUfVF1ZXBH3JNunYsAMz2P6i+7v5gzoJ60sVp0= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From fe0cb3bfcb425d0d944a89d0f17c722ef22d922b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 07:57:35 -0400 Subject: [PATCH 090/190] build(deps): bump sigstore/cosign-installer from 4.1.1 to 4.1.2 in the actions group (#1265) Bumps the actions group with 1 update: [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer). Updates `sigstore/cosign-installer` from 4.1.1 to 4.1.2 Release notes
Sourced from sigstore/cosign-installer's releases.
v4.1.2
What's Changed
- Bump cosign to 3.0.6 in sigstore/cosign-installer#232
Commits
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Radoslav Dimitrov --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7b248f2..1f51d3b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: cache: true - name: Install cosign - uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1 + uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 - name: Install Syft uses: anchore/sbom-action/download-syft@v0.24.0 From 7bc506f24598c611d566a21c2a0b77f423e5ded1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 05:10:33 -0400 Subject: [PATCH 091/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.236.0 to 3.237.0 in /deploy (#1272) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.236.0 to 3.237.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.237.0
3.237.0 (2026-05-08)
Features
[cli] Include the running command name and detected AI agent (when present) in the User-Agent header on Pulumi Cloud API requests #22908
[engine] Include
resulton the summary engine event #22883[sdkgen] Eagerly error on schemas with unconstructable types #22890
[cli/cloud] Auto-fill
langandosquery parameters onpulumi cloud apiGET/HEAD requests when the matched OpenAPI operation declares them and the caller hasn't supplied them #22726[cli/package] Add
pulumi package newto bootstrap a Pulumi package from a template #22837Bug Fixes
[cli] Add blank-line gaps between
pulumi neoTUI conversation blocks #22846[cli/import] Preserve
__-prefixed keys when generating PCL for imported resource state, so provider-defined payloads round-trip correctly #22856[cli/neo] Render
ux__ask_userclarifying questions as questions instead of approval prompts #22862[cli/neo] Fix a panic when cancelling a
pulumi neosession #22898[cli/neo] Render every assistant message in the TUI scrollback so multi-turn commentary no longer disappears between tool calls
[cli/neo] Return the bare stack name and canonical project name from
pulumi_previewandpulumi_uptool results instead of echoing the raw input #22891[codegen/pcl] Stop reporting spurious circular references when an
ignoreChanges,hideDiffs,replaceOnChanges, oradditionalSecretOutputsentry shares a name with a top-level node #22916[programgen/pcl] Fix PCL binder panic when a conditional mixes a Promise-typed branch with a try() branch #22907
[sdk/python] Support
NotRequired,Requiredandtotal=Falsein TypedDicts for component resource arg types #22858... (truncated)
Changelog
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.237.0 (2026-05-08)
Features
[cli] Include the running command name and detected AI agent (when present) in the User-Agent header on Pulumi Cloud API requests #22908
[engine] Include
resulton the summary engine event #22883[sdkgen] Eagerly error on schemas with unconstructable types #22890
[cli/cloud] Auto-fill
langandosquery parameters onpulumi cloud apiGET/HEAD requests when the matched OpenAPI operation declares them and the caller hasn't supplied them #22726[cli/package] Add
pulumi package newto bootstrap a Pulumi package from a template #22837Bug Fixes
[cli] Add blank-line gaps between
pulumi neoTUI conversation blocks #22846[cli/import] Preserve
__-prefixed keys when generating PCL for imported resource state, so provider-defined payloads round-trip correctly #22856[cli/neo] Render
ux__ask_userclarifying questions as questions instead of approval prompts #22862[cli/neo] Fix a panic when cancelling a
pulumi neosession #22898[cli/neo] Render every assistant message in the TUI scrollback so multi-turn commentary no longer disappears between tool calls
[cli/neo] Return the bare stack name and canonical project name from
pulumi_previewandpulumi_uptool results instead of echoing the raw input #22891[codegen/pcl] Stop reporting spurious circular references when an
ignoreChanges,hideDiffs,replaceOnChanges, oradditionalSecretOutputsentry shares a name with a top-level node #22916[programgen/pcl] Fix PCL binder panic when a conditional mixes a Promise-typed branch with a try() branch #22907
[sdk/python] Support
NotRequired,Requiredandtotal=Falsein TypedDicts for component resource arg types #22858... (truncated)
Commits
dc35affonly don't run CI if changelog/config.yaml changes (#22937)a38b7dccli/neo: keep prior streaming text when the agent emits a new turn (#22897)6d84bb5add continue-on-error to upload code coverage and upload codecov test results...8377d12Eagerly error on schemas with unconstructable types (#22890)9d209a0bump java and yaml dependencies (#22932)dd82f69LocalWorkspace.nested_config: use a new stack per test (#22926)c518056Fix flaky TestFuzz: targeted update with refresh + deleted parent (#22925)46486daThread workspace.Context to ProviderFromSource (#22880)ad42ef3increase nodejs automation API timeout (#22920)0b8a78bTest on Node.js 26 and drop 20 (#22872)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 64f31cf..a4c3090 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 - github.com/pulumi/pulumi/sdk/v3 v3.236.0 + github.com/pulumi/pulumi/sdk/v3 v3.237.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/deploy/go.sum b/deploy/go.sum index 150ed1a..eac6818 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -185,8 +185,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 h1:nF0Y1F7fUGL6RYD9EAtHTdDbNFmDaA3xcEiRlvCDV5E= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.236.0 h1:vX+0ZCmylokASSKRqvx8ryRnLeFl87xqh3l5cKAI4Ko= -github.com/pulumi/pulumi/sdk/v3 v3.236.0/go.mod h1:ybUihqUfVF1ZXBH3JNunYsAMz2P6i+7v5gzoJ60sVp0= +github.com/pulumi/pulumi/sdk/v3 v3.237.0 h1:D0kx4fkUkiZWfreQg1ekeAifLJEC2+VRYzgboQClg9Q= +github.com/pulumi/pulumi/sdk/v3 v3.237.0/go.mod h1:ybUihqUfVF1ZXBH3JNunYsAMz2P6i+7v5gzoJ60sVp0= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From 1d3680696025dc9d7dcccb464aca72a1b31d304d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 05:10:51 -0400 Subject: [PATCH 092/190] build(deps): bump golang.org/x/mod from 0.35.0 to 0.36.0 (#1271) Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.35.0 to 0.36.0. Commits
643da9bgo.mod: update golang.org/x dependenciesccc3cdfzip: include 'but content has correct sum' note in TestVCSab30318zip: update zip hashes for new flate compression- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 558ebd8..247ffc7 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( go.opentelemetry.io/otel/metric v1.43.0 go.opentelemetry.io/otel/sdk v1.43.0 go.opentelemetry.io/otel/sdk/metric v1.43.0 - golang.org/x/mod v0.35.0 + golang.org/x/mod v0.36.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index cc6c8e6..1a65b0f 100644 --- a/go.sum +++ b/go.sum @@ -166,8 +166,8 @@ go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= -golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= -golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= +golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= +golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= From 276037b1ad877fa2990c2aed5bafb90a737da9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?d=20=F0=9F=94=B9?= Date: Mon, 11 May 2026 21:01:52 +0800 Subject: [PATCH 093/190] docs(complete): align publish CLI flags with implementation (closes #767) (#1278) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary `complete.md` documents three flags for `mcp-publisher publish` that the CLI does not actually parse: - `--file=PATH` — Path to server.json - `--registry=URL` — Registry URL override - `--dry-run` — Validate without publishing Reading [`cmd/publisher/commands/publish.go`](https://github.com/modelcontextprotocol/registry/blob/main/cmd/publisher/commands/publish.go) and [`cmd/publisher/main.go`](https://github.com/modelcontextprotocol/registry/blob/main/cmd/publisher/main.go) confirms the actual interface is a single positional `PATH` argument (default `./server.json`): ```go serverFile := \"server.json\" if len(args) > 0 && !strings.HasPrefix(args[0], \"-\") { serverFile = args[0] } ``` Registry URL is bound at login time via the saved token, and \"validate without publishing\" is a separate `mcp-publisher validate` subcommand. The bug user in #767 hit \"server.json not found\" precisely because `--file .registry/server.json` is filtered out by the `HasPrefix(args[0], \"-\")` check, leaving the default lookup in place. ## Background The canonical reference at [`docs/reference/cli/commands.md`](https://github.com/modelcontextprotocol/registry/blob/main/docs/reference/cli/commands.md) was already updated to the correct positional shape. `complete.md` (the concatenated single-file mirror of `docs/` used for LLM/quickstart consumption) had drifted out of sync — these were the only remaining `--file` references in the repo outside of test fixtures. Per the discussion on the prior flag-implementation attempt in #771, maintainers preferred fixing the documentation over adding the unimplemented flags: > @domdomegg: I'd lean towards removing the options from the docs. This PR closes that loop on the last stale doc surface. ## Changes `complete.md`: the `mcp-publisher publish` block now matches `docs/reference/cli/commands.md` line-for-line (positional `PATH`, no spurious flags, no dry-run example). ```diff -mcp-publisher publish [options] +mcp-publisher publish [PATH] -- \`--file=PATH\` - Path to server.json (default: \`./server.json\`) -- \`--registry=URL\` - Registry URL override -- \`--dry-run\` - Validate without publishing +- \`PATH\` - Path to server.json (default: \`./server.json\`) -# Dry run validation -mcp-publisher publish --dry-run - # Custom file location -mcp-publisher publish --file=./config/server.json +mcp-publisher publish ./config/server.json ``` Closes #767. ## Out of scope - `cmd/publisher/README.md:17` still shows `./bin/mcp-publisher publish --registry=http://localhost:8080` in the contributor quickstart. The flag is silently ignored at runtime (caught by the same `HasPrefix(\"-\")` filter). Happy to fold that fix into this PR or send a follow-up — flagging here in case a maintainer prefers one option. - `complete.md` is missing `mcp-publisher validate` and `mcp-publisher status` sections that exist in `docs/reference/cli/commands.md`. Out of scope for this single-concern PR; if there's interest, a broader sync would be a separate PR. ## Test plan - [x] `grep -r -- '--file' .` outside test fixtures returns 0 hits after the change - [x] `grep -r 'mcp-publisher publish --' docs/ complete.md` shows only legitimate flags (`--registry` on `login`) - [x] No code changes — `make check` not exercised since this is doc-only 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: d 🔹 <258577966+voidborne-d@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) --- complete.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/complete.md b/complete.md index 2355e4b..e9040fa 100644 --- a/complete.md +++ b/complete.md @@ -1991,30 +1991,26 @@ For detailed guidance on the publishing process, see the [publishing guide](../. **Usage:** ```bash -mcp-publisher publish [options] +mcp-publisher publish [PATH] ``` **Options:** -- `--file=PATH` - Path to server.json (default: `./server.json`) -- `--registry=URL` - Registry URL override -- `--dry-run` - Validate without publishing +- `PATH` - Path to server.json (default: `./server.json`) **Process:** 1. Validates `server.json` against schema -2. Verifies package ownership (see [Official Registry Requirements](../server-json/official-registry-requirements.md)) -3. Checks namespace authentication -4. Publishes to registry +2. Publishes the `server.json` to the registry server URL specified in the login token +3. Server: Verifies package ownership (see [Official Registry Requirements](../server-json/official-registry-requirements.md)) +4. Server: Checks namespace authentication +5. Server: Publishes to registry **Example:** ```bash # Basic publish mcp-publisher publish -# Dry run validation -mcp-publisher publish --dry-run - # Custom file location -mcp-publisher publish --file=./config/server.json +mcp-publisher publish ./config/server.json ``` ### `mcp-publisher logout` From 4e319e81ff006a4f1a06b9fb4ceb00c39f52e58b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 07:21:18 -0400 Subject: [PATCH 094/190] build(deps): bump github.com/go-git/go-git/v5 from 5.18.0 to 5.19.0 in /deploy (#1279) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.18.0 to 5.19.0. Release notes
Sourced from github.com/go-git/go-git/v5's releases.
v5.19.0
What's Changed
- build: Update module github.com/go-git/go-git/v5 to v5.18.0 [SECURITY] (releases/v5.x) by
@go-git-renovate[bot] in go-git/go-git#2010- v5: Bump sha1cd and go-billy by
@pjbgfin go-git/go-git#2060- v5: Align object encoding with upstream by
@pjbgfin go-git/go-git#2065Full Changelog: https://github.com/go-git/go-git/compare/v5.18.0...v5.19.0
Commits
bc930f4Merge pull request #2065 from go-git/commit-v5d315264plumbing: object, Reset object before decode6e1d348plumbing: object, Align Tree handling with upstreame134ba3tests: Skip double checks in Git v2.111971422tests: Add git conformance tests for signing verificationa387aa8plumbing: object, Add ErrMalformedTagf415670plumbing: object, Decode Tag headers via a state machine5b0cd38plumbing: object, Reject multi-signature commits at Verifyfe8ed62plumbing: object, Align Tag.EncodeWithoutSignature with Commit98e337dplumbing: object, Add support for Tag.SignatureSHA256- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/modelcontextprotocol/registry/network/alerts). Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 25 +++++++++++++------------ deploy/go.sum | 50 ++++++++++++++++++++++++++------------------------ 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index a4c3090..ecd0260 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -32,13 +32,13 @@ require ( github.com/clipperhouse/displaywidth v0.11.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/cloudflare/circl v1.6.3 // indirect - github.com/cyphar/filepath-securejoin v0.4.1 // indirect + github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/djherbis/times v1.5.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.8.0 // indirect - github.com/go-git/go-git/v5 v5.18.0 // indirect + github.com/go-git/go-billy/v5 v5.9.0 // indirect + github.com/go-git/go-git/v5 v5.19.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -56,6 +56,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/compress v1.18.0 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect @@ -70,7 +71,7 @@ require ( github.com/opentracing/basictracer-go v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pgavlin/fx v0.1.6 // indirect - github.com/pjbgf/sha1cd v0.3.2 // indirect + github.com/pjbgf/sha1cd v0.6.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/term v1.1.0 // indirect github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect @@ -101,15 +102,15 @@ require ( go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.49.0 // indirect - golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/mod v0.33.0 // indirect - golang.org/x/net v0.52.0 // indirect + golang.org/x/crypto v0.50.0 // indirect + golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/net v0.53.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.42.0 // indirect - golang.org/x/term v0.41.0 // indirect - golang.org/x/text v0.35.0 // indirect - golang.org/x/tools v0.42.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/term v0.42.0 // indirect + golang.org/x/text v0.36.0 // indirect + golang.org/x/tools v0.44.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260311181403-84a4fc48630c // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c // indirect google.golang.org/grpc v1.80.0 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index eac6818..8d59fda 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -50,8 +50,8 @@ github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJ github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= -github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= +github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -70,12 +70,12 @@ github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0= -github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY= +github.com/go-git/go-billy/v5 v5.9.0 h1:jItGXszUDRtR/AlferWPTMN4j38BQ88XnXKbilmmBPA= +github.com/go-git/go-billy/v5 v5.9.0/go.mod h1:jCnQMLj9eUgGU7+ludSTYoZL/GGmii14RxKFj7ROgHw= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM= -github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo= +github.com/go-git/go-git/v5 v5.19.0 h1:+WkVUQZSy/F1Gb13udrMKjIM2PrzsNfDKFSfo5tkMtc= +github.com/go-git/go-git/v5 v5.19.0/go.mod h1:Pb1v0c7/g8aGQJwx9Us09W85yGoyvSwuhEGMH7zjDKQ= 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= @@ -121,6 +121,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 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/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -169,8 +171,8 @@ github.com/pgavlin/fx v0.1.6 h1:r9jEg69DhNoCd3Xh0+5mIbdbS3PqWrVWujkY76MFRTU= github.com/pgavlin/fx v0.1.6/go.mod h1:KWZJ6fqBBSh8GxHYqwYCf3rYE7Gp2p0N8tJp8xv9u9M= github.com/pgavlin/fx/v2 v2.0.12 h1:SjjaJ68Dt8Z4zHwOpY/RPijd7lShs6xYupJbF9ra00M= github.com/pgavlin/fx/v2 v2.0.12/go.mod h1:M/nF/ooAOy+NUBooYYXl2REARzJ/giPJxfMs8fINfKc= -github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= -github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= +github.com/pjbgf/sha1cd v0.6.0 h1:3WJ8Wz8gvDz29quX1OcEmkAlUg9diU4GxJHqs0/XiwU= +github.com/pjbgf/sha1cd v0.6.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= @@ -270,24 +272,24 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= -golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -307,24 +309,24 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 35b20719ee7714ad18d0f81af6798ac0a46e2b9b Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Tue, 12 May 2026 16:59:59 -0400 Subject: [PATCH 095/190] fix(validators/oci): fail closed on upstream rate limiting (#1281) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary When the OCI validator's anonymous manifest fetch returns HTTP 429, return a retryable error instead of `nil`. This aligns OCI with the fail-closed behavior of the npm / PyPI / NuGet / MCPB validators, and ensures the `io.modelcontextprotocol.server.name` label-match always runs before a publish is accepted. ## Test plan - [x] `go test ./internal/validators/registries/ -run TestValidateOCI` passes locally - [x] `gofmt` + `golangci-lint` clean on the changed file - [ ] CI green 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- internal/validators/registries/oci.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/internal/validators/registries/oci.go b/internal/validators/registries/oci.go index d4ab56c..f303267 100644 --- a/internal/validators/registries/oci.go +++ b/internal/validators/registries/oci.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "log" "net/http" "strings" "time" @@ -106,10 +105,13 @@ func ValidateOCI(ctx context.Context, pkg model.Package, serverName string) erro if errors.As(err, &transportErr) { switch transportErr.StatusCode { case http.StatusTooManyRequests: - // Rate limited - skip validation to avoid blocking publishers - // This is intentional: we prioritize UX over strict validation during high traffic - log.Printf("Skipping OCI validation for %s due to rate limiting", pkg.Identifier) - return nil + // Fail closed: a 429 means we could not verify the + // `io.modelcontextprotocol.server.name` label on the image, which is + // the only ownership proof we apply to OCI packages. Returning nil + // here would let a publisher bind their server record to an arbitrary + // public image they do not control, which is the bug this branch + // used to have. Surface the rate-limit as a retryable error instead. + return fmt.Errorf("OCI registry is currently rate-limiting validations for '%s'; please retry shortly", pkg.Identifier) case http.StatusNotFound: return fmt.Errorf("OCI image '%s' does not exist in the registry", pkg.Identifier) case http.StatusUnauthorized, http.StatusForbidden: From 4f75308d176a7b7a803238388506d64b24571b00 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Tue, 12 May 2026 17:08:24 -0400 Subject: [PATCH 096/190] deploy: update prod to v1.7.9 (#1282) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Promotes [v1.7.9](https://github.com/modelcontextprotocol/registry/releases/tag/v1.7.9) to production. Includes the OCI validator fail-closed fix from #1281. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- deploy/Pulumi.gcpProd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/Pulumi.gcpProd.yaml b/deploy/Pulumi.gcpProd.yaml index f4ce516..f222920 100644 --- a/deploy/Pulumi.gcpProd.yaml +++ b/deploy/Pulumi.gcpProd.yaml @@ -1,7 +1,7 @@ config: mcp-registry:environment: prod mcp-registry:provider: gcp - mcp-registry:imageTag: 1.7.8 # Set specific image tag for production (change this to deploy different versions) + mcp-registry:imageTag: 1.7.9 # Set specific image tag for production (change this to deploy different versions) gcp:project: mcp-registry-prod mcp-registry:githubClientId: Iv23liUydBbI7Z2Q9bOZ mcp-registry:githubClientSecret: From 4819463aaa03e21e84b840ee2789cab7436bd76a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 08:01:51 -0400 Subject: [PATCH 097/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.237.0 to 3.238.0 in /deploy (#1283) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.237.0 to 3.238.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.238.0
3.238.0 (2026-05-13)
Features
[cli] Add a
--languageflag topulumi package addto run outside a Pulumi project or plugin #22791[cli] Add
--output jsontopulumi upfor a structured JSON summary of the operation result #22870[cli] Recommend
pulumi cloud api describeinpulumi cloud api --helpto verify operation parameters before calling #22881[cli] Add
pulumi stack webhook listto list all webhooks configured for a stack #23082[cli/cloud] Rename
pulumi cloud apitopulumi api#22970[cli/cloud] Add
pulumi insights resource getto look up a single resource discovered by Pulumi Insights #23077[cli/cloud] Add
pulumi template listto list registry-backed templates #23074[cli/cloud] Rename the
--formatflag to--outputonpulumi apiand its subcommands #23072[cli/cloud] Add
pulumi insights resource searchto search for resources discovered by Pulumi Insights #23087[cli/engine] Add
--skip-plugin-pre-installto skip up-front plugin installation[engine] Fail the deployment when an after hook fails #22935
[cli/neo] Render the agent's TODO list in the
pulumi neoTUI #22864[cli/neo] Add
--approval-modeand--permission-modeflags topulumi neo, with Ctrl+A and Ctrl+R hotkeys to switch modes mid-session #22950[cli/package] When invoked by an AI coding agent, print
pulumi apipointers afterpulumi package addandpulumi package gen-sdk#22904[pkg/testing] Recognize the
hclandpclruntimes inintegration.ProgramTest#23018... (truncated)
Commits
71ddfb5Allow skipping up-front provider plugin installs for engine commands (#22947)f3da388[cli/import] Strip InputType after union reduction in structural typing (#23115)11a5257Neo auto-approve switch (#22950)3dd972cBump language providers (#23103)b88c0b2Add l1-config-types-optional conformance test (#23108)4b708ecAdd registerPackage helper to cache package references per deployment (#23014)c7ddd56cli/cloud: addpulumi insights resource search(#23087)3b02eb9Update module github.com/go-git/go-git/v5 to v5.19.0 [SECURITY] (#22971)81026a0[cli/package] Use --output=markdown in package-add docs hint (#23098)69d216cunflake TestConstructUnknownPython (#23086)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index ecd0260..21c9de3 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 - github.com/pulumi/pulumi/sdk/v3 v3.237.0 + github.com/pulumi/pulumi/sdk/v3 v3.238.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/deploy/go.sum b/deploy/go.sum index 8d59fda..c5d6ff0 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -187,8 +187,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 h1:nF0Y1F7fUGL6RYD9EAtHTdDbNFmDaA3xcEiRlvCDV5E= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.237.0 h1:D0kx4fkUkiZWfreQg1ekeAifLJEC2+VRYzgboQClg9Q= -github.com/pulumi/pulumi/sdk/v3 v3.237.0/go.mod h1:ybUihqUfVF1ZXBH3JNunYsAMz2P6i+7v5gzoJ60sVp0= +github.com/pulumi/pulumi/sdk/v3 v3.238.0 h1:V15ghoymebrhKsZeGRzs3rwmWD1MmuR7F2fx+2slct8= +github.com/pulumi/pulumi/sdk/v3 v3.238.0/go.mod h1:J8QFD7dwiCGSvBlcYwECmX/b3JKNXR85bv6BbjhPV3U= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From deb5e7b24a8ca30fb3ffdac55fbabf99b26614e4 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Thu, 14 May 2026 08:09:05 -0400 Subject: [PATCH 098/190] chore(deps): reduce dependabot frequency from daily to weekly (#1284) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Dependency update PRs were arriving daily across gomod (root + `/deploy`), github-actions, and docker — creating significant review noise. - Switch all four update entries in `.github/dependabot.yml` from `interval: daily` to `interval: weekly` so they batch on a weekly cadence (Dependabot defaults to Mondays). ## Test plan - [ ] Confirm `.github/dependabot.yml` parses correctly (Dependabot will report a config error on the repo if not) - [ ] Observe that new dependency PRs stop appearing daily after merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- .github/dependabot.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ea28507..775df1b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,7 +7,7 @@ updates: patterns: - "go.opentelemetry.io/*" schedule: - interval: daily + interval: weekly - package-ecosystem: gomod directory: /deploy groups: @@ -15,7 +15,7 @@ updates: patterns: - "go.opentelemetry.io/*" schedule: - interval: daily + interval: weekly - package-ecosystem: github-actions directory: / groups: @@ -23,8 +23,8 @@ updates: patterns: - "*" schedule: - interval: daily + interval: weekly - package-ecosystem: "docker" directory: "/" schedule: - interval: "daily" + interval: "weekly" From 49cea83c9d746b9fc7d4f9684deac1abdc45b815 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 May 2026 06:41:58 -0400 Subject: [PATCH 099/190] build(deps): bump github.com/go-git/go-git/v5 from 5.19.0 to 5.19.1 in /deploy (#1292) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.19.0 to 5.19.1. Release notes
Sourced from github.com/go-git/go-git/v5's releases.
v5.19.1
What's Changed
- v5: plumbing: transport/ssh, Shell-quote path by
@hiddecoin go-git/go-git#2068- v5: git: submodule, Fix relative URL resolution by
@hiddecoin go-git/go-git#2070- v5: git: submodule, canonical remote for relative URLs by
@hiddecoin go-git/go-git#2074- v5: git: submodule, error on remote without URLs by
@hiddecoin go-git/go-git#2078- v5: plumbing: format/idxfile, Validate offset64 indices by
@hiddecoin go-git/go-git#2084- v5: *: Reject malformed variable-length integers by
@hiddecoin go-git/go-git#2092- v5: plumbing: format/packfile, Tighten delta validation by
@hiddecoin go-git/go-git#2091- v5: Add
worktreeFilesystemwrapper for worktree and hardening by@hiddecoin go-git/go-git#2100- v5: config: validate submodule names by
@hiddecoin go-git/go-git#2082- build: Update module github.com/go-git/go-git/v5 to v5.19.0 [SECURITY] (releases/v5.x) by
@go-git-renovate[bot] in go-git/go-git#2111- v5: git: Allow MkdirAll on worktree-root paths by
@hiddecoin go-git/go-git#2117- v5: git: Stop validating symlink target paths by
@pjbgfin go-git/go-git#2116- v5: plumbing: format decoder input bounds and contracts by
@hiddecoin go-git/go-git#2125- plumbing: format/packfile, cap delta chain depth in parser by
@pjbgfin go-git/go-git#2137Full Changelog: https://github.com/go-git/go-git/compare/v5.19.0...v5.19.1
Commits
3c3be60Merge pull request #2137 from go-git/validate-v53fba897plumbing: format/packfile, cap delta chain depth in parsera97d660Merge pull request #2125 from hiddeco/v5/format-input-boundsaeaa125plumbing: format/objfile, require Header before Read1f38e17plumbing: format/packfile, bound inflate sizef7545a0plumbing: format/idxfile, bound nr by file size170b881Merge pull request #2116 from pjbgf/symlink-v57b6d994Merge pull request #2117 from hiddeco/v5/worktree-fs-mkdirall-root-noopf0709b3git: Stop validating symlink target paths776d00fgit: Allow MkdirAll on worktree-root paths- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/modelcontextprotocol/registry/network/alerts). Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 21c9de3..8354647 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -38,7 +38,7 @@ require ( github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.9.0 // indirect - github.com/go-git/go-git/v5 v5.19.0 // indirect + github.com/go-git/go-git/v5 v5.19.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index c5d6ff0..7bc5320 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -74,8 +74,8 @@ github.com/go-git/go-billy/v5 v5.9.0 h1:jItGXszUDRtR/AlferWPTMN4j38BQ88XnXKbilmm github.com/go-git/go-billy/v5 v5.9.0/go.mod h1:jCnQMLj9eUgGU7+ludSTYoZL/GGmii14RxKFj7ROgHw= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.19.0 h1:+WkVUQZSy/F1Gb13udrMKjIM2PrzsNfDKFSfo5tkMtc= -github.com/go-git/go-git/v5 v5.19.0/go.mod h1:Pb1v0c7/g8aGQJwx9Us09W85yGoyvSwuhEGMH7zjDKQ= +github.com/go-git/go-git/v5 v5.19.1 h1:nX27AnaU43/K5bKktKwgBmR9lawoYVe1Ckg0rgzzN00= +github.com/go-git/go-git/v5 v5.19.1/go.mod h1:Pb1v0c7/g8aGQJwx9Us09W85yGoyvSwuhEGMH7zjDKQ= 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= From b90f63f52cea2c0476b80f6b8d982b294af7aa7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 May 2026 06:42:13 -0400 Subject: [PATCH 100/190] build(deps): bump github.com/google/go-containerregistry from 0.21.5 to 0.21.6 (#1295) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.5 to 0.21.6. Release notes
Sourced from github.com/google/go-containerregistry's releases.
v0.21.6
What's Changed
- fix: update dependencies to use new azure sdk components by
@gaganhr94in google/go-containerregistry#2262- transport: restore resp.Body in retryError so CheckError can parse it by
@alliasgherin google/go-containerregistry#2264- pkg/registry: return 202 Accepted for PATCH chunk uploads by
@alliasgherin google/go-containerregistry#2265- Follow OCI distribution spec for artifactType and annotations by
@malt3in google/go-containerregistry#2269- actions: attach Codecov token to coverage tests on main by
@Subserialin google/go-containerregistry#2270- remote: use DeleteScope (with "delete" action) for manifest deletion by
@alliasgherin google/go-containerregistry#2266- remote: limit concurrent layer pulls by
@gnix0in google/go-containerregistry#2271- pkg/registry: reject corrupt disk blobs by
@gnix0in google/go-containerregistry#2272- mutate: close layer readers during export by
@gnix0in google/go-containerregistry#2277- crane/flatten: preserve image media type when flattening by
@alliasgherin google/go-containerregistry#2267- build(deps): bump goreleaser/goreleaser-action from 7.0.0 to 7.2.1 in the actions group across 1 directory by
@dependabot[bot] in google/go-containerregistry#2273- build(deps): bump go.opentelemetry.io/otel from 1.36.0 to 1.41.0 by
@dependabot[bot] in google/go-containerregistry#2278- build(deps): bump the go-deps group across 3 directories with 6 updates by
@dependabot[bot] in google/go-containerregistry#2280- Replace go-homedir with os.UserHomeDir by
@jammie-jellyin google/go-containerregistry#2282- pkg/name: only treat .localhost as non-HTTPS, not .local by
@blackwell-systemsin google/go-containerregistry#2281- transport: block unspecified IPs (0.0.0.0, ::) in validateRealmURL by
@marwan9696in google/go-containerregistry#2285- test(mutate): add Extract round-trip test for filesystem object preservation by
@blackwell-systemsin google/go-containerregistry#2283- experiments: remove deprecated support for estargz by
@thaJeztahin google/go-containerregistry#2288- build(deps): bump aws-actions/configure-aws-credentials from 6.1.0 to 6.1.1 in the actions group by
@dependabot[bot] in google/go-containerregistry#2289- fix: limit HTTP response body reads to prevent OOM by
@evilgensecin google/go-containerregistry#2296- build(deps): bump the go-deps group across 3 directories with 6 updates by
@dependabot[bot] in google/go-containerregistry#2297- transport: block redirects from token server to private/link-local addresses (SSRF fix) by
@evilgensecin google/go-containerregistry#2292- pkg/v1/mutate: preserve relative symlinks that stay within rootfs in Extract by
@anishesgin google/go-containerregistry#2279- validate: skip non-layer layers by
@imjasonhin google/go-containerregistry#2298- remote: validate foreign layer URLs to prevent SSRF (fixes #2259) by
@evilgensecin google/go-containerregistry#2293- remote: block SSRF via private-IP Location headers in blob uploads by
@adilburaksenin google/go-containerregistry#2295- fix(mutate): preserve config blob and layers for non-Docker OCI artifacts by
@blackwell-systemsin google/go-containerregistry#2286- fix: preserve per-occurrence layer identity in mutate.Image.Layers() by
@iahsanGillin google/go-containerregistry#2299- transport: retry HTTP 429 (Too Many Requests) by
@iahsanGillin google/go-containerregistry#2301- transport: allow bearer realm at same host:port as registry by
@iahsanGillin google/go-containerregistry#2302- Update go version to 1.26.3 by
@Subserialin google/go-containerregistry#2300New Contributors
@gaganhr94made their first contribution in google/go-containerregistry#2262@alliasghermade their first contribution in google/go-containerregistry#2264@malt3made their first contribution in google/go-containerregistry#2269@gnix0made their first contribution in google/go-containerregistry#2271@blackwell-systemsmade their first contribution in google/go-containerregistry#2281@marwan9696made their first contribution in google/go-containerregistry#2285@anishesgmade their first contribution in google/go-containerregistry#2279@adilburaksenmade their first contribution in google/go-containerregistry#2295@iahsanGillmade their first contribution in google/go-containerregistry#2299Full Changelog: https://github.com/google/go-containerregistry/compare/v0.21.5...v0.21.6
Commits
53f7e39Update go version to 1.26.3 (#2300)bf87c3btransport: allow bearer realm at same host:port as registry (#2302)c55facdtransport: retry HTTP 429 (Too Many Requests) (#2301)68a569efix: preserve per-occurrence layer identity in Layers() (#2299)35b354bfix(mutate): preserve config blob and layers for non-Docker OCI artifacts (#2...e5983f2remote: block SSRF via private-IP Location headers in blob uploads (#2295)6dad820remote: validate foreign layer URLs to prevent SSRF (fixes #2259) (#2293)78bdf1bvalidate: skip non-layer layers (#2298)c29d91cpkg/v1/mutate: preserve relative symlinks that stay within rootfs in Extract ...a70d75atransport: block redirects from token server to private/link-local addresses ...- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 11 ++++------- go.sum | 22 ++++++++-------------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 247ffc7..6a54948 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/coreos/go-oidc/v3 v3.18.0 github.com/danielgtaylor/huma/v2 v2.37.3 github.com/golang-jwt/jwt/v5 v5.3.1 - github.com/google/go-containerregistry v0.21.5 + github.com/google/go-containerregistry v0.21.6 github.com/jackc/pgx/v5 v5.9.2 github.com/prometheus/client_golang v1.23.2 github.com/rs/cors v1.11.1 @@ -39,9 +39,8 @@ require ( github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/docker/cli v29.4.0+incompatible // indirect + github.com/docker/cli v29.4.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-jose/go-jose/v4 v4.1.4 // indirect @@ -54,9 +53,8 @@ require ( 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.5 // indirect + github.com/klauspost/compress v1.18.6 // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect @@ -67,7 +65,6 @@ require ( github.com/prometheus/otlptranslator v1.0.0 // indirect github.com/prometheus/procfs v0.20.1 // indirect github.com/sirupsen/logrus v1.9.4 // indirect - github.com/vbatts/tar-split v0.12.2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect @@ -77,7 +74,7 @@ require ( golang.org/x/net v0.53.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.43.0 // indirect + golang.org/x/sys v0.44.0 // indirect golang.org/x/text v0.36.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/api v0.274.0 // indirect diff --git a/go.sum b/go.sum index 1a65b0f..ebf0ad1 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,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/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= -github.com/containerd/stargz-snapshotter/estargz v0.18.2 h1:yXkZFYIzz3eoLwlTUZKz2iQ4MrckBxJjkmD16ynUTrw= -github.com/containerd/stargz-snapshotter/estargz v0.18.2/go.mod h1:XyVU5tcJ3PRpkA9XS2T5us6Eg35yM0214Y+wvrZTBrY= github.com/coreos/go-oidc/v3 v3.18.0 h1:V9orjXynvu5wiC9SemFTWnG4F45v403aIcjWo0d41+A= github.com/coreos/go-oidc/v3 v3.18.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4= github.com/danielgtaylor/huma/v2 v2.37.3 h1:6Av0Vj45Vk5lDxRVfoO2iPlEdvCvwLc7pl5nbqGOkYM= @@ -45,8 +43,8 @@ github.com/danielgtaylor/huma/v2 v2.37.3/go.mod h1:OeHHtCEAaNiuVbAVdYu4IQ0UOmnb4 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/cli v29.4.0+incompatible h1:+IjXULMetlvWJiuSI0Nbor36lcJ5BTcVpUmB21KBoVM= -github.com/docker/cli v29.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v29.4.3+incompatible h1:u+UliYm2J/rYrIh2FqHQg32neRG8GjbvNuwQRTzGspU= +github.com/docker/cli v29.4.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= @@ -71,8 +69,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 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/go-containerregistry v0.21.5 h1:KTJG9Pn/jC0VdZR6ctV3/jcN+q6/Iqlx0sTVz3ywZlM= -github.com/google/go-containerregistry v0.21.5/go.mod h1:ySvMuiWg+dOsRW0Hw8GYwfMwBlNRTmpYBFJPlkco5zU= +github.com/google/go-containerregistry v0.21.6 h1:T+yqQIlJXKrM98Om4DlW3GoWQAmhZuLMwoDOvVrtiUM= +github.com/google/go-containerregistry v0.21.6/go.mod h1:U7MMSBIJynke2MVQrQk19NP9k/uQsGz/h0amIFSHMbo= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -91,16 +89,14 @@ 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/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= -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.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= +github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= @@ -136,8 +132,6 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4= -github.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= @@ -175,8 +169,8 @@ golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7 golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.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/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= From 3a8d268a876d1f6653df45a9c136019993bc7b0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 May 2026 06:42:29 -0400 Subject: [PATCH 101/190] build(deps): bump github.com/danielgtaylor/huma/v2 from 2.37.3 to 2.38.0 (#1296) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/danielgtaylor/huma/v2](https://github.com/danielgtaylor/huma) from 2.37.3 to 2.38.0. Release notes
Sourced from github.com/danielgtaylor/huma/v2's releases.
v2.38.0
Overview
Fiber v3
This release adds support for Fiber v3. Dedicated v2 functions have been added to ensure support for both.
What's Changed
- Fix header regression by
@wolveixin danielgtaylor/huma#1007- feat(humafiber): add Fiber v3 support by
@wheinzein danielgtaylor/huma#962- Accept empty base64 inputs by
@wolveixin danielgtaylor/huma#1013- chore(deps): bump github.com/gofiber/fiber/v3 from 3.1.0 to 3.2.0 by
@dependabot[bot] in danielgtaylor/huma#1018- Propagate underlying context to GET/PUT requests in the autopatch handler by
@alixinnein danielgtaylor/huma#1019- chore(deps): bump github.com/gofiber/fiber/v2 from 2.52.12 to 2.52.13 by
@dependabot[bot] in danielgtaylor/huma#1022New Contributors
@wheinzemade their first contribution in danielgtaylor/huma#962@alixinnemade their first contribution in danielgtaylor/huma#1019Full Changelog: https://github.com/danielgtaylor/huma/compare/v2.37.3...v2.38.0
Commits
c3f1651chore(deps): bump github.com/gofiber/fiber/v2 from 2.52.12 to 2.52.13 (#1022)0dc6f40Propagate underlying context to GET/PUT requests in the autopatch handler (#1...ce91c48chore(deps): bump github.com/gofiber/fiber/v3 from 3.1.0 to 3.2.0 (#1018)8fb47eeAccept empty base64 inputs (#1013)e2db596feat(humafiber): add Fiber v3 support (#962)b2d8a3aFix header regression (#1007)- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 6a54948..2d7ed4a 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 github.com/caarlos0/env/v11 v11.4.1 github.com/coreos/go-oidc/v3 v3.18.0 - github.com/danielgtaylor/huma/v2 v2.37.3 + github.com/danielgtaylor/huma/v2 v2.38.0 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/go-containerregistry v0.21.6 github.com/jackc/pgx/v5 v5.9.2 diff --git a/go.sum b/go.sum index ebf0ad1..77dcd5a 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,8 @@ github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/T github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= github.com/coreos/go-oidc/v3 v3.18.0 h1:V9orjXynvu5wiC9SemFTWnG4F45v403aIcjWo0d41+A= github.com/coreos/go-oidc/v3 v3.18.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4= -github.com/danielgtaylor/huma/v2 v2.37.3 h1:6Av0Vj45Vk5lDxRVfoO2iPlEdvCvwLc7pl5nbqGOkYM= -github.com/danielgtaylor/huma/v2 v2.37.3/go.mod h1:OeHHtCEAaNiuVbAVdYu4IQ0UOmnb4x3yMUOShNlZ53g= +github.com/danielgtaylor/huma/v2 v2.38.0 h1:fb0WZCatnaiHLphMQDDWDjygNxfMkX/ENma3QsRl7vY= +github.com/danielgtaylor/huma/v2 v2.38.0/go.mod h1:k9hwjlgWFt1t2jsmQGlsgXAG2FBTZa4kkjV581qAtfo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -54,8 +54,8 @@ github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= -github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ= +github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= From a23a5185929bd17024c22b6f415fc3faf1ebafc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 May 2026 06:42:44 -0400 Subject: [PATCH 102/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.238.0 to 3.242.0 in /deploy (#1297) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.238.0 to 3.242.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.242.0
3.242.0 (2026-05-19)
Features
[cli] Add a
pulumipackage for npx support[cli] Add the
pulumi org member editcommand #23235[cli] Add the
pulumi org member removecommand #23237[cli/cloud] Add
pulumi deployment getto retrieve details for a specific deployment #23238[cli/cloud] Add
pulumi insights account scan get <account> <scan-id>to show the full workflow run for a single Insights scan #23255[cli/cloud] Add
pulumi insights account scan list <account>to discover recent scan IDs to feed intopulumi insights account scan log#23255[cli/deployment] Add dedicated flags for each deployment setting #23236
[cli/do] Add the start of
pulumi do#23176[cli/neo] Add
-ptopulumi neoto run a single prompt non-interactively and print the agent's final response to stdout #23245Bug Fixes
[cli/cloud] Fix
pulumi insights account scan log --allto follow the server's pagination cursor through the end of the log, and render--job/--stepmode as structured lines instead of an empty raw-string blob #23256[sdk] Close gzip.Writer in archiveTarGZIP to produce valid tar.gz output #23240
[sdkgen/python] Fix usage of ArgsDict types in typed dictionaries #23253
v3.241.0
3.241.0 (2026-05-18)
Features
... (truncated)
Changelog
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.242.0 (2026-05-19)
Features
[cli] Add a
pulumipackage for npx support[cli] Add the
pulumi org member editcommand #23235[cli] Add the
pulumi org member removecommand #23237[cli/cloud] Add
pulumi deployment getto retrieve details for a specific deployment #23238[cli/cloud] Add
pulumi insights account scan get <account> <scan-id>to show the full workflow run for a single Insights scan #23255[cli/cloud] Add
pulumi insights account scan list <account>to discover recent scan IDs to feed intopulumi insights account scan log#23255[cli/deployment] Add dedicated flags for each deployment setting #23236
[cli/do] Add the start of
pulumi do#23176[cli/neo] Add
-ptopulumi neoto run a single prompt non-interactively and print the agent's final response to stdout #23245Bug Fixes
[cli/cloud] Fix
pulumi insights account scan log --allto follow the server's pagination cursor through the end of the log, and render--job/--stepmode as structured lines instead of an empty raw-string blob #23256[sdk] Close gzip.Writer in archiveTarGZIP to produce valid tar.gz output #23240
[sdkgen/python] Fix usage of ArgsDict types in typed dictionaries #23253
3.241.0 (2026-05-18)
Features
- [cli] Add
--output jsontopulumi previewfor a structured JSON summary of the operation result #22927... (truncated)
Commits
f4db8b5Upgrade Pulumi HCL to v0.3.2 (#23261)cd682b8cli: add apulumipackage for npx support (#23145)e836499cli/neo: set AI_AGENT=neo for shell-tool child processes (#23251)2560b90unhideorg usagecommand tree (#23259)4588160unhideorg membercommands (#23257)f821c0dunhideorg rolecommands (#23258)9356340docs(contributing): minor grammar fixes (PR->PRs,Here's-> `Here are...3779d16unhideorg member(#23241)c28bf15unhide a couplestackcommands (#23243)90caf84cli/cloud: fixpulumi insights account scan logpagination (#23256)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 5 +++-- deploy/go.sum | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 8354647..45181c9 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 - github.com/pulumi/pulumi/sdk/v3 v3.238.0 + github.com/pulumi/pulumi/sdk/v3 v3.242.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -71,11 +71,12 @@ require ( github.com/opentracing/basictracer-go v1.1.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pgavlin/fx v0.1.6 // indirect + github.com/pgavlin/fx/v2 v2.0.12 // indirect github.com/pjbgf/sha1cd v0.6.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/term v1.1.0 // indirect github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect - github.com/pulumi/esc v0.17.0 // indirect + github.com/pulumi/esc v0.24.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index 7bc5320..a72e887 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -181,14 +181,14 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 h1:vkHw5I/plNdTr435cARxCW6q9gc0S/Yxz7Mkd38pOb0= github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231/go.mod h1:murToZ2N9hNJzewjHBgfFdXhZKjY3z5cYC1VXk+lbFE= -github.com/pulumi/esc v0.17.0 h1:oaVOIyFTENlYDuqc3pW75lQT9jb2cd6ie/4/Twxn66w= -github.com/pulumi/esc v0.17.0/go.mod h1:XnSxlt5NkmuAj304l/gK4pRErFbtqq6XpfX1tYT9Jbc= +github.com/pulumi/esc v0.24.0 h1:sCtiB0qbyrlU1ZNzJn4dTLYiChl8xeCBFbHWl1YoXJg= +github.com/pulumi/esc v0.24.0/go.mod h1:eCOOkcDJS6eooGwdE4/E0+pOsvUWG254+KBmPCFwJpA= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9FjWCUBCq6U= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 h1:nF0Y1F7fUGL6RYD9EAtHTdDbNFmDaA3xcEiRlvCDV5E= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.238.0 h1:V15ghoymebrhKsZeGRzs3rwmWD1MmuR7F2fx+2slct8= -github.com/pulumi/pulumi/sdk/v3 v3.238.0/go.mod h1:J8QFD7dwiCGSvBlcYwECmX/b3JKNXR85bv6BbjhPV3U= +github.com/pulumi/pulumi/sdk/v3 v3.242.0 h1:gQIZ1ALbT5gCMuRoBscGzk7Rdbx9mbOc+YwDFxvRyss= +github.com/pulumi/pulumi/sdk/v3 v3.242.0/go.mod h1:P9VS6pQws3YBu67uszFRHn24n5AwzeMlyC2hIiHGWHg= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From 5fe2c79e5c55632a3891177ba3288b8f9cd59dcf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 May 2026 06:43:29 -0400 Subject: [PATCH 103/190] build(deps): bump goreleaser/goreleaser-action from 7.2.1 to 7.2.2 in the actions group (#1299) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the actions group with 1 update: [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action). Updates `goreleaser/goreleaser-action` from 7.2.1 to 7.2.2 Release notes
Sourced from goreleaser/goreleaser-action's releases.
v7.2.2
What's Changed
- ci(deps): bump the actions group with 3 updates by
@dependabot[bot] in goreleaser/goreleaser-action#560- fix: nightly resolution to select newest published release by
@Copilotin goreleaser/goreleaser-action#562New Contributors
@Copilotmade their first contribution in goreleaser/goreleaser-action#562Full Changelog: https://github.com/goreleaser/goreleaser-action/compare/v7...v7.2.2
Commits
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1f51d3b..63805ab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: anchore/sbom-action/download-syft@v0.24.0 - name: Run GoReleaser - uses: goreleaser/goreleaser-action@1a80836c5c9d9e5755a25cb59ec6f45a3b5f41a8 + uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 with: distribution: goreleaser version: v2.12.0 From 66cc039facdd8cdba7deca56389f8114f2703620 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Mon, 25 May 2026 07:02:10 -0400 Subject: [PATCH 104/190] build(deps): bump golang.org/x/net to v0.55.0 (#1308) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Bumps `golang.org/x/net` from v0.53.0 to v0.55.0 to fix [GO-2026-5026](https://pkg.go.dev/vuln/GO-2026-5026) (failure to reject ASCII-only Punycode-encoded labels in `golang.org/x/net/idna`). - govulncheck flagged the vuln via `auth.DefaultHTTPKeyFetcher.FetchKey` → `http.Client.Do` → `idna.ToASCII` at `internal/api/handlers/v0/auth/http.go:191`. - Also brings in associated `x/crypto`, `x/sys`, `x/text` bumps via `go mod tidy`. This unblocks open dependabot PRs (e.g. #1298) that are failing CI on the same govulncheck finding despite not touching the root module. ## Test plan - [x] `go build ./...` - [x] `govulncheck` no longer reports GO-2026-5026 locally - [ ] CI passes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 2d7ed4a..c4dcb1d 100644 --- a/go.mod +++ b/go.mod @@ -70,12 +70,12 @@ require ( go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - golang.org/x/crypto v0.50.0 // indirect - golang.org/x/net v0.53.0 // indirect + golang.org/x/crypto v0.51.0 // indirect + golang.org/x/net v0.55.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.44.0 // indirect - golang.org/x/text v0.36.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/api v0.274.0 // indirect google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect diff --git a/go.sum b/go.sum index 77dcd5a..5231bde 100644 --- a/go.sum +++ b/go.sum @@ -158,21 +158,21 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= -golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +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/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +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/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= From f0f03c01270285df05f41a51acad8c20c8576706 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 May 2026 07:09:26 -0400 Subject: [PATCH 105/190] build(deps): bump github.com/pulumi/pulumi-kubernetes/sdk/v4 from 4.30.0 to 4.31.1 in /deploy (#1298) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/pulumi/pulumi-kubernetes/sdk/v4](https://github.com/pulumi/pulumi-kubernetes) from 4.30.0 to 4.31.1. Release notes
Sourced from github.com/pulumi/pulumi-kubernetes/sdk/v4's releases.
v4.31.1
Changed
- pulumi/pulumi-kubernetes#4364 Update github.com/go-git/go-git/v5 to v5.19.1 (SECURITY).
- Update first-party Pulumi dependencies to v3.242.0. which fixes pulumi/pulumi-kubernetes#4354
v4.31.0
Added
- #2744 Advertise a
helmmapping forterraformconversion sopulumi import --from terraformandpulumi convert --from terraformrecognizehelm_releaseand emitkubernetes:helm.sh/v3:Release.- #4332 Implement the
Listprovider RPC and advertiselistInputs(namespace,name,labelSelector,fieldSelector) on every non-nested resource.namespaceis omitted fromlistInputson cluster-scoped kinds. Seehttps://github.com/pulumi/pulumi-kubernetes/blob/HEAD/docs/list-rpc-semantics.mdfor design notes.Fixed
- #4261 Fix CRD parameterization: implement
Parameterize(Value)so subsequent runs can reconstruct the CRD schema from saved state, and flatten array-of-objects in OpenAPI specs so nested fields likespec.listenersgenerate typed args.Changed
- Upgrade Kubernetes schema and libraries to v1.36.1.
Changelog
Sourced from github.com/pulumi/pulumi-kubernetes/sdk/v4's changelog.
4.31.1 (May 19, 2026)
Changed
- #4364 Update
github.com/go-git/go-git/v5to v5.19.1 (SECURITY).- Update first-party Pulumi dependencies to v3.242.0.
4.31.0 (May 14, 2026)
Added
- #2744 Advertise a
helmmapping forterraformconversion sopulumi import --from terraformandpulumi convert --from terraformrecognizehelm_releaseand emitkubernetes:helm.sh/v3:Release.- #4332 Implement the
Listprovider RPC and advertiselistInputs(namespace,name,labelSelector,fieldSelector) on every non-nested resource.namespaceis omitted fromlistInputson cluster-scoped kinds. Seehttps://github.com/pulumi/pulumi-kubernetes/blob/master/docs/list-rpc-semantics.mdfor design notes.Fixed
- #4261 Fix CRD parameterization: implement
Parameterize(Value)so subsequent runs can reconstruct the CRD schema from saved state, and flatten array-of-objects in OpenAPI specs so nested fields likespec.listenersgenerate typed args.Changed
- Upgrade Kubernetes schema and libraries to v1.36.1.
Commits
7bc3a67Prepare for v4.31.1 release (#4366)1f5b4d2Update first-party Pulumi dependencies to v3.242.0 (#4365)e8f0d87Update module github.com/go-git/go-git/v5 to v5.19.1 [SECURITY] (#4364)51e8420Update GitHub Actions workflows. (#4361)ccadf55Update first-party Pulumi dependencies to v3.241.0 (#4360)e0ac4d3Bump kind 0.29.0 → 0.31.0 (#4358)6b10bbeUpdate GitHub Actions workflows. (#4353)ee00284Update module github.com/pulumi/esc to v0.24.0 (#4351)ed357fbFix duplicate ### Changed heading in k8s auto-bump workflow (#4345)52169e8Update first-party Pulumi dependencies to v4.31.0 (#4349)- Additional commits viewable in compare view
Signed-off-by: dependabot[bot]Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Radoslav Dimitrov --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 45181c9..ec61bb7 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -4,7 +4,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 - github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 + github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1 github.com/pulumi/pulumi/sdk/v3 v3.242.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/deploy/go.sum b/deploy/go.sum index a72e887..e5837f4 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -185,8 +185,8 @@ github.com/pulumi/esc v0.24.0 h1:sCtiB0qbyrlU1ZNzJn4dTLYiChl8xeCBFbHWl1YoXJg= github.com/pulumi/esc v0.24.0/go.mod h1:eCOOkcDJS6eooGwdE4/E0+pOsvUWG254+KBmPCFwJpA= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9FjWCUBCq6U= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= -github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0 h1:nF0Y1F7fUGL6RYD9EAtHTdDbNFmDaA3xcEiRlvCDV5E= -github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.30.0/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= +github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1 h1:Hg9RK9zqIU9kFbD5KeiON06gPP7cLgS68jvsgMBmPgw= +github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= github.com/pulumi/pulumi/sdk/v3 v3.242.0 h1:gQIZ1ALbT5gCMuRoBscGzk7Rdbx9mbOc+YwDFxvRyss= github.com/pulumi/pulumi/sdk/v3 v3.242.0/go.mod h1:P9VS6pQws3YBu67uszFRHn24n5AwzeMlyC2hIiHGWHg= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= From b97cc9fbd62eeb92ad352a8de2a60a341e6b8fa8 Mon Sep 17 00:00:00 2001 From: Tadas Antanavicius Date: Sun, 31 May 2026 00:20:31 -0700 Subject: [PATCH 106/190] docs: update maintainer/collaborator matrix in README (#1324) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cbd9670..33ce337 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,11 @@ The MCP registry provides MCP clients with a list of MCP servers, like an app st **2025-09-08 update**: The registry has launched in preview 🎉 ([announcement blog post](https://blog.modelcontextprotocol.io/posts/2025-09-08-mcp-registry-preview/)). While the system is now more stable, this is still a preview release and breaking changes or data resets may occur. A general availability (GA) release will follow later. We'd love your feedback in [GitHub discussions](https://github.com/modelcontextprotocol/registry/discussions/new?category=ideas) or in the [#registry-dev Discord](https://discord.com/channels/1358869848138059966/1369487942862504016) ([joining details here](https://modelcontextprotocol.io/community/communication)). -Current key maintainers: -- **Adam Jones** (Anthropic) [@domdomegg](https://github.com/domdomegg) +Registry Working Group: - **Tadas Antanavicius** (PulseMCP) [@tadasant](https://github.com/tadasant) -- **Toby Padilla** (GitHub) [@toby](https://github.com/toby) - **Radoslav (Rado) Dimitrov** (Stacklok) [@rdimitrov](https://github.com/rdimitrov) +- **Bob Dickinson** (TeamSpark) [@BobDickinson](https://github.com/BobDickinson) +- **Preeti (Pree) Dewani** (Ravenmail) [@pree-dew](https://github.com/pree-dew) ## Contributing From 224f50288d2c040a7502017c8b5cbda03522c797 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 03:21:50 -0400 Subject: [PATCH 107/190] build(deps): bump the actions group with 2 updates (#1314) --- .github/workflows/ci.yml | 2 +- .github/workflows/deploy-staging.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0dbb93..ce8f267 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: cache: true - name: Run lint - uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 + uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee with: version: v2.11.4 diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index 074bb4a..c461511 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -34,7 +34,7 @@ jobs: uses: ko-build/setup-ko@v0.9 - name: Log in to Container Registry - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee with: registry: ghcr.io username: ${{ github.actor }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 63805ab..f41dcaa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,7 +57,7 @@ jobs: uses: ko-build/setup-ko@v0.9 - name: Log in to Container Registry - uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 + uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee with: registry: ghcr.io username: ${{ github.actor }} From 51f37e8de587126c2d8f4ce3fc3d5a860bc6bf79 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 03:22:20 -0400 Subject: [PATCH 108/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.242.0 to 3.243.0 in /deploy (#1313) --- deploy/go.mod | 3 ++- deploy/go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index ec61bb7..f2e8b8b 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,12 +5,13 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1 - github.com/pulumi/pulumi/sdk/v3 v3.242.0 + github.com/pulumi/pulumi/sdk/v3 v3.243.0 gopkg.in/yaml.v2 v2.4.0 ) require ( dario.cat/mergo v1.0.0 // indirect + github.com/BurntSushi/toml v1.6.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.1.6 // indirect github.com/agext/levenshtein v1.2.3 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index e5837f4..8b29f96 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -1,5 +1,7 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= +github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= @@ -187,8 +189,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1 h1:Hg9RK9zqIU9kFbD5KeiON06gPP7cLgS68jvsgMBmPgw= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.242.0 h1:gQIZ1ALbT5gCMuRoBscGzk7Rdbx9mbOc+YwDFxvRyss= -github.com/pulumi/pulumi/sdk/v3 v3.242.0/go.mod h1:P9VS6pQws3YBu67uszFRHn24n5AwzeMlyC2hIiHGWHg= +github.com/pulumi/pulumi/sdk/v3 v3.243.0 h1:pZaMx58nXrdh4XB0cgTlHnL3EMy3/JQwuin3aDuWyRM= +github.com/pulumi/pulumi/sdk/v3 v3.243.0/go.mod h1:BPWWuYPXcPH5YbXGoyy9Rrfa+evrh6IdM51AjDhcDpM= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From 3a8e5428db14fb5821cf0fc0b1ade2e2e4534ea5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 03:22:40 -0400 Subject: [PATCH 109/190] build(deps): bump github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys from 1.4.0 to 1.5.0 (#1312) --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index c4dcb1d..bf8826a 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( cloud.google.com/go/kms v1.31.0 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 - github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 + github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.5.0 github.com/caarlos0/env/v11 v11.4.1 github.com/coreos/go-oidc/v3 v3.18.0 github.com/danielgtaylor/huma/v2 v2.38.0 @@ -33,10 +33,10 @@ require ( cloud.google.com/go/compute/metadata v0.9.0 // indirect cloud.google.com/go/iam v1.7.0 // indirect cloud.google.com/go/longrunning v0.9.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/go.sum b/go.sum index 5231bde..cd14952 100644 --- a/go.sum +++ b/go.sum @@ -12,22 +12,22 @@ cloud.google.com/go/kms v1.31.0 h1:LS8N92OxFDgOLg5NCo3OmbvjtQAIVT5gUHVLKIDHaFE= cloud.google.com/go/kms v1.31.0/go.mod h1:YIyXZym11R5uovJJt4oN5eUL3oPmirF3yKeIh6QAf4U= cloud.google.com/go/longrunning v0.9.0 h1:0EzbDEGsAvOZNbqXopgniY0w0a1phvu5IdUFq8grmqY= cloud.google.com/go/longrunning v0.9.0/go.mod h1:pkTz846W7bF4o2SzdWJ40Hu0Re+UoNT6Q5t+igIcb8E= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 h1:fou+2+WFTib47nS+nz/ozhEBnvU96bKHy6LjRsY4E28= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0/go.mod h1:t76Ruy8AHvUAC8GfMWJMa0ElSbuIcO03NLpynfbgsPA= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 h1:E4MgwLBGeVB5f2MdcIVD3ELVAWpr+WD6MUe1i+tM/PA= -github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0/go.mod h1:Y2b/1clN4zsAoUd/pgNAQHjLDnTis/6ROkUfyob6psM= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.5.0 h1:MaKvxE6D0KkjOg6Wd9M00iqP5PR0kUxCfiezes4JweM= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.5.0/go.mod h1:i2h9fsTFKZorh8RdV2IcSUf/Qj98GlTkrTvUbX/s8as= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfgcSyHZXJI8J0IWE5MsCGlb2xp9fJiXyxWgmOFg4= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= -github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs= -github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= +github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0 h1:4iB+IesclUXdP0ICgAabvq2FYLXrJWKx1fJQ+GxSo3Y= +github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/caarlos0/env/v11 v11.4.1 h1:fYwH0sWEsBSMPG7t4e/PEfTFzrWrpjyygXyUnWiSwEw= From 5d91ce7c2e83942435db8df818aa6ae924ed5d3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 03:23:00 -0400 Subject: [PATCH 110/190] build(deps): bump the opentelemetry group with 5 updates (#1311) --- go.mod | 12 ++++++------ go.sum | 26 ++++++++++++++------------ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index bf8826a..fd152fc 100644 --- a/go.mod +++ b/go.mod @@ -17,11 +17,11 @@ require ( github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/stretchr/testify v1.11.1 go.opentelemetry.io/contrib/instrumentation/runtime v0.68.0 - go.opentelemetry.io/otel v1.43.0 - go.opentelemetry.io/otel/exporters/prometheus v0.65.0 - go.opentelemetry.io/otel/metric v1.43.0 - go.opentelemetry.io/otel/sdk v1.43.0 - go.opentelemetry.io/otel/sdk/metric v1.43.0 + go.opentelemetry.io/otel v1.44.0 + go.opentelemetry.io/otel/exporters/prometheus v0.66.0 + go.opentelemetry.io/otel/metric v1.44.0 + go.opentelemetry.io/otel/sdk v1.44.0 + go.opentelemetry.io/otel/sdk/metric v1.44.0 golang.org/x/mod v0.36.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -68,7 +68,7 @@ require ( go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel/trace v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect golang.org/x/crypto v0.51.0 // indirect golang.org/x/net v0.55.0 // indirect diff --git a/go.sum b/go.sum index cd14952..d738e87 100644 --- a/go.sum +++ b/go.sum @@ -142,18 +142,20 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6h go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= go.opentelemetry.io/contrib/instrumentation/runtime v0.68.0 h1:jhVIQEprwUTV+KfzzliLidclhoTOoHTgdz96kAyR8mU= go.opentelemetry.io/contrib/instrumentation/runtime v0.68.0/go.mod h1:4HsdbLUbernaTnA8CNaNE+1g026SciXb3juRYe3l8EY= -go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= -go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= -go.opentelemetry.io/otel/exporters/prometheus v0.65.0 h1:jOveH/b4lU9HT7y+Gfamf18BqlOuz2PWEvs8yM7Q6XE= -go.opentelemetry.io/otel/exporters/prometheus v0.65.0/go.mod h1:i1P8pcumauPtUI4YNopea1dhzEMuEqWP1xoUZDylLHo= -go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= -go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= -go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= -go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= -go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= -go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= -go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= -go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel/exporters/prometheus v0.66.0 h1:vkrK8PAznv2NKt2r+kdu252ccGzkEqLc2aSXbQIALYQ= +go.opentelemetry.io/otel/exporters/prometheus v0.66.0/go.mod h1:V/UB6D3vMF/UBOL5igAsAYnk1nG/bzYYTzvsB16cy7o= +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/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/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/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +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.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= From 685e354b2fa37e5fe6d70dab0edb26a84e7ddf64 Mon Sep 17 00:00:00 2001 From: Wolfe-James Date: Wed, 3 Jun 2026 10:56:43 -0400 Subject: [PATCH 111/190] feat: add cargo (crates.io) as a package registry type (#1207) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit > **Update — 2026-06-01 (commit 1f3be53)** > > - **All @P4ST4S review feedback addressed** — positive-path hermetic mock + live anchor against `rust-faf-mcp v0.3.1`; 5xx routed as transient; doc comment qualified. See the [close-out comment](https://github.com/modelcontextprotocol/registry/pull/1207#issuecomment-4589711057) for the per-item breakdown. > - **Runtime-model question RESOLVED** — `package-types.mdx` documents cargo and MCPB as both first-class Rust MCP distribution paths (cargo for source-distributed, MCPB for prebuilt-binary). The "Open question" section below was the original draft framing; the doc now ships the resolution. > - **Cargo-specific gotcha discovered and documented** — crates.io strips HTML comments during README rendering, unlike PyPI/NuGet. `package-types.mdx` now spells this out so cargo authors don't ship invisible mcp-name tokens (which is exactly what happened to `rust-faf-mcp v0.3.0`; fixed in v0.3.1). > - **Stale reference removed in this update** — the "Out of scope" line mentioning `docs/guides/publishing/publish-cargo.md` pointed at a path that doesn't exist. The canonical per-type doc is `docs/modelcontextprotocol-io/package-types.mdx`; the Cargo section has been added there directly. > - **Two real-world Rust MCP servers queued for day-one register**: `rust-faf-mcp v0.3.1` (live, end-to-end validated by the new live test) and `perfetto-mcp-rs` ([@0xZOne](https://github.com/0xZOne) in #1055). > - **Tests:** 19/19 cargo tests pass (16 existing + 2 hermetic + 1 live anchor). `make validate` clean. `golangci-lint` 0 issues. --- Adds support for `registryType: cargo` so Rust MCP servers published to crates.io can be registered through the documented validation flow rather than the MCPB binary-packaging workaround. Closes #1055. ## Motivation and Context #1055 noted that crates.io has ~1,800 MCP-related packages with no direct path into the registry — only the MCPB binary-packaging workaround. This PR adds first-class support for cargo as a package registry type: schema + API surface, validator, integration tests, and a documented example. The publishing guide (`docs/guides/publishing/publish-cargo.md`) follows on this branch once the runtime-model direction in **Additional context** is settled. ## How Has This Been Tested? - **`make validate`** — clean. Schema-vs-openapi sync verified; 17/17 examples in `generic-server-json.md` validate against the schema; `expectedServerJSONCount` bumped 16 → 17 to match the new Cargo example. - **`go test ./internal/validators/...`** — passes. 16 cargo validator sub-cases across 4 test functions, run against real crates.io (~2.5s wall): - Input validation rejection paths - Registry-baseURL rejection (4 variants: different host, trailing slash, http-not-https, subdomain typo) - Ownership validation against real crates (`serde`, `tokio`, `rand`) — all correctly rejected for missing `mcp-name` token - Server-name format variations (canonical `io.github.OWNER/REPO`, multi-hyphen, underscore, numeric suffix) - **Positive-path test** — gated on `rust-faf-mcp` v0.2.3+ being published with `mcp-name: io.github.Wolfe-Jam/rust-faf-mcp` in its README. Reserved as a TODO in `cargo_test.go`; uncomments to become the live anchor once that publish lands. - **Local `make test-unit`** — not run due to a Go toolchain version quirk on my workstation (project auto-downloads 1.26.0; my local `go` is 1.25.6, causing compile mismatch). CI will exercise the full PostgreSQL-backed suite. ## Breaking Changes None. This is an additive change — `cargo` joins the supported `registryType` enum alongside `npm`/`pypi`/`nuget`/`oci`/`mcpb`. Existing publishes continue to work unchanged. ## Types of changes - [x] New feature (non-breaking change which adds functionality) - [x] Documentation update (new Cargo example in `generic-server-json.md`) ## Checklist - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [x] I have added appropriate error handling - [x] I have added or updated documentation as needed ## Additional context ### Validator design — two-call retrieval on the documented API `internal/validators/registries/cargo.go` mirrors the PyPI validator's README-token approach (substring-match `mcp-name: `), with a two-call retrieval pattern to stay on the documented public crates.io API: 1. `GET /api/v1/crates/{name}/{version}/readme` returns 200 OK with a JSON pointer (`{"url": "https://static.crates.io/readmes/.../...html"}`) — crates.io hands us the URL rather than emitting a 302. 2. Follow the pointer to the rendered HTML; substring-match for the token. The two-call pattern stays on the documented public surface. The CDN URL layout is observed-stable, but treating it as the entry point would mean depending on an undocumented path. With two calls, crates.io controls where the README lives — if they move it, the metadata endpoint hands us the new URL. Missing crates and missing versions surface as **403** from the CDN (S3's default for missing keys), not 404. The validator treats any non-200 as "not found" and surfaces the actual status code in the error message. ### Open question — runtime model Cargo's runtime model is genuinely different from npm/PyPI/NuGet. `cargo install` is one-time (binary lands on PATH at `~/.cargo/bin`), not per-invocation like `npx`, `uvx`, or `dnx` (the new one in .NET 10 SDK Preview 6+). The new Cargo example in `generic-server-json.md` annotates this honestly and omits `runtimeHint`. If a different framing is preferred — e.g. recommending **MCPB** (prebuilt binary distribution via GitHub Releases) as the primary path for Rust MCP servers instead of cargo — happy to adjust the documentation accordingly. The schema + validator code in this PR is **additive** and doesn't force a recommendation either way; a Rust author who chooses cargo can use it, and one who prefers MCPB still can. ### Out of scope (deferred) - **`docs/guides/publishing/publish-cargo.md`** — follows on this branch once the runtime-model direction above is settled. - **Publisher CLI `Cargo.toml` autodetect** in `cmd/publisher/commands/init.go` — separate concern, separate PR. - **Positive-path validator test** — gated on `rust-faf-mcp` v0.2.3+ publishing as noted in *How Has This Been Tested?*. --------- Co-authored-by: Claude Co-authored-by: Radoslav Dimitrov --- .../modelcontextprotocol-io/package-types.mdx | 51 +++ docs/reference/api/openapi.yaml | 4 +- .../server-json/draft/server.schema.json | 4 +- .../server-json/generic-server-json.md | 29 ++ internal/validators/package.go | 2 + internal/validators/registries/cargo.go | 160 +++++++ internal/validators/registries/cargo_test.go | 411 ++++++++++++++++++ internal/validators/registries/export_test.go | 9 + pkg/model/constants.go | 2 + tools/validate-examples/main.go | 2 +- 10 files changed, 671 insertions(+), 3 deletions(-) create mode 100644 internal/validators/registries/cargo.go create mode 100644 internal/validators/registries/cargo_test.go create mode 100644 internal/validators/registries/export_test.go diff --git a/docs/modelcontextprotocol-io/package-types.mdx b/docs/modelcontextprotocol-io/package-types.mdx index b7a31b9..6cac890 100644 --- a/docs/modelcontextprotocol-io/package-types.mdx +++ b/docs/modelcontextprotocol-io/package-types.mdx @@ -125,6 +125,57 @@ This MCP server manages Azure DevOps work items and pipelines. ``` +## Cargo (Rust) Packages + +For Cargo packages, the MCP Registry currently supports the official crates.io registry (`https://crates.io`) only. + +Cargo packages use `"registryType": "cargo"` in `server.json`. For example: + +```json server.json highlight={9} +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", + "name": "io.github.username/widget-mcp", + "title": "Widget", + "description": "Rust-native MCP server", + "version": "0.3.0", + "packages": [ + { + "registryType": "cargo", + "identifier": "widget-mcp", + "version": "0.3.0", + "transport": { + "type": "stdio" + } + } + ] +} +``` + +### Runtime Model + +Cargo's runtime model differs from npm/PyPI/NuGet. `cargo install ` places the compiled binary on PATH at `~/.cargo/bin`, after which MCP clients invoke it directly by name. There is no per-invocation runner equivalent to `npx` (npm), `uvx` (PyPI), or `dnx` (NuGet, .NET 10 SDK Preview 6+) — install is one-time, execution is by binary name. The Cargo example above intentionally omits `runtimeHint` for this reason. + +Rust MCP authors have two first-class distribution paths: + +- **Cargo (`registryType: cargo`)** — source-distributed via crates.io. End users need the Rust toolchain (`rustup`) to run `cargo install`. Idiomatic for the Rust ecosystem and consistent with how Rust CLIs are typically published. +- **MCPB (`registryType: mcpb`)** — prebuilt binary distributed via GitHub or GitLab Releases. End users need no toolchain. Right choice if the priority is "no Rust toolchain required." + +Both paths are supported; the choice is the author's. Cargo native support exists so Rust authors who prefer source distribution are not forced into the MCPB binary-packaging workaround. + +### Ownership Verification + +The MCP Registry verifies ownership of Cargo packages by checking for the existence of an `mcp-name: $SERVER_NAME` string in the package README (which is rendered to HTML and served by crates.io's static CDN). The `$SERVER_NAME` portion **MUST** match the server name from `server.json`. For example: + +```markdown README.md highlight={5} +# Widget MCP Server + +A Rust-native MCP server for widget operations. + +- MCP Registry name: `mcp-name: io.github.username/widget-mcp` +``` + +**Cargo-specific gotcha:** Unlike PyPI and NuGet (which preserve HTML comments in their README rendering), **crates.io strips HTML comments during markdown→HTML conversion**. The `` hidden-comment form that works for PyPI/NuGet **does not work for cargo** — the token will not appear in the rendered HTML the validator inspects. Cargo authors must include the `mcp-name:` token as visible markdown text. A simple bullet in the Links section is the recommended pattern. + ## Docker/OCI Images For Docker/OCI images, the MCP Registry currently supports: diff --git a/docs/reference/api/openapi.yaml b/docs/reference/api/openapi.yaml index 108e2fb..61cae2d 100644 --- a/docs/reference/api/openapi.yaml +++ b/docs/reference/api/openapi.yaml @@ -659,10 +659,11 @@ components: properties: registryType: type: string - description: Registry type indicating how to download packages (e.g., 'npm', 'pypi', 'oci', 'nuget', 'mcpb') + description: Registry type indicating how to download packages (e.g., 'npm', 'pypi', 'cargo', 'oci', 'nuget', 'mcpb') examples: - "npm" - "pypi" + - "cargo" - "oci" - "nuget" - "mcpb" @@ -673,6 +674,7 @@ components: examples: - "https://registry.npmjs.org" - "https://pypi.org" + - "https://crates.io" - "https://docker.io" - "https://api.nuget.org/v3/index.json" - "https://github.com" diff --git a/docs/reference/server-json/draft/server.schema.json b/docs/reference/server-json/draft/server.schema.json index 95539fe..e3aeab6 100644 --- a/docs/reference/server-json/draft/server.schema.json +++ b/docs/reference/server-json/draft/server.schema.json @@ -239,6 +239,7 @@ "examples": [ "https://registry.npmjs.org", "https://pypi.org", + "https://crates.io", "https://docker.io", "https://api.nuget.org/v3/index.json", "https://github.com", @@ -248,10 +249,11 @@ "type": "string" }, "registryType": { - "description": "Registry type indicating how to download packages (e.g., 'npm', 'pypi', 'oci', 'nuget', 'mcpb')", + "description": "Registry type indicating how to download packages (e.g., 'npm', 'pypi', 'cargo', 'oci', 'nuget', 'mcpb')", "examples": [ "npm", "pypi", + "cargo", "oci", "nuget", "mcpb" diff --git a/docs/reference/server-json/generic-server-json.md b/docs/reference/server-json/generic-server-json.md index bb5cc44..7415988 100644 --- a/docs/reference/server-json/generic-server-json.md +++ b/docs/reference/server-json/generic-server-json.md @@ -372,6 +372,35 @@ The same `registryType` / `identifier` pattern works for other supported OCI hos } ``` +### Cargo (Rust) Package Example + +`cargo install ` places the binary on PATH (via `~/.cargo/bin`); MCP clients invoke it directly by name. There is no single-shot equivalent of `npx` (npm), `uvx` (PyPI), or `dnx` (NuGet, .NET 10 SDK) for cargo — install once, run by name. + +```json +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", + "name": "io.github.example/widget-mcp", + "description": "Rust-native MCP server", + "title": "Widget", + "repository": { + "url": "https://github.com/example/widget-mcp", + "source": "github" + }, + "version": "0.3.0", + "packages": [ + { + "registryType": "cargo", + "registryBaseUrl": "https://crates.io", + "identifier": "widget-mcp", + "version": "0.3.0", + "transport": { + "type": "stdio" + } + } + ] +} +``` + ### NuGet (.NET) Package Example The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6. diff --git a/internal/validators/package.go b/internal/validators/package.go index 7104f73..b458244 100644 --- a/internal/validators/package.go +++ b/internal/validators/package.go @@ -23,6 +23,8 @@ func ValidatePackage(ctx context.Context, pkg model.Package, serverName string) return registries.ValidateOCI(ctx, pkg, serverName) case model.RegistryTypeMCPB: return registries.ValidateMCPB(ctx, pkg, serverName) + case model.RegistryTypeCargo: + return registries.ValidateCargo(ctx, pkg, serverName) default: return fmt.Errorf("unsupported registry type: %s", pkg.RegistryType) } diff --git a/internal/validators/registries/cargo.go b/internal/validators/registries/cargo.go new file mode 100644 index 0000000..18f7c0f --- /dev/null +++ b/internal/validators/registries/cargo.go @@ -0,0 +1,160 @@ +package registries + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "time" + + "github.com/modelcontextprotocol/registry/pkg/model" +) + +var ( + ErrMissingIdentifierForCargo = errors.New("package identifier is required for Cargo packages") + ErrMissingVersionForCargo = errors.New("package version is required for Cargo packages") +) + +// CargoReadmeMetaResponse is the structure returned by the crates.io readme metadata endpoint. +// +// With `Accept: application/json`, crates.io's /api/v1/crates/{name}/{version}/readme +// endpoint returns 200 OK with a JSON body containing a `url` field that points to the +// rendered README on the static CDN. (Without the Accept header, or via HEAD, the same +// endpoint emits a 302 redirect to the CDN URL — the validator uses the JSON path so +// that crates.io controls where the README lives.) Validators must follow the pointer +// to retrieve the actual README content. +type CargoReadmeMetaResponse struct { + URL string `json:"url"` +} + +// ValidateCargo validates that a Cargo (crates.io) package contains the correct MCP server name. +// +// Verification mechanism: the `mcp-name: ` token is searched for in the package's +// rendered README. This mirrors the PyPI validator's README-token approach (see ValidatePyPI), +// requiring no Cargo.toml parsing on the registry side. Crate authors add a single line +// `mcp-name: io.github.OWNER/REPO` to their README before publishing. +// +// Two-call retrieval pattern: +// 1. GET https://crates.io/api/v1/crates/{name}/{version}/readme +// → 200 OK with JSON: {"url": "https://static.crates.io/readmes/.../...html"} +// 2. GET +// → 200 OK with rendered README HTML, or 403 if the crate/version is missing +// +// The two-call pattern stays on the documented crates.io API surface rather than relying +// on the CDN URL layout being stable. +func ValidateCargo(ctx context.Context, pkg model.Package, serverName string) error { + // Set default registry base URL if empty + if pkg.RegistryBaseURL == "" { + pkg.RegistryBaseURL = model.RegistryURLCrates + } + + if pkg.Identifier == "" { + return ErrMissingIdentifierForCargo + } + + if pkg.Version == "" { + return ErrMissingVersionForCargo + } + + // Validate that MCPB-specific fields are not present + if pkg.FileSHA256 != "" { + return fmt.Errorf("cargo packages must not have 'fileSha256' field - this is only for MCPB packages") + } + + // Validate that the registry base URL matches crates.io exactly + if pkg.RegistryBaseURL != model.RegistryURLCrates { + return fmt.Errorf("registry type and base URL do not match: '%s' is not valid for registry type '%s'. Expected: %s", + pkg.RegistryBaseURL, model.RegistryTypeCargo, model.RegistryURLCrates) + } + + return validateCargoREADME(ctx, pkg, serverName) +} + +// validateCargoREADME performs the two-call README fetch and the mcp-name token +// check. It is split out from ValidateCargo so that httptest-based tests can +// drive the HTTP pipeline against a mock server (exposed via export_test.go), +// bypassing the exact-baseURL guard that ValidateCargo enforces for callers. +func validateCargoREADME(ctx context.Context, pkg model.Package, serverName string) error { + client := &http.Client{Timeout: 10 * time.Second} + // crates.io's crawler policy expects a non-generic User-Agent identifying the source. + userAgent := "MCP-Registry-Validator/1.0 (https://registry.modelcontextprotocol.io)" + + // Step 1: fetch the README pointer from the documented API endpoint. + metaURL := fmt.Sprintf("%s/api/v1/crates/%s/%s/readme", + pkg.RegistryBaseURL, + url.PathEscape(pkg.Identifier), + url.PathEscape(pkg.Version)) + + metaReq, err := http.NewRequestWithContext(ctx, http.MethodGet, metaURL, nil) + if err != nil { + return fmt.Errorf("failed to create crates.io metadata request: %w", err) + } + metaReq.Header.Set("User-Agent", userAgent) + metaReq.Header.Set("Accept", "application/json") + + metaResp, err := client.Do(metaReq) + if err != nil { + return fmt.Errorf("failed to fetch package metadata from crates.io: %w", err) + } + defer metaResp.Body.Close() + + if metaResp.StatusCode != http.StatusOK { + // 5xx from the metadata endpoint is upstream availability, not a missing crate. + if metaResp.StatusCode >= 500 && metaResp.StatusCode < 600 { + return fmt.Errorf("crates.io upstream error fetching metadata for cargo package '%s' (status: %d) — likely transient, retry later", pkg.Identifier, metaResp.StatusCode) + } + return fmt.Errorf("cargo package '%s' metadata fetch failed (status: %d)", pkg.Identifier, metaResp.StatusCode) + } + + var meta CargoReadmeMetaResponse + if err := json.NewDecoder(metaResp.Body).Decode(&meta); err != nil { + return fmt.Errorf("failed to parse crates.io readme metadata: %w", err) + } + if meta.URL == "" { + return fmt.Errorf("cargo package '%s' metadata response missing 'url' field", pkg.Identifier) + } + + // Step 2: fetch the rendered README from the URL the API gave us. + readmeReq, err := http.NewRequestWithContext(ctx, http.MethodGet, meta.URL, nil) + if err != nil { + return fmt.Errorf("failed to create crates.io readme request: %w", err) + } + readmeReq.Header.Set("User-Agent", userAgent) + readmeReq.Header.Set("Accept", "text/html") + + readmeResp, err := client.Do(readmeReq) + if err != nil { + return fmt.Errorf("failed to fetch rendered README from crates.io: %w", err) + } + defer readmeResp.Body.Close() + + // Missing crates and missing versions surface as 403 from static.crates.io + // (S3's default for missing keys), not 404. 5xx from the CDN is upstream + // availability — surface it as transient so callers can distinguish retryable + // failures from genuinely missing crates. + if readmeResp.StatusCode != http.StatusOK { + if readmeResp.StatusCode >= 500 && readmeResp.StatusCode < 600 { + return fmt.Errorf("crates.io upstream error fetching README for cargo package '%s' version '%s' (status: %d) — likely transient, retry later", pkg.Identifier, pkg.Version, readmeResp.StatusCode) + } + return fmt.Errorf("cargo package '%s' version '%s' not found on crates.io (status: %d)", pkg.Identifier, pkg.Version, readmeResp.StatusCode) + } + + body, err := io.ReadAll(readmeResp.Body) + if err != nil { + return fmt.Errorf("failed to read rendered README: %w", err) + } + + // Search for the mcp-name: token. The token contains no characters + // that get HTML-escaped during README rendering (no <, >, &, ", '), so a direct + // substring match against the rendered HTML is reliable. + mcpNamePattern := "mcp-name: " + serverName + if strings.Contains(string(body), mcpNamePattern) { + return nil + } + + return fmt.Errorf("cargo package '%s' ownership validation failed. The server name '%s' must appear as 'mcp-name: %s' in the package README", pkg.Identifier, serverName, serverName) +} diff --git a/internal/validators/registries/cargo_test.go b/internal/validators/registries/cargo_test.go new file mode 100644 index 0000000..e06d099 --- /dev/null +++ b/internal/validators/registries/cargo_test.go @@ -0,0 +1,411 @@ +package registries_test + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "strings" + "sync/atomic" + "testing" + + "github.com/modelcontextprotocol/registry/internal/validators/registries" + "github.com/modelcontextprotocol/registry/pkg/model" + "github.com/stretchr/testify/assert" +) + +func TestValidateCargo_RealPackages(t *testing.T) { + ctx := context.Background() + + tests := []struct { + name string + packageName string + version string + serverName string + expectError bool + errorMessage string + }{ + { + name: "empty package identifier should fail", + packageName: "", + version: "0.1.0", + serverName: "io.github.example/test", + expectError: true, + errorMessage: "package identifier is required for Cargo packages", + }, + { + name: "empty package version should fail", + packageName: "rust-faf-mcp", + version: "", + serverName: "io.github.example/test", + expectError: true, + errorMessage: "package version is required for Cargo packages", + }, + { + name: "non-existent crate should fail", + packageName: generateRandomPackageName(), + version: "0.1.0", + serverName: "io.github.example/test", + expectError: true, + errorMessage: "not found", + }, + { + name: "non-existent version of real crate should fail", + packageName: "serde", + version: "99.99.99-not-real", + serverName: "io.github.example/test", + expectError: true, + errorMessage: "not found", + }, + { + name: "real crate without mcp-name token should fail", + packageName: "serde", // most-downloaded crate; no MCP server claim + version: "1.0.219", + serverName: "io.github.example/test", + expectError: true, + errorMessage: "ownership validation failed", + }, + { + name: "real crate with mismatched mcp-name should fail", + packageName: "tokio", + version: "1.40.0", + serverName: "io.github.example/completely-different-name", + expectError: true, + errorMessage: "ownership validation failed", + }, + { + name: "additional real crate without mcp-name (rand)", + packageName: "rand", + version: "0.9.0", + serverName: "io.github.example/test", + expectError: true, + errorMessage: "ownership validation failed", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pkg := model.Package{ + RegistryType: model.RegistryTypeCargo, + Identifier: tt.packageName, + Version: tt.version, + } + + err := registries.ValidateCargo(ctx, pkg, tt.serverName) + + if tt.expectError { + assert.Error(t, err) + assert.Contains(t, err.Error(), tt.errorMessage) + } else { + assert.NoError(t, err) + } + }) + } +} + +func TestValidateCargo_RegistryBaseURLMismatch(t *testing.T) { + ctx := context.Background() + + tests := []struct { + name string + baseURL string + }{ + {name: "different host", baseURL: "https://example.com"}, + {name: "trailing slash", baseURL: "https://crates.io/"}, + {name: "http (not https)", baseURL: "http://crates.io"}, + {name: "subdomain", baseURL: "https://www.crates.io"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pkg := model.Package{ + RegistryType: model.RegistryTypeCargo, + RegistryBaseURL: tt.baseURL, + Identifier: "rust-faf-mcp", + Version: "0.2.2", + } + + err := registries.ValidateCargo(ctx, pkg, "io.github.Wolfe-Jam/rust-faf-mcp") + assert.Error(t, err) + assert.Contains(t, err.Error(), "registry type and base URL do not match") + }) + } +} + +func TestValidateCargo_RejectsMCPBOnlyFields(t *testing.T) { + ctx := context.Background() + + pkg := model.Package{ + RegistryType: model.RegistryTypeCargo, + Identifier: "rust-faf-mcp", + Version: "0.2.2", + FileSHA256: "0000000000000000000000000000000000000000000000000000000000000000", + } + + err := registries.ValidateCargo(ctx, pkg, "io.github.Wolfe-Jam/rust-faf-mcp") + assert.Error(t, err) + assert.Contains(t, err.Error(), "cargo packages must not have 'fileSha256' field") +} + +// Server names follow io.github.OWNER/REPO and may contain dots, slashes, +// hyphens, underscores, and digits. None of these get HTML-escaped during +// README rendering, so substring match against the rendered HTML is reliable. +// These tests exercise format variations against a real crate that doesn't +// declare any mcp-name (serde) — every case fails ownership, but we verify +// the failure error preserves the exact server name unchanged. +func TestValidateCargo_ServerNameFormats(t *testing.T) { + ctx := context.Background() + + tests := []struct { + name string + serverName string + }{ + {name: "canonical io.github format", serverName: "io.github.Wolfe-Jam/rust-faf-mcp"}, + {name: "multiple hyphens", serverName: "io.github.example/multi-hyphen-test-name"}, + {name: "underscore", serverName: "io.github.example/snake_case_name"}, + {name: "numeric suffix", serverName: "io.github.example/server-v2"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pkg := model.Package{ + RegistryType: model.RegistryTypeCargo, + Identifier: "serde", + Version: "1.0.219", + } + + err := registries.ValidateCargo(ctx, pkg, tt.serverName) + assert.Error(t, err) + assert.Contains(t, err.Error(), tt.serverName) + }) + } +} + +// TestValidateCargo_PositivePathMock exercises the success branch: a README +// that contains the exact mcp-name token must return no error. Uses httptest +// to stand in for crates.io, so the test is hermetic — it doesn't depend on +// any live crate publishing a specific mcp-name line or on network reachability. +// Calls the test-only ValidateCargoREADME shim so the mock URL can take the +// place of https://crates.io without tripping the exact-baseURL guard. +func TestValidateCargo_PositivePathMock(t *testing.T) { + ctx := context.Background() + const serverName = "io.github.test/positive-path" + + var mock *httptest.Server + mock = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasSuffix(r.URL.Path, "/readme") { + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(map[string]string{ + "url": mock.URL + "/static-readme", + }); err != nil { + t.Fatalf("encode meta response: %v", err) + } + return + } + // Rendered README HTML containing the mcp-name token. + fmt.Fprintf(w, " some content
mcp-name: %s
", serverName) + })) + defer mock.Close() + + pkg := model.Package{ + RegistryType: model.RegistryTypeCargo, + RegistryBaseURL: mock.URL, + Identifier: "test-crate", + Version: "0.1.0", + } + + err := registries.ValidateCargoREADME(ctx, pkg, serverName) + assert.NoError(t, err, "validator should accept a README containing the exact mcp-name token") +} + +// TestValidateCargo_LivePositivePath is the live anchor — it validates against +// rust-faf-mcp v0.3.1 on real crates.io, the first crate published with the +// mcp-name token as visible markdown (v0.3.0 used a hidden HTML comment, which +// crates.io strips during README rendering — see package-types.mdx for the +// cargo-specific gotcha). Complements TestValidateCargo_PositivePathMock: +// the mock proves the validator works in principle (hermetic, fast); the live +// anchor proves it works against the real crates.io API + static CDN pipeline. +// +// If this test ever starts failing, check (in order): +// 1. Has rust-faf-mcp v0.3.1 been yanked or replaced? +// 2. Did crates.io change its README rendering pipeline (e.g., start +// stripping markdown lines that look like email-like tokens)? +// 3. Is the test machine network-blocked from crates.io or static.crates.io? +func TestValidateCargo_LivePositivePath(t *testing.T) { + ctx := context.Background() + + pkg := model.Package{ + RegistryType: model.RegistryTypeCargo, + Identifier: "rust-faf-mcp", + Version: "0.3.1", + } + + err := registries.ValidateCargo(ctx, pkg, "io.github.Wolfe-Jam/rust-faf-mcp") + assert.NoError(t, err, "validator should accept the live rust-faf-mcp v0.3.1 crate (the canonical live anchor for cargo positive-path)") +} + +// TestValidateCargo_TransientUpstreamError exercises the 5xx-as-transient branch: +// a 502/503 from static.crates.io is upstream availability, not "crate missing", +// and the error message must signal a retryable failure rather than imply the +// crate doesn't exist (the previous behavior, flagged in PR #1207 review). +func TestValidateCargo_TransientUpstreamError(t *testing.T) { + ctx := context.Background() + + var mock *httptest.Server + mock = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasSuffix(r.URL.Path, "/readme") { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]string{ + "url": mock.URL + "/static-readme", + }) + return + } + // Simulate static.crates.io 502 — upstream blip, not a missing crate. + http.Error(w, "bad gateway", http.StatusBadGateway) + })) + defer mock.Close() + + pkg := model.Package{ + RegistryType: model.RegistryTypeCargo, + RegistryBaseURL: mock.URL, + Identifier: "test-crate", + Version: "0.1.0", + } + + err := registries.ValidateCargoREADME(ctx, pkg, "io.github.test/transient") + assert.Error(t, err) + assert.Contains(t, err.Error(), "transient") + assert.NotContains(t, err.Error(), "not found", "transient upstream errors should not be reported as 'not found'") +} + +// TestValidateCargoCombinedFixture exercises path-encoding and the full status +// matrix in one httptest fixture — the same pattern praised by @P4ST4S on +// PR #1321 for Go modules. One server dispatches on the crate identifier +// embedded in the URL path; wrong encoding routes to the fallback 500, which +// breaks the appropriate assertion. The explicit path assertion (assert.Equal +// on lastMetaPath) also catches encoding regressions directly. +func TestValidateCargoCombinedFixture(t *testing.T) { + ctx := context.Background() + const serverName = "io.github.test/combined" + + tests := []struct { + name string + crateName string + version string + metaStatus int + readmeStatus int + readmeBody string + wantErr bool + wantContains []string + wantNotContains []string + }{ + { + name: "happy_path_visible_token", + crateName: "combined-happy", + version: "0.1.0", + metaStatus: http.StatusOK, + readmeStatus: http.StatusOK, + readmeBody: fmt.Sprintf("mcp-name: %s
", serverName), + }, + { + name: "metadata_404", + crateName: "combined-meta404", + version: "0.1.0", + metaStatus: http.StatusNotFound, + wantErr: true, + wantContains: []string{"metadata fetch failed", "status: 404"}, + }, + { + name: "readme_403_s3_not_found", + crateName: "combined-readme403", + version: "0.1.0", + metaStatus: http.StatusOK, + readmeStatus: http.StatusForbidden, + wantErr: true, + wantContains: []string{"not found", "status: 403"}, + }, + { + name: "readme_502_transient", + crateName: "combined-readme502", + version: "0.1.0", + metaStatus: http.StatusOK, + readmeStatus: http.StatusBadGateway, + wantErr: true, + wantContains: []string{"transient"}, + wantNotContains: []string{"not found"}, + }, + } + + // lastMetaPath captures the metadata request path seen by the handler so + // each sub-test can assert the exact url.PathEscape-encoded form. + var lastMetaPath atomic.Value + lastMetaPath.Store("") + + var srv *httptest.Server + srv = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + for i := range tests { + tt := &tests[i] + metaPath := fmt.Sprintf("/api/v1/crates/%s/%s/readme", + url.PathEscape(tt.crateName), url.PathEscape(tt.version)) + staticPath := "/readme-static/" + url.PathEscape(tt.crateName) + + if r.URL.Path == metaPath { + lastMetaPath.Store(r.URL.Path) + if tt.metaStatus != http.StatusOK { + http.Error(w, "simulated non-200", tt.metaStatus) + return + } + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]string{"url": srv.URL + staticPath}) + return + } + if r.URL.Path == staticPath { + if tt.readmeStatus != http.StatusOK { + http.Error(w, "simulated non-200", tt.readmeStatus) + return + } + fmt.Fprint(w, tt.readmeBody) + return + } + } + http.Error(w, "unexpected path: "+r.URL.Path, http.StatusInternalServerError) + })) + defer srv.Close() + + for i := range tests { + tt := tests[i] + lastMetaPath.Store("") + t.Run(tt.name, func(t *testing.T) { + wantMetaPath := fmt.Sprintf("/api/v1/crates/%s/%s/readme", + url.PathEscape(tt.crateName), url.PathEscape(tt.version)) + + pkg := model.Package{ + RegistryType: model.RegistryTypeCargo, + RegistryBaseURL: srv.URL, + Identifier: tt.crateName, + Version: tt.version, + } + + err := registries.ValidateCargoREADME(ctx, pkg, serverName) + + // Assert encode step: the validator must have requested exactly the + // url.PathEscape-encoded path; wrong encoding hits the fallback 500. + assert.Equal(t, wantMetaPath, lastMetaPath.Load().(string), + "meta request path must be exactly the url.PathEscape-encoded form") + + if tt.wantErr { + assert.Error(t, err) + for _, want := range tt.wantContains { + assert.Contains(t, err.Error(), want) + } + for _, notWant := range tt.wantNotContains { + assert.NotContains(t, err.Error(), notWant) + } + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/internal/validators/registries/export_test.go b/internal/validators/registries/export_test.go new file mode 100644 index 0000000..89878de --- /dev/null +++ b/internal/validators/registries/export_test.go @@ -0,0 +1,9 @@ +package registries + +// ValidateCargoREADME exposes the package-private validateCargoREADME to the +// external _test package so httptest-driven tests can exercise the README-fetch +// and mcp-name token-match pipeline against a mock server, bypassing the +// exact-baseURL guard that the public ValidateCargo enforces. +// +// Intended for cargo_test.go's positive-path and transient-error tests only. +var ValidateCargoREADME = validateCargoREADME diff --git a/pkg/model/constants.go b/pkg/model/constants.go index ead176d..98a3ba1 100644 --- a/pkg/model/constants.go +++ b/pkg/model/constants.go @@ -7,10 +7,12 @@ const ( RegistryTypeOCI = "oci" RegistryTypeNuGet = "nuget" RegistryTypeMCPB = "mcpb" + RegistryTypeCargo = "cargo" ) // Registry Base URLs - supported package registry base URLs const ( + RegistryURLCrates = "https://crates.io" RegistryURLGitHub = "https://github.com" RegistryURLGitLab = "https://gitlab.com" RegistryURLNPM = "https://registry.npmjs.org" diff --git a/tools/validate-examples/main.go b/tools/validate-examples/main.go index 2f8be56..4c48ae6 100644 --- a/tools/validate-examples/main.go +++ b/tools/validate-examples/main.go @@ -33,7 +33,7 @@ func main() { func runValidation() error { // Define what we validate and how - expectedServerJSONCount := 16 + expectedServerJSONCount := 17 targets := []validationTarget{ { path: filepath.Join("docs", "reference", "server-json", "generic-server-json.md"), From 78bc7006b04bf621db69613ef52129c4c026924a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jun 2026 16:02:25 -0400 Subject: [PATCH 112/190] build(deps): bump go.opentelemetry.io/contrib/instrumentation/runtime from 0.68.0 to 0.69.0 in the opentelemetry group (#1332) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the opentelemetry group with 1 update: [go.opentelemetry.io/contrib/instrumentation/runtime](https://github.com/open-telemetry/opentelemetry-go-contrib). Updates `go.opentelemetry.io/contrib/instrumentation/runtime` from 0.68.0 to 0.69.0Release notes
Sourced from go.opentelemetry.io/contrib/instrumentation/runtime's releases.
v1.44.0/v2.5.1/v0.69.0/v0.37.1/v0.24.0/v0.19.0/v0.16.1/v0.16.0
Added
- Add
error.typeattribute tohttp.client.request.durationfor transport failures inotelhttp. (#8801)- Add examples for prometheus compatibility document. (#8716)
- Add support for
cardinality_limitsinPeriodicMetricReaderinotelconf. (#8885)- Add
Resourcemethod toSDKingo.opentelemetry.io/contrib/otelconf/xto expose the resolved SDK resource from declarative configuration. (#8913)- Add
go.opentelemetry.io/contrib/detectors/hetzner, a new resource detector for Hetzner Cloud servers, ported fromgithub.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/hetzner. Detectscloud.provider,cloud.platform,cloud.region,cloud.availability_zone,host.id, andhost.name. (#8979)Changed
- Set error field as
record.SetErrinstead of a plain attribute ingo.opentelemetry.io/contrib/bridges/otellogrus. (#8776)- Set the "error" field (e.g. created via
zap.Error) asrecord.SetErrinstead of a plain attribute ingo.opentelemetry.io/contrib/bridges/otelzap. (#8719)- Set fields implementing
errorinterface fromslogrecords asrecord.SetErrinstead of plain attributes ingo.opentelemetry.io/contrib/bridges/otelslog. (#8774)- Set emitted errors in
go.opentelemetry.io/contrib/bridges/otellogras record errors (Record.SetErr) instead ofexception.messageattributes. (#8775)Fixed
- Fix header attributes lost when using sub-spans in
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace. (#8797)- Validate
encodingconfiguration for OTLP HTTP exporters ingo.opentelemetry.io/contrib/otelconf. (#8772)- Remove the custom body wrapper from the request's body after the request is processed to allow body type comparisons with the original type in
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttpandgo.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux. (#6914)- Unknown or empty HTTP methods now report "_OTHER" instead of "GET" across all HTTP instrumentations to align with OpenTelemetry semantic conventions. (#8868)
- The default span name formatter in
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttpnow conforms to the OpenTelemetry HTTP semantic conventions for server span names. (#8871)
- The default span name is now
{method} {route}(e.g.GET /foo/{id}) when a route pattern is available, or{method}(e.g.GET) otherwise.Removed
- Remove the deprecated
WithSpanOptionsoption ingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc. (#8991)What's Changed
- otelconf: validate encoding configuration for OTLP HTTP exporters by
@sonalgaud12in open-telemetry/opentelemetry-go-contrib#8772- fix(deps): update module github.com/aws/aws-sdk-go-v2/service/s3 to v1.99.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8780- chore(deps): update prom/prometheus docker tag to v3.11.1 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8779- otellogrus: Set error field as
record.SetErrby@sonalgaud12in open-telemetry/opentelemetry-go-contrib#8778- chore(deps): update module golang.org/x/sys to v0.43.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8783- chore(deps): update golang.org/x/telemetry digest to 93c7c8a by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8786- chore(deps): update module github.com/mattn/go-isatty to v0.0.21 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8787- chore(deps): update module github.com/mattn/go-runewidth to v0.0.23 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8788- chore(deps): update golang.org/x by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8791- chore(deps): update actions/github-script action to v9 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8795- fix(deps): update golang.org/x by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8794- otelzap: set error field as record.SetErr by
@iblancasain open-telemetry/opentelemetry-go-contrib#8719- fix(deps): update golang.org/x to 746e56f by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8796- chore(deps): update module golang.org/x/arch to v0.26.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8798- Check if otelgrpc metrics are enabled by
@dashpolein open-telemetry/opentelemetry-go-contrib#8792- chore(deps): update actions/upload-artifact action to v7.0.1 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8800- Check instrument enabled in deprecatedruntime by
@dashpolein open-telemetry/opentelemetry-go-contrib#8793- chore(deps): update module github.com/ashanbrown/forbidigo/v2 to v2.3.1 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8804- chore(deps): update module github.com/ashanbrown/makezero/v2 to v2.2.1 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8802- chore(deps): update module github.com/manuelarte/funcorder to v0.6.0 by
@renovate[bot] in open-telemetry/opentelemetry-go-contrib#8803... (truncated)
Changelog
Sourced from go.opentelemetry.io/contrib/instrumentation/runtime's changelog.
[1.44.0/2.5.1/0.69.0/0.37.1/0.24.0/0.19.0/0.16.1/0.16.0] - 2026-05-28
Added
- Add
error.typeattribute tohttp.client.request.durationfor transport failures inotelhttp. (#8801)- Add examples for prometheus compatibility document. (#8716)
- Add support for
cardinality_limitsinPeriodicMetricReaderinotelconf. (#8885)- Add
Resourcemethod toSDKingo.opentelemetry.io/contrib/otelconf/xto expose the resolved SDK resource from declarative configuration. (#8913)- Add
go.opentelemetry.io/contrib/detectors/hetzner, a new resource detector for Hetzner Cloud servers, ported fromgithub.com/open-telemetry/opentelemetry-collector-contrib/processor/resourcedetectionprocessor/internal/hetzner. Detectscloud.provider,cloud.platform,cloud.region,cloud.availability_zone,host.id, andhost.name. (#8979)Changed
- Set error field as
record.SetErrinstead of a plain attribute ingo.opentelemetry.io/contrib/bridges/otellogrus. (#8776)- Set the "error" field (e.g. created via
zap.Error) asrecord.SetErrinstead of a plain attribute ingo.opentelemetry.io/contrib/bridges/otelzap. (#8719)- Set fields implementing
errorinterface fromslogrecords asrecord.SetErrinstead of plain attributes ingo.opentelemetry.io/contrib/bridges/otelslog. (#8774)- Set emitted errors in
go.opentelemetry.io/contrib/bridges/otellogras record errors (Record.SetErr) instead ofexception.messageattributes. (#8775)Fixed
- Fix header attributes lost when using sub-spans in
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace. (#8797)- Validate
encodingconfiguration for OTLP HTTP exporters ingo.opentelemetry.io/contrib/otelconf. (#8772)- Remove the custom body wrapper from the request's body after the request is processed to allow body type comparisons with the original type in
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttpandgo.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux. (#6914)- Unknown or empty HTTP methods now report "_OTHER" instead of "GET" across all HTTP instrumentations to align with OpenTelemetry semantic conventions. (#8868)
- The default span name formatter in
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttpnow conforms to the OpenTelemetry HTTP semantic conventions for server span names. (#8871)
- The default span name is now
{method} {route}(e.g.GET /foo/{id}) when a route pattern is available, or{method}(e.g.GET) otherwise.Removed
- Remove the deprecated
WithSpanOptionsoption ingo.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc. (#8991)Commits
03b2bcdRelease v1.44.0/v2.5.1/v0.69.0/v0.37.1/v0.24.0/v0.19.0/v0.16.1/v0.16.0 (#9033)80c46d4chore(deps): update module github.com/alecthomas/chroma/v2 to v2.26.0 (#9034)51f2921fix(deps): update module github.com/hetznercloud/hcloud-go/v2 to v2.41.2 (#9026)db82162fix(deps): update aws-sdk-go-v2 monorepo (#9031)5a3e533fix(deps): update module github.com/aws/smithy-go to v1.26.0 (#9032)c67843cotelhttp: Remove custom wrapper after handling request (#6914)c0a4135docs(otelhttptrace): add performance guidance for WithoutSubSpans (#8785)a51a867otelconf: implement cardinality_limits support in PeriodicMetricReader (#8885)dead6e5chore(deps): update module go.yaml.in/yaml/v2 to v2.4.4 (#8994)979ce18chore(deps): update module github.com/jgautheron/goconst to v1.10.2 (#9030)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fd152fc..82afd5b 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/cors v1.11.1 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/stretchr/testify v1.11.1 - go.opentelemetry.io/contrib/instrumentation/runtime v0.68.0 + go.opentelemetry.io/contrib/instrumentation/runtime v0.69.0 go.opentelemetry.io/otel v1.44.0 go.opentelemetry.io/otel/exporters/prometheus v0.66.0 go.opentelemetry.io/otel/metric v1.44.0 diff --git a/go.sum b/go.sum index d738e87..1898d3a 100644 --- a/go.sum +++ b/go.sum @@ -140,8 +140,8 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= 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/contrib/instrumentation/runtime v0.68.0 h1:jhVIQEprwUTV+KfzzliLidclhoTOoHTgdz96kAyR8mU= -go.opentelemetry.io/contrib/instrumentation/runtime v0.68.0/go.mod h1:4HsdbLUbernaTnA8CNaNE+1g026SciXb3juRYe3l8EY= +go.opentelemetry.io/contrib/instrumentation/runtime v0.69.0 h1:MtkMsuRo3zEXTTMALfyrszwCDZTkB6wolyPjbwFAdq0= +go.opentelemetry.io/contrib/instrumentation/runtime v0.69.0/go.mod h1:FYTxnpsm+UPD0erZNq20GvnM8T2YQHiHtT2vokdpoac= go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel/exporters/prometheus v0.66.0 h1:vkrK8PAznv2NKt2r+kdu252ccGzkEqLc2aSXbQIALYQ= From a1ffe33fba05835bb20375c3f1b439b68459bb1c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jun 2026 16:02:45 -0400 Subject: [PATCH 113/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.243.0 to 3.244.0 in /deploy (#1333) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.243.0 to 3.244.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.244.0
3.244.0 (2026-05-28)
Bug Fixes
- [cli/do] Fix top level flags like
--logtostderrbeing recognized when usingpulumi do#23355- [cli/install] Distinguish multiple packages with the same plugin
- [engine] Fix snapshot integrity issue with
up --refresh- [engine] Forward all provider errors to error hooks for retry #23347
- [engine] Trace cancel RPCs sent to plugins during shutdown as children of the active operation instead of emitting separate root spans #23362
- [sdk/python] Merge requirements.txt into pyproject.toml when using uv without a project section #23340
Changelog
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.244.0 (2026-05-28)
Bug Fixes
- [cli/do] Fix top level flags like
--logtostderrbeing recognized when usingpulumi do#23355- [cli/install] Distinguish multiple packages with the same plugin
- [engine] Fix snapshot integrity issue with
up --refresh- [engine] Forward all provider errors to error hooks for retry #23347
- [engine] Trace cancel RPCs sent to plugins during shutdown as children of the active operation instead of emitting separate root spans #23362
- [sdk/python] Merge requirements.txt into pyproject.toml when using uv without a project section #23340
Commits
fc6566bActually deprecateConfigureRequest.variables(#23367)6a91079Fix Cancel/Shutdown methods to have the right tracing spans (#23362)74734c3Fix do and root flags (#23355)8deae80Tighten component dependency tests (#23353)e6a7bccAddruntimefield to policy packs (#23319)ceeab7dintroduce otel logging exporter (#22609)a7d5f52Update dependency tmp to v0.2.6 [SECURITY] (#23354)6b81137s/go-change/changie/g (#23316)51fd46bFix Mise troubles withprotoc-gen-js/grpc-tools(#23350)7b59639Retry all errors (#23347)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 2 +- deploy/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index f2e8b8b..6fc92d3 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1 - github.com/pulumi/pulumi/sdk/v3 v3.243.0 + github.com/pulumi/pulumi/sdk/v3 v3.244.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/deploy/go.sum b/deploy/go.sum index 8b29f96..dc36d65 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -189,8 +189,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1 h1:Hg9RK9zqIU9kFbD5KeiON06gPP7cLgS68jvsgMBmPgw= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.243.0 h1:pZaMx58nXrdh4XB0cgTlHnL3EMy3/JQwuin3aDuWyRM= -github.com/pulumi/pulumi/sdk/v3 v3.243.0/go.mod h1:BPWWuYPXcPH5YbXGoyy9Rrfa+evrh6IdM51AjDhcDpM= +github.com/pulumi/pulumi/sdk/v3 v3.244.0 h1:oyQ9bwDE58wrQOqS70JrojJSlNoLcVhVcQgK4yusgcg= +github.com/pulumi/pulumi/sdk/v3 v3.244.0/go.mod h1:BPWWuYPXcPH5YbXGoyy9Rrfa+evrh6IdM51AjDhcDpM= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From 227621f1d0e36db0acd90a89fd77ad4d469a4bf6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 4 Jun 2026 16:03:35 -0400 Subject: [PATCH 114/190] build(deps): bump github.com/jackc/pgx/v5 from 5.9.2 to 5.10.0 (#1334) Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.9.2 to 5.10.0. Changelog
Sourced from github.com/jackc/pgx/v5's changelog.
5.10.0 (June 3, 2026)
This release includes a significant amount of hardening against malicious or compromised PostgreSQL servers, contributed by Sean Chittenden at CrowdStrike, Inc. This work bounds binary decoders against attacker-controlled message sizes, caps server-supplied SCRAM iteration counts, adds
require_authto restrict which authentication methods a server may use (mitigating downgrade attacks undersslmode=prefer), and ensures cancellation requests are sent over TLS when the original connection used TLS.Features
- Add
require_authto restrict accepted server authentication methods (Sean Chittenden at CrowdStrike, Inc.)- Add
ParseConfigOptions.ConnStringAllowedKeysto restrict allowed connection string keys (Sean Chittenden at CrowdStrike, Inc.)- Add
StructArgsandStrictStructArgsfor@-named queries (Tubelight30)- Add
ErrConnClosedsentinel error and unwrap it fromconnLockError(Charlie Tonneslan)- pgxpool: check if connection is expired before acquire (arthurdotwork)
Security Hardening
- Encrypt
CancelRequestconnection when the primary connection used TLS (Sean Chittenden at CrowdStrike, Inc.)- Cap server-supplied SCRAM iteration count (Sean Chittenden at CrowdStrike, Inc.)
- Default Frontend max message body length to ~1 GiB (Sean Chittenden at CrowdStrike, Inc.)
- Bound hstore binary decode against malicious server input (Sean Chittenden at CrowdStrike, Inc.)
- Bound array binary decode element length against remaining message bytes (Sean Chittenden at CrowdStrike, Inc.)
- Bound array element count against remaining message bytes (Sean Chittenden at CrowdStrike, Inc.)
- Bound range, multirange, and tsvector binary decoders (Sean Chittenden at CrowdStrike, Inc.)
- Document secure connection configuration (Sean Chittenden at CrowdStrike, Inc.)
- Fix panic on malformed geometric text; return an error instead (MaIII)
Fixes
- Fix scanning
"char"(OID 18) into*stringin binary format (luongs3)- Fix handling of typed-nil
driver.Valuerin array and composite codecs (Donncha Fahy)- Fix
CopyData.Datahex decoding inUnmarshalJSON(Charlie Tonneslan)- Fix data race when context is cancelled during connect
- Fix
parseKeywordValueSettingsrejecting trailing whitespace (alliasgher)- pgconn: preserve full error chain in
normalizeTimeoutError(Charlie Tonneslan)- pgconn: use a fresh context for the fallback connection in
connectPreferred(Charlie Tonneslan)- pgxpool: fix
MaxLifetimeDestroyCountand ping order for acquire-time expiry check- Add missing error check of
rows.Errto load types (Jen Altavilla)Commits
7293fb1Update changelog for v5.10.01ade285pgconn: document secure connection configurationb4d6d4dpgtype: bound range, multirange, and tsvector binary decoders0639b37pgconn: add ParseConfigOptions.ConnStringAllowedKeysb28e65bpgtype: bound array element count against remaining message bytescd1f389pgtype: bound array binary decode element length against remaining bytesff27b5bpgtype: bound hstore binary decode against malicious server inputa6002e1pgproto3: default Frontend max message body length to ~1 GiB44f6173pgconn: cap server-supplied SCRAM iteration count1a976f7pgconn: add require_auth to restrict accepted server auth methods- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 82afd5b..1dbf670 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/danielgtaylor/huma/v2 v2.38.0 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/go-containerregistry v0.21.6 - github.com/jackc/pgx/v5 v5.9.2 + github.com/jackc/pgx/v5 v5.10.0 github.com/prometheus/client_golang v1.23.2 github.com/rs/cors v1.11.1 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 diff --git a/go.sum b/go.sum index 1898d3a..af66f73 100644 --- a/go.sum +++ b/go.sum @@ -83,8 +83,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.9.2 h1:3ZhOzMWnR4yJ+RW1XImIPsD1aNSz4T4fyP7zlQb56hw= -github.com/jackc/pgx/v5 v5.9.2/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= +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/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= From 7a6d1bc30a538a4a792e1ccab25680a247acf472 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Thu, 4 Jun 2026 17:34:54 -0400 Subject: [PATCH 115/190] fix(cargo): harden README fetch, clarify status handling, strengthen tests (#1330) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to #1207, addressing items from the cargo validator review. **Scoped to cargo + shared helpers — no behavior change for existing npm/pypi/nuget/oci/mcpb publishers.** Safe to merge and promote. ### Changes **SSRF hardening of the two-call README retrieval** - Pin the step-2 README URL to an allowed host (`static.crates.io` in prod; the base host under test) *before* fetching, so a metadata response can't steer the validator at an internal/attacker host. - `CheckRedirect` policy pins every redirect hop to the same allowlist (the initial URL being pinned isn't enough if an upstream 3xx is followed). - Cap the README body with `io.LimitReader` (5 MiB). > Not publisher-exploitable today (the URL comes from crates.io), so this is defense-in-depth — but it makes the "host is pinned" guarantee hold in code rather than rely on crates.io's behavior. **Clearer status handling** (previously any non-5xx/non-200 collapsed to "not found") - **429** → reported as transient/retryable, at both the metadata and README steps. - **403** → disambiguated via the crate-version endpoint: genuinely-missing stays "not found"; *exists-but-no-README* gets an actionable "add a README with `mcp-name` and republish" message (mirrors the NuGet validator). This continues the 5xx-vs-403 diagnostic split @P4ST4S started in the #1207 review — thanks! **Shared `containsMCPNameToken` helper** Boundary-anchored ownership-token match (prevents prefix confusion, e.g. a README declaring `io.github.acme/widget-pro` satisfying a claim for `io.github.acme/widget`), used here **by the cargo validator only**. Adopting it in PyPI/NuGet is a separate follow-up because it's a behavior change for those already-live registries. **Tests & docs** Hermetic positive `ServerNameFormats`; combined fixture gains a version-existence endpoint + cases for 403-missing vs 403-no-README, 429, and prefix-confusion rejection; new foreign-README-host (SSRF) test; internal test for the helper. Docs: list `crates.io` in the registry-requirements list + the `Package` model doc. ### Testing `go build`, `go vet`, full `./internal/validators/...` suite (incl. live cargo positive), `make check-schema`, `validate-examples` all pass. No new `golangci-lint` findings. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) --- .../official-registry-requirements.md | 1 + internal/validators/registries/cargo.go | 183 +++++++++++++++--- internal/validators/registries/cargo_test.go | 143 +++++++++++--- internal/validators/registries/mcpname.go | 53 +++++ .../registries/mcpname_internal_test.go | 35 ++++ pkg/model/types.go | 7 +- 6 files changed, 370 insertions(+), 52 deletions(-) create mode 100644 internal/validators/registries/mcpname.go create mode 100644 internal/validators/registries/mcpname_internal_test.go diff --git a/docs/reference/server-json/official-registry-requirements.md b/docs/reference/server-json/official-registry-requirements.md index e03b659..886aee0 100644 --- a/docs/reference/server-json/official-registry-requirements.md +++ b/docs/reference/server-json/official-registry-requirements.md @@ -33,6 +33,7 @@ Only trusted public registries are supported. Private registries and alternative - **NPM**: `https://registry.npmjs.org` only - **PyPI**: `https://pypi.org` only - **NuGet**: `https://api.nuget.org/v3/index.json` only +- **Cargo**: `https://crates.io` only - **Docker/OCI**: - Docker Hub (`docker.io`) - GitHub Container Registry (`ghcr.io`) diff --git a/internal/validators/registries/cargo.go b/internal/validators/registries/cargo.go index 18f7c0f..d90af77 100644 --- a/internal/validators/registries/cargo.go +++ b/internal/validators/registries/cargo.go @@ -8,7 +8,6 @@ import ( "io" "net/http" "net/url" - "strings" "time" "github.com/modelcontextprotocol/registry/pkg/model" @@ -19,6 +18,19 @@ var ( ErrMissingVersionForCargo = errors.New("package version is required for Cargo packages") ) +// cargoUserAgent identifies the validator to crates.io. crates.io's crawler +// policy expects a non-generic User-Agent with a contact URL; a bare UA may be +// rate-limited or blocked. (Distinct from the package-level userAgent constant +// used by the NuGet validator, which has no contact URL.) +const cargoUserAgent = "MCP-Registry-Validator/1.0 (https://registry.modelcontextprotocol.io)" + +// cargoStaticHost is the CDN host crates.io serves rendered READMEs from. +const cargoStaticHost = "static.crates.io" + +// maxCargoReadmeBytes caps how much of a rendered README we buffer, so a hostile +// or oversized response cannot exhaust validator memory. +const maxCargoReadmeBytes = 5 << 20 // 5 MiB + // CargoReadmeMetaResponse is the structure returned by the crates.io readme metadata endpoint. // // With `Accept: application/json`, crates.io's /api/v1/crates/{name}/{version}/readme @@ -74,14 +86,134 @@ func ValidateCargo(ctx context.Context, pkg model.Package, serverName string) er return validateCargoREADME(ctx, pkg, serverName) } +// cargoAllowedHosts returns the set of hosts the validator is permitted to talk +// to for a given base URL. For the real crates.io base this is crates.io (the API) +// plus static.crates.io (the rendered-README CDN). For any other base — only the +// httptest-driven tests, since the public ValidateCargo pins the base to +// crates.io — it is the base host itself, so mock servers keep working. +// +// This is the allowlist enforced both on the README pointer (step 2 URL) and on +// every redirect hop, so a metadata response or redirect cannot steer the +// validator at an internal or attacker-chosen host (SSRF). +func cargoAllowedHosts(baseURL string) map[string]struct{} { + hosts := map[string]struct{}{} + if u, err := url.Parse(baseURL); err == nil && u.Hostname() != "" { + hosts[u.Hostname()] = struct{}{} + } + if baseURL == model.RegistryURLCrates { + hosts[cargoStaticHost] = struct{}{} + } + return hosts +} + +// newCargoHTTPClient builds the client used for all crates.io calls. The +// CheckRedirect policy pins every redirect hop to allowedHosts, so even though +// the initial URL is host-pinned, an upstream 3xx cannot redirect the validator +// to an unexpected host. +func newCargoHTTPClient(allowedHosts map[string]struct{}) *http.Client { + return &http.Client{ + Timeout: 10 * time.Second, + CheckRedirect: func(req *http.Request, via []*http.Request) error { + if _, ok := allowedHosts[req.URL.Hostname()]; !ok { + return fmt.Errorf("refusing redirect to unexpected host %q", req.URL.Hostname()) + } + if len(via) >= 10 { + return errors.New("stopped after 10 redirects") + } + return nil + }, + } +} + +// cargoVersionExists checks whether a specific crate version exists on crates.io, +// used to disambiguate a 403 from the README CDN. static.crates.io (S3) returns +// 403 both for a genuinely-missing crate/version AND for a crate that exists but +// has no rendered README, so a 403 alone cannot tell a publisher which it is. +// +// Returns (exists, determined): determined is false if the existence endpoint +// itself was unreachable or returned an unexpected status, in which case the +// caller should fall back to a generic message rather than assert existence. +func cargoVersionExists(ctx context.Context, client *http.Client, baseURL, identifier, version string) (exists, determined bool) { + versionURL := fmt.Sprintf("%s/api/v1/crates/%s/%s", + baseURL, url.PathEscape(identifier), url.PathEscape(version)) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, versionURL, nil) + if err != nil { + return false, false + } + req.Header.Set("User-Agent", cargoUserAgent) + req.Header.Set("Accept", "application/json") + + resp, err := client.Do(req) + if err != nil { + return false, false + } + defer resp.Body.Close() + + switch resp.StatusCode { + case http.StatusOK: + return true, true + case http.StatusNotFound: + return false, true + default: + return false, false + } +} + +// cargoMetadataStatusError maps a non-200 status from the metadata endpoint to a +// caller-actionable error, distinguishing transient upstream conditions (429, +// 5xx) from a genuine fetch failure. +func cargoMetadataStatusError(identifier string, status int) error { + switch { + case status == http.StatusTooManyRequests: + return fmt.Errorf("crates.io rate-limited the metadata request for cargo package '%s' (status: 429) — likely transient, retry later", identifier) + case status >= 500 && status < 600: + return fmt.Errorf("crates.io upstream error fetching metadata for cargo package '%s' (status: %d) — likely transient, retry later", identifier, status) + default: + return fmt.Errorf("cargo package '%s' metadata fetch failed (status: %d)", identifier, status) + } +} + +// cargoReadmeStatusError maps a non-200 status from the README CDN to a +// caller-actionable error. 429/5xx are transient; 403 is disambiguated (see +// cargoReadme403Error) because static.crates.io returns it both for a missing +// crate/version and for a crate that has no rendered README. +func cargoReadmeStatusError(ctx context.Context, client *http.Client, pkg model.Package, serverName string, status int) error { + switch { + case status == http.StatusTooManyRequests: + return fmt.Errorf("crates.io rate-limited the README fetch for cargo package '%s' version '%s' (status: 429) — likely transient, retry later", pkg.Identifier, pkg.Version) + case status >= 500 && status < 600: + return fmt.Errorf("crates.io upstream error fetching README for cargo package '%s' version '%s' (status: %d) — likely transient, retry later", pkg.Identifier, pkg.Version, status) + case status == http.StatusForbidden: + return cargoReadme403Error(ctx, client, pkg, serverName) + default: + return fmt.Errorf("cargo package '%s' version '%s' README fetch failed (status: %d)", pkg.Identifier, pkg.Version, status) + } +} + +// cargoReadme403Error disambiguates a 403 from static.crates.io (S3's default +// for a missing key): a genuinely-missing crate/version versus a crate that +// exists but has no rendered README. It probes the crate-version metadata +// endpoint so the publisher gets an actionable message rather than a blanket +// "not found". +func cargoReadme403Error(ctx context.Context, client *http.Client, pkg model.Package, serverName string) error { + exists, determined := cargoVersionExists(ctx, client, pkg.RegistryBaseURL, pkg.Identifier, pkg.Version) + switch { + case determined && exists: + return fmt.Errorf("cargo package '%s' version '%s' exists on crates.io but has no rendered README. Add a README containing 'mcp-name: %s' and publish a new version", pkg.Identifier, pkg.Version, serverName) + case determined && !exists: + return fmt.Errorf("cargo package '%s' version '%s' not found on crates.io", pkg.Identifier, pkg.Version) + default: + return fmt.Errorf("cargo package '%s' version '%s' not found on crates.io (status: 403)", pkg.Identifier, pkg.Version) + } +} + // validateCargoREADME performs the two-call README fetch and the mcp-name token // check. It is split out from ValidateCargo so that httptest-based tests can // drive the HTTP pipeline against a mock server (exposed via export_test.go), // bypassing the exact-baseURL guard that ValidateCargo enforces for callers. func validateCargoREADME(ctx context.Context, pkg model.Package, serverName string) error { - client := &http.Client{Timeout: 10 * time.Second} - // crates.io's crawler policy expects a non-generic User-Agent identifying the source. - userAgent := "MCP-Registry-Validator/1.0 (https://registry.modelcontextprotocol.io)" + allowedHosts := cargoAllowedHosts(pkg.RegistryBaseURL) + client := newCargoHTTPClient(allowedHosts) // Step 1: fetch the README pointer from the documented API endpoint. metaURL := fmt.Sprintf("%s/api/v1/crates/%s/%s/readme", @@ -93,7 +225,7 @@ func validateCargoREADME(ctx context.Context, pkg model.Package, serverName stri if err != nil { return fmt.Errorf("failed to create crates.io metadata request: %w", err) } - metaReq.Header.Set("User-Agent", userAgent) + metaReq.Header.Set("User-Agent", cargoUserAgent) metaReq.Header.Set("Accept", "application/json") metaResp, err := client.Do(metaReq) @@ -103,11 +235,7 @@ func validateCargoREADME(ctx context.Context, pkg model.Package, serverName stri defer metaResp.Body.Close() if metaResp.StatusCode != http.StatusOK { - // 5xx from the metadata endpoint is upstream availability, not a missing crate. - if metaResp.StatusCode >= 500 && metaResp.StatusCode < 600 { - return fmt.Errorf("crates.io upstream error fetching metadata for cargo package '%s' (status: %d) — likely transient, retry later", pkg.Identifier, metaResp.StatusCode) - } - return fmt.Errorf("cargo package '%s' metadata fetch failed (status: %d)", pkg.Identifier, metaResp.StatusCode) + return cargoMetadataStatusError(pkg.Identifier, metaResp.StatusCode) } var meta CargoReadmeMetaResponse @@ -118,12 +246,22 @@ func validateCargoREADME(ctx context.Context, pkg model.Package, serverName stri return fmt.Errorf("cargo package '%s' metadata response missing 'url' field", pkg.Identifier) } - // Step 2: fetch the rendered README from the URL the API gave us. + // Pin the README pointer to an allowed host before fetching it, so a metadata + // response cannot steer the validator at an internal or attacker-chosen host. + readmeParsed, err := url.Parse(meta.URL) + if err != nil || readmeParsed.Hostname() == "" { + return fmt.Errorf("cargo package '%s': crates.io returned an unparseable README URL", pkg.Identifier) + } + if _, ok := allowedHosts[readmeParsed.Hostname()]; !ok { + return fmt.Errorf("cargo package '%s': crates.io returned a README URL on unexpected host %q — refusing to fetch", pkg.Identifier, readmeParsed.Hostname()) + } + + // Step 2: fetch the rendered README from the (now host-validated) URL. readmeReq, err := http.NewRequestWithContext(ctx, http.MethodGet, meta.URL, nil) if err != nil { return fmt.Errorf("failed to create crates.io readme request: %w", err) } - readmeReq.Header.Set("User-Agent", userAgent) + readmeReq.Header.Set("User-Agent", cargoUserAgent) readmeReq.Header.Set("Accept", "text/html") readmeResp, err := client.Do(readmeReq) @@ -132,27 +270,20 @@ func validateCargoREADME(ctx context.Context, pkg model.Package, serverName stri } defer readmeResp.Body.Close() - // Missing crates and missing versions surface as 403 from static.crates.io - // (S3's default for missing keys), not 404. 5xx from the CDN is upstream - // availability — surface it as transient so callers can distinguish retryable - // failures from genuinely missing crates. if readmeResp.StatusCode != http.StatusOK { - if readmeResp.StatusCode >= 500 && readmeResp.StatusCode < 600 { - return fmt.Errorf("crates.io upstream error fetching README for cargo package '%s' version '%s' (status: %d) — likely transient, retry later", pkg.Identifier, pkg.Version, readmeResp.StatusCode) - } - return fmt.Errorf("cargo package '%s' version '%s' not found on crates.io (status: %d)", pkg.Identifier, pkg.Version, readmeResp.StatusCode) + return cargoReadmeStatusError(ctx, client, pkg, serverName, readmeResp.StatusCode) } - body, err := io.ReadAll(readmeResp.Body) + body, err := io.ReadAll(io.LimitReader(readmeResp.Body, maxCargoReadmeBytes)) if err != nil { return fmt.Errorf("failed to read rendered README: %w", err) } - // Search for the mcp-name: token. The token contains no characters - // that get HTML-escaped during README rendering (no <, >, &, ", '), so a direct - // substring match against the rendered HTML is reliable. - mcpNamePattern := "mcp-name: " + serverName - if strings.Contains(string(body), mcpNamePattern) { + // Search for the mcp-name: ownership token. The token contains no + // characters that get HTML-escaped during README rendering (no <, >, &, ", '), + // so matching against the rendered HTML is reliable; containsMCPNameToken + // additionally requires a trailing boundary to avoid prefix confusion. + if containsMCPNameToken(string(body), serverName) { return nil } diff --git a/internal/validators/registries/cargo_test.go b/internal/validators/registries/cargo_test.go index e06d099..d2c8128 100644 --- a/internal/validators/registries/cargo_test.go +++ b/internal/validators/registries/cargo_test.go @@ -151,10 +151,11 @@ func TestValidateCargo_RejectsMCPBOnlyFields(t *testing.T) { // Server names follow io.github.OWNER/REPO and may contain dots, slashes, // hyphens, underscores, and digits. None of these get HTML-escaped during -// README rendering, so substring match against the rendered HTML is reliable. -// These tests exercise format variations against a real crate that doesn't -// declare any mcp-name (serde) — every case fails ownership, but we verify -// the failure error preserves the exact server name unchanged. +// README rendering, so a boundary-anchored match against the rendered HTML is +// reliable. This is a hermetic POSITIVE test: each format variation is placed in +// a mock README as the exact mcp-name token and must validate successfully, so +// it actually exercises the match (the earlier version used a token-less live +// crate, where every case failed and the assertion was satisfied trivially). func TestValidateCargo_ServerNameFormats(t *testing.T) { ctx := context.Background() @@ -166,19 +167,33 @@ func TestValidateCargo_ServerNameFormats(t *testing.T) { {name: "multiple hyphens", serverName: "io.github.example/multi-hyphen-test-name"}, {name: "underscore", serverName: "io.github.example/snake_case_name"}, {name: "numeric suffix", serverName: "io.github.example/server-v2"}, + {name: "dotted name segment", serverName: "io.github.example/group.tool"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + serverName := tt.serverName + var mock *httptest.Server + mock = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if strings.HasSuffix(r.URL.Path, "/readme") { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]string{"url": mock.URL + "/static-readme"}) + return + } + // Token on its own line; the trailing newline is the boundary. + fmt.Fprintf(w, "\nmcp-name: %s\n", serverName) + })) + defer mock.Close() + pkg := model.Package{ - RegistryType: model.RegistryTypeCargo, - Identifier: "serde", - Version: "1.0.219", + RegistryType: model.RegistryTypeCargo, + RegistryBaseURL: mock.URL, + Identifier: "fmt-crate", + Version: "0.1.0", } - err := registries.ValidateCargo(ctx, pkg, tt.serverName) - assert.Error(t, err) - assert.Contains(t, err.Error(), tt.serverName) + err := registries.ValidateCargoREADME(ctx, pkg, serverName) + assert.NoError(t, err, "server name %q should validate when present as an exact mcp-name token", serverName) }) } } @@ -197,11 +212,10 @@ func TestValidateCargo_PositivePathMock(t *testing.T) { mock = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if strings.HasSuffix(r.URL.Path, "/readme") { w.Header().Set("Content-Type", "application/json") - if err := json.NewEncoder(w).Encode(map[string]string{ - "url": mock.URL + "/static-readme", - }); err != nil { - t.Fatalf("encode meta response: %v", err) - } + // Encode of a static map cannot fail; ignore the error rather than + // calling t.Fatalf from this (server) goroutine, which is not the test + // goroutine and would truncate the response instead of failing cleanly. + _ = json.NewEncoder(w).Encode(map[string]string{"url": mock.URL + "/static-readme"}) return } // Rendered README HTML containing the mcp-name token. @@ -280,6 +294,34 @@ func TestValidateCargo_TransientUpstreamError(t *testing.T) { assert.NotContains(t, err.Error(), "not found", "transient upstream errors should not be reported as 'not found'") } +// TestValidateCargo_RejectsForeignReadmeHost is the SSRF guard: the README +// pointer returned by the metadata endpoint must be on an allowed host. Here the +// (mock) metadata endpoint points the README at an unrelated host; the validator +// must refuse to fetch it rather than follow the pointer anywhere crates.io names. +// The ".invalid" host never resolves, so a regression that dropped the host check +// would fail to connect rather than silently pass — but the assertion targets the +// explicit "unexpected host" refusal, which happens before any fetch. +func TestValidateCargo_RejectsForeignReadmeHost(t *testing.T) { + ctx := context.Background() + + mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]string{"url": "http://internal.invalid/secret-readme"}) + })) + defer mock.Close() + + pkg := model.Package{ + RegistryType: model.RegistryTypeCargo, + RegistryBaseURL: mock.URL, + Identifier: "evil-crate", + Version: "0.1.0", + } + + err := registries.ValidateCargoREADME(ctx, pkg, "io.github.test/evil") + assert.Error(t, err) + assert.Contains(t, err.Error(), "unexpected host", "a README URL on a foreign host must be refused (SSRF guard)") +} + // TestValidateCargoCombinedFixture exercises path-encoding and the full status // matrix in one httptest fixture — the same pattern praised by @P4ST4S on // PR #1321 for Go modules. One server dispatches on the crate identifier @@ -297,6 +339,7 @@ func TestValidateCargoCombinedFixture(t *testing.T) { metaStatus int readmeStatus int readmeBody string + versionExists bool // response for the /api/v1/crates/{n}/{v} existence probe (403 disambiguation) wantErr bool wantContains []string wantNotContains []string @@ -310,7 +353,11 @@ func TestValidateCargoCombinedFixture(t *testing.T) { readmeBody: fmt.Sprintf(" mcp-name: %s
", serverName), }, { - name: "metadata_404", + // Defensive branch: crates.io's metadata endpoint returns 200 (with a + // CDN url) even for missing crates, so it does NOT 404 in practice for a + // missing crate — the real missing-crate path is readme_403_missing below. + // This case only covers what we'd report if the API ever did 404. + name: "metadata_404_defensive", crateName: "combined-meta404", version: "0.1.0", metaStatus: http.StatusNotFound, @@ -318,13 +365,39 @@ func TestValidateCargoCombinedFixture(t *testing.T) { wantContains: []string{"metadata fetch failed", "status: 404"}, }, { - name: "readme_403_s3_not_found", - crateName: "combined-readme403", - version: "0.1.0", - metaStatus: http.StatusOK, - readmeStatus: http.StatusForbidden, - wantErr: true, - wantContains: []string{"not found", "status: 403"}, + // Real missing-crate/version path: CDN 403 + existence probe 404. + name: "readme_403_missing", + crateName: "combined-readme403-missing", + version: "0.1.0", + metaStatus: http.StatusOK, + readmeStatus: http.StatusForbidden, + versionExists: false, + wantErr: true, + wantContains: []string{"not found"}, + wantNotContains: []string{"has no rendered README"}, + }, + { + // Crate/version exists but has no rendered README: CDN 403 + existence + // probe 200. Must NOT be reported as "not found". + name: "readme_403_no_readme", + crateName: "combined-readme403-noreadme", + version: "0.1.0", + metaStatus: http.StatusOK, + readmeStatus: http.StatusForbidden, + versionExists: true, + wantErr: true, + wantContains: []string{"has no rendered README"}, + wantNotContains: []string{"not found"}, + }, + { + name: "readme_429_transient", + crateName: "combined-readme429", + version: "0.1.0", + metaStatus: http.StatusOK, + readmeStatus: http.StatusTooManyRequests, + wantErr: true, + wantContains: []string{"transient"}, + wantNotContains: []string{"not found"}, }, { name: "readme_502_transient", @@ -336,6 +409,18 @@ func TestValidateCargoCombinedFixture(t *testing.T) { wantContains: []string{"transient"}, wantNotContains: []string{"not found"}, }, + { + // Prefix confusion: README declares a LONGER name; a claim for the + // shorter serverName must be rejected by the boundary-anchored match. + name: "prefix_confusion_rejected", + crateName: "combined-prefix", + version: "0.1.0", + metaStatus: http.StatusOK, + readmeStatus: http.StatusOK, + readmeBody: fmt.Sprintf("mcp-name: %s-extended
", serverName), + wantErr: true, + wantContains: []string{"ownership validation failed"}, + }, } // lastMetaPath captures the metadata request path seen by the handler so @@ -349,6 +434,8 @@ func TestValidateCargoCombinedFixture(t *testing.T) { tt := &tests[i] metaPath := fmt.Sprintf("/api/v1/crates/%s/%s/readme", url.PathEscape(tt.crateName), url.PathEscape(tt.version)) + versionPath := fmt.Sprintf("/api/v1/crates/%s/%s", + url.PathEscape(tt.crateName), url.PathEscape(tt.version)) staticPath := "/readme-static/" + url.PathEscape(tt.crateName) if r.URL.Path == metaPath { @@ -361,6 +448,16 @@ func TestValidateCargoCombinedFixture(t *testing.T) { _ = json.NewEncoder(w).Encode(map[string]string{"url": srv.URL + staticPath}) return } + // Existence probe used to disambiguate a README 403. + if r.URL.Path == versionPath { + if tt.versionExists { + w.Header().Set("Content-Type", "application/json") + _ = json.NewEncoder(w).Encode(map[string]any{"version": map[string]string{"num": tt.version}}) + } else { + http.Error(w, "not found", http.StatusNotFound) + } + return + } if r.URL.Path == staticPath { if tt.readmeStatus != http.StatusOK { http.Error(w, "simulated non-200", tt.readmeStatus) diff --git a/internal/validators/registries/mcpname.go b/internal/validators/registries/mcpname.go new file mode 100644 index 0000000..a757db3 --- /dev/null +++ b/internal/validators/registries/mcpname.go @@ -0,0 +1,53 @@ +package registries + +import "strings" + +// isServerNameChar reports whether c can appear in an MCP server name. +// +// Server names follow the schema pattern ^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+$ +// (reverse-DNS namespace + "/" + name), so the full set of characters that may +// continue a server name is [A-Za-z0-9._/-]. +func isServerNameChar(c byte) bool { + switch { + case c >= 'a' && c <= 'z', c >= 'A' && c <= 'Z', c >= '0' && c <= '9': + return true + case c == '.', c == '-', c == '_', c == '/': + return true + default: + return false + } +} + +// containsMCPNameToken reports whether the package README/description contains +// the ownership token "mcp-name:" as a complete token — i.e. the +// matched server name is not merely a prefix of a longer declared name. +// +// A bare strings.Contains check is vulnerable to prefix confusion: a README that +// legitimately declares `mcp-name: io.github.acme/widget-pro` would otherwise +// satisfy an ownership claim for the shorter `io.github.acme/widget`, because the +// shorter string is a substring of the longer one. This is contained by namespace +// authorization (a publisher can only claim names within a namespace they own), +// but it still weakens the crate↔server-name binding the token is meant to prove, +// so we require a trailing boundary: the character following the server name must +// be the end of the content or any non-server-name character (whitespace, a +// newline, or an HTML tag delimiter from a rendered README such as `<`). +// +// Shared by the README-token validators (PyPI, NuGet, Cargo). NPM is unaffected +// because it compares an exact metadata field rather than scanning README text. +func containsMCPNameToken(content, serverName string) bool { + token := "mcp-name: " + serverName + searchFrom := 0 + for { + idx := strings.Index(content[searchFrom:], token) + if idx < 0 { + return false + } + tokenEnd := searchFrom + idx + len(token) + if tokenEnd >= len(content) || !isServerNameChar(content[tokenEnd]) { + return true + } + // This occurrence is a prefix of a longer name; keep scanning in case a + // properly-terminated occurrence appears later in the content. + searchFrom = searchFrom + idx + 1 + } +} diff --git a/internal/validators/registries/mcpname_internal_test.go b/internal/validators/registries/mcpname_internal_test.go new file mode 100644 index 0000000..0d69352 --- /dev/null +++ b/internal/validators/registries/mcpname_internal_test.go @@ -0,0 +1,35 @@ +package registries + +import "testing" + +// TestContainsMCPNameToken covers the boundary-anchored ownership-token match +// shared by the PyPI, NuGet, and Cargo validators — in particular that a server +// name which is a prefix of a longer declared name does not satisfy the match. +func TestContainsMCPNameToken(t *testing.T) { + const name = "io.github.acme/widget" + + cases := []struct { + desc string + content string + want bool + }{ + {"exact on its own line", "intro text\nmcp-name: io.github.acme/widget\nmore text", true}, + {"exact at end of content", "mcp-name: io.github.acme/widget", true}, + {"followed by HTML tag", " mcp-name: io.github.acme/widget
", true}, + {"followed by space", "mcp-name: io.github.acme/widget is the name", true}, + {"longer hyphenated name not a match", "mcp-name: io.github.acme/widget-pro\n", false}, + {"longer dotted name not a match", "mcp-name: io.github.acme/widget.core\n", false}, + {"longer slashed name not a match", "mcp-name: io.github.acme/widget/sub\n", false}, + {"absent", "nothing to see here", false}, + {"different name", "mcp-name: io.github.other/thing\n", false}, + {"prefix occurrence before a real one still matches", "mcp-name: io.github.acme/widget-pro then mcp-name: io.github.acme/widget\n", true}, + } + + for _, tc := range cases { + t.Run(tc.desc, func(t *testing.T) { + if got := containsMCPNameToken(tc.content, name); got != tc.want { + t.Fatalf("containsMCPNameToken(%q, %q) = %v, want %v", tc.content, name, got, tc.want) + } + }) + } +} diff --git a/pkg/model/types.go b/pkg/model/types.go index b0bf8e4..e9ade02 100644 --- a/pkg/model/types.go +++ b/pkg/model/types.go @@ -22,12 +22,13 @@ type Transport struct { // - NPM: RegistryType, Identifier (package name), Version, RegistryBaseURL (optional) // - PyPI: RegistryType, Identifier (package name), Version, RegistryBaseURL (optional) // - NuGet: RegistryType, Identifier (package ID), Version, RegistryBaseURL (optional) +// - Cargo: RegistryType, Identifier (crate name), Version, RegistryBaseURL (optional) // - OCI: RegistryType, Identifier (full image reference like "ghcr.io/owner/repo:tag") // - MCPB: RegistryType, Identifier (download URL), Version (optional), FileSHA256 (required) type Package struct { - // RegistryType indicates how to download packages (e.g., "npm", "pypi", "oci", "nuget", "mcpb") - RegistryType string `json:"registryType" minLength:"1" doc:"Registry type indicating how to download packages (e.g., 'npm', 'pypi', 'oci', 'nuget', 'mcpb')" example:"npm"` - // RegistryBaseURL is the base URL of the package registry (used by npm, pypi, nuget; not used by oci, mcpb) + // RegistryType indicates how to download packages (e.g., "npm", "pypi", "cargo", "oci", "nuget", "mcpb") + RegistryType string `json:"registryType" minLength:"1" doc:"Registry type indicating how to download packages (e.g., 'npm', 'pypi', 'cargo', 'oci', 'nuget', 'mcpb')" example:"npm"` + // RegistryBaseURL is the base URL of the package registry (used by npm, pypi, nuget, cargo; not used by oci, mcpb) RegistryBaseURL string `json:"registryBaseUrl,omitempty" format:"uri" doc:"Base URL of the package registry" example:"https://registry.npmjs.org"` // Identifier is the package identifier: // - For NPM/PyPI/NuGet: package name or ID From 04623ed9250f633a9bf80f60e8ad2b6a46d049d6 Mon Sep 17 00:00:00 2001 From: Radoslav DimitrovDate: Fri, 5 Jun 2026 02:28:41 -0400 Subject: [PATCH 116/190] fix(validators): harden mcp-name matching (PyPI/NuGet anchoring, comment-form safe) + cargo follow-ups (#1331) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registry-wide hardening of the `mcp-name:` ownership-token match, plus the cargo follow-up fixes from the #1330 review — consolidated here per maintainer request. Rebased onto current `main` (the merged #1330 cargo commit drops out), so the diff is just the net-new work. ### Changes - **PyPI/NuGet: boundary-anchored token match.** Replace `strings.Contains(readme, "mcp-name: "+name)` with the shared `containsMCPNameToken`, so a README declaring a longer name (`…/widget-pro`) no longer satisfies an ownership claim for a shorter prefix (`…/widget`). (Cargo already got this in #1330; NPM is unaffected — it compares an exact metadata field.) - **Matcher: treat the HTML comment close as a boundary.** `` / `` (any spacing) validate again — the documented hidden-comment form for PyPI/NuGet — while a genuine longer name (`…/widget--pro`) still does not. - **Cargo hardening (review of #1330):** pin scheme+port (not just host) on the README fetch and redirects; a rate-limited/failed crate-version existence probe now reports *transient* instead of "not found"; a 403 with the crate present no longer flatly asserts "no README". - **Docs:** note the token must be followed by a boundary. ### ⚠️ Behavior change for PyPI/NuGet — read before merging The match is **strictly stricter** (verified by fuzz, 2.3M execs: it can only flip pass→fail, never fail→pass). After the comment-close fix, the **only** forms that newly fail are unusual *inline* ones: the token ending a sentence (`…/my-mcp.`) or glued to a trailing `/`. The documented forms (own line, in ``) are unaffected. **Correcting an earlier claim:** this re-validates on **edits too**, not just new versions — `edit.go → UpdateServer → ValidateUpdateRequest → validateRegistryOwnership` runs the token check on any edit of a live server (only delete-transitions skip it). So an existing PyPI/NuGet server whose README uses one of the breaking inline forms would fail on its next publish *or* edit. Given the v0.1 API-freeze posture, this should land as a deliberate, noted change. ### Testing `go build`, `vet`, `gofmt`, `golangci-lint` (prod files), `check-schema`, `validate-examples` all clean. Hermetic + **live** PyPI/NuGet/cargo suite passes. New: `TestCargoURLAllowed`, a combined-fixture probe-429→transient case, comment-form matcher cases, and `FuzzContainsMCPNameToken` (the strictly-stricter property, 2.3M execs). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 (1M context) --- .../modelcontextprotocol-io/package-types.mdx | 4 + internal/validators/registries/cargo.go | 120 +++++++++++++----- .../registries/cargo_internal_test.go | 47 +++++++ internal/validators/registries/cargo_test.go | 40 +++++- internal/validators/registries/mcpname.go | 54 +++++++- .../registries/mcpname_internal_test.go | 71 ++++++++++- internal/validators/registries/nuget.go | 16 ++- internal/validators/registries/pypi.go | 15 ++- 8 files changed, 312 insertions(+), 55 deletions(-) create mode 100644 internal/validators/registries/cargo_internal_test.go diff --git a/docs/modelcontextprotocol-io/package-types.mdx b/docs/modelcontextprotocol-io/package-types.mdx index 6cac890..0367fac 100644 --- a/docs/modelcontextprotocol-io/package-types.mdx +++ b/docs/modelcontextprotocol-io/package-types.mdx @@ -87,6 +87,8 @@ This MCP server executes SQL queries and manages database connections. ``` +The `mcp-name:` token must be followed by a boundary — a newline, whitespace, an HTML tag, or the comment close `-->`. Keep it on its own line or inside ``; do not glue it directly to trailing characters such as a sentence-ending period (`…/database-query-mcp.`), which prevents the match. + ## NuGet Packages For NuGet packages, the MCP Registry currently supports the official NuGet registry (`https://api.nuget.org/v3/index.json`) only. @@ -125,6 +127,8 @@ This MCP server manages Azure DevOps work items and pipelines. ``` +The `mcp-name:` token must be followed by a boundary — a newline, whitespace, an HTML tag, or the comment close `-->`. Keep it on its own line or inside ``; do not glue it directly to trailing characters such as a sentence-ending period (`…/azure-devops-mcp.`), which prevents the match. + ## Cargo (Rust) Packages For Cargo packages, the MCP Registry currently supports the official crates.io registry (`https://crates.io`) only. diff --git a/internal/validators/registries/cargo.go b/internal/validators/registries/cargo.go index d90af77..5aa72b1 100644 --- a/internal/validators/registries/cargo.go +++ b/internal/validators/registries/cargo.go @@ -106,16 +106,37 @@ func cargoAllowedHosts(baseURL string) map[string]struct{} { return hosts } +// cargoURLAllowed reports whether u is a URL the validator may fetch for the +// given base. The host must be in allowedHosts; additionally, for the real +// crates.io base, the scheme must be https and the port must be the default — +// so a metadata response or redirect cannot downgrade to http or steer the +// validator at a non-standard port on an otherwise-trusted host. For test bases +// (httptest servers) only the host is checked, so mocks keep working. +func cargoURLAllowed(u *url.URL, baseURL string, allowedHosts map[string]struct{}) bool { + if _, ok := allowedHosts[u.Hostname()]; !ok { + return false + } + if baseURL == model.RegistryURLCrates { + if u.Scheme != "https" { + return false + } + if p := u.Port(); p != "" && p != "443" { + return false + } + } + return true +} + // newCargoHTTPClient builds the client used for all crates.io calls. The -// CheckRedirect policy pins every redirect hop to allowedHosts, so even though -// the initial URL is host-pinned, an upstream 3xx cannot redirect the validator -// to an unexpected host. -func newCargoHTTPClient(allowedHosts map[string]struct{}) *http.Client { +// CheckRedirect policy pins every redirect hop via cargoURLAllowed, so even +// though the initial URL is checked, an upstream 3xx cannot redirect the +// validator to an unexpected host, scheme, or port. +func newCargoHTTPClient(baseURL string, allowedHosts map[string]struct{}) *http.Client { return &http.Client{ Timeout: 10 * time.Second, CheckRedirect: func(req *http.Request, via []*http.Request) error { - if _, ok := allowedHosts[req.URL.Hostname()]; !ok { - return fmt.Errorf("refusing redirect to unexpected host %q", req.URL.Hostname()) + if !cargoURLAllowed(req.URL, baseURL, allowedHosts) { + return fmt.Errorf("refusing redirect to unexpected URL %q", req.URL.Redacted()) } if len(via) >= 10 { return errors.New("stopped after 10 redirects") @@ -125,37 +146,53 @@ func newCargoHTTPClient(allowedHosts map[string]struct{}) *http.Client { } } -// cargoVersionExists checks whether a specific crate version exists on crates.io, -// used to disambiguate a 403 from the README CDN. static.crates.io (S3) returns -// 403 both for a genuinely-missing crate/version AND for a crate that exists but -// has no rendered README, so a 403 alone cannot tell a publisher which it is. -// -// Returns (exists, determined): determined is false if the existence endpoint -// itself was unreachable or returned an unexpected status, in which case the -// caller should fall back to a generic message rather than assert existence. -func cargoVersionExists(ctx context.Context, client *http.Client, baseURL, identifier, version string) (exists, determined bool) { +// cargoVersionState is the outcome of probing the crate-version metadata +// endpoint, used to disambiguate a 403 from the README CDN. +type cargoVersionState int + +const ( + // cargoVersionUnknown: the probe returned an unexpected status we can't classify. + cargoVersionUnknown cargoVersionState = iota + // cargoVersionExists: the crate version exists (200). + cargoVersionExists + // cargoVersionMissing: the crate version does not exist (404). + cargoVersionMissing + // cargoVersionTransient: the probe failed for a retryable reason (network + // error, 429, or 5xx) — existence is undetermined and the caller should not + // report "not found". + cargoVersionTransient +) + +// probeCargoVersion checks whether a specific crate version exists on crates.io. +// static.crates.io (S3) returns 403 both for a genuinely-missing crate/version +// AND for a crate that exists but has no rendered README, so a 403 from the CDN +// alone cannot tell a publisher which it is; this probe disambiguates, while +// distinguishing a transient failure from a definitive missing/exists answer. +func probeCargoVersion(ctx context.Context, client *http.Client, baseURL, identifier, version string) cargoVersionState { versionURL := fmt.Sprintf("%s/api/v1/crates/%s/%s", baseURL, url.PathEscape(identifier), url.PathEscape(version)) req, err := http.NewRequestWithContext(ctx, http.MethodGet, versionURL, nil) if err != nil { - return false, false + return cargoVersionUnknown } req.Header.Set("User-Agent", cargoUserAgent) req.Header.Set("Accept", "application/json") resp, err := client.Do(req) if err != nil { - return false, false + return cargoVersionTransient } defer resp.Body.Close() - switch resp.StatusCode { - case http.StatusOK: - return true, true - case http.StatusNotFound: - return false, true + switch { + case resp.StatusCode == http.StatusOK: + return cargoVersionExists + case resp.StatusCode == http.StatusNotFound: + return cargoVersionMissing + case resp.StatusCode == http.StatusTooManyRequests, resp.StatusCode >= 500 && resp.StatusCode < 600: + return cargoVersionTransient default: - return false, false + return cargoVersionUnknown } } @@ -196,15 +233,21 @@ func cargoReadmeStatusError(ctx context.Context, client *http.Client, pkg model. // endpoint so the publisher gets an actionable message rather than a blanket // "not found". func cargoReadme403Error(ctx context.Context, client *http.Client, pkg model.Package, serverName string) error { - exists, determined := cargoVersionExists(ctx, client, pkg.RegistryBaseURL, pkg.Identifier, pkg.Version) - switch { - case determined && exists: - return fmt.Errorf("cargo package '%s' version '%s' exists on crates.io but has no rendered README. Add a README containing 'mcp-name: %s' and publish a new version", pkg.Identifier, pkg.Version, serverName) - case determined && !exists: + switch probeCargoVersion(ctx, client, pkg.RegistryBaseURL, pkg.Identifier, pkg.Version) { + case cargoVersionExists: + // The crate/version exists but the README CDN returned 403. The likely + // cause is a missing README, but a 403 is not definitive proof (e.g. a + // transient CDN/WAF block), so don't flatly assert "no README". + return fmt.Errorf("cargo package '%s' version '%s' exists on crates.io, but its rendered README could not be retrieved (status: 403). If it has no README, add one containing 'mcp-name: %s' and publish a new version", pkg.Identifier, pkg.Version, serverName) + case cargoVersionMissing: return fmt.Errorf("cargo package '%s' version '%s' not found on crates.io", pkg.Identifier, pkg.Version) - default: - return fmt.Errorf("cargo package '%s' version '%s' not found on crates.io (status: 403)", pkg.Identifier, pkg.Version) + case cargoVersionTransient: + return fmt.Errorf("crates.io could not confirm cargo package '%s' version '%s' (README status: 403, version check inconclusive) — likely transient, retry later", pkg.Identifier, pkg.Version) + case cargoVersionUnknown: + // Probe returned an unclassifiable status — fall through to the + // best-effort message below. } + return fmt.Errorf("cargo package '%s' version '%s' not found on crates.io (status: 403)", pkg.Identifier, pkg.Version) } // validateCargoREADME performs the two-call README fetch and the mcp-name token @@ -213,7 +256,7 @@ func cargoReadme403Error(ctx context.Context, client *http.Client, pkg model.Pac // bypassing the exact-baseURL guard that ValidateCargo enforces for callers. func validateCargoREADME(ctx context.Context, pkg model.Package, serverName string) error { allowedHosts := cargoAllowedHosts(pkg.RegistryBaseURL) - client := newCargoHTTPClient(allowedHosts) + client := newCargoHTTPClient(pkg.RegistryBaseURL, allowedHosts) // Step 1: fetch the README pointer from the documented API endpoint. metaURL := fmt.Sprintf("%s/api/v1/crates/%s/%s/readme", @@ -246,14 +289,15 @@ func validateCargoREADME(ctx context.Context, pkg model.Package, serverName stri return fmt.Errorf("cargo package '%s' metadata response missing 'url' field", pkg.Identifier) } - // Pin the README pointer to an allowed host before fetching it, so a metadata - // response cannot steer the validator at an internal or attacker-chosen host. + // Pin the README pointer to an allowed host/scheme/port before fetching it, so + // a metadata response cannot steer the validator at an internal or + // attacker-chosen URL. readmeParsed, err := url.Parse(meta.URL) if err != nil || readmeParsed.Hostname() == "" { return fmt.Errorf("cargo package '%s': crates.io returned an unparseable README URL", pkg.Identifier) } - if _, ok := allowedHosts[readmeParsed.Hostname()]; !ok { - return fmt.Errorf("cargo package '%s': crates.io returned a README URL on unexpected host %q — refusing to fetch", pkg.Identifier, readmeParsed.Hostname()) + if !cargoURLAllowed(readmeParsed, pkg.RegistryBaseURL, allowedHosts) { + return fmt.Errorf("cargo package '%s': crates.io returned a README URL on an unexpected host/scheme %q — refusing to fetch", pkg.Identifier, readmeParsed.Redacted()) } // Step 2: fetch the rendered README from the (now host-validated) URL. @@ -287,5 +331,11 @@ func validateCargoREADME(ctx context.Context, pkg model.Package, serverName stri return nil } + // If the token IS present but glued to a trailing character, explain that + // rather than telling the publisher to add a token they can already see. + if trailing, glued := mcpNameTokenGluedTrailing(string(body), serverName); glued { + return fmt.Errorf("cargo package '%s' ownership validation failed: found 'mcp-name: %s' in the README, but it is immediately followed by %q rather than a boundary. The token must be followed by a space, newline, or an HTML tag — put it on its own line and publish a new version", pkg.Identifier, serverName, trailing) + } + return fmt.Errorf("cargo package '%s' ownership validation failed. The server name '%s' must appear as 'mcp-name: %s' in the package README", pkg.Identifier, serverName, serverName) } diff --git a/internal/validators/registries/cargo_internal_test.go b/internal/validators/registries/cargo_internal_test.go new file mode 100644 index 0000000..44273b5 --- /dev/null +++ b/internal/validators/registries/cargo_internal_test.go @@ -0,0 +1,47 @@ +package registries + +import ( + "net/url" + "testing" + + "github.com/modelcontextprotocol/registry/pkg/model" +) + +// TestCargoURLAllowed covers the SSRF allow-check: for the real crates.io base, +// the host must be allow-listed AND the scheme/port must be https/default; for a +// test (httptest) base only the host is checked so mocks keep working. +func TestCargoURLAllowed(t *testing.T) { + prodHosts := cargoAllowedHosts(model.RegistryURLCrates) // {crates.io, static.crates.io} + mockBase := "http://127.0.0.1:54321" + mockHosts := cargoAllowedHosts(mockBase) // {127.0.0.1} + + cases := []struct { + desc string + raw string + baseURL string + hosts map[string]struct{} + want bool + }{ + {"prod: https static.crates.io", "https://static.crates.io/readmes/x/x.html", model.RegistryURLCrates, prodHosts, true}, + {"prod: https crates.io", "https://crates.io/api/v1/crates/x/1.0.0", model.RegistryURLCrates, prodHosts, true}, + {"prod: http downgrade rejected", "http://static.crates.io/x", model.RegistryURLCrates, prodHosts, false}, + {"prod: non-default port rejected", "https://static.crates.io:8443/x", model.RegistryURLCrates, prodHosts, false}, + {"prod: explicit 443 ok", "https://static.crates.io:443/x", model.RegistryURLCrates, prodHosts, true}, + {"prod: foreign host rejected", "https://evil.example/x", model.RegistryURLCrates, prodHosts, false}, + {"prod: userinfo host is evil rejected", "https://static.crates.io@evil.example/x", model.RegistryURLCrates, prodHosts, false}, + {"test base: mock host any scheme/port ok", "http://127.0.0.1:54321/readme-static/x", mockBase, mockHosts, true}, + {"test base: foreign host rejected", "http://127.0.0.2:54321/x", mockBase, mockHosts, false}, + } + + for _, tc := range cases { + t.Run(tc.desc, func(t *testing.T) { + u, err := url.Parse(tc.raw) + if err != nil { + t.Fatalf("parse %q: %v", tc.raw, err) + } + if got := cargoURLAllowed(u, tc.baseURL, tc.hosts); got != tc.want { + t.Fatalf("cargoURLAllowed(%q, base=%q) = %v, want %v", tc.raw, tc.baseURL, got, tc.want) + } + }) + } +} diff --git a/internal/validators/registries/cargo_test.go b/internal/validators/registries/cargo_test.go index d2c8128..5328f45 100644 --- a/internal/validators/registries/cargo_test.go +++ b/internal/validators/registries/cargo_test.go @@ -340,6 +340,7 @@ func TestValidateCargoCombinedFixture(t *testing.T) { readmeStatus int readmeBody string versionExists bool // response for the /api/v1/crates/{n}/{v} existence probe (403 disambiguation) + versionProbe int // if non-zero, the existence probe returns this status (overrides versionExists) wantErr bool wantContains []string wantNotContains []string @@ -377,8 +378,9 @@ func TestValidateCargoCombinedFixture(t *testing.T) { wantNotContains: []string{"has no rendered README"}, }, { - // Crate/version exists but has no rendered README: CDN 403 + existence - // probe 200. Must NOT be reported as "not found". + // Crate/version exists but the README CDN 403s: existence probe 200. + // Must NOT be reported as "not found", and must not flatly assert the + // README is absent (a 403 isn't definitive proof of that). name: "readme_403_no_readme", crateName: "combined-readme403-noreadme", version: "0.1.0", @@ -386,7 +388,20 @@ func TestValidateCargoCombinedFixture(t *testing.T) { readmeStatus: http.StatusForbidden, versionExists: true, wantErr: true, - wantContains: []string{"has no rendered README"}, + wantContains: []string{"exists on crates.io", "could not be retrieved"}, + wantNotContains: []string{"not found"}, + }, + { + // CDN 403 + the existence probe itself is rate-limited (429): existence + // is undetermined, so report transient/retryable, NOT "not found". + name: "readme_403_probe_transient", + crateName: "combined-readme403-probe429", + version: "0.1.0", + metaStatus: http.StatusOK, + readmeStatus: http.StatusForbidden, + versionProbe: http.StatusTooManyRequests, + wantErr: true, + wantContains: []string{"transient"}, wantNotContains: []string{"not found"}, }, { @@ -421,6 +436,18 @@ func TestValidateCargoCombinedFixture(t *testing.T) { wantErr: true, wantContains: []string{"ownership validation failed"}, }, + { + // Token present but glued to a trailing period — the error must explain + // the boundary cause, not tell the publisher to add a token they can see. + name: "glued_trailing_period_explained", + crateName: "combined-glued", + version: "0.1.0", + metaStatus: http.StatusOK, + readmeStatus: http.StatusOK, + readmeBody: fmt.Sprintf(" mcp-name: %s.
", serverName), + wantErr: true, + wantContains: []string{"immediately followed by", `"."`}, + }, } // lastMetaPath captures the metadata request path seen by the handler so @@ -450,10 +477,13 @@ func TestValidateCargoCombinedFixture(t *testing.T) { } // Existence probe used to disambiguate a README 403. if r.URL.Path == versionPath { - if tt.versionExists { + switch { + case tt.versionProbe != 0: + http.Error(w, "simulated probe status", tt.versionProbe) + case tt.versionExists: w.Header().Set("Content-Type", "application/json") _ = json.NewEncoder(w).Encode(map[string]any{"version": map[string]string{"num": tt.version}}) - } else { + default: http.Error(w, "not found", http.StatusNotFound) } return diff --git a/internal/validators/registries/mcpname.go b/internal/validators/registries/mcpname.go index a757db3..527aefb 100644 --- a/internal/validators/registries/mcpname.go +++ b/internal/validators/registries/mcpname.go @@ -18,6 +18,28 @@ func isServerNameChar(c byte) bool { } } +// isMCPNameBoundary reports whether the content immediately following a matched +// server name terminates the token, so that the matched name is not merely a +// prefix of a longer declared name. +// +// A boundary is the end of content, any non-server-name character (whitespace, a +// newline, or an HTML tag delimiter such as `<`), or the start of an HTML comment +// close (`-->` / `--!>`). The comment-close case matters because PyPI and NuGet +// publishers commonly hide the token in ``, and authors +// (or minifiers) frequently omit the space before `-->`, producing +// ``. There the byte after NAME is `-`, which is a +// server-name character, so without this case the documented hidden-comment form +// would fail to validate. +func isMCPNameBoundary(rest string) bool { + if rest == "" { + return true + } + if !isServerNameChar(rest[0]) { + return true + } + return strings.HasPrefix(rest, "-->") || strings.HasPrefix(rest, "--!>") +} + // containsMCPNameToken reports whether the package README/description contains // the ownership token "mcp-name:" as a complete token — i.e. the // matched server name is not merely a prefix of a longer declared name. @@ -27,10 +49,9 @@ func isServerNameChar(c byte) bool { // satisfy an ownership claim for the shorter `io.github.acme/widget`, because the // shorter string is a substring of the longer one. This is contained by namespace // authorization (a publisher can only claim names within a namespace they own), -// but it still weakens the crate↔server-name binding the token is meant to prove, -// so we require a trailing boundary: the character following the server name must -// be the end of the content or any non-server-name character (whitespace, a -// newline, or an HTML tag delimiter from a rendered README such as `<`). +// but it still weakens the package↔server-name binding the token is meant to +// prove, so we require a trailing boundary after the server name (see +// isMCPNameBoundary). // // Shared by the README-token validators (PyPI, NuGet, Cargo). NPM is unaffected // because it compares an exact metadata field rather than scanning README text. @@ -43,7 +64,7 @@ func containsMCPNameToken(content, serverName string) bool { return false } tokenEnd := searchFrom + idx + len(token) - if tokenEnd >= len(content) || !isServerNameChar(content[tokenEnd]) { + if isMCPNameBoundary(content[tokenEnd:]) { return true } // This occurrence is a prefix of a longer name; keep scanning in case a @@ -51,3 +72,26 @@ func containsMCPNameToken(content, serverName string) bool { searchFrom = searchFrom + idx + 1 } } + +// mcpNameTokenGluedTrailing explains why a visibly-present token failed to match. +// When containsMCPNameToken has already returned false, it reports whether the +// literal "mcp-name: " string is nonetheless present and, if so, the +// character immediately following it — i.e. the trailing character that made the +// occurrence look like a prefix of a longer name rather than a complete token. +// Validators use it to turn an unhelpful "token must appear" message into an +// actionable "found it, but it's glued to %q — put it on its own line" message. +// Returns ("", false) when the literal token is absent (a genuinely missing token). +func mcpNameTokenGluedTrailing(content, serverName string) (trailing string, glued bool) { + token := "mcp-name: " + serverName + idx := strings.Index(content, token) + if idx < 0 { + return "", false + } + end := idx + len(token) + if end >= len(content) { + // A token at end-of-content is a valid boundary, so containsMCPNameToken + // would not have failed; be defensive and treat it as not-glued. + return "", false + } + return string(content[end]), true +} diff --git a/internal/validators/registries/mcpname_internal_test.go b/internal/validators/registries/mcpname_internal_test.go index 0d69352..cd0bc38 100644 --- a/internal/validators/registries/mcpname_internal_test.go +++ b/internal/validators/registries/mcpname_internal_test.go @@ -1,6 +1,9 @@ package registries -import "testing" +import ( + "strings" + "testing" +) // TestContainsMCPNameToken covers the boundary-anchored ownership-token match // shared by the PyPI, NuGet, and Cargo validators — in particular that a server @@ -23,6 +26,17 @@ func TestContainsMCPNameToken(t *testing.T) { {"absent", "nothing to see here", false}, {"different name", "mcp-name: io.github.other/thing\n", false}, {"prefix occurrence before a real one still matches", "mcp-name: io.github.acme/widget-pro then mcp-name: io.github.acme/widget\n", true}, + + // HTML hidden-comment form (documented for PyPI/NuGet). The canonical + // spaced form has always passed; the no-space variants must pass too, + // since the byte after the name is the `-` of the comment close. + {"comment, spaced (canonical)", "", true}, + {"comment, no trailing space", "", true}, + {"comment, no spaces at all", "", true}, + {"legacy comment close --!>", "", true}, + // A genuine longer name with a double hyphen is still NOT a match for the + // shorter claim (it is not an HTML comment close). + {"double-hyphen longer name not a match", "mcp-name: io.github.acme/widget--pro\n", false}, } for _, tc := range cases { @@ -33,3 +47,58 @@ func TestContainsMCPNameToken(t *testing.T) { }) } } + +// TestMCPNameTokenGluedTrailing covers the diagnostic helper that explains why a +// visibly-present token failed: it reports the trailing character gluing the +// token to a longer name, or ("", false) when the token is genuinely absent. +func TestMCPNameTokenGluedTrailing(t *testing.T) { + const name = "io.github.acme/widget" + cases := []struct { + desc string + content string + wantTrailing string + wantGlued bool + }{ + {"absent", "no token here", "", false}, + {"glued period", "mcp-name: io.github.acme/widget.", ".", true}, + {"glued hyphen (longer name)", "mcp-name: io.github.acme/widget-pro", "-", true}, + {"glued slash", "mcp-name: io.github.acme/widget/x", "/", true}, + {"at end of content (boundary, not glued)", "mcp-name: io.github.acme/widget", "", false}, + } + for _, tc := range cases { + t.Run(tc.desc, func(t *testing.T) { + gotTrailing, gotGlued := mcpNameTokenGluedTrailing(tc.content, name) + if gotGlued != tc.wantGlued || gotTrailing != tc.wantTrailing { + t.Fatalf("mcpNameTokenGluedTrailing(%q) = (%q, %v), want (%q, %v)", + tc.content, gotTrailing, gotGlued, tc.wantTrailing, tc.wantGlued) + } + }) + } +} + +// FuzzContainsMCPNameToken pins the core safety property of the boundary-anchored +// matcher: it is strictly stricter than a bare substring check. A true result +// must imply the literal token is present (strings.Contains). This guards against +// a future edit to isServerNameChar/isMCPNameBoundary accidentally accepting +// something the old behavior rejected — i.e. it can only ever flip pass→fail, +// never fail→pass. Runs the seed corpus under `go test`; exhaustively under +// `go test -fuzz`. +func FuzzContainsMCPNameToken(f *testing.F) { + seeds := []struct{ content, name string }{ + {"mcp-name: io.github.acme/widget", "io.github.acme/widget"}, + {"mcp-name: io.github.acme/widget-pro", "io.github.acme/widget"}, + {"", "io.github.acme/widget"}, + {"prefix mcp-name: a/b then mcp-name: a/b-c", "a/b"}, + {"", ""}, + {"mcp-name: ", ""}, + {"random text with no token", "io.github.x/y"}, + } + for _, s := range seeds { + f.Add(s.content, s.name) + } + f.Fuzz(func(t *testing.T, content, name string) { + if containsMCPNameToken(content, name) && !strings.Contains(content, "mcp-name: "+name) { + t.Fatalf("matcher accepted but literal token absent: content=%q name=%q", content, name) + } + }) +} diff --git a/internal/validators/registries/nuget.go b/internal/validators/registries/nuget.go index 0c6d4c5..c229ba0 100644 --- a/internal/validators/registries/nuget.go +++ b/internal/validators/registries/nuget.go @@ -51,6 +51,9 @@ type ReadmeState int const ( ValidReadme ReadmeState = iota InvalidReadme + // GluedReadme: the literal token is present but glued to a trailing character + // (so the boundary-anchored match rejected it as a prefix of a longer name). + GluedReadme NoReadme ) @@ -99,6 +102,8 @@ func ValidateNuGet(ctx context.Context, pkg model.Package, serverName string) er return nil case InvalidReadme: return fmt.Errorf("NuGet package '%s' ownership validation for version %s failed. The server name '%s' must appear as 'mcp-name: %s' in the package README. Add it to your README and publish a new package version", pkg.Identifier, pkg.Version, serverName, serverName) + case GluedReadme: + return fmt.Errorf("NuGet package '%s' ownership validation for version %s failed: found 'mcp-name: %s' in the README, but it is immediately followed by another character rather than a boundary. The token must be followed by a space, newline, an HTML tag, or a comment close ('-->') — put it on its own line and publish a new package version", pkg.Identifier, pkg.Version, serverName) case NoReadme: // Continue to check if package exists default: @@ -237,10 +242,13 @@ func validateReadme(ctx context.Context, serverName, lowerID, lowerVersion strin readmeContent := string(readmeBytes) - // Check for mcp-name: format (more specific) - mcpNamePattern := "mcp-name: " + serverName - if strings.Contains(readmeContent, mcpNamePattern) { - return ValidReadme, nil // Found as mcp-name: format + // Check for the mcp-name: ownership token (boundary-anchored + // to avoid prefix confusion — see containsMCPNameToken). + if containsMCPNameToken(readmeContent, serverName) { + return ValidReadme, nil + } + if _, glued := mcpNameTokenGluedTrailing(readmeContent, serverName); glued { + return GluedReadme, nil } return InvalidReadme, nil diff --git a/internal/validators/registries/pypi.go b/internal/validators/registries/pypi.go index 2bac843..ec160bd 100644 --- a/internal/validators/registries/pypi.go +++ b/internal/validators/registries/pypi.go @@ -7,7 +7,6 @@ import ( "fmt" "net/http" "net/url" - "strings" "time" "github.com/modelcontextprotocol/registry/pkg/model" @@ -85,10 +84,16 @@ func ValidatePyPI(ctx context.Context, pkg model.Package, serverName string) err // Check description (README) content description := pypiResp.Info.Description - // Check for mcp-name: format (more specific) - mcpNamePattern := "mcp-name: " + serverName - if strings.Contains(description, mcpNamePattern) { - return nil // Found as mcp-name: format + // Check for the mcp-name: ownership token (boundary-anchored to + // avoid prefix confusion — see containsMCPNameToken). + if containsMCPNameToken(description, serverName) { + return nil + } + + // If the token IS present but glued to a trailing character, say so — otherwise + // the publisher sees "must appear as mcp-name: X" while looking at exactly that. + if trailing, glued := mcpNameTokenGluedTrailing(description, serverName); glued { + return fmt.Errorf("PyPI package '%s' ownership validation failed: found 'mcp-name: %s' in the README, but it is immediately followed by %q rather than a boundary. The token must be followed by a space, newline, an HTML tag, or a comment close ('-->') — put it on its own line and republish", pkg.Identifier, serverName, trailing) } return fmt.Errorf("PyPI package '%s' ownership validation failed. The server name '%s' must appear as 'mcp-name: %s' in the package README", pkg.Identifier, serverName, serverName) From ef29673221f34fb3b949c343b2279040b29cc203 Mon Sep 17 00:00:00 2001 From: CK Date: Fri, 5 Jun 2026 01:59:47 -0500 Subject: [PATCH 117/190] fix: client-cancelled GET /v0/servers returns 499 without error log (#1335) Maps context.Canceled from ListServers to 499 and skips the error-level log on client disconnect. Merged as-is per maintainer decision; known follow-up tracked in #1337 (500-path error-detail leak + WriteHeader claim correction + nits). --- internal/api/handlers/v0/list_errors.go | 21 +++++++++++++ internal/api/handlers/v0/list_errors_test.go | 31 ++++++++++++++++++++ internal/api/handlers/v0/servers.go | 3 +- 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 internal/api/handlers/v0/list_errors.go create mode 100644 internal/api/handlers/v0/list_errors_test.go diff --git a/internal/api/handlers/v0/list_errors.go b/internal/api/handlers/v0/list_errors.go new file mode 100644 index 0000000..8ef89a1 --- /dev/null +++ b/internal/api/handlers/v0/list_errors.go @@ -0,0 +1,21 @@ +package v0 + +import ( + "context" + "errors" + "log" + + "github.com/danielgtaylor/huma/v2" +) + +// ListServersError maps ListServers failures; client disconnects must not log as 500s. +func ListServersError(ctx context.Context, err error) error { + if err == nil { + return nil + } + if errors.Is(err, context.Canceled) || errors.Is(ctx.Err(), context.Canceled) { + return huma.NewError(499, "Client closed request", err) + } + log.Printf("list servers failed: %v", err) + return huma.Error500InternalServerError("Failed to get registry list", err) +} diff --git a/internal/api/handlers/v0/list_errors_test.go b/internal/api/handlers/v0/list_errors_test.go new file mode 100644 index 0000000..9baca41 --- /dev/null +++ b/internal/api/handlers/v0/list_errors_test.go @@ -0,0 +1,31 @@ +package v0_test + +import ( + "context" + "errors" + "testing" + + "github.com/danielgtaylor/huma/v2" + v0 "github.com/modelcontextprotocol/registry/internal/api/handlers/v0" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestListServersError_clientCanceled(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + + err := v0.ListServersError(ctx, errors.New("error iterating rows: context canceled")) + require.Error(t, err) + var se huma.StatusError + require.True(t, errors.As(err, &se)) + assert.Equal(t, 499, se.GetStatus()) +} + +func TestListServersError_realFailure(t *testing.T) { + err := v0.ListServersError(context.Background(), errors.New("database unavailable")) + require.Error(t, err) + var se huma.StatusError + require.True(t, errors.As(err, &se)) + assert.Equal(t, 500, se.GetStatus()) +} diff --git a/internal/api/handlers/v0/servers.go b/internal/api/handlers/v0/servers.go index bc7c618..059095d 100644 --- a/internal/api/handlers/v0/servers.go +++ b/internal/api/handlers/v0/servers.go @@ -132,8 +132,7 @@ func RegisterServersEndpoints(api huma.API, pathPrefix string, registry service. // Get paginated results with filtering servers, nextCursor, err := registry.ListServers(ctx, filter, input.Cursor, input.Limit) if err != nil { - log.Printf("list servers failed: %v", err) - return nil, huma.Error500InternalServerError("Failed to get registry list") + return nil, ListServersError(ctx, err) } // Convert []*ServerResponse to []ServerResponse From fecef4f9ed5ad063b8c726dc7fca4eb69dba69a3 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Fri, 5 Jun 2026 03:08:33 -0400 Subject: [PATCH 118/190] fix: don't leak internal error detail in GET /v0/servers 500 response (#1338) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes the information-disclosure regression introduced by #1335 (item 1 of #1337). `ListServersError` passed the raw `err` into `huma.Error500InternalServerError(...)`. huma serializes extra error args into the response body's `errors` array (`ErrorModel.Errors`, `json:"errors,omitempty"`), so on the **public, unauthenticated** `GET /v0/servers` endpoint a genuine DB failure echoed the internal wrapped error from `internal/database/postgres.go` (`error iterating rows: `) back to the client. pgx/pgconn errors can carry SQLSTATE codes, constraint/table/column names, and internal messages (CWE-209). ## Change - Drop `err` from the 500 call so only the generic message is returned; keep `log.Printf` for the server-side detail — matching the sibling handlers (`servers.go:190/220`, `edit.go`, `status.go`). - Add a regression test (`TestListServersError_realFailureDoesNotLeakDetail`) that marshals the 500 error and asserts the internal detail is absent from the client-visible body. Existing tests only asserted status codes, which is why the leak slipped through. The 499 client-cancelled path is unchanged (the client has already disconnected, so nothing is leaked there). ## Test plan - [x] `go test ./internal/api/handlers/v0/... -run ListServersError` (3/3 pass) - [x] `go build ./...`, `go vet`, `golangci-lint` (no new findings in changed files) ## Note This leaves the non-security items in #1337 (correcting the `superfluous WriteHeader` claim, `statusClientClosed` const reuse, broader cancellation-guard scope) for separate follow-up. Closing #1337 here since the only security-impacting item is addressed; reopen/split if you'd prefer to track the nits independently. Closes #1337 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) --- internal/api/handlers/v0/list_errors.go | 5 ++++- internal/api/handlers/v0/list_errors_test.go | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/internal/api/handlers/v0/list_errors.go b/internal/api/handlers/v0/list_errors.go index 8ef89a1..b83f04e 100644 --- a/internal/api/handlers/v0/list_errors.go +++ b/internal/api/handlers/v0/list_errors.go @@ -17,5 +17,8 @@ func ListServersError(ctx context.Context, err error) error { return huma.NewError(499, "Client closed request", err) } log.Printf("list servers failed: %v", err) - return huma.Error500InternalServerError("Failed to get registry list", err) + // Do not pass err here: huma serializes extra error args into the response + // body, which would leak internal (e.g. pgx) error detail to clients. Log it + // server-side only, like the sibling handlers in servers.go. + return huma.Error500InternalServerError("Failed to get registry list") } diff --git a/internal/api/handlers/v0/list_errors_test.go b/internal/api/handlers/v0/list_errors_test.go index 9baca41..7c50d38 100644 --- a/internal/api/handlers/v0/list_errors_test.go +++ b/internal/api/handlers/v0/list_errors_test.go @@ -2,6 +2,7 @@ package v0_test import ( "context" + "encoding/json" "errors" "testing" @@ -29,3 +30,16 @@ func TestListServersError_realFailure(t *testing.T) { require.True(t, errors.As(err, &se)) assert.Equal(t, 500, se.GetStatus()) } + +// The 500 response body must not echo the internal error back to the client, +// since it can carry DB/driver detail (CWE-209). +func TestListServersError_realFailureDoesNotLeakDetail(t *testing.T) { + const internal = "database unavailable: dsn=postgres://user:pw@internal-host/db" + err := v0.ListServersError(context.Background(), errors.New(internal)) + require.Error(t, err) + + body, marshalErr := json.Marshal(err) + require.NoError(t, marshalErr) + assert.NotContains(t, string(body), "database unavailable") + assert.NotContains(t, string(body), "internal-host") +} From f54f3b831c1c94501161e7592c97122eb349c4fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 02:41:46 -0400 Subject: [PATCH 119/190] build(deps): bump the actions group with 2 updates (#1392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the actions group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [actions/setup-go](https://github.com/actions/setup-go). Updates `actions/checkout` from 6 to 7 Release notes
Sourced from actions/checkout's releases.
v7.0.0
What's Changed
- block checking out fork pr for pull_request_target and workflow_run by
@aiqiaoyin actions/checkout#2454- Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by
@dependabot[bot] in actions/checkout#2458- Bump flatted from 3.3.1 to 3.4.2 by
@dependabot[bot] in actions/checkout#2460- Bump js-yaml from 4.1.0 to 4.2.0 by
@dependabot[bot] in actions/checkout#2461- Bump
@actions/coreand@actions/tool-cacheand Remove uuid by@dependabot[bot] in actions/checkout#2459- upgrade module to esm and update dependencies by
@aiqiaoyin actions/checkout#2463- Bump the minor-npm-dependencies group across 1 directory with 3 updates by
@dependabot[bot] in actions/checkout#2462- getting ready for checkout v7 release by
@aiqiaoyin actions/checkout#2464- update error wording by
@aiqiaoyin actions/checkout#2467New Contributors
@aiqiaoymade their first contribution in actions/checkout#2454Full Changelog: https://github.com/actions/checkout/compare/v6.0.3...v7.0.0
v6.0.3
What's Changed
- Update changelog by
@ericsciplein actions/checkout#2357- fix: expand merge commit SHA regex and add SHA-256 test cases by
@yaananthin actions/checkout#2414- Fix checkout init for SHA-256 repositories by
@yaananthin actions/checkout#2439- Update changelog for v6.0.3 by
@yaananthin actions/checkout#2446New Contributors
@yaananthmade their first contribution in actions/checkout#2414Full Changelog: https://github.com/actions/checkout/compare/v6...v6.0.3
v6.0.2
What's Changed
- Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID is set by
@TingluoHuangin actions/checkout#2355- Fix tag handling: preserve annotations and explicit fetch-tags by
@ericsciplein actions/checkout#2356Full Changelog: https://github.com/actions/checkout/compare/v6.0.1...v6.0.2
v6.0.1
What's Changed
- Update all references from v5 and v4 to v6 by
@ericsciplein actions/checkout#2314- Add worktree support for persist-credentials includeIf by
@ericsciplein actions/checkout#2327- Clarify v6 README by
@ericsciplein actions/checkout#2328Full Changelog: https://github.com/actions/checkout/compare/v6...v6.0.1
Commits
9c091bbupdate error wording (#2467)1044a6dgetting ready for checkout v7 release (#2464)f028218Bump the minor-npm-dependencies group across 1 directory with 3 updates (#2462)d914b26upgrade module to esm and update dependencies (#2463)537c7efBump@actions/coreand@actions/tool-cacheand Remove uuid (#2459)130a169Bump js-yaml from 4.1.0 to 4.2.0 (#2461)7d09575Bump flatted from 3.3.1 to 3.4.2 (#2460)0f9f3aaBump actions/publish-immutable-action (#2458)f9e715ablock checking out fork pr for pull_request_target and workflow_run (#2454)- See full diff in compare view
Updates `actions/setup-go` from 6.4.0 to 6.5.0Release notes
Sourced from actions/setup-go's releases.
v6.5.0
What's Changed
Dependency update
- Upgrade actions dependencies by
@priyagupta108with@Copilotin actions/setup-go#744- Upgrade
@types/nodeand typescript-eslint dependencies to resolve npm audit findings by@HarithaVattikutiin actions/setup-go#755- Upgrade
@actions/cacheto 5.1.0, log cache write denied by@jasonginin actions/setup-go#758- Upgrade version to 6.5.0 in package.json and package-lock.json by
@HarithaVattikutiin actions/setup-go#762New Contributors
@priyagupta108with@Copilotmade their first contribution in actions/setup-go#744@jasonginmade their first contribution in actions/setup-go#758Full Changelog: https://github.com/actions/setup-go/compare/v6...v6.5.0
Commits
924ae3achore: bump version to 6.5.0 in package.json and package-lock.json (#762)e91cc3bBump@actions/cacheto 5.1.0, log cache write denied (#758)4a2405echore: update@types/nodeand@typescript-eslintdependencies to latest versi...78961f6chore: update@actionsdependencies and refresh license cache (#744)- See full diff in compare view
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cancel-pulumi-lock.yml | 2 +- .github/workflows/ci.yml | 8 ++++---- .github/workflows/claude.yml | 2 +- .github/workflows/deploy-production.yml | 4 ++-- .github/workflows/deploy-staging.yml | 8 ++++---- .github/workflows/release.yml | 8 ++++---- .github/workflows/sync-schema.yml | 4 ++-- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/cancel-pulumi-lock.yml b/.github/workflows/cancel-pulumi-lock.yml index 06f1305..a42911f 100644 --- a/.github/workflows/cancel-pulumi-lock.yml +++ b/.github/workflows/cancel-pulumi-lock.yml @@ -24,7 +24,7 @@ jobs: environment: ${{ inputs.environment }} steps: - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Setup Pulumi uses: pulumi/actions@8e5e406f4007fca908480587cb9893c07090f58d diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce8f267..5c5edb0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,10 +16,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Set up Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 with: go-version: 'stable' cache: true @@ -48,10 +48,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Set up Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 with: go-version: 'stable' cache: true diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 36a9fc2..01e2b06 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -26,7 +26,7 @@ jobs: actions: read steps: - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: fetch-depth: 1 diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index bf8f4f2..443ec9a 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -23,10 +23,10 @@ jobs: cancel-in-progress: false steps: - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 with: go-version: 'stable' cache: true diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index c461511..7ef30b9 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -22,10 +22,10 @@ jobs: packages: write steps: - name: Checkout repository - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Set up Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 with: go-version: 'stable' cache: true @@ -70,10 +70,10 @@ jobs: cancel-in-progress: false steps: - name: Checkout code - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Setup Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 with: go-version: 'stable' cache: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f41dcaa..13fb866 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,12 +14,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 with: fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 with: go-version: 'stable' cache: true @@ -45,10 +45,10 @@ jobs: needs: goreleaser steps: - name: Checkout - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 - name: Set up Go - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c + uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 with: go-version: 'stable' cache: true diff --git a/.github/workflows/sync-schema.yml b/.github/workflows/sync-schema.yml index a59583b..7fbe6a7 100644 --- a/.github/workflows/sync-schema.yml +++ b/.github/workflows/sync-schema.yml @@ -15,10 +15,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@v7 - name: Checkout static repo - uses: actions/checkout@v6 + uses: actions/checkout@v7 with: repository: modelcontextprotocol/static path: static-repo From cefa07dfe81225161208b38ddc9be4a1e8afd643 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 02:42:05 -0400 Subject: [PATCH 120/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.244.0 to 3.248.0 in /deploy (#1391) Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.244.0 to 3.248.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.248.0
3.248.0 (2026-06-24)
Bug Fixes
- [cli] Fix a panic in
pulumi package get-schemawhen binding a schema that references an uninstalled plugin #23647Improvements
- [cli] Add options to
pulumi stack getfor parity with barepulumi stack#23623- [cli] Add
--outputflag to about and whoami commands #23651Features
- [engine] Add support for 'snippets', blocks of PCL kept in state to track ad-hoc resources #23286
- [engine] Send the address of a schema loader service to resource providers as part of the provider handshake #23645
- [engine] Send the address of a package resolver service to resource providers as part of the provider handshake #23654
Bug Fixes
- [programgen] Guard references to conditionally-created (boolean
range) resources in generated Python and NodeJS programs so they type-check #23634- [programgen] Generate map
rangeresource collections as key-indexed maps in Python and NodeJS so they can be indexed by key #23639Features
- [sdk/nodejs] Add
Output.recoverto catch and recover from exceptions in outputs #23642Bug Fixes
- [sdkgen] Fix extra trailing new lines in comments #23619
Improvements
- [sdkgen] Require callers to pass an explicit schema loader when binding PCL programs and package schemas #23672
v3.247.0
3.247.0 (2026-06-18)
Features
- [cli/config] Add --raw flag to
pulumi config setto avoid stripping newlines when input is piped through stdin #23593- [cli/do] Add
--providerflag to pull provider config to use from existing provider state #23560- [cli/engine] Resource providers now receive the active login's API address and access token through PULUMI_API and PULUMI_ACCESS_TOKEN #23589
- [cli/neo] Add a
--disable-integrationsflag topulumi neothat runs the task with no integration credentials #23531- [engine] Send the address of a mapper service to resource providers as part of the provider handshake
- [programgen/go] Support functions with multiArgumentInputs #23554
- [programgen/python] Support functions with multiArgumentInputs #23574
- [sdk/nodejs] Registered resources can now be retrieved from the mock monitor for test assertions #20539
- [sdk/python] Add
Output.recoverto catch and recover from exceptions in outputs #23591- [sdkgen] Adds support for language agnostic cross references in schemas. Use the form
{{% ref <target> %}}to reference other schema components in markdown descriptions. Such as `{{% ref #21369... (truncated)
Changelog
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.248.0 (2026-06-24)
Bug Fixes
- [cli] Fix a panic in
pulumi package get-schemawhen binding a schema that references an uninstalled plugin #23647Improvements
- [cli] Add options to
pulumi stack getfor parity with barepulumi stack#23623- [cli] Add
--outputflag to about and whoami commands #23651Features
- [engine] Add support for 'snippets', blocks of PCL kept in state to track ad-hoc resources #23286
- [engine] Send the address of a schema loader service to resource providers as part of the provider handshake #23645
- [engine] Send the address of a package resolver service to resource providers as part of the provider handshake #23654
Bug Fixes
- [programgen] Guard references to conditionally-created (boolean
range) resources in generated Python and NodeJS programs so they type-check #23634- [programgen] Generate map
rangeresource collections as key-indexed maps in Python and NodeJS so they can be indexed by key #23639Features
- [sdk/nodejs] Add
Output.recoverto catch and recover from exceptions in outputs #23642Bug Fixes
- [sdkgen] Fix extra trailing new lines in comments #23619
Improvements
- [sdkgen] Require callers to pass an explicit schema loader when binding PCL programs and package schemas #23672
3.247.0 (2026-06-18)
Bug Fixes
- [cli] Ensure
pulumi logoutclears the current tokenless backend in coding agent environments #23540- [cli] Read Git metadata correctly in repositories that enable the worktreeConfig extension, such as those hosted on Azure DevOps #23535
Improvements
- [cli] Respect PULUMI_SKIP_CONFIRMATIONS whenever we ask for confirmation #23607
- [cli] Use list and remove as the canonical names for list/remove commands, with ls and rm as aliases #23608
Features
- [cli/config] Add --raw flag to
pulumi config setto avoid stripping newlines when input is piped through stdin #23593Bug Fixes
... (truncated)
Commits
a88168d[programgen] Generate map ranges as key-indexed collections (Python & NodeJS)...3263e4aBump language versions (#23685)a95f24cBump the Pulumi HCL version to 0.8.0 (#23679)91f59ddRequire an explicit schema loader when binding programs and specs (#23672)35eb973Actually set an input in TestRefreshBeforeUpdateDeletedResource (#23681)9fd06c1Send a resolver target to providers during handshake (#23654)1091491Start changing PolicyRemediationEvent to property.Map (#23667)e2cca27[programgen] Guard references to conditionally-created resources (Python & No...109f27fNodeJS recover method (#23642)facc18eSend a loader target to providers during handshake (#23645)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 37 +++++++++----------- deploy/go.sum | 95 +++++++++++++++++++++------------------------------ 2 files changed, 55 insertions(+), 77 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 6fc92d3..53463fe 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,15 +5,14 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1 - github.com/pulumi/pulumi/sdk/v3 v3.244.0 + github.com/pulumi/pulumi/sdk/v3 v3.248.0 gopkg.in/yaml.v2 v2.4.0 ) require ( - dario.cat/mergo v1.0.0 // indirect github.com/BurntSushi/toml v1.6.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/ProtonMail/go-crypto v1.1.6 // indirect + github.com/ProtonMail/go-crypto v1.4.1 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect @@ -33,18 +32,16 @@ require ( github.com/clipperhouse/displaywidth v0.11.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/cloudflare/circl v1.6.3 // indirect - github.com/cyphar/filepath-securejoin v0.6.1 // indirect github.com/djherbis/times v1.5.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect - github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.9.0 // indirect - github.com/go-git/go-git/v5 v5.19.1 // indirect + github.com/go-git/gcfg/v2 v2.0.2 // indirect + github.com/go-git/go-billy/v6 v6.0.0-alpha.1 // indirect + github.com/go-git/go-git/v6 v6.0.0-alpha.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.5 // indirect - github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect @@ -53,9 +50,8 @@ require ( github.com/hashicorp/go-version v1.8.0 // indirect github.com/hashicorp/hcl/v2 v2.22.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/kevinburke/ssh_config v1.6.0 // indirect github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/lucasb-eyer/go-colorful v1.3.0 // indirect @@ -82,42 +78,43 @@ require ( github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect github.com/sergi/go-diff v1.4.0 // indirect - github.com/skeema/knownhosts v1.3.1 // indirect github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect - github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/zclconf/go-cty v1.13.2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/featuregate v1.53.0 // indirect go.opentelemetry.io/collector/pdata v1.53.0 // indirect + go.opentelemetry.io/contrib/bridges/otelslog v0.18.0 // indirect go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect + go.opentelemetry.io/otel/log v0.19.0 // indirect go.opentelemetry.io/otel/metric v1.43.0 // indirect go.opentelemetry.io/otel/sdk v1.43.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.19.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.50.0 // indirect + golang.org/x/crypto v0.52.0 // indirect golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f // indirect golang.org/x/mod v0.35.0 // indirect - golang.org/x/net v0.53.0 // indirect + golang.org/x/net v0.55.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.43.0 // indirect - golang.org/x/term v0.42.0 // indirect - golang.org/x/text v0.36.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/term v0.43.0 // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/tools v0.44.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260311181403-84a4fc48630c // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect google.golang.org/grpc v1.80.0 // indirect google.golang.org/protobuf v1.36.11 // indirect - gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/frand v1.5.1 // indirect ) diff --git a/deploy/go.sum b/deploy/go.sum index dc36d65..995e9c1 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -1,14 +1,11 @@ -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= -github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/ProtonMail/go-crypto v1.4.1 h1:9RfcZHqEQUvP8RzecWEUafnZVtEvrBVL9BiF67IQOfM= +github.com/ProtonMail/go-crypto v1.4.1/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= @@ -52,15 +49,11 @@ github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJ github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE= -github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/djherbis/times v1.5.0 h1:79myA211VwPhFTqUk8xehWrsEO+zcIZj0zT8mXPVARU= github.com/djherbis/times v1.5.0/go.mod h1:5q7FDLvbNg1L/KaBmPcWlVR9NmoKo3+ucqUA3ijQhA0= -github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= -github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= @@ -70,14 +63,14 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.9.0 h1:jItGXszUDRtR/AlferWPTMN4j38BQ88XnXKbilmmBPA= -github.com/go-git/go-billy/v5 v5.9.0/go.mod h1:jCnQMLj9eUgGU7+ludSTYoZL/GGmii14RxKFj7ROgHw= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.19.1 h1:nX27AnaU43/K5bKktKwgBmR9lawoYVe1Ckg0rgzzN00= -github.com/go-git/go-git/v5 v5.19.1/go.mod h1:Pb1v0c7/g8aGQJwx9Us09W85yGoyvSwuhEGMH7zjDKQ= +github.com/go-git/gcfg/v2 v2.0.2 h1:MY5SIIfTGGEMhdA7d7JePuVVxtKL7Hp+ApGDJAJ7dpo= +github.com/go-git/gcfg/v2 v2.0.2/go.mod h1:/lv2NsxvhepuMrldsFilrgct6pxzpGdSRC13ydTLSLs= +github.com/go-git/go-billy/v6 v6.0.0-alpha.1 h1:xVjAR4oUvrKy7/Xuw/lLlV3gkxR3KO2H8W+MamuVVsQ= +github.com/go-git/go-billy/v6 v6.0.0-alpha.1/go.mod h1:eaCUpHbedW7//EwcYmUDfJe2N6sJC9O12AT0OTqJR1E= +github.com/go-git/go-git-fixtures/v6 v6.0.0-alpha.1 h1:gmqi2jvsreu0s8JMLylYDFq4sbjHwwlhktMw0DUg3mA= +github.com/go-git/go-git-fixtures/v6 v6.0.0-alpha.1/go.mod h1:ECf1MqJlBdYpKggBrOXjo/0EnvRZx6D++I86UYjPgAQ= +github.com/go-git/go-git/v6 v6.0.0-alpha.4 h1:aDTc2UGanmaE7FkGLSlBEB9nohMnQ+RKXcfq/D+esDQ= +github.com/go-git/go-git/v6 v6.0.0-alpha.4/go.mod h1:4ODa/G7hPWrh4Y+7lmt59Ij3zW38IEfvRoAZxLYYBhc= 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= @@ -88,8 +81,6 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v1.2.5 h1:DrW6hGnjIhtvhOIiAKT6Psh/Kd/ldepEa81DKeiRJ5I= github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= -github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -112,12 +103,10 @@ github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul1 github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 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/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v1.6.0 h1:J1FBfmuVosPHf5GRdltRLhPJtJpTlMdKTBjRgTaQBFY= +github.com/kevinburke/ssh_config v1.6.0/go.mod h1:q2RIzfka+BXARoNexmF9gkxEX7DmvbW9P4hIVx2Kg4M= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -162,8 +151,6 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= -github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= -github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opentracing/basictracer-go v1.1.0 h1:Oa1fTSBvAl8pa3U+IJYqrKm0NALwH9OsgwOqDv4xJW0= github.com/opentracing/basictracer-go v1.1.0/go.mod h1:V2HZueSJEp879yv285Aap1BS69fQMD+MNP1mRs6mBQc= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -189,8 +176,8 @@ github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9 github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1 h1:Hg9RK9zqIU9kFbD5KeiON06gPP7cLgS68jvsgMBmPgw= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= -github.com/pulumi/pulumi/sdk/v3 v3.244.0 h1:oyQ9bwDE58wrQOqS70JrojJSlNoLcVhVcQgK4yusgcg= -github.com/pulumi/pulumi/sdk/v3 v3.244.0/go.mod h1:BPWWuYPXcPH5YbXGoyy9Rrfa+evrh6IdM51AjDhcDpM= +github.com/pulumi/pulumi/sdk/v3 v3.248.0 h1:TwY9uuToQO8xIey4a7awRzNX7iJ/doDmZkl1MzxULCE= +github.com/pulumi/pulumi/sdk/v3 v3.248.0/go.mod h1:67RnWlA0uRHJKjbOkk1Hqz8BNefYv8csNLgln1EmmII= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -200,9 +187,6 @@ github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9Am github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= -github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= @@ -225,8 +209,6 @@ github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaO github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= -github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -241,16 +223,26 @@ go.opentelemetry.io/collector/internal/testutil v0.147.0 h1:DFlRxBRp23/sZnpTITK2 go.opentelemetry.io/collector/internal/testutil v0.147.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= go.opentelemetry.io/collector/pdata v1.53.0 h1:DlYDbRwammEZaxDZHINx5v0n8SEOVNniPbi6FRTlVkA= go.opentelemetry.io/collector/pdata v1.53.0/go.mod h1:LRSYGNjKXaUrZEwZv3Yl+8/zV2HmRGKXW62zB2bysms= +go.opentelemetry.io/contrib/bridges/otelslog v0.18.0 h1:hhPGP3zvvy1xWT9RTy970wlniSxFttBIsAK1gvMguJM= +go.opentelemetry.io/contrib/bridges/otelslog v0.18.0/go.mod h1:twJF7inoMza6kxMcF8JOdL3mPmtOZu7GEr34CUNE6Dg= go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 h1:Dn8rkudDzY6KV9dr/D/bTUuWgqDf9xe0rr4G2elrn0Y= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0/go.mod h1:gMk9F0xDgyN9M/3Ed5Y1wKcx/9mlU91NXY2SNq7RQuU= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= +go.opentelemetry.io/otel/log v0.19.0 h1:KUZs/GOsw79TBBMfDWsXS+KZ4g2Ckzksd1ymzsIEbo4= +go.opentelemetry.io/otel/log v0.19.0/go.mod h1:5DQYeGmxVIr4n0/BcJvF4upsraHjg6vudJJpnkL6Ipk= go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/log v0.19.0 h1:scYVLqT22D2gqXItnWiocLUKGH9yvkkeql5dBDiXyko= +go.opentelemetry.io/otel/sdk/log v0.19.0/go.mod h1:vFBowwXGLlW9AvpuF7bMgnNI95LiW10szrOdvzBHlAg= +go.opentelemetry.io/otel/sdk/log/logtest v0.19.0 h1:BEbF7ZBB6qQloV/Ub1+3NQoOUnVtcGkU3XX4Ws3GQfk= +go.opentelemetry.io/otel/sdk/log/logtest v0.19.0/go.mod h1:Lua81/3yM0wOmoHTokLj9y9ADeA02v1naRrVrkAZuKk= go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= @@ -273,9 +265,8 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= -golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= +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/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= @@ -289,9 +280,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= -golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +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/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -304,23 +294,16 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= -golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= -golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= +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/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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -335,10 +318,10 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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-20260311181403-84a4fc48630c h1:OyQPd6I3pN/9gDxz6L13kYGJgqkpdrAohJRBeXyxlgI= -google.golang.org/genproto/googleapis/api v0.0.0-20260311181403-84a4fc48630c/go.mod h1:X2gu9Qwng7Nn009s/r3RUxqkzQNqOrAy79bluY7ojIg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c h1:xgCzyF2LFIO/0X2UAoVRiXKU5Xg6VjToG4i2/ecSswk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= @@ -347,8 +330,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= From 39e33b5d168de50c238cd7432d5fc411f8fc68ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 02:42:30 -0400 Subject: [PATCH 121/190] build(deps): bump github.com/Azure/azure-sdk-for-go/sdk/azidentity from 1.13.1 to 1.14.0 (#1375) Bumps [github.com/Azure/azure-sdk-for-go/sdk/azidentity](https://github.com/Azure/azure-sdk-for-go) from 1.13.1 to 1.14.0. Release notes
Sourced from github.com/Azure/azure-sdk-for-go/sdk/azidentity's releases.
sdk/azidentity/v1.14.0
1.14.0 (2026-06-15)
Breaking Changes
These changes affect only code written against a beta version such as v1.14.0-beta.3
- Removed
WorkloadIdentityCredentialOptions.EnableAzureProxy. It will return in v1.15.0-beta.1Bugs Fixed
AzureDeveloperCLICredentialimproved reporting of error messages returned fromazdOther Changes
- Returned
azidentityerrors include links to the troubleshooting guide when appropriate- This module now requires a minimum Go version of 1.25
- Upgraded dependencies
Commits
0495c20Prep azcore 1.14.0 for release (#23293)217edeefix(generator tool): filter tsp-client diagnostics log (#23292)023c88fIncrement package version after release of azidentity (#23290)17f3361Sync eng/common directory with azure-sdk-tools for PR 8760 (#23271)f5f3234bump proxy to one with an audit log and more correct locking (#23288)d707091Prepare azidentity v1.8.0-beta.2 for release (#23289)84d213cNewManagedIdentityCredential returns an error for unsupported ID options (#23...ea67e9cazcontainerregistry: move method to function (#23270)40dad0afix (#23287)a368082fix generator tool: ExecuteGoGenerate func (#23286)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 1dbf670..07af7a0 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.26 require ( cloud.google.com/go/kms v1.31.0 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.5.0 github.com/caarlos0/env/v11 v11.4.1 github.com/coreos/go-oidc/v3 v3.18.0 @@ -33,10 +33,10 @@ require ( cloud.google.com/go/compute/metadata v0.9.0 // indirect cloud.google.com/go/iam v1.7.0 // indirect cloud.google.com/go/longrunning v0.9.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.22.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/go.sum b/go.sum index af66f73..6f5f000 100644 --- a/go.sum +++ b/go.sum @@ -12,22 +12,22 @@ cloud.google.com/go/kms v1.31.0 h1:LS8N92OxFDgOLg5NCo3OmbvjtQAIVT5gUHVLKIDHaFE= cloud.google.com/go/kms v1.31.0/go.mod h1:YIyXZym11R5uovJJt4oN5eUL3oPmirF3yKeIh6QAf4U= cloud.google.com/go/longrunning v0.9.0 h1:0EzbDEGsAvOZNbqXopgniY0w0a1phvu5IdUFq8grmqY= cloud.google.com/go/longrunning v0.9.0/go.mod h1:pkTz846W7bF4o2SzdWJ40Hu0Re+UoNT6Q5t+igIcb8E= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 h1:fou+2+WFTib47nS+nz/ozhEBnvU96bKHy6LjRsY4E28= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0/go.mod h1:t76Ruy8AHvUAC8GfMWJMa0ElSbuIcO03NLpynfbgsPA= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0= -github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= -github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.22.0 h1:aokoqcHvaGjiM3VpjKDfMMnF/8epJ+Q1HLJ7CudztqE= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.22.0/go.mod h1:/WYEx9pcM9Y+Dd/APJaNlSvVSvzl54rrMdZT5+Oi2LM= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0 h1:CU4+EJeJi3TKYWEcYuSdWsjzw0nVsK/H0MSQOiPcymU= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0/go.mod h1:q0+UTSRvShwUCrR/s5HtyInYphN7Wvxb7snFM3u+SLA= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.4.0 h1:xFaZZ+IubdftrDHnGGwZ6QvQ3KHTtWl2MCK+GMt2vxs= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.4.0/go.mod h1:mCBhUhlMjLLJKr5aqw2TNS/VqJOie8MzWq3DAMJeKso= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6XuRW0nU7hgg4zlmZZa+a9q4= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.5.0 h1:MaKvxE6D0KkjOg6Wd9M00iqP5PR0kUxCfiezes4JweM= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.5.0/go.mod h1:i2h9fsTFKZorh8RdV2IcSUf/Qj98GlTkrTvUbX/s8as= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfgcSyHZXJI8J0IWE5MsCGlb2xp9fJiXyxWgmOFg4= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= -github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0 h1:4iB+IesclUXdP0ICgAabvq2FYLXrJWKx1fJQ+GxSo3Y= -github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= +github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2 h1:RHK7bS+HQMslb1sZpAokUt+zTVmue0hKSs2C791hhzU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.7.2/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/caarlos0/env/v11 v11.4.1 h1:fYwH0sWEsBSMPG7t4e/PEfTFzrWrpjyygXyUnWiSwEw= From 12b31e9d0934ae014189faeb27b91eaa0963ef64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 02:42:46 -0400 Subject: [PATCH 122/190] build(deps): bump github.com/coreos/go-oidc/v3 from 3.18.0 to 3.19.0 (#1374) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc) from 3.18.0 to 3.19.0. Release notes
Sourced from github.com/coreos/go-oidc/v3's releases.
v3.19.0
What's Changed
- fix: Key refresh should set
no-cacheto get most up to date keys by@Yanni8in coreos/go-oidc#485- oidc: add support for validating back-channel logout tokens by
@ericchiangin coreos/go-oidc#486New Contributors
@Yanni8made their first contribution in coreos/go-oidc#485Full Changelog: https://github.com/coreos/go-oidc/compare/v3.18.0...v3.19.0
Commits
4204f0boidc: add support for validating back-channel logout tokensf77e01cfix: Key refresh should set no-cache to get most up to date keys- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 07af7a0..ec720a0 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.5.0 github.com/caarlos0/env/v11 v11.4.1 - github.com/coreos/go-oidc/v3 v3.18.0 + github.com/coreos/go-oidc/v3 v3.19.0 github.com/danielgtaylor/huma/v2 v2.38.0 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/go-containerregistry v0.21.6 diff --git a/go.sum b/go.sum index 6f5f000..fb9aa28 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ 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/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= -github.com/coreos/go-oidc/v3 v3.18.0 h1:V9orjXynvu5wiC9SemFTWnG4F45v403aIcjWo0d41+A= -github.com/coreos/go-oidc/v3 v3.18.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4= +github.com/coreos/go-oidc/v3 v3.19.0 h1:F/xyOi3x1UnG1U27YVnM1N6bHiL1K2upi6U/0qr8r+I= +github.com/coreos/go-oidc/v3 v3.19.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4= github.com/danielgtaylor/huma/v2 v2.38.0 h1:fb0WZCatnaiHLphMQDDWDjygNxfMkX/ENma3QsRl7vY= github.com/danielgtaylor/huma/v2 v2.38.0/go.mod h1:k9hwjlgWFt1t2jsmQGlsgXAG2FBTZa4kkjV581qAtfo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From dda760f0a9105d6dfe7b05e7e2c202ce1059f28b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 02:43:06 -0400 Subject: [PATCH 123/190] build(deps): bump github.com/google/go-containerregistry from 0.21.6 to 0.21.7 (#1373) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.21.6 to 0.21.7. Release notes
Sourced from github.com/google/go-containerregistry's releases.
v0.21.7
What's Changed
- tarball: return error instead of panicking on missing rootfs.diff_ids by
@iahsanGillin google/go-containerregistry#2304- gcrane: honor --platform flag in copy by
@iahsanGillin google/go-containerregistry#2307- mutate: verify layer digests in Extract and Time by
@momenashrafffin google/go-containerregistry#2303- tarball: close layer readers during Write by
@nandbhatin google/go-containerregistry#2308- build(deps): bump the actions group across 1 directory with 2 updates by
@dependabot[bot] in google/go-containerregistry#2311- build(deps): bump github.com/docker/cli from 29.4.3+incompatible to 29.5.2+incompatible in the go-deps group across 1 directory by
@dependabot[bot] in google/go-containerregistry#2312- BUGFIX: Fail with error when read exceeds maximum by
@inteonin google/go-containerregistry#2328- build(deps): bump the actions group across 1 directory with 2 updates by
@dependabot[bot] in google/go-containerregistry#2327- fix(name): anchor loopback registry detection by
@rohan-patnaikin google/go-containerregistry#2314- Reject symlinks in OCI layout blobs by
@mosskappain google/go-containerregistry#2306- fix(crane): avoid creating export tar on pull failure by
@Haihan-Jiangin google/go-containerregistry#2318- feat(kubernetes): allow ignoring pull secrets by
@rohan-patnaikin google/go-containerregistry#2315- fix(name): preserve localhost registry references by
@rohan-patnaikin google/go-containerregistry#2316- pkg/registry: export ErrNotFound by
@malt3in google/go-containerregistry#2176- pkg/registry: export RedirectError by
@malt3in google/go-containerregistry#2177- build(deps): bump the go-deps group across 1 directory with 2 updates by
@dependabot[bot] in google/go-containerregistry#2343- build(deps): bump the actions group across 1 directory with 2 updates by
@dependabot[bot] in google/go-containerregistry#2344- fix: prevent SSRF in google.List() pagination by
@tufstrakain google/go-containerregistry#2332- internal/gzip: fix goroutine leak in ReadCloserLevel by
@amarkdotdevin google/go-containerregistry#2347- fix(transport): apply refreshed bearer token after cross-host redirect by
@64johnleein google/go-containerregistry#2337- build(deps): bump the go-deps group across 3 directories with 4 updates by
@dependabot[bot] in google/go-containerregistry#2348- fix(tarball): normalize paths when matching files by
@bstollin google/go-containerregistry#2334- transport: do not re-attach bearer token after cross-host redirect by
@evilgensecin google/go-containerregistry#2349- Bump CI go version to 1.26.4 by
@Subserialin google/go-containerregistry#2350New Contributors
@momenashrafffmade their first contribution in google/go-containerregistry#2303@nandbhatmade their first contribution in google/go-containerregistry#2308@inteonmade their first contribution in google/go-containerregistry#2328@rohan-patnaikmade their first contribution in google/go-containerregistry#2314@mosskappamade their first contribution in google/go-containerregistry#2306@Haihan-Jiangmade their first contribution in google/go-containerregistry#2318@tufstrakamade their first contribution in google/go-containerregistry#2332@amarkdotdevmade their first contribution in google/go-containerregistry#2347@64johnleemade their first contribution in google/go-containerregistry#2337@bstollmade their first contribution in google/go-containerregistry#2334Full Changelog: https://github.com/google/go-containerregistry/compare/v0.21.6...v0.21.7
Commits
c68d899Bump go version to 1.26.4 (#2350)da61d86transport: do not re-attach bearer token after cross-host redirect (#2349)09fe1e5fix(tarball): normalize paths when matching files (#2334)5baa399build(deps): bump the go-deps group across 3 directories with 4 updates (#2348)97a8a17fix(transport): apply refreshed bearer token after cross-host redirect (#2337)e963497internal/gzip: fix goroutine leak in ReadCloserLevel (#2347)02649eafix: prevent SSRF in google.List() pagination (#2332)7204b40build(deps): bump the actions group across 1 directory with 2 updates (#2344)4cfaa93build(deps): bump the go-deps group across 1 directory with 2 updates (#2343)6849394pkg/registry: export RedirectError (#2177)- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index ec720a0..c0a9a45 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/coreos/go-oidc/v3 v3.19.0 github.com/danielgtaylor/huma/v2 v2.38.0 github.com/golang-jwt/jwt/v5 v5.3.1 - github.com/google/go-containerregistry v0.21.6 + github.com/google/go-containerregistry v0.21.7 github.com/jackc/pgx/v5 v5.10.0 github.com/prometheus/client_golang v1.23.2 github.com/rs/cors v1.11.1 @@ -22,7 +22,7 @@ require ( go.opentelemetry.io/otel/metric v1.44.0 go.opentelemetry.io/otel/sdk v1.44.0 go.opentelemetry.io/otel/sdk/metric v1.44.0 - golang.org/x/mod v0.36.0 + golang.org/x/mod v0.37.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -40,7 +40,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/docker/cli v29.4.3+incompatible // indirect + github.com/docker/cli v29.5.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-jose/go-jose/v4 v4.1.4 // indirect @@ -73,8 +73,8 @@ require ( golang.org/x/crypto v0.51.0 // indirect golang.org/x/net v0.55.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.45.0 // indirect + golang.org/x/sync v0.21.0 // indirect + golang.org/x/sys v0.46.0 // indirect golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/api v0.274.0 // indirect diff --git a/go.sum b/go.sum index fb9aa28..f7a0590 100644 --- a/go.sum +++ b/go.sum @@ -43,8 +43,8 @@ github.com/danielgtaylor/huma/v2 v2.38.0/go.mod h1:k9hwjlgWFt1t2jsmQGlsgXAG2FBTZ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/docker/cli v29.4.3+incompatible h1:u+UliYm2J/rYrIh2FqHQg32neRG8GjbvNuwQRTzGspU= -github.com/docker/cli v29.4.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v29.5.3+incompatible h1:nbEFfz774vBwQ5KRYv7c/AghjReqnGISvrRhzjV0evs= +github.com/docker/cli v29.5.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= @@ -69,8 +69,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 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/go-containerregistry v0.21.6 h1:T+yqQIlJXKrM98Om4DlW3GoWQAmhZuLMwoDOvVrtiUM= -github.com/google/go-containerregistry v0.21.6/go.mod h1:U7MMSBIJynke2MVQrQk19NP9k/uQsGz/h0amIFSHMbo= +github.com/google/go-containerregistry v0.21.7 h1:/vPFuVXDjtFREsVArW+0h1CIl5urnOhzei4X2DMW9IU= +github.com/google/go-containerregistry v0.21.7/go.mod h1:kjSbt7/zMsKLWfnHrIvKvhXHUw91jbe9DNjPPJ32gXE= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -162,17 +162,17 @@ go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= -golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= -golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= 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/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +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/sys v0.1.0/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.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= From 44397cbe1d796a351ae6645c8332e2311e2ba2f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Bay=C4=B1r?= Date: Thu, 25 Jun 2026 13:44:48 +0300 Subject: [PATCH 124/190] Fix broken reference documentation links (#1387) Summary: - Fix the reference index FAQ link to point at the existing docs FAQ. - Correct package registry guide links from docs/contributing into docs/reference. Validation: - Focused markdown-link-check on the changed docs passed. - Git whitespace check passed. Co-authored-by: kriptoburak --- docs/contributing/add-package-registry.md | 10 +++++----- docs/reference/README.md | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/contributing/add-package-registry.md b/docs/contributing/add-package-registry.md index be0a6ea..170c2d2 100644 --- a/docs/contributing/add-package-registry.md +++ b/docs/contributing/add-package-registry.md @@ -2,9 +2,9 @@ The MCP Registry project is a **metaregistry**, meaning that it hosts metadata for MCP servers but does not host the code for the servers directly. -For local MCP servers, the MCP Registry has pointers in the `packages` node of the [`server.json`](../../reference/server-json/generic-server-json.md) schema that refer to packages in supported package managers. +For local MCP servers, the MCP Registry has pointers in the `packages` node of the [`server.json`](../reference/server-json/generic-server-json.md) schema that refer to packages in supported package managers. -The list of supported package managers for hosting MCP servers is defined by the `properties.packages[N].properties.registryType` string enum in the [`server.json` schema](../../reference/server-json/draft/server.schema.json). For example, this could be "npm" (for npmjs.com packages) or "pypi" (for PyPI packages). +The list of supported package managers for hosting MCP servers is defined by the `properties.packages[N].properties.registryType` string enum in the [`server.json` schema](../reference/server-json/draft/server.schema.json). For example, this could be "npm" (for npmjs.com packages) or "pypi" (for PyPI packages). For remote MCP servers, the package registry is not relevant. The MCP client consumes the server via a URL instead of by downloading and running a package. In other words, this document only applies to local MCP servers. @@ -33,15 +33,15 @@ These steps may evolve as additional validations or details are discovered and m 1. [Create a feature request issue](https://github.com/modelcontextprotocol/registry/issues/new?template=feature_request.md) on the MCP Registry repository to begin the discussion about adding the package registry. - Example for NuGet: https://github.com/modelcontextprotocol/registry/issues/126 1. Open a PR with the following changes: - - Update the [`server.json` schema](../../reference/server-json/draft/server.schema.json) + - Update the [`server.json` schema](../reference/server-json/draft/server.schema.json) - Add your package registry name to the `registryType` example array. - Add your package registry base url to the `registryBaseUrl` example array. - Add the single-shot CLI command name to the `runtimeHint` example value array. - - Update the [`openapi.yaml`](../../reference/api/openapi.yaml) + - Update the [`openapi.yaml`](../reference/api/openapi.yaml) - Add your package registry name to the `registryType` enum value array. - Add your package registry base url to the `registryBaseUrl` enum value array. - Add the single-shot CLI command name to the `runtimeHint` example value array. - - Add a sample, minimal `server.json` to the [`server.json` examples](../../reference/server-json/generic-server-json.md). + - Add a sample, minimal `server.json` to the [`server.json` examples](../reference/server-json/generic-server-json.md). - Implement a registry validator: - Create a new validator file: `internal/validators/registries/yourregistry.go`, following the pattern of existing validators. Examples: - **npm**: Checks for an `mcpName` field in `package.json` that matches the server name diff --git a/docs/reference/README.md b/docs/reference/README.md index 73f3518..ea77b30 100644 --- a/docs/reference/README.md +++ b/docs/reference/README.md @@ -19,4 +19,4 @@ Technical specifications and quick lookups for the MCP Registry. ## Quick Reference -- [FAQ](./faq.md) \ No newline at end of file +- [FAQ](../modelcontextprotocol-io/faq.mdx) From 535941a30e92c88b5bc83ef4e951d4183ccf19db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 06:46:17 -0400 Subject: [PATCH 125/190] build(deps): bump github.com/pulumi/pulumi-kubernetes/sdk/v4 from 4.31.1 to 4.32.0 in /deploy (#1353) Bumps [github.com/pulumi/pulumi-kubernetes/sdk/v4](https://github.com/pulumi/pulumi-kubernetes) from 4.31.1 to 4.32.0. Release notes
Sourced from github.com/pulumi/pulumi-kubernetes/sdk/v4's releases.
v4.32.0
No release notes provided.
Changelog
Sourced from github.com/pulumi/pulumi-kubernetes/sdk/v4's changelog.
4.32.0 (June 5, 2026)
Fixed
- #3176 ensure Helm-installed CRDs can be resolved during preview
- #4396 Fix panic when creating a
kubernetes.io/service-account-tokenSecret with a non-existent ServiceAccount.- #4394 Don't fail YAML render when a custom resource's namespace scope can't be determined offline. The resource is rendered without a namespace and a warning is logged, rather than erroring.
Changed
- Align the documented minimum supported Kubernetes version and local SDK install instructions with current provider behavior.
Commits
a03ff6bhotfix: e2e test failure on master (#4427)27f2e0bUpdate GitHub Actions workflows. (#4425)1db6d7eUpdate GitHub Actions workflows. (#4424)b53dfdcUpdate GitHub Actions workflows. (#4422)9275022Prepare for v4.32.0 release (#4419)845c3a3Resolve custom resource namespace scope from Helm release CRDs (#4417)db24ea9fix: allow ambient KUBECONFIG in render mode (#4406)0833fabUpdate GitHub Actions workflows. (#4418)efa552fUpdate GitHub Actions workflows. (#4415)6f12951Update GitHub Actions workflows. (#4414)- Additional commits viewable in compare view
Signed-off-by: dependabot[bot]Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 33 ++++++++++---------- deploy/go.sum | 83 +++++++++++++++++++++++++-------------------------- 2 files changed, 56 insertions(+), 60 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 53463fe..14d4db7 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -4,7 +4,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 - github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1 + github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.32.0 github.com/pulumi/pulumi/sdk/v3 v3.248.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -14,7 +14,6 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProtonMail/go-crypto v1.4.1 // indirect github.com/agext/levenshtein v1.2.3 // indirect - github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect @@ -25,7 +24,7 @@ require ( github.com/charmbracelet/bubbletea v1.3.10 // indirect github.com/charmbracelet/colorprofile v0.4.3 // indirect github.com/charmbracelet/lipgloss v1.1.0 // indirect - github.com/charmbracelet/x/ansi v0.11.6 // indirect + github.com/charmbracelet/x/ansi v0.11.7 // indirect github.com/charmbracelet/x/cellbuf v0.0.15 // indirect github.com/charmbracelet/x/term v0.2.2 // indirect github.com/cheggaaa/pb v1.0.29 // indirect @@ -43,21 +42,21 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.5 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-version v1.8.0 // indirect - github.com/hashicorp/hcl/v2 v2.22.0 // indirect + github.com/hashicorp/go-version v1.9.0 // indirect + github.com/hashicorp/hcl/v2 v2.24.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kevinburke/ssh_config v1.6.0 // indirect github.com/klauspost/compress v1.18.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect - github.com/lucasb-eyer/go-colorful v1.3.0 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect + github.com/lucasb-eyer/go-colorful v1.4.0 // indirect + github.com/mattn/go-isatty v0.0.22 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.21 // indirect + github.com/mattn/go-runewidth v0.0.23 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -85,15 +84,15 @@ require ( github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect - github.com/zclconf/go-cty v1.13.2 // indirect + github.com/zclconf/go-cty v1.16.3 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.53.0 // indirect - go.opentelemetry.io/collector/pdata v1.53.0 // indirect + go.opentelemetry.io/collector/featuregate v1.58.0 // indirect + go.opentelemetry.io/collector/pdata v1.58.0 // indirect go.opentelemetry.io/contrib/bridges/otelslog v0.18.0 // indirect go.opentelemetry.io/otel v1.43.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 // indirect go.opentelemetry.io/otel/log v0.19.0 // indirect go.opentelemetry.io/otel/metric v1.43.0 // indirect go.opentelemetry.io/otel/sdk v1.43.0 // indirect @@ -111,9 +110,9 @@ require ( golang.org/x/term v0.43.0 // indirect golang.org/x/text v0.37.0 // indirect golang.org/x/tools v0.44.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect - google.golang.org/grpc v1.80.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260522204824-7f3bc5b78da9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260522204824-7f3bc5b78da9 // indirect + google.golang.org/grpc v1.81.1 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/frand v1.5.1 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index 995e9c1..9eb3acd 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -10,8 +10,6 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= -github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= -github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -34,8 +32,8 @@ github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q= github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= -github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8= -github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ= +github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI= +github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ= github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= @@ -88,8 +86,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 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/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -97,10 +95,10 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= -github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= -github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA= +github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hcl/v2 v2.24.0 h1:2QJdZ454DSsYGoaE6QheQZjtKZSUs9Nh2izTWiwQxvE= +github.com/hashicorp/hcl/v2 v2.24.0/go.mod h1:oGoO1FIQYfn/AgyOhlg9qLC6/nOJPX3qGbkZpYAcqfM= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -121,20 +119,20 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/lucasb-eyer/go-colorful v1.3.0 h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag= -github.com/lucasb-eyer/go-colorful v1.3.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4= +github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= -github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4= +github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.21 h1:jJKAZiQH+2mIinzCJIaIG9Be1+0NR+5sz/lYEEjdM8w= -github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= +github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw= +github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs= github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= @@ -174,8 +172,8 @@ github.com/pulumi/esc v0.24.0 h1:sCtiB0qbyrlU1ZNzJn4dTLYiChl8xeCBFbHWl1YoXJg= github.com/pulumi/esc v0.24.0/go.mod h1:eCOOkcDJS6eooGwdE4/E0+pOsvUWG254+KBmPCFwJpA= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9FjWCUBCq6U= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= -github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1 h1:Hg9RK9zqIU9kFbD5KeiON06gPP7cLgS68jvsgMBmPgw= -github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.31.1/go.mod h1:BAWI9R3JEEGOp1JlXLPSZKwBGANSrPGUWKtMnS5w5qw= +github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.32.0 h1:QwJzM3PseaorfASUlDXxsyntVGac7ZSYjqjxa038uoU= +github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.32.0/go.mod h1:MtckkCd6mzQQ3AYw+qjdt6ROfdBB3dr8dI/dE5/jxrM= github.com/pulumi/pulumi/sdk/v3 v3.248.0 h1:TwY9uuToQO8xIey4a7awRzNX7iJ/doDmZkl1MzxULCE= github.com/pulumi/pulumi/sdk/v3 v3.248.0/go.mod h1:67RnWlA0uRHJKjbOkk1Hqz8BNefYv8csNLgln1EmmII= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= @@ -213,26 +211,26 @@ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavM github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0= -github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= +github.com/zclconf/go-cty v1.16.3 h1:osr++gw2T61A8KVYHoQiFbFd1Lh3JOCXc/jFLJXKTxk= +github.com/zclconf/go-cty v1.16.3/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= 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/collector/featuregate v1.53.0 h1:cgjXdtl7jezWxq6V0eohe/JqjY4PBotZGb5+bTR2OJw= -go.opentelemetry.io/collector/featuregate v1.53.0/go.mod h1:PS7zY/zaCb28EqciePVwRHVhc3oKortTFXsi3I6ee4g= -go.opentelemetry.io/collector/internal/testutil v0.147.0 h1:DFlRxBRp23/sZnpTITK25yqe0d56yNvK+63IaWc6OsU= -go.opentelemetry.io/collector/internal/testutil v0.147.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= -go.opentelemetry.io/collector/pdata v1.53.0 h1:DlYDbRwammEZaxDZHINx5v0n8SEOVNniPbi6FRTlVkA= -go.opentelemetry.io/collector/pdata v1.53.0/go.mod h1:LRSYGNjKXaUrZEwZv3Yl+8/zV2HmRGKXW62zB2bysms= +go.opentelemetry.io/collector/featuregate v1.58.0 h1:Kh6Dpgbxywv/Q3D6qPehaSxNCxvr/U/ki7CL4y3udCo= +go.opentelemetry.io/collector/featuregate v1.58.0/go.mod h1:4ga1QBMPEejXXmpyJS8lmaRpknJ3Lb9Bvk6e420bUFU= +go.opentelemetry.io/collector/internal/testutil v0.152.0 h1:8LGwekR7mLcUDhT1ofLmdnrHRFuUa3U7PBd95ZvJEjQ= +go.opentelemetry.io/collector/internal/testutil v0.152.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= +go.opentelemetry.io/collector/pdata v1.58.0 h1:5Lxut3NxKp87066Pzt+3q7+JUuFI5B3teCyLZIF8wIs= +go.opentelemetry.io/collector/pdata v1.58.0/go.mod h1:4vZtODINbC/JF3eGocnatdImzbRHseOywIcr+aULjCg= go.opentelemetry.io/contrib/bridges/otelslog v0.18.0 h1:hhPGP3zvvy1xWT9RTy970wlniSxFttBIsAK1gvMguJM= go.opentelemetry.io/contrib/bridges/otelslog v0.18.0/go.mod h1:twJF7inoMza6kxMcF8JOdL3mPmtOZu7GEr34CUNE6Dg= go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 h1:Dn8rkudDzY6KV9dr/D/bTUuWgqDf9xe0rr4G2elrn0Y= go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0/go.mod h1:gMk9F0xDgyN9M/3Ed5Y1wKcx/9mlU91NXY2SNq7RQuU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bTWkw0ICGcOLCAI5l6zsD1j20k= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 h1:RAE+JPfvEmvy+0LzyUA25/SGawPwIUbZ6u0Wug54sLc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0/go.mod h1:AGmbycVGEsRx9mXMZ75CsOyhSP6MFIcj/6dnG+vhVjk= go.opentelemetry.io/otel/log v0.19.0 h1:KUZs/GOsw79TBBMfDWsXS+KZ4g2Ckzksd1ymzsIEbo4= go.opentelemetry.io/otel/log v0.19.0/go.mod h1:5DQYeGmxVIr4n0/BcJvF4upsraHjg6vudJJpnkL6Ipk= go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= @@ -249,12 +247,12 @@ go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09 go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= 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/slim/otlp v1.9.0 h1:fPVMv8tP3TrsqlkH1HWYUpbCY9cAIemx184VGkS6vlE= -go.opentelemetry.io/proto/slim/otlp v1.9.0/go.mod h1:xXdeJJ90Gqyll+orzUkY4bOd2HECo5JofeoLpymVqdI= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0 h1:o13nadWDNkH/quoDomDUClnQBpdQQ2Qqv0lQBjIXjE8= -go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.2.0/go.mod h1:Gyb6Xe7FTi/6xBHwMmngGoHqL0w29Y4eW8TGFzpefGA= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0 h1:EiUYvtwu6PMrMHVjcPfnsG3v+ajPkbUeH+IL93+QYyk= -go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.2.0/go.mod h1:mUUHKFiN2SST3AhJ8XhJxEoeVW12oqfXog0Bo8W3Ec4= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= 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= @@ -295,7 +293,6 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/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/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= @@ -318,12 +315,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA= -google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= -google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/genproto/googleapis/api v0.0.0-20260522204824-7f3bc5b78da9 h1:dlKupvNsf7YXJYxduemxBzqGX8zjzedsttskfjgLIO8= +google.golang.org/genproto/googleapis/api v0.0.0-20260522204824-7f3bc5b78da9/go.mod h1:1dCETSCY2YKZNXQE3h4fun3TYwF5p8jejRKZgfWAgAY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260522204824-7f3bc5b78da9 h1:UScUq4IhqF8ll85bMGS/l0D+iGzwQXpX5RBYQEwjahU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260522204824-7f3bc5b78da9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ= +google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= 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 65aab7999707e1d3a76955e6b65d02fa43b5cea6 Mon Sep 17 00:00:00 2001 From: Radoslav Dimitrov Date: Thu, 9 Jul 2026 22:43:23 +0300 Subject: [PATCH 126/190] ci: auto-close PRs that try to publish servers via the repo (#1393) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary We keep getting PRs (e.g. #1385, #1368, #1367, #1363, #1354) that try to "publish" an MCP server by adding files under `servers/` or editing `data/seed.json`. That isn't how publishing works — servers are published with the `mcp-publisher` CLI against the live registry API. This adds automation that detects those PRs, comments with a pointer to the publishing quickstart, labels them `invalid`, and closes them. ## How it works (two stages, no `pull_request_target`) `pull_request_target` is intentionally avoided. Instead: - **Stage 1 — `detect-invalid-publish-prs.yml`** runs on `pull_request` (opened/reopened) with a **read-only** token. It only reads the changed file paths and, if the PR *exclusively* touches `servers/**` and/or `data/seed.json` (and the author isn't a MEMBER/OWNER/COLLABORATOR), records just the PR number as a short-lived artifact. It can't comment or close anything. - **Stage 2 — `close-invalid-publish-prs.yml`** runs via `workflow_run` in the trusted base-repo context (write token). It picks up the flagged PR number, **independently re-validates** the PR from the API (still open, external author, files still match, not already labeled), then comments, labels `invalid`, and closes. ### Trust boundary The only thing crossing from the untrusted stage to the privileged stage is the **PR number**, sanitized to digits only. Stage 2 never trusts stage 1's verdict — it re-derives every decision. Neither stage ever checks out or runs PR code. ### Safety against false positives - Fires only when a PR touches *exclusively* `servers/**` and/or `data/seed.json` — a real code PR that also happens to touch seed data is left alone. - Skips `MEMBER`/`OWNER`/`COLLABORATOR` authors, so maintainers editing dev seed data aren't auto-closed. - Idempotent: skips PRs already labeled `invalid` (e.g. if a maintainer reopens one). ## Notes - Like any `pull_request`/`workflow_run` automation, this only takes effect **once merged to `main`** — it is not retroactive and won't run on this PR. The currently-open offending PRs should be closed manually. - Pinned action SHAs match the repo's existing convention (`upload-artifact` reuses the SHA already in `ci.yml`). 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.8 --- .../workflows/close-invalid-publish-prs.yml | 141 ++++++++++++++++++ .../workflows/detect-invalid-publish-prs.yml | 82 ++++++++++ 2 files changed, 223 insertions(+) create mode 100644 .github/workflows/close-invalid-publish-prs.yml create mode 100644 .github/workflows/detect-invalid-publish-prs.yml diff --git a/.github/workflows/close-invalid-publish-prs.yml b/.github/workflows/close-invalid-publish-prs.yml new file mode 100644 index 0000000..27f69a8 --- /dev/null +++ b/.github/workflows/close-invalid-publish-prs.yml @@ -0,0 +1,141 @@ +name: Close invalid publish PRs + +# Stage 2 of 2 (see detect-invalid-publish-prs.yml for stage 1). +# +# Runs in the trusted base-repo context (triggered by workflow_run, not by the +# PR itself), so it has a write token. It picks up the PR number flagged by +# stage 1 and, after independently re-validating the PR from the API, posts a +# comment pointing at the publishing docs, labels it `invalid`, and closes it. +# +# Trust boundary: the ONLY thing crossing from the untrusted stage is the PR +# number (sanitized to digits below). We re-derive every decision (state, +# author, changed files) here, so a wrong/stale artifact can never cause us to +# close a PR that doesn't actually match. + +on: + workflow_run: + workflows: ["Detect invalid publish PRs"] + types: [completed] + +permissions: + contents: read + pull-requests: write + issues: write # labels on PRs go through the issues API + actions: read # needed to list/download the stage-1 artifact + +jobs: + close: + if: github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + RUN_ID: ${{ github.event.workflow_run.id }} + COMMENT_BODY: | + Hi @__AUTHOR__ 👋 — thanks for your interest in the MCP Registry! + + It looks like this PR is trying to publish an MCP server by adding or editing files in this repository (under `servers/` or in `data/seed.json`). That isn't how servers get published, so I'm closing this PR automatically. + + **Servers are published with the [`mcp-publisher`](https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/quickstart.mdx) CLI**, not by opening a pull request against this repo. The CLI verifies that you own your namespace and submits your `server.json` directly to the live registry API. + + To publish your server, follow the **[Publishing Quickstart](https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/quickstart.mdx)**. In short: + + ```bash + # Build the publisher CLI + make publisher + + # Authenticate (e.g. via GitHub) and publish your server.json + ./bin/mcp-publisher login github + ./bin/mcp-publisher publish + ``` + + Note: `data/seed.json` is seed data for **local development only** — adding entries there does not publish anything to the registry. + + If you believe this was closed in error, please leave a comment and a maintainer will take a look. 🙇 + + _This is an automated message._ + + steps: + - name: Check for flagged-pr artifact + id: check + run: | + set -euo pipefail + names="$(gh api "repos/$GH_REPO/actions/runs/$RUN_ID/artifacts" --jq '.artifacts[].name' || true)" + if printf '%s\n' "$names" | grep -qx "flagged-pr"; then + echo "found=true" >> "$GITHUB_OUTPUT" + else + echo "No flagged-pr artifact on run $RUN_ID; nothing to do." + echo "found=false" >> "$GITHUB_OUTPUT" + fi + + - name: Download flagged PR number + if: steps.check.outputs.found == 'true' + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: flagged-pr + run-id: ${{ github.event.workflow_run.id }} + github-token: ${{ github.token }} + + - name: Re-validate and close + if: steps.check.outputs.found == 'true' + run: | + set -euo pipefail + + # Sanitize: the only cross-boundary input. Keep digits only. + PR_NUMBER="$(tr -dc '0-9' < pr-number.txt)" + if [ -z "$PR_NUMBER" ]; then + echo "No valid PR number in artifact; skipping." + exit 0 + fi + echo "Re-validating PR #$PR_NUMBER" + + state="$(gh pr view "$PR_NUMBER" --json state --jq '.state')" + if [ "$state" != "OPEN" ]; then + echo "PR #$PR_NUMBER is $state, not OPEN; skipping." + exit 0 + fi + + assoc="$(gh pr view "$PR_NUMBER" --json authorAssociation --jq '.authorAssociation')" + case "$assoc" in + MEMBER|OWNER|COLLABORATOR) + echo "Author association '$assoc' is trusted; skipping." + exit 0 + ;; + esac + + # Idempotency: if a maintainer reopens after we labeled it, leave it be. + # Capture into a var first so a transient gh failure can't fail open + # (an errored fetch piped to grep would otherwise look "not labeled"). + labels="$(gh pr view "$PR_NUMBER" --json labels --jq '.labels[].name' || true)" + if printf '%s\n' "$labels" | grep -qx "invalid"; then + echo "PR #$PR_NUMBER already labeled 'invalid'; skipping." + exit 0 + fi + + # Paginated REST endpoint (gh pr view --json files caps at 100, no pagination). + mapfile -t FILES < <(gh api --paginate "repos/$GH_REPO/pulls/$PR_NUMBER/files" --jq '.[].filename') + if [ "${#FILES[@]}" -eq 0 ]; then + echo "No files for PR #$PR_NUMBER; skipping." + exit 0 + fi + publish_attempt=0 + other=0 + for f in "${FILES[@]}"; do + if [[ "$f" == servers/* || "$f" == "data/seed.json" ]]; then + publish_attempt=1 + else + other=1 + fi + done + if [ "$publish_attempt" -ne 1 ] || [ "$other" -ne 0 ]; then + echo "PR #$PR_NUMBER no longer matches the publish-attempt pattern; skipping." + exit 0 + fi + + author="$(gh pr view "$PR_NUMBER" --json author --jq '.author.login')" + body="${COMMENT_BODY//__AUTHOR__/$author}" + + echo "Commenting on, labeling, and closing PR #$PR_NUMBER" + gh pr comment "$PR_NUMBER" --body "$body" + gh pr edit "$PR_NUMBER" --add-label "invalid" || echo "Could not add label; continuing." + gh pr close "$PR_NUMBER" diff --git a/.github/workflows/detect-invalid-publish-prs.yml b/.github/workflows/detect-invalid-publish-prs.yml new file mode 100644 index 0000000..355521b --- /dev/null +++ b/.github/workflows/detect-invalid-publish-prs.yml @@ -0,0 +1,82 @@ +name: Detect invalid publish PRs + +# Stage 1 of 2 (see close-invalid-publish-prs.yml for stage 2). +# +# Some contributors try to "publish" a server by opening a PR that adds files +# under servers/ or edits data/seed.json. That is not how publishing works - +# servers are published with the mcp-publisher CLI against the live registry +# API. This job only DETECTS such PRs. It runs from the (untrusted) PR context +# with a read-only token, so it cannot comment on or close anything. When it +# finds a match it records just the PR number as an artifact; the privileged +# stage-2 workflow picks that up via workflow_run and acts on it. +# +# We never check out or run the PR's code - we only read changed file paths. + +on: + pull_request: + types: [opened, reopened] + +permissions: + contents: read + pull-requests: read + +jobs: + detect: + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ github.token }} + GH_REPO: ${{ github.repository }} + PR_NUMBER: ${{ github.event.pull_request.number }} + AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association }} + steps: + - name: Classify PR + id: classify + run: | + set -euo pipefail + match=false + + # Maintainers may legitimately touch these files (e.g. dev seed data), + # so never flag their PRs. + case "$AUTHOR_ASSOCIATION" in + MEMBER|OWNER|COLLABORATOR) + echo "Author association '$AUTHOR_ASSOCIATION' is trusted; not flagging." + ;; + *) + # Use the paginated REST endpoint: `gh pr view --json files` caps + # at 100 files with no pagination, which could truncate a large PR + # and cause a false match. + mapfile -t FILES < <(gh api --paginate "repos/$GH_REPO/pulls/$PR_NUMBER/files" --jq '.[].filename') + if [ "${#FILES[@]}" -gt 0 ]; then + # Flag only if the PR touches *exclusively* publish-attempt files + # (servers/** and/or data/seed.json) and nothing else, so that + # legit PRs touching seed data alongside real code are left alone. + publish_attempt=0 + other=0 + for f in "${FILES[@]}"; do + if [[ "$f" == servers/* || "$f" == "data/seed.json" ]]; then + publish_attempt=1 + else + echo "Non-publish file changed: $f" + other=1 + fi + done + if [ "$publish_attempt" -eq 1 ] && [ "$other" -eq 0 ]; then + match=true + fi + fi + ;; + esac + + echo "PR #$PR_NUMBER match=$match" + echo "match=$match" >> "$GITHUB_OUTPUT" + if [ "$match" = "true" ]; then + echo "$PR_NUMBER" > pr-number.txt + fi + + - name: Record flagged PR number + if: steps.classify.outputs.match == 'true' + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v4 + with: + name: flagged-pr + path: pr-number.txt + retention-days: 1 From f3162dbc1ecf54d27b5778bed62842078c7ece09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jul 2026 15:52:31 -0400 Subject: [PATCH 127/190] build(deps): bump golang.org/x/mod from 0.37.0 to 0.38.0 (#1428) Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.37.0 to 0.38.0. Commits
792ac16go.mod: update golang.org/x dependenciesfe2ec04all: fix some comments to improve readability- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c0a9a45..75e750d 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( go.opentelemetry.io/otel/metric v1.44.0 go.opentelemetry.io/otel/sdk v1.44.0 go.opentelemetry.io/otel/sdk/metric v1.44.0 - golang.org/x/mod v0.37.0 + golang.org/x/mod v0.38.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index f7a0590..f3500a1 100644 --- a/go.sum +++ b/go.sum @@ -162,8 +162,8 @@ go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= -golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= -golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= +golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= +golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40= 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/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= From 5cc44d091c4e76b1daaf127f0ac62ddbdb590f7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jul 2026 15:52:55 -0400 Subject: [PATCH 128/190] build(deps): bump github.com/coreos/go-oidc/v3 from 3.19.0 to 3.20.0 (#1429) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc) from 3.19.0 to 3.20.0. Release notes
Sourced from github.com/coreos/go-oidc/v3's releases.
v3.20.0
What's Changed
- oidc: modernize with new Go APIs by
@ericchiangin coreos/go-oidc#487- oidc: improve documentation for APIs by
@ericchiangin coreos/go-oidc#488- SECURITY.md: add a security policy and point to project-level reporting by
@ericchiangin coreos/go-oidc#489- oidc: ignore JWKs with unknown signing algorithms rather than failing by
@ericchiangin coreos/go-oidc#491- readme: update README and docs by
@ericchiangin coreos/go-oidc#492- oidc: add API for determining when issuer URLs mismatch by
@ericchiangin coreos/go-oidc#493- oidc: add constants for "email" and "profile" scopes by
@ericchiangin coreos/go-oidc#494Full Changelog: https://github.com/coreos/go-oidc/compare/v3.19.0...v3.20.0
Commits
75dfa5coidc: add constants for "email" and "profile" scopesa89f046oidc: add API for determining when issuer URLs mismatch6a69b6dreadme: update README and docsf9049c9oidc: ignore JWKs with unknown signing algorithms rather than failing2f178e0SECURITY.md: add a security policy and point to project-level reportingb3bc7daoidc: improve documentation for APIs0db9053oidc: modernize with new Go APIs- See full diff in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 75e750d..6e3d61f 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.14.0 github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.5.0 github.com/caarlos0/env/v11 v11.4.1 - github.com/coreos/go-oidc/v3 v3.19.0 + github.com/coreos/go-oidc/v3 v3.20.0 github.com/danielgtaylor/huma/v2 v2.38.0 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/go-containerregistry v0.21.7 diff --git a/go.sum b/go.sum index f3500a1..d6507fd 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,8 @@ 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/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= -github.com/coreos/go-oidc/v3 v3.19.0 h1:F/xyOi3x1UnG1U27YVnM1N6bHiL1K2upi6U/0qr8r+I= -github.com/coreos/go-oidc/v3 v3.19.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4= +github.com/coreos/go-oidc/v3 v3.20.0 h1:EtE0WIBHk03N+DqGkY4+UONzzZHk7amKt6IyNd7OsZE= +github.com/coreos/go-oidc/v3 v3.20.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4= github.com/danielgtaylor/huma/v2 v2.38.0 h1:fb0WZCatnaiHLphMQDDWDjygNxfMkX/ENma3QsRl7vY= github.com/danielgtaylor/huma/v2 v2.38.0/go.mod h1:k9hwjlgWFt1t2jsmQGlsgXAG2FBTZa4kkjV581qAtfo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From 7f647ef44fafa91be0cb549880a1440cb17e0daf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jul 2026 15:53:11 -0400 Subject: [PATCH 129/190] build(deps): bump the actions group across 1 directory with 4 updates (#1430) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the actions group with 4 updates in the / directory: [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action), [ko-build/setup-ko](https://github.com/ko-build/setup-ko), [docker/login-action](https://github.com/docker/login-action) and [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action). Updates `golangci/golangci-lint-action` from 9.2.1 to 9.3.0 Release notes
Sourced from golangci/golangci-lint-action's releases.
v9.3.0
What's Changed
Changes
- feat: add no-run-logs-group as experimental option by
@ldezin golangci/golangci-lint-action#1403Dependencies
- build(deps): bump github/codeql-action from 4.35.4 to 4.35.5 in the github-actions group by
@dependabot[bot] in golangci/golangci-lint-action#1395- build(deps): bump tmp from 0.2.5 to 0.2.6 by
@dependabot[bot] in golangci/golangci-lint-action#1397- build(deps): bump github/codeql-action from 4.35.5 to 4.36.0 in the github-actions group by
@dependabot[bot] in golangci/golangci-lint-action#1398- build(deps): bump tmp from 0.2.6 to 0.2.7 by
@dependabot[bot] in golangci/golangci-lint-action#1399- build(deps-dev): bump js-yaml from 4.1.1 to 4.2.0 by
@dependabot[bot] in golangci/golangci-lint-action#1400Full Changelog: https://github.com/golangci/golangci-lint-action/compare/v9.2.1...v9.3.0
Commits
ba0d7d2chore: prepare release v9.3.0efd0857feat: add no-run-logs-group as experimental option (#1403)ed485debuild(deps): bump undici from 6.24.0 to 6.27.08872e8dbuild(deps-dev): bump js-yaml from 4.1.1 to 4.2.0 (#1400)b163415build(deps): bump tmp from 0.2.6 to 0.2.7 (#1399)e52a9f8build(deps): bump github/codeql-action from 4.35.5 to 4.36.0 in the github-ac...8182aa3build(deps): bump tmp from 0.2.5 to 0.2.6 (#1397)5403a41build(deps): bump github/codeql-action from 4.35.4 to 4.35.5 in the github-ac...- See full diff in compare view
Updates `ko-build/setup-ko` from 0.9 to 0.10Release notes
Sourced from ko-build/setup-ko's releases.
v0.10
What's Changed
- Harden composite action against shell expression and env-file injection by
@imjasonhwith@Copilotin ko-build/setup-ko#66New Contributors
@imjasonhwith@Copilotmade their first contribution in ko-build/setup-ko#66Full Changelog: https://github.com/ko-build/setup-ko/compare/v0.9...v0.10
Commits
61b4d1dMerge pull request #66 from ko-build/copilot/address-findings-report92951cdHarden composite action shell input handling369dc1fMerge pull request #64 from ko-build/dependabot/github_actions/actions/checko...aa4f2f2Bump actions/checkout from 6.0.3 to 7.0.02e5f3a9Merge pull request #62 from ko-build/dependabot/github_actions/all-22d6a8b472fefb89fUpdate use-action.yaml074c423Update Go version from 1.25 to 1.26 in CI workflowd43b839Bump the all group across 1 directory with 2 updates8719e8eMerge pull request #60 from ko-build/dependabot/github_actions/all-2c6e677ddc9beb6abBump actions/setup-go from 6.2.0 to 6.3.0 in the all group- Additional commits viewable in compare view
Updates `docker/login-action` from 4.2.0 to 4.4.0Release notes
Sourced from docker/login-action's releases.
v4.4.0
- Skip empty
registry-authsecret mask by@crazy-maxin docker/login-action#1035- Bump
@aws-sdk/client-ecrand@aws-sdk/client-ecr-publicto 3.1077.0 docker/login-action#1034Full Changelog: https://github.com/docker/login-action/compare/v4.3.0...v4.4.0
v4.3.0
- Preserve names in esbuild bundle by
@crazy-maxin docker/login-action#1022- Bump
@aws-sdk/client-ecrand@aws-sdk/client-ecr-publicto 3.1076.0 docker/login-action#999 docker/login-action#1030- Bump
@docker/actions-toolkitfrom 0.90.0 to 0.92.0 in docker/login-action#1004 docker/login-action#1027- Bump
@sigstore/corefrom 3.1.0 to 3.2.1 in docker/login-action#1023- Bump
@sigstore/verifyfrom 3.1.0 to 3.1.1 in docker/login-action#1029- Bump http-proxy-agent and https-proxy-agent to 9.1.0 in docker/login-action#1017
- Bump js-yaml from 4.1.1 to 5.2.0 in docker/login-action#1028
- Bump sigstore from 4.1.0 to 4.1.1 in docker/login-action#1031
- Bump tmp from 0.2.5 to 0.2.7 in docker/login-action#1002
- Bump undici from 6.24.1 to 6.27.0 in docker/login-action#1020
- Bump vite from 7.3.3 to 7.3.6 in docker/login-action#1019
Full Changelog: https://github.com/docker/login-action/compare/v4.2.0...v4.3.0
Commits
af1e73fMerge pull request #1034 from docker/dependabot/npm_and_yarn/aws-sdk-dependen...da722bd[dependabot skip] chore: update generated content2916ad6build(deps): bump the aws-sdk-dependencies group across 1 directory with 2 up...ca0a662Merge pull request #1035 from crazy-max/fix-registry-auth-empty-maskc455755chore: update generated content4835190skip empty registry-auth secret mask992421cMerge pull request #1033 from docker/dependabot/github_actions/docker/bake-ac...b249b43Merge pull request #1032 from docker/dependabot/github_actions/docker/bake-ac...1b67977build(deps): bump docker/bake-action from 7.2.0 to 7.3.09d49d6abuild(deps): bump docker/bake-action/subaction/matrix- Additional commits viewable in compare view
Updates `goreleaser/goreleaser-action` from 7.2.2 to 7.2.3Release notes
Sourced from goreleaser/goreleaser-action's releases.
v7.2.3
What's Changed
- ci(deps): bump the actions group with 3 updates by
@dependabot[bot] in goreleaser/goreleaser-action#563- chore(deps): bump undici from 6.24.1 to 6.27.0 by
@dependabot[bot] in goreleaser/goreleaser-action#565- build: regenerate dist after undici 6.27.0 bump by
@caarlos0in goreleaser/goreleaser-action#567- ci: auto-rebuild dist on dependabot PRs by
@caarlos0in goreleaser/goreleaser-action#568- ci: use a GitHub App token to rebuild dist on dependabot PRs by
@caarlos0in goreleaser/goreleaser-action#569Full Changelog: https://github.com/goreleaser/goreleaser-action/compare/v7.2.2...v7.2.3
Commits
f06c13bchore: update distd393459ci: fix jobee731b1chore: workflow dispatch55de448chore(deps): bump js-yaml from 4.1.1 to 4.2.0a4f614eci: use a GitHub App token to rebuild dist on dependabot PRs (#569)d2d17a6ci: auto-rebuild dist on dependabot PRs (#568)d13def3build: regenerate dist after undici 6.27.0 bump (#567)21549b6chore(deps): bump undici from 6.24.1 to 6.27.0 (#565)47c416dci(deps): bump the actions group with 3 updates (#563)- See full diff in compare view
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/deploy-staging.yml | 4 ++-- .github/workflows/release.yml | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c5edb0..54a4942 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: cache: true - name: Run lint - uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee + uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a with: version: v2.11.4 @@ -57,7 +57,7 @@ jobs: cache: true - name: Set up ko - uses: ko-build/setup-ko@v0.9 + uses: ko-build/setup-ko@v0.10 - name: Run all tests run: make test-all diff --git a/.github/workflows/deploy-staging.yml b/.github/workflows/deploy-staging.yml index 7ef30b9..7093f4d 100644 --- a/.github/workflows/deploy-staging.yml +++ b/.github/workflows/deploy-staging.yml @@ -31,10 +31,10 @@ jobs: cache: true - name: Set up ko - uses: ko-build/setup-ko@v0.9 + uses: ko-build/setup-ko@v0.10 - name: Log in to Container Registry - uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee + uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 13fb866..2e2df6a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,7 +31,7 @@ jobs: uses: anchore/sbom-action/download-syft@v0.24.0 - name: Run GoReleaser - uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 + uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 with: distribution: goreleaser version: v2.12.0 @@ -54,10 +54,10 @@ jobs: cache: true - name: Set up ko - uses: ko-build/setup-ko@v0.9 + uses: ko-build/setup-ko@v0.10 - name: Log in to Container Registry - uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee + uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 with: registry: ghcr.io username: ${{ github.actor }} From 224e23dc2c9fc68ed054e335defd6ca8b64235b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jul 2026 15:53:31 -0400 Subject: [PATCH 130/190] build(deps): bump github.com/pulumi/pulumi/sdk/v3 from 3.248.0 to 3.251.0 in /deploy (#1431) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from 3.248.0 to 3.251.0. Release notes
Sourced from github.com/pulumi/pulumi/sdk/v3's releases.
v3.251.0
3.251.0 (2026-07-08)
Bug Fixes
- [cli] Show a
retainmarker for retain-on-delete resources in--diffoutput #23754- [cli] Don't miscopy out archives #23798
Miscellaneous
- [cli] Add
pulumi neo --debug-updateandpulumi neo --debug-previewflags to investigate a failed update or preview, suggested in the failure output #23499Improvements
- [cli/convert] Add an
ecosystemfield to converter mapping requests so a converter can request mappings for the ecosystem it consumes rather than its own name #23804- [cli/deployment]
pulumi deployment settingsno longer writes the localPulumi.<stack>.deploy.yamlfile: the experimentalinit,pull,configure, andenvsubcommands have been removed, and the CLI no longer calls the deployment-settings encrypt endpoint.get/edit/destroycontinue to manage settings directly in Pulumi Cloud #23480- [cli/deployment] The deployment settings file (
Pulumi.<stack>.deploy.yaml) has been removed entirely. The experimentalpulumi deployment settings push(update/up) command, the--config-fileflag, and the SDK helpers that read the file have been removed. Manage deployment settings directly in Pulumi Cloud withpulumi deployment settings get,edit, anddestroy#23480Bug Fixes
- [cli/display] Prevent plugin debug logs from appearing as raw JSON in the CLI's output when logging with
--logtostderr#23633Improvements
- [cli/env] Report the new revision number when an environment definition is updated (e.g.
pulumi env edit,pulumi env provider,pulumi env version rollback) #23799Miscellaneous
- [cli/env] Fold the Pulumi ESC engine and CLI into the pulumi/pulumi monorepo, removing the sdk↔esc Go module cycle. Internal refactor with no user-facing behavior change;
pulumi env/pulumi escare unaffected. #23746Improvements
- [cli/import] Support importing resources under parameterized providers from a converter or import file #23763
- [cli/import] Support importing resources under extension-parameterized providers #23779
Features
- [engine] Add
TargetSnippetsto deployment options to target snippets by UUID. #23745Improvements
- [engine] Add OpenTelemetry spans to the StackReference read path so performance traces can pinpoint slow snapshot fetches, deserialization, or secret decryption #23787
Features
- [programgen/pcl] Invoke functions declared with multi-argument inputs using positional arguments in PCL #23571
Bug Fixes
- [sdk/nodejs] Don't include the version in module paths when serializing functions when using pnpm #23767
... (truncated)
Changelog
Sourced from github.com/pulumi/pulumi/sdk/v3's changelog.
3.251.0 (2026-07-08)
Bug Fixes
- [cli] Show a
retainmarker for retain-on-delete resources in--diffoutput #23754- [cli] Don't miscopy out archives #23798
Miscellaneous
- [cli] Add
pulumi neo --debug-updateandpulumi neo --debug-previewflags to investigate a failed update or preview, suggested in the failure output #23499Improvements
- [cli/convert] Add an
ecosystemfield to converter mapping requests so a converter can request mappings for the ecosystem it consumes rather than its own name #23804- [cli/deployment]
pulumi deployment settingsno longer writes the localPulumi.<stack>.deploy.yamlfile: the experimentalinit,pull,configure, andenvsubcommands have been removed, and the CLI no longer calls the deployment-settings encrypt endpoint.get/edit/destroycontinue to manage settings directly in Pulumi Cloud #23480- [cli/deployment] The deployment settings file (
Pulumi.<stack>.deploy.yaml) has been removed entirely. The experimentalpulumi deployment settings push(update/up) command, the--config-fileflag, and the SDK helpers that read the file have been removed. Manage deployment settings directly in Pulumi Cloud withpulumi deployment settings get,edit, anddestroy#23480Bug Fixes
- [cli/display] Prevent plugin debug logs from appearing as raw JSON in the CLI's output when logging with
--logtostderr#23633Improvements
- [cli/env] Report the new revision number when an environment definition is updated (e.g.
pulumi env edit,pulumi env provider,pulumi env version rollback) #23799Miscellaneous
- [cli/env] Fold the Pulumi ESC engine and CLI into the pulumi/pulumi monorepo, removing the sdk↔esc Go module cycle. Internal refactor with no user-facing behavior change;
pulumi env/pulumi escare unaffected. #23746Improvements
- [cli/import] Support importing resources under parameterized providers from a converter or import file #23763
- [cli/import] Support importing resources under extension-parameterized providers #23779
Features
- [engine] Add
TargetSnippetsto deployment options to target snippets by UUID. #23745Improvements
- [engine] Add OpenTelemetry spans to the StackReference read path so performance traces can pinpoint slow snapshot fetches, deserialization, or secret decryption #23787
Features
- [programgen/pcl] Invoke functions declared with multi-argument inputs using positional arguments in PCL #23571
Bug Fixes
... (truncated)
Commits
aff0ffado: fix--dry-runfor delete (#23809)c9a8790Add pulumi neo debug command (#23499)4a79549Invoke multi-argument-input functions positionally in PCL (#23571)3212152do: make default input YAML (#23808)93ab968Add an ecosystem to converter mapping requests (#23804)82c4164do: align prompting with up/destroy (#23805)3ec2532Update actions/download-artifact action to v8 (#23793)5e1b1d0Add more tracing spans around stack references (#23787)45b7ec7do: improve usage section (#23782)54b4e80Don't include the version in module paths when serializing functions when usi...- Additional commits viewable in compare view
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---Signed-off-by: dependabot[bot]Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot showignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- deploy/go.mod | 3 +-- deploy/go.sum | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/deploy/go.mod b/deploy/go.mod index 14d4db7..10d9778 100644 --- a/deploy/go.mod +++ b/deploy/go.mod @@ -5,7 +5,7 @@ go 1.26 require ( github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.32.0 - github.com/pulumi/pulumi/sdk/v3 v3.248.0 + github.com/pulumi/pulumi/sdk/v3 v3.251.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -72,7 +72,6 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pkg/term v1.1.0 // indirect github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect - github.com/pulumi/esc v0.24.0 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect diff --git a/deploy/go.sum b/deploy/go.sum index 9eb3acd..86abe20 100644 --- a/deploy/go.sum +++ b/deploy/go.sum @@ -168,14 +168,12 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 h1:vkHw5I/plNdTr435cARxCW6q9gc0S/Yxz7Mkd38pOb0= github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231/go.mod h1:murToZ2N9hNJzewjHBgfFdXhZKjY3z5cYC1VXk+lbFE= -github.com/pulumi/esc v0.24.0 h1:sCtiB0qbyrlU1ZNzJn4dTLYiChl8xeCBFbHWl1YoXJg= -github.com/pulumi/esc v0.24.0/go.mod h1:eCOOkcDJS6eooGwdE4/E0+pOsvUWG254+KBmPCFwJpA= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1 h1:w6OnO3d4j5yVf2vpm8OzXFC/xHOEGqt+9FjWCUBCq6U= github.com/pulumi/pulumi-gcp/sdk/v8 v8.41.1/go.mod h1:UyZyv7hz4knpFx6/Sh+SkZe6hT6sJHtDvw9A0TbvEsk= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.32.0 h1:QwJzM3PseaorfASUlDXxsyntVGac7ZSYjqjxa038uoU= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.32.0/go.mod h1:MtckkCd6mzQQ3AYw+qjdt6ROfdBB3dr8dI/dE5/jxrM= -github.com/pulumi/pulumi/sdk/v3 v3.248.0 h1:TwY9uuToQO8xIey4a7awRzNX7iJ/doDmZkl1MzxULCE= -github.com/pulumi/pulumi/sdk/v3 v3.248.0/go.mod h1:67RnWlA0uRHJKjbOkk1Hqz8BNefYv8csNLgln1EmmII= +github.com/pulumi/pulumi/sdk/v3 v3.251.0 h1:H1D42Jra2jvnEij0M0dZcNGz3Q9DyANsvzQqalncsXU= +github.com/pulumi/pulumi/sdk/v3 v3.251.0/go.mod h1:ZXd0WRd89VLX2juP+HEXMZ+J2AFPfcJTXhdmmv9cMgY= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= From 2bc37b199917aee2eb225f39fbb2474bbc26405c Mon Sep 17 00:00:00 2001 From: Tadas Antanavicius Date: Fri, 10 Jul 2026 14:05:47 -0700 Subject: [PATCH 131/190] fix(auth): grant org namespace only to org Owners, not all members (#1383) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## The bug (scoped to `github-at`) When you exchange a GitHub OAuth/PAT token for a registry JWT, the handler granted `io.github. /*` publish permission for **every** organization you belong to. It derived that list from [`GET /users/{username}/orgs`](https://docs.github.com/en/rest/orgs/orgs#list-organizations-for-a-user), which: 1. returns only **public** org memberships, and 2. carries **no role** — an org Owner and a brand-new member look identical. So membership was silently treated as publishing authority. Anyone who is (or whose public membership lists them as) a member of `acme` could publish — and, because publish is a pure namespace-glob with no per-server ownership check, **overwrite** — any server under `io.github.acme/*`. ## The fix Switch to [`GET /user/memberships/orgs`](https://docs.github.com/en/rest/orgs/members#list-organization-memberships-for-the-authenticated-user), which returns the **authenticated caller's role** per org (and includes private memberships), and grant the org namespace only when the role is `admin` (org Owner). - **Personal namespaces are unchanged** — you always get `io.github. /*`. - **Org namespaces now require Owner.** GitHub has no org-level "maintainer" role; org membership is either `admin` (Owner) or `member`. We grant only on `admin`. - **`read:org` is the only scope needed.** A minimal token without it still authenticates and still publishes to your personal namespace; a genuine missing-scope `403` from the memberships call is treated as "no admin orgs" rather than a hard failure, so we don't push anyone to over-scope a token. A `403`/`429` that is actually a rate limit (`X-RateLimit-Remaining: 0` / `Retry-After`) fails closed instead, so a throttle can't silently strip a real Owner's org grant. Critically, the token needs **no repository scopes** — the registry never reads or writes code, so an org Owner can hand CI a near-powerless `read:org` token. The authorization decision stays stateless and delegated to GitHub — no new storage, no new endpoints, no schema changes — consistent with [design principle #2](docs/design/design-principles.md) (minimal operational burden). ### Containing the CI token The registry-side change makes the org Owner the only one who can mint org-namespace authority. But if that Owner drops the resulting PAT into a plain repo secret, **every repository writer** can reach it (via branch/tag pushes that run repo-controlled build/test code in the privileged job) — quietly re-widening publish access beyond Owners. External fork contributors still cannot reach it by default (no secrets on fork PRs, no branch push), barring misconfigurations like `pull_request_target`-with-checkout or self-hosted runners on public repos. `docs/modelcontextprotocol-io/github-actions.mdx` documents how to contain that blast radius: - store the token as a **GitHub Actions Environment secret** (the PAT example uses `environment:`), - restrict that environment to the default branch / release tags and require PR reviews on it, so only reviewed, maintainer-approved code can reach the token, - optionally add a **required environment reviewer** for explicit per-publish approval, - and avoid the two footguns (`pull_request_target` checkout, self-hosted runners on public repos). This shrinks *who holds* the org credential; it does not change the fact that an authorized publish can still overwrite a different server in the same namespace until per-server publisher ownership exists (the follow-up noted below). ## Why this shape, given the alternatives [Pree's writeup](https://github.com/modelcontextprotocol/registry/issues/982#issuecomment-3982959559) ([Notion analysis doc](https://www.notion.so/MCP-Registry-Authorization-Model-Analysis-Issue-982-31736f79f74980bc90c6e53de1c564c5)) is the clearest framing of the problem and the option space, laying out three broad solutions: - **Approach A — GitHub App as the authority layer.** Strong model, but its natural unit of authority is a *repo*, so it needs a repo→server mapping to authorize a namespace. The safe, flexible version of that mapping is registry-managed state — which collapses into Approach B. It's also GitHub-only. - **Approach B — a registry-managed grants table** (OIDC bootstrap, or device-flow admin check). The most capable and provider-agnostic option, and probably where v1 wants to go. But it introduces exactly the "registry manages an authorization database" layer we wanted to avoid taking on right now: revocation, sync, audit, migration. - **Approach C — scoped bearer tokens (npm-style).** Good ergonomics, but again implies issuance/storage the registry would own. The two-property test (does the registry control the decision? is it granted through an act requiring real authority?) is the right lens. This change satisfies it **without** new state: the registry makes the decision (it filters on role), and the authority is real (live GitHub Owner role, re-checked on every short-lived token exchange). **What this deliberately gives up**, so reviewers can weigh it honestly: - **Owners are always in the loop.** Only org Owners can publish org servers; there's no delegated "this team can publish this server" — that needs Approach B's state. Reduced flexibility in exchange for zero new infrastructure. - **Blast radius within an org is unchanged.** An Owner (or Owner-scoped CI token) can still overwrite *any* server under the org namespace, because there's still no per-server publisher ownership. That hijack-an-existing-server problem is real but **orthogonal** to this fix and belongs in its own change (record publisher identity per server; enforce it on update) — a follow-up to take alongside the OIDC hardening below. - **OIDC is untouched and remains coarser.** The `github-oidc` path still grants the whole `io.github. /*` namespace to any workflow with `id-token: write`, i.e. effectively anyone with write access to any repo in the org, and it excludes non-Actions CI (Jenkins/GitLab can't mint GitHub Actions OIDC). The admin-PAT path here is the higher-assurance option for org publishing; OIDC stays as a lower-assurance Actions convenience to be tightened separately. ## Revocation The registry JWT is **5-minute, no-refresh** (per #264/#273), so loss of Owner status propagates within minutes on the next token exchange, with no revocation list to maintain. ## Tests `go test ./internal/api/handlers/v0/auth/...` passes, including: - member-role org is **not** granted; only admin orgs are - a missing-scope `403` (no `read:org`) still yields the personal namespace and no error - an admin org on a **later page** of memberships is still granted (pagination correctness) - a `5xx` from the memberships call **fails closed** (no token issued) rather than degrading to personal-only - a rate-limit `403` (`X-RateLimit-Remaining: 0` / `Retry-After`) **fails closed** — not mistaken for a missing-scope `403` - existing org/name-validation tests updated to the new endpoint + role shape `gofmt`/`go vet`/`golangci-lint` (CI-pinned v2.11.4) clean; CI green on all checks. ## Live verification Confirmed end-to-end against real `api.github.com` (not just mocks) by exercising this branch's `ExchangeToken` and decoding the `permissions` claim of the returned JWT. A dedicated org, **Tadasant Test Org** (login `Tadasant-Test-Org`), is Owned by one account and has a second account joined as a plain **member**. Both memberships are `active`, verified via the same endpoint the fix uses (`GET /user/memberships/orgs/{org}`): | Token (role) | `io.github.Tadasant-Test-Org/*` granted? | Other patterns granted | |---|---|---| | Owner (`admin`) | ✅ yes | personal `io.github. /*` | | member | ❌ no | personal `io.github. /*` + the orgs that account actually Owns | The member case is the meaningful one: that membership is **active and returned** by `GET /user/memberships/orgs`, and is excluded purely because its role is `member`, not `admin`. Under the previous `GET /users/{username}/orgs` behavior (membership = authority, no role), the same active membership **would have granted** the org namespace. The role filter is also selective rather than blanket-deny — the member account still receives the namespaces of the orgs where it genuinely holds Owner. --------- Co-authored-by: Claude Opus 4.8 Co-authored-by: Radoslav Dimitrov --- .../authentication.mdx | 8 + .../github-actions.mdx | 25 +- internal/api/handlers/v0/auth/github_at.go | 159 +++++++- .../v0/auth/github_at_internal_test.go | 33 ++ .../api/handlers/v0/auth/github_at_test.go | 385 +++++++++++++++++- 5 files changed, 573 insertions(+), 37 deletions(-) create mode 100644 internal/api/handlers/v0/auth/github_at_internal_test.go diff --git a/docs/modelcontextprotocol-io/authentication.mdx b/docs/modelcontextprotocol-io/authentication.mdx index 78bf23a..98131d5 100644 --- a/docs/modelcontextprotocol-io/authentication.mdx +++ b/docs/modelcontextprotocol-io/authentication.mdx @@ -47,6 +47,14 @@ Successfully authenticated! ✓ Successfully logged in ``` +### Personal vs. organization namespaces + +GitHub authentication always grants your personal namespace, `io.github.