Serve Secrets Manager last-known-good entitlement on CDot 5xx
What does this MR do and why?
The Secrets Manager entitlement resolver calls CustomersDot (CDot) to decide whether a customer can use Secrets Manager. A last-known-good (LKG) fallback added in !254445 (merged) replays CDot's last successful answer when CDot cannot be reached, but it only fired on transport errors. A CDot HTTP 5xx was raised as a plain status error with no cause, so the fallback never fired and the resolution failed closed to ineligible, hiding the sidebar, 404ing the secrets page, and failing CI jobs. Since 2026-09-01 this happened at least 44,240 times, about 97% of them HTTP 502 from CDot's nginx while its Puma workers were wedged.
This MR makes 5xx responses eligible for the LKG fallback:
- Adds a
Gitlab::SubscriptionPortal::SecretsManagerResponseErrorbase class withcdot_statusandcdot_block_reason, and anUNAVAILABLE_STATUSESlist of500, 502, 503, 504. - Has both per-endpoint
Errorclasses inherit from it and adds anUnavailableErrorsubclass for each. Callers that rescue the baseErrorare unaffected. - Makes the REST client raise
UnavailableErrorfor 500/502/503/504 and a plainErrorfor any other unexpected status, carrying the HTTP status and anyblock_reasonfrom the body, and handling HTML or unparseable bodies. - Makes the resolver's fallback treat
UnavailableErrorthe same as a transport error. 402 still maps to a blocked response and every other 4xx still fails closed. - Adds
cdot_statusandcdot_block_reasonto the fail-closed and stale-served log lines. - Updates the Prometheus metrics doc so
lkg_staleis documented as covering 5xx as well as unreachability.
The existing secrets_manager_entitlement_lkg_fallback kill switch still gates the whole fallback, including the new 5xx path.
Out of scope: alerting on the fail_closed counter and fixing CDot's own capacity issue.
References
Screenshots or screen recordings
No UI change.
| Before | After |
|---|---|
How to set up and validate locally
It is not practical to make a real CDot instance return a 5xx from GDK, so validate with specs or a console stub.
-
Run the updated spec files:
bundle exec rspec ee/spec/lib/secrets_management/entitlement/resolver_spec.rb \ ee/spec/lib/gitlab/subscription_portal/clients/rest_spec.rb \ ee/spec/lib/gitlab/subscription_portal/secrets_manager_response_error_spec.rb -
Or, in a Rails console on a SaaS-simulating GDK, stub
Gitlab::HTTP.getto return a double withcode: 502. -
Call
SecretsManagement::Entitlement.for(group):- after one prior successful resolution, it returns the stored (warm) state.
- with no stored state, it returns
ineligible.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.