diff --git a/workhorse/internal/api/api.go b/workhorse/internal/api/api.go
index aa6d7cf1bc785cf78ae8677f96edc8dc16b779c0..6a6a51b27bbd0c56b685ca6531dd539fa1a1fee8 100644
--- a/workhorse/internal/api/api.go
+++ b/workhorse/internal/api/api.go
@@ -19,7 +19,6 @@ import (
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/log"
-
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/secret"
 )
 
diff --git a/workhorse/internal/dependencyproxy/dependencyproxy.go b/workhorse/internal/dependencyproxy/dependencyproxy.go
index 90f3042a342c452fa7a3dbbcbf1fbe406103a025..6651b5aee8417a66ee21383b7c82b4a817096c9b 100644
--- a/workhorse/internal/dependencyproxy/dependencyproxy.go
+++ b/workhorse/internal/dependencyproxy/dependencyproxy.go
@@ -9,12 +9,12 @@ import (
 	"gitlab.com/gitlab-org/labkit/log"
 
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
-	"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/senddata"
+	"gitlab.com/gitlab-org/gitlab/workhorse/internal/transport"
 )
 
 var httpClient = &http.Client{
-	Transport: httptransport.New(),
+	Transport: transport.NewRestrictedTransport(),
 }
 
 type Injector struct {
diff --git a/workhorse/internal/helper/httptransport/http_transport.go b/workhorse/internal/helper/httptransport/http_transport.go
deleted file mode 100644
index c7c3c5283f5d019a175a0862cdb5e5355f2e621f..0000000000000000000000000000000000000000
--- a/workhorse/internal/helper/httptransport/http_transport.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package httptransport
-
-import (
-	"net/http"
-	"time"
-
-	"gitlab.com/gitlab-org/labkit/correlation"
-	"gitlab.com/gitlab-org/labkit/tracing"
-)
-
-type Option func(*http.Transport)
-
-// Defines a http.Transport with values
-// that are more restrictive than for http.DefaultTransport,
-// they define shorter TLS Handshake, and more aggressive connection closing
-// to prevent the connection hanging and reduce FD usage
-func New(options ...Option) http.RoundTripper {
-	t := http.DefaultTransport.(*http.Transport).Clone()
-
-	// To avoid keep around TCP connections to http servers we're done with
-	t.MaxIdleConns = 2
-
-	// A stricter timeout for fetching from external sources that can be slow
-	t.ResponseHeaderTimeout = 30 * time.Second
-
-	for _, option := range options {
-		option(t)
-	}
-
-	return tracing.NewRoundTripper(correlation.NewInstrumentedRoundTripper(t))
-}
-
-func WithDisabledCompression() Option {
-	return func(t *http.Transport) {
-		t.DisableCompression = true
-	}
-}
diff --git a/workhorse/internal/imageresizer/image_resizer.go b/workhorse/internal/imageresizer/image_resizer.go
index 8c3271b6f11badac20b56dfcf97227ac97a86aba..092369cd2af8be2c256946ef4be0832398c6687a 100644
--- a/workhorse/internal/imageresizer/image_resizer.go
+++ b/workhorse/internal/imageresizer/image_resizer.go
@@ -21,9 +21,9 @@ import (
 
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
-	"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/log"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/senddata"
+	"gitlab.com/gitlab-org/gitlab/workhorse/internal/transport"
 )
 
 type Resizer struct {
@@ -69,7 +69,7 @@ const (
 var envInjector = tracing.NewEnvInjector()
 
 var httpClient = &http.Client{
-	Transport: httptransport.New(),
+	Transport: transport.NewRestrictedTransport(),
 }
 
 const (
diff --git a/workhorse/internal/sendurl/sendurl.go b/workhorse/internal/sendurl/sendurl.go
index 205ec8a0e9fbb09956e7e3f0e6c5940612329063..8e679c6b47524a39eb991c7af69133e7fb6a3af6 100644
--- a/workhorse/internal/sendurl/sendurl.go
+++ b/workhorse/internal/sendurl/sendurl.go
@@ -11,9 +11,9 @@ import (
 	"gitlab.com/gitlab-org/labkit/mask"
 
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
-	"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/log"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/senddata"
+	"gitlab.com/gitlab-org/gitlab/workhorse/internal/transport"
 )
 
 type entry struct{ senddata.Prefix }
@@ -44,7 +44,7 @@ var preserveHeaderKeys = map[string]bool{
 	"Pragma":        true, // Support for HTTP 1.0 proxies
 }
 
-var httpTransport = httptransport.New()
+var httpTransport = transport.NewRestrictedTransport()
 
 var httpClient = &http.Client{
 	Transport: httpTransport,
diff --git a/workhorse/internal/transport/transport.go b/workhorse/internal/transport/transport.go
new file mode 100644
index 0000000000000000000000000000000000000000..f19d332a28a63263378944fded2358d5106b8f2f
--- /dev/null
+++ b/workhorse/internal/transport/transport.go
@@ -0,0 +1,58 @@
+package transport
+
+import (
+	"net/http"
+	"time"
+
+	"gitlab.com/gitlab-org/labkit/correlation"
+	"gitlab.com/gitlab-org/labkit/tracing"
+
+	"gitlab.com/gitlab-org/gitlab/workhorse/internal/version"
+)
+
+// Creates a new default transport that has Workhorse's User-Agent header set.
+func NewDefaultTransport() http.RoundTripper {
+	return &DefaultTransport{Next: http.DefaultTransport}
+}
+
+// Defines a http.Transport with values that are more restrictive than for
+// http.DefaultTransport, they define shorter TLS Handshake, and more
+// aggressive connection closing to prevent the connection hanging and reduce
+// FD usage
+func NewRestrictedTransport(options ...Option) http.RoundTripper {
+	return &DefaultTransport{Next: newRestrictedTransport(options...)}
+}
+
+type DefaultTransport struct {
+	Next http.RoundTripper
+}
+
+func (t DefaultTransport) RoundTrip(req *http.Request) (*http.Response, error) {
+	req.Header.Set("User-Agent", version.GetUserAgent())
+
+	return t.Next.RoundTrip(req)
+}
+
+type Option func(*http.Transport)
+
+func WithDisabledCompression() Option {
+	return func(t *http.Transport) {
+		t.DisableCompression = true
+	}
+}
+
+func newRestrictedTransport(options ...Option) http.RoundTripper {
+	t := http.DefaultTransport.(*http.Transport).Clone()
+
+	// To avoid keep around TCP connections to http servers we're done with
+	t.MaxIdleConns = 2
+
+	// A stricter timeout for fetching from external sources that can be slow
+	t.ResponseHeaderTimeout = 30 * time.Second
+
+	for _, option := range options {
+		option(t)
+	}
+
+	return tracing.NewRoundTripper(correlation.NewInstrumentedRoundTripper(t))
+}
diff --git a/workhorse/internal/upload/destination/objectstore/object.go b/workhorse/internal/upload/destination/objectstore/object.go
index 36ffa0eb12e725bf8d18af63effaa9163cece592..1086332312c0f96151d2d464002287446173d988 100644
--- a/workhorse/internal/upload/destination/objectstore/object.go
+++ b/workhorse/internal/upload/destination/objectstore/object.go
@@ -8,11 +8,11 @@ import (
 
 	"gitlab.com/gitlab-org/labkit/mask"
 
-	"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport"
+	"gitlab.com/gitlab-org/gitlab/workhorse/internal/transport"
 )
 
 var httpClient = &http.Client{
-	Transport: httptransport.New(),
+	Transport: transport.NewRestrictedTransport(),
 }
 
 // Object represents an object on a S3 compatible Object Store service.
diff --git a/workhorse/internal/version/version.go b/workhorse/internal/version/version.go
new file mode 100644
index 0000000000000000000000000000000000000000..790edf8ffca9b6b8ed1d638cadfd57db23121795
--- /dev/null
+++ b/workhorse/internal/version/version.go
@@ -0,0 +1,20 @@
+package version
+
+import "fmt"
+
+var version = "unknown"
+var build = "unknown"
+var schema = "gitlab-workhorse (%s)-(%s)"
+
+func SetVersion(v, b string) {
+	version = v
+	build = b
+}
+
+func GetUserAgent() string {
+	return GetApplicationVersion()
+}
+
+func GetApplicationVersion() string {
+	return fmt.Sprintf(schema, version, build)
+}
diff --git a/workhorse/internal/version/version_test.go b/workhorse/internal/version/version_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..9d0581e093b3de507976f760ee1ffc80e9709166
--- /dev/null
+++ b/workhorse/internal/version/version_test.go
@@ -0,0 +1,19 @@
+package version
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestVersion(t *testing.T) {
+	require.Equal(t, GetApplicationVersion(), "gitlab-workhorse (unknown)-(unknown)")
+
+	SetVersion("15.3", "123.123")
+
+	require.Equal(t, GetApplicationVersion(), "gitlab-workhorse (15.3)-(123.123)")
+
+	SetVersion("", "123.123")
+
+	require.Equal(t, GetApplicationVersion(), "gitlab-workhorse ()-(123.123)")
+}
diff --git a/workhorse/internal/zipartifacts/open_archive.go b/workhorse/internal/zipartifacts/open_archive.go
index 881ef915d75dad73abecbd2cbd4c96da0d51b5cb..d477725a39f722c661cca6129779865b88d0a1fa 100644
--- a/workhorse/internal/zipartifacts/open_archive.go
+++ b/workhorse/internal/zipartifacts/open_archive.go
@@ -8,16 +8,16 @@ import (
 	"os"
 	"strings"
 
-	"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/httptransport"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/httprs"
+	"gitlab.com/gitlab-org/gitlab/workhorse/internal/transport"
 
 	zip "gitlab.com/gitlab-org/golang-archive-zip"
 	"gitlab.com/gitlab-org/labkit/mask"
 )
 
 var httpClient = &http.Client{
-	Transport: httptransport.New(
-		httptransport.WithDisabledCompression(), // To avoid bugs when serving compressed files from object storage
+	Transport: transport.NewRestrictedTransport(
+		transport.WithDisabledCompression(), // To avoid bugs when serving compressed files from object storage
 	),
 }
 
diff --git a/workhorse/main.go b/workhorse/main.go
index b0f9760b0d5dbe2eb07796cfa62d905c4b4d77ab..ca9b86de528a73f78d3c9e0808634d628cb1c04b 100644
--- a/workhorse/main.go
+++ b/workhorse/main.go
@@ -23,6 +23,7 @@ import (
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/redis"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/secret"
 	"gitlab.com/gitlab-org/gitlab/workhorse/internal/upstream"
+	"gitlab.com/gitlab-org/gitlab/workhorse/internal/version"
 )
 
 // Version is the current version of GitLab Workhorse
@@ -55,8 +56,10 @@ func main() {
 		os.Exit(2)
 	}
 
+	version.SetVersion(Version, BuildTime)
+
 	if boot.printVersion {
-		fmt.Printf("gitlab-workhorse %s-%s\n", Version, BuildTime)
+		fmt.Println(version.GetApplicationVersion())
 		os.Exit(0)
 	}