diff --git a/go/go.mod b/go/go.mod
index 68638c04e30..65d59972f02 100644
--- a/go/go.mod
+++ b/go/go.mod
@@ -23,7 +23,7 @@ require (
github.com/klauspost/compress v1.20.0
github.com/microcosm-cc/bluemonday v1.0.27
github.com/nikolalohinski/gonja/v2 v2.9.0
- github.com/ossf/osv-schema/bindings/go v0.0.0-20260902031056-b388a18021a3
+ github.com/ossf/osv-schema/bindings/go v0.0.0-20260924053548-8e3305dedc07
github.com/package-url/packageurl-go v0.1.7
github.com/pandatix/go-cvss v0.6.4
github.com/prometheus/client_golang v1.24.1
diff --git a/go/go.sum b/go/go.sum
index 75b765b290f..3473da2ef0a 100644
--- a/go/go.sum
+++ b/go/go.sum
@@ -235,6 +235,8 @@ github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/ossf/osv-schema/bindings/go v0.0.0-20260902031056-b388a18021a3 h1:mNqW4tPTIPcx3KL5qZCByAHiTwGcwD/eCEfKOEvLA4g=
github.com/ossf/osv-schema/bindings/go v0.0.0-20260902031056-b388a18021a3/go.mod h1:aW9XJyUJfg0r+HogMGMagTt4hF6ibBkH/FZenG/KiyE=
+github.com/ossf/osv-schema/bindings/go v0.0.0-20260924053548-8e3305dedc07 h1:iSGN4UeIRS7B8jKaOsisArXvD7poOLUgEwcAIHuvTC4=
+github.com/ossf/osv-schema/bindings/go v0.0.0-20260924053548-8e3305dedc07/go.mod h1:aW9XJyUJfg0r+HogMGMagTt4hF6ibBkH/FZenG/KiyE=
github.com/package-url/packageurl-go v0.1.7 h1:iFWg6tzAjLA6F/qX3M5nZaiMHJgc+p2zxVyr/fY+sZY=
github.com/package-url/packageurl-go v0.1.7/go.mod h1:nKAWB8E6uk1MHqiS/lQb9pYBGH2+mdJ2PJc2s50dQY0=
github.com/pandatix/go-cvss v0.6.4 h1:9w2RCO/Q4UTiJyEgpCHRiVc6CfrsFEnkoX+OtATqKio=
diff --git a/go/osv/ecosystem/ecosystem.go b/go/osv/ecosystem/ecosystem.go
index 9ae50baf1a5..18b6dfd2423 100644
--- a/go/osv/ecosystem/ecosystem.go
+++ b/go/osv/ecosystem/ecosystem.go
@@ -70,6 +70,7 @@ var ecosystems = map[osvconstants.Ecosystem]ecosystemFactory{
osvconstants.EcosystemPub: func(p *Provider, _ string) Ecosystem { return pubEcosystem{p: p} },
osvconstants.EcosystemPyPI: func(p *Provider, _ string) Ecosystem { return pypiEcosystem{p: p} },
osvconstants.EcosystemRedHat: statelessFactory[rpmEcosystem],
+ osvconstants.EcosystemRedHatLightwell: redHatLightwellFactory,
osvconstants.EcosystemRockyLinux: statelessFactory[rpmEcosystem],
osvconstants.EcosystemRoot: rootEcosystemFactory,
osvconstants.EcosystemRubyGems: func(p *Provider, _ string) Ecosystem { return rubyGemsEcosystem{p: p} },
diff --git a/go/osv/ecosystem/red_hat_lightwell.go b/go/osv/ecosystem/red_hat_lightwell.go
new file mode 100644
index 00000000000..c0abf874953
--- /dev/null
+++ b/go/osv/ecosystem/red_hat_lightwell.go
@@ -0,0 +1,24 @@
+package ecosystem
+
+import (
+ "github.com/ossf/osv-schema/bindings/go/osvconstants"
+)
+
+// redHatLightwellFactory builds the Ecosystem for a "Red Hat Lightwell:"
+// OSV ecosystem, e.g. "Red Hat Lightwell:Maven" or "Red Hat Lightwell:PyPI".
+//
+// Red Hat Lightwell republishes upstream artifacts carrying a backport version
+// marker (Maven ".rhlw-NNNNN", PyPI "+rhlw.N") that sorts within the base
+// ecosystem's own version space, so version semantics delegate to the base
+// ecosystem named by the ":" suffix. An unsupported suffix yields a nil
+// Ecosystem, which Provider.Get reports as "not found".
+func redHatLightwellFactory(p *Provider, suffix string) Ecosystem {
+ switch osvconstants.Ecosystem(suffix) {
+ case osvconstants.EcosystemMaven:
+ return mavenEcosystem{p: p}
+ case osvconstants.EcosystemPyPI:
+ return pypiEcosystem{p: p}
+ default:
+ return nil
+ }
+}
diff --git a/go/osv/ecosystem/red_hat_lightwell_test.go b/go/osv/ecosystem/red_hat_lightwell_test.go
new file mode 100644
index 00000000000..1083d21e252
--- /dev/null
+++ b/go/osv/ecosystem/red_hat_lightwell_test.go
@@ -0,0 +1,29 @@
+package ecosystem
+
+import (
+ "testing"
+)
+
+func TestRedHatLightwell_Get(t *testing.T) {
+ p := NewProvider(nil)
+
+ tests := []struct {
+ name string
+ eco string
+ found bool
+ }{
+ {"maven suffix delegates", "Red Hat Lightwell:Maven", true},
+ {"pypi suffix delegates", "Red Hat Lightwell:PyPI", true},
+ {"unsupported suffix", "Red Hat Lightwell:npm", false},
+ {"missing suffix", "Red Hat Lightwell", false},
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ _, ok := p.Get(tt.eco)
+ if ok != tt.found {
+ t.Errorf("Get(%q) found = %v, want %v", tt.eco, ok, tt.found)
+ }
+ })
+ }
+}
diff --git a/go/purl/ecosystem_red_hat_lightwell.go b/go/purl/ecosystem_red_hat_lightwell.go
new file mode 100644
index 00000000000..b6b66bb9687
--- /dev/null
+++ b/go/purl/ecosystem_red_hat_lightwell.go
@@ -0,0 +1,39 @@
+package purl
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/ossf/osv-schema/bindings/go/osvconstants"
+ "github.com/package-url/packageurl-go"
+)
+
+//nolint:gochecknoinits // init is used here to register the ecosystem with the global PURL registry.
+func init() {
+ registerGenerator(osvconstants.EcosystemRedHatLightwell, generatorFunc(redHatLightwellGenerator))
+ // No reverse parser is registered on purpose: Red Hat Lightwell records carry
+ // pkg:maven / pkg:pypi PURLs, whose types are already owned by the Maven/PyPI
+ // parsers (registerParser panics on collision). PURL -> ecosystem resolution
+ // for Lightwell is done via explicit ecosystem queries rather than the shared
+ // pkg:maven/pkg:pypi types, which belong to the upstream ecosystems.
+}
+
+// redHatLightwellGenerator builds the PURL for a "Red Hat Lightwell:"
+// package by delegating to the base ecosystem's registered generator, named by
+// the ":" suffix (e.g. "Red Hat Lightwell:Maven" -> pkg:maven, ":PyPI" -> pkg:pypi).
+func redHatLightwellGenerator(ecosystem, packageName string) (packageurl.PackageURL, error) {
+ _, suffix, _ := strings.Cut(ecosystem, ":")
+ base := osvconstants.Ecosystem(suffix)
+
+ switch base {
+ case osvconstants.EcosystemMaven, osvconstants.EcosystemPyPI:
+ gen, ok := generators[base]
+ if !ok {
+ return packageurl.PackageURL{}, fmt.Errorf("no PURL generator registered for base ecosystem %q", base)
+ }
+
+ return gen.generate(string(base), packageName)
+ default:
+ return packageurl.PackageURL{}, fmt.Errorf("unsupported Red Hat Lightwell ecosystem suffix %q", suffix)
+ }
+}
diff --git a/go/purl/ecosystem_red_hat_lightwell_test.go b/go/purl/ecosystem_red_hat_lightwell_test.go
new file mode 100644
index 00000000000..129c9a8ef25
--- /dev/null
+++ b/go/purl/ecosystem_red_hat_lightwell_test.go
@@ -0,0 +1,34 @@
+package purl
+
+import (
+ "testing"
+)
+
+func TestRedHatLightwellGenerate(t *testing.T) {
+ tests := []struct {
+ ecosystem string
+ packageName string
+ want string
+ wantErr bool
+ }{
+ {"Red Hat Lightwell:Maven", "org.apache.commons:commons-lang3", "pkg:maven/org.apache.commons/commons-lang3", false},
+ {"Red Hat Lightwell:PyPI", "requests", "pkg:pypi/requests", false},
+ // Unsupported / missing suffix.
+ {"Red Hat Lightwell:npm", "foo", "", true},
+ {"Red Hat Lightwell", "foo", "", true},
+ }
+
+ for _, tt := range tests {
+ got, err := Generate(tt.ecosystem, tt.packageName)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("Generate(%q, %q) error = %v, wantErr %v", tt.ecosystem, tt.packageName, err, tt.wantErr)
+ continue
+ }
+ if tt.wantErr {
+ continue
+ }
+ if got != tt.want {
+ t.Errorf("Generate(%q, %q) = %q, want %q", tt.ecosystem, tt.packageName, got, tt.want)
+ }
+ }
+}