diff --git a/.gitlab/ci/templates/gem.gitlab-ci.yml b/.gitlab/ci/templates/gem.gitlab-ci.yml
index e366538e9e55210ed80e871cc5cfd2ca98130dc2..3d55bccac06b807421c21e862f7e37f7d7157dfc 100644
--- a/.gitlab/ci/templates/gem.gitlab-ci.yml
+++ b/.gitlab/ci/templates/gem.gitlab-ci.yml
@@ -18,6 +18,7 @@ spec:
         - ".gitlab/ci/gitlab-gems.gitlab-ci.yml"
         - ".gitlab/ci/vendored-gems.gitlab-ci.yml"
         - ".gitlab/ci/templates/gem.gitlab-ci.yml"
+        - "scripts/validate-monorepo-gem"
         # Ensure dependency updates don't fail child pipelines: https://gitlab.com/gitlab-org/gitlab/-/issues/417428
         - "Gemfile.lock"
         - "gems/gem.gitlab-ci.yml"
diff --git a/scripts/validate-monorepo-gem b/scripts/validate-monorepo-gem
index 9c379072102b89509352cea43a61cccb8efd611a..4086f2edea49db767ae8940f91f85e981e5183f5 100755
--- a/scripts/validate-monorepo-gem
+++ b/scripts/validate-monorepo-gem
@@ -1,17 +1,57 @@
 #!/bin/bash
 
-if [[ $# -ne 1 ]]; then
-  echo "usage: $0 <gem-name>"
+set -euo pipefail
+
+OWNER_HANDLE="gitlab_rubygems"
+
+error() {
+  echo "ERROR:" "$@"
   exit 1
-fi
+}
 
-if gem specification --remote --ruby "$1"; then
-  exit 0
-fi
+warn() {
+  echo "WARNING:" "$@"
+}
+
+validate_gem() {
+  validate_existence "$1"
+  validate_owners "$1"
+  validate_content "$1"
+}
+
+validate_existence() {
+  if gem specification --quiet --silent --remote --ruby "$1"; then
+    return 0
+  fi
 
-if gem specification --remote --ruby --pre "$1"; then
-  exit 0
+  if gem specification --quiet --silent --remote --ruby --pre "$1"; then
+    return 0
+  fi
+
+  error "The '$1' is missing. Push stub gem to RubyGems with version 0.0.0. See https://docs.gitlab.com/ee/development/gems.html#reserve-a-gem-name"
+}
+
+validate_owners() {
+  if ! curl --silent --fail "https://rubygems.org/api/v1/gems/$1/owners.json" | grep --silent "\"handle\":\"$OWNER_HANDLE\""; then
+    error "Gem '$1' does not contain '$OWNER_HANDLE' as owner."
+  fi
+}
+
+validate_content() {
+  local tmpdir
+  tmpdir=$(mktemp --directory)
+  gem unpack "$1" --quiet --silent --target "$tmpdir"
+
+  if ! grep --silent --recursive --perl-regexp '^\s*raise "Reserved for GitLab"$' "$tmpdir"; then
+    warn "Contents of gem '$1' does not contain 'raise \"Reserved for GitLab\"'."
+  fi
+}
+
+if [[ $# -ne 1 ]]; then
+  error "usage: $0 <gem-name>"
 fi
 
-echo "The '$1' is missing. Push stub gem to RubyGems with version 0.0.1."
-exit 1
+echo "Validating gem '$1'"
+
+validate_gem "$1"
+echo "SUCCESS!"