Remove secrets_manager_paid_experience flag
What does this MR do and why?
Related: MR 6 of 6 removing Secrets Manager feature flags for GA. Targets master. All earlier MRs in the series are merged. Related to https://gitlab.com/groups/gitlab-org/-/work_items/21755 and !239358 (merged). Replaces the exploratory all-flags MR !254806 (closed), which will be closed once this one is up.
All MRs in this series
secrets_manager,group_secrets_manager: !259222 (merged) (merged)- Enrollment flags (
secrets_manager_namespace_enrollment,secrets_manager_instance_enrollment): !260090 (merged) (merged) secrets_manager_async_audit_logs: !260091 (merged) (merged)- Billing event flags (
secrets_manager_emit_secret_read_events,secrets_manager_emit_secret_stored_events): !260092 (merged) (merged) secrets_manager_denial_telemetry: !260094 (merged) (merged)secrets_manager_paid_experience: !260110 (merged) (this MR)
secrets_manager_api_access stays in beta and default disabled for GA, so it is not part of this series.
Problem
With secrets_manager_paid_experience off (the default, so all of Self-Managed), every entitlement check is skipped. This covers policies, the GraphQL write concern, the service gate, the CI runner payload, job scheduling, trial and add-on mutations, the entitlement GraphQL field, the sidebar, and the nav badge. Self-Managed still behaves like the free beta.
Solution
Backend
- Remove every flag check. Entitlement checks always run now.
EE::ProjectPolicyandEE::GroupPolicydrop thesecrets_manager_entitlement_awarecondition from their rules.EntitlementGate,EE::Ci::RegisterJobService, andEffectiveCapabilitiesServicedrop the flag guard.NamespaceEnrollmentService: enroll always writesbeta: false. Unenroll always soft-disables the record. There is no more destroy path or "Enrollment not found." response.InstanceEnrollmentService: enroll always writessecrets_manager_instance_beta_enrolled: false.- SaaS top-level groups keep the implicit grant before enrollment unless opted out. The SaaS guard stays, only the flag check is dropped.
NavBadge.visible?no longer takesroot_namespace.- Controllers drop
push_frontend_feature_flagcalls. The secrets controllers losecheck_secrets_enabled!, since it became a no-op. Two helper methods that became unused are removed:secrets_manager_available_and_active_for_group?andsecrets_manager_available_and_active_for_project?. - Mutations
start_trial,enable_add_on, andrefresh_entitlementno longer raise when the flag is off.
Frontend
glFeatures.secretsManagerPaidExperiencechecks removed from 7 Vue components.- The beta provisioning toggle in
secrets_manager_settings.vueis removed, since it only existed in the beta experience. Its now-unused enable/disable config entries, constants, and the billing alert in the settings components go with it. - 7 POT strings removed.
CI
- Remove
secrets_manager_paid_experiencefromQA_FEATURE_FLAGSincng-secrets-manager.secrets_manager_api_access=enabledstays, because that flag stays in beta and default disabled.
Docs
- The developer docs (
enrollment.md,fulfillment.md,services.md) no longer describe the flag or the beta behavior when it was off. - The experimental GraphQL reference (
doc/api/graphql/reference/experimental/objects.md) is regenerated for the three Secrets Manager rows only. Other rows that are already out of date onmasterbelong to other teams and are left alone.
Specs
- Flag stubs removed and flag-off cases deleted.
- Where a false stub was only a shortcut to skip the entitlement gate, it is now a paid entitlement stub. This covers provision and initialize services and workers, effective capabilities, and project and group policy baselines.
- Jest: added polling transition tests to replace the coverage lost with the toggle tests.
GraphQL: experiment markers stay on Group.secretsManagerEntitlement and writeDenialReason, since they are shared with sibling fields and not flag-specific. Descriptions lost the "or when the flag is disabled" wording. The GraphQL reference doc and introspection JSON are regenerated for 3 field descriptions.
Views: the CI/CD variables nudge shows for trial_eligible. Group Secure settings always show the SaaS description.
Left in place on purpose: the policy condition name instance_secrets_manager_paid_experience_allowed and InstanceEnrollment.paid_experience_allowed?. No renames in this MR.
Behavior changes
This MR is the one that ends the Self-Managed beta.
- Entitlement now runs everywhere, including Self-Managed. Instances without the
secrets_manageradd-on (offline) or without CustomersDot access resolve through the offline path or to ineligible or blocked. This is the intended GA behavior. The SaaS beta already ended on 2026-09-21. - The beta cohort is frozen. Nothing writes
beta: trueorsecrets_manager_instance_beta_enrolled: trueanymore. Existing records keep their value. - Unenroll on GitLab.com always soft-disables the enrollment record instead of deleting it.
- Off SaaS, a project whose secrets manager is deprovisioning now shows the Secrets manager sidebar item to an Owner who can provision. It was hidden before.
- On a Self-Managed instance that is not enrolled, CI jobs that request GitLab Secrets Manager secrets are now dropped with
secrets_manager_access_denied, instead of getting an empty secrets payload.
Open question
ee/app/assets/javascripts/ci/secrets/components/secrets_manager_billing_alert.vue and the two disable_*secret_manager.mutation.graphql files are now unused. Should we remove them here, or leave that for a follow-up?
Before merge
-
cng-secrets-managere2e job is green on this MR. - Re-run the group
feature_provisionQA spec locally.
Reviewed in parallel: !260806 (merged) is the fix for the bug in #631312. It does not block this MR, but it is best if it merges before or together with this one.
Why it matters for this MR
During a CustomersDot outage, the resolver only reused a saved answer that allows direct reads. So a trial_eligible namespace lost even its read-only access during an outage. GitLab.com already has this today. This MR turns on the same path for Self-Managed instances with an online license, where the saved answer is shared by the whole instance.
After merge
- Run
/chatops gitlab run feature delete secrets_manager_paid_experience --dev --pre --staging --staging-ref --production. - Close !254806 (closed).
Impact
- Self-Managed instances, where this flag was off by default, now get the real entitlement checks that GitLab.com already has. This ends the free beta on Self-Managed.
- Billing delivery is already handled on
master: !260610 (merged) removedbilling_event_tracking, andlocal_billing_persistenceis on by default. This MR does not change either. - No database changes.
- Changelog: commit trailer
Changelog: changedandEE: true. The commit message says this is the change that ends the Self-Managed beta.
References
- Related to https://gitlab.com/groups/gitlab-org/-/work_items/21755 (epic)
- Introduced in !239358 (merged)
- Related to #631312, fixed in !260806 (merged) (reviewed in parallel)
Screenshots or screen recordings
Not applicable yet. The UI changes are removals: the beta provisioning toggle in project and group settings, and the billing alert in the settings components.
How to set up and validate locally
-
Get a license with the Secrets Manager add-on. Use an offline license from CustomersDot staging, or seed an
AddOnPurchasein the console for spec work. -
Run the key specs:
bundle exec rspec ee/spec/lib/secrets_management/availability_spec.rb ee/spec/lib/secrets_management/entitlement/resolver_spec.rb ee/spec/services/secrets_management/namespace_enrollment_service_spec.rb ee/spec/requests/api/ci/runner -
Run the Jest specs:
yarn jest ee/spec/frontend/ci/secrets
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.