diff --git a/app/models/cloud_connector/service_access_token.rb b/app/models/cloud_connector/service_access_token.rb
index e026b10ec0c037f90876f28704df8ae4914e9dde..eeaf946b774fe2eb43f653e936e4d8525a8938ee 100644
--- a/app/models/cloud_connector/service_access_token.rb
+++ b/app/models/cloud_connector/service_access_token.rb
@@ -15,5 +15,9 @@ class ServiceAccessToken < ApplicationRecord
       encode_iv: false
 
     validates :token, :expires_at, presence: true
+
+    def expired?
+      expires_at.past?
+    end
   end
 end
diff --git a/ee/app/models/cloud_connector/access.rb b/ee/app/models/cloud_connector/access.rb
index 8b2656c31eef9d5d78fdc23b7b7bf4bdca18fa24..370671ab1fbe9c6c35909aa272c4038de6033b1d 100644
--- a/ee/app/models/cloud_connector/access.rb
+++ b/ee/app/models/cloud_connector/access.rb
@@ -2,6 +2,10 @@
 
 module CloudConnector
   class Access < ApplicationRecord
+    # Technically, access data has no expiration date, but we know that tokens
+    # are good for at most 3 days currently, so this is a good estimate.
+    STALE_PERIOD = 3.days
+
     self.table_name = 'cloud_connector_access'
     validates :data, json_schema: { filename: "cloud_connector_access" }
     validates :data, presence: true
diff --git a/ee/app/services/cloud_connector/status_checks/probes/access_probe.rb b/ee/app/services/cloud_connector/status_checks/probes/access_probe.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4bfb8713796a8f8e6d1f9743d52e2c015b978df5
--- /dev/null
+++ b/ee/app/services/cloud_connector/status_checks/probes/access_probe.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module CloudConnector
+  module StatusChecks
+    module Probes
+      class AccessProbe < BaseProbe
+        def execute(*)
+          access_record = CloudConnector::Access.last
+          return failure("Access data is missing") unless access_record
+
+          is_stale = (Time.current - access_record.updated_at) > CloudConnector::Access::STALE_PERIOD
+          return failure("Access data is stale") if is_stale
+
+          last_token = CloudConnector::ServiceAccessToken.last
+          return failure("Access token is missing") unless last_token
+          return failure("Access token has expired") if last_token.expired?
+
+          success("Access data is valid")
+        end
+      end
+    end
+  end
+end
diff --git a/ee/app/services/cloud_connector/status_checks/status_service.rb b/ee/app/services/cloud_connector/status_checks/status_service.rb
index d2b5842a21443293721ee11b377dfc7b2ebdccff..96c61906e4df1f53fe342196a705229eff7b806f 100644
--- a/ee/app/services/cloud_connector/status_checks/status_service.rb
+++ b/ee/app/services/cloud_connector/status_checks/status_service.rb
@@ -12,6 +12,7 @@ class StatusService
         CloudConnector::StatusChecks::Probes::LicenseProbe.new,
         CloudConnector::StatusChecks::Probes::HostProbe.new(CUSTOMERS_DOT_HOST, 443),
         CloudConnector::StatusChecks::Probes::HostProbe.new(CLOUD_CONNECTOR_HOST, 443),
+        CloudConnector::StatusChecks::Probes::AccessProbe.new,
         CloudConnector::StatusChecks::Probes::EndToEndProbe.new
       ].freeze
 
diff --git a/ee/spec/factories/cloud_connector/access.rb b/ee/spec/factories/cloud_connector/access.rb
index 6d13f4b0cf69463d787669f645dc65b2e0993fcd..66d97aac6f714e5483f88d260b4ea913301b5d2d 100644
--- a/ee/spec/factories/cloud_connector/access.rb
+++ b/ee/spec/factories/cloud_connector/access.rb
@@ -18,5 +18,13 @@
         ]
       }
     end
+
+    trait :current do
+      updated_at { Time.current }
+    end
+
+    trait :stale do
+      updated_at { Time.current - ::CloudConnector::Access::STALE_PERIOD - 1.minute }
+    end
   end
 end
diff --git a/ee/spec/services/cloud_connector/status_checks/probes/access_probe_spec.rb b/ee/spec/services/cloud_connector/status_checks/probes/access_probe_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..63ff61e5b36e82988276f548e2f907b2e36cb365
--- /dev/null
+++ b/ee/spec/services/cloud_connector/status_checks/probes/access_probe_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe CloudConnector::StatusChecks::Probes::AccessProbe, :freeze_time, feature_category: :cloud_connector do
+  describe '#execute' do
+    using RSpec::Parameterized::TableSyntax
+
+    subject(:probe) { described_class.new }
+
+    let(:now) { Time.current }
+
+    # nil trait means record is missing
+    where(:access_trait, :token_trait, :success?, :message) do
+      :current | :active  | true  | 'Access data is valid'
+      nil      | :active  | false | 'Access data is missing'
+      :stale   | :active  | false | 'Access data is stale'
+      :current | nil      | false | 'Access token is missing'
+      :current | :expired | false | 'Access token has expired'
+    end
+
+    with_them do
+      it 'returns the expected result' do
+        create(:cloud_connector_access, access_trait) if access_trait
+        create(:service_access_token, token_trait) if token_trait
+
+        result = probe.execute
+
+        expect(result).to be_a(CloudConnector::StatusChecks::Probes::ProbeResult)
+        expect(result.success?).to be success?
+        expect(result.message).to eq(message)
+      end
+    end
+  end
+end
diff --git a/ee/spec/services/cloud_connector/status_checks/status_service_spec.rb b/ee/spec/services/cloud_connector/status_checks/status_service_spec.rb
index 7138b86509fc23688fe1722b3962180f63d6bee5..0008a08b5048889ea67886e43b63fa6f11949320 100644
--- a/ee/spec/services/cloud_connector/status_checks/status_service_spec.rb
+++ b/ee/spec/services/cloud_connector/status_checks/status_service_spec.rb
@@ -20,6 +20,7 @@
       an_instance_of(CloudConnector::StatusChecks::Probes::HostProbe).and(
         have_attributes(host: 'customers.staging.gitlab.com', port: 443)
       ),
+      an_instance_of(CloudConnector::StatusChecks::Probes::AccessProbe),
       an_instance_of(CloudConnector::StatusChecks::Probes::EndToEndProbe)
     ])
   end
diff --git a/spec/models/cloud_connector/service_access_token_spec.rb b/spec/models/cloud_connector/service_access_token_spec.rb
index 4239ec486a50584b54b3843375c94240bd40100d..462a20d858f413a884a9d283735cfa53c848c4e8 100644
--- a/spec/models/cloud_connector/service_access_token_spec.rb
+++ b/spec/models/cloud_connector/service_access_token_spec.rb
@@ -3,19 +3,16 @@
 require 'spec_helper'
 
 RSpec.describe CloudConnector::ServiceAccessToken, type: :model, feature_category: :cloud_connector do
-  describe '.expired', :freeze_time do
-    let_it_be(:expired_token) { create(:service_access_token, :expired) }
-    let_it_be(:active_token) {  create(:service_access_token, :active) }
+  let_it_be(:expired_token) { create(:service_access_token, :expired) }
+  let_it_be(:active_token) {  create(:service_access_token, :active) }
 
+  describe '.expired', :freeze_time do
     it 'selects all expired tokens' do
       expect(described_class.expired).to match_array([expired_token])
     end
   end
 
   describe '.active', :freeze_time do
-    let_it_be(:expired_token) { create(:service_access_token, :expired) }
-    let_it_be(:active_token) {  create(:service_access_token, :active) }
-
     it 'selects all active tokens' do
       expect(described_class.active).to match_array([active_token])
     end
@@ -42,4 +39,14 @@
       it { is_expected.to validate_presence_of(:expires_at) }
     end
   end
+
+  describe '#expired?' do
+    it 'returns false for active token' do
+      expect(active_token).not_to be_expired
+    end
+
+    it 'returns true for expired token' do
+      expect(expired_token).to be_expired
+    end
+  end
 end