Loading
Add entry-point guards for Secrets Manager entitlement enforcement (D2)
What does this MR do and why?
D2 of the Secrets Manager entitlement enforcement epic: wires every Secrets Manager write GraphQL mutation and the internal OpenBao audit-log API to D1's entitlement policy, so a blocked/ineligible namespace gets a structured denial instead of the write silently succeeding.
- Adds
SecretsManagement::Entitlement#write_denial_reasonand.root_namespace_for(shared "what's the entitlement-relevant namespace" resolution). - Adds a
SecretsManagement::EnforcesWriteEntitlementmutation concern. It hooks GraphQL-Ruby's#ready?(the framework's pre-resolvefilter) to short-circuit denied writes with a structured payload, and declares the newreasonfield — so each of the 16 write mutations only needs one line:enforces_write_entitlement_for :payload_key.resolvemethods are untouched. - Adds
Types::SecretsManagement::WriteDenialReasonEnum(SecretsManagerWriteDenialReason), exposed as a new, additive, nullablereasonfield next to the existingerrors: [String]on every affected mutation payload — no breaking change toerrors. - Adds the same entitlement check to
ee/lib/api/internal/secrets_manager.rb's audit-log endpoint (returns403instead of logging/billing a blocked namespace). - Adds test coverage confirming read paths are already hard-denied by D1's policy (
EE::GroupPolicy/EE::ProjectPolicy), with no resolver code changes needed. - All new behavior is gated behind the existing
secrets_manager_paid_experiencefeature flag; with it off, behavior is unchanged from before this MR.
See the implementation update note on the issue for where this diverges from the original proposal (error shape, feature flag reuse, secretsManagerStartTrial exclusion) and why.
References
- Closes https://gitlab.com/gitlab-org/gitlab/-/work_items/602362
- Depends on D1: https://gitlab.com/gitlab-org/gitlab/-/work_items/602361
How to set up and validate locally
- Enable the flag for a top-level group:
Feature.enable(:secrets_manager_paid_experience, Group.find_by_full_path('my-group')) - Stub or set up an entitlement state that denies writes (e.g.
:ineligible, or:blockedwithblocked_reason: :trial_expired) for that group. - Call any Secrets Manager write mutation (e.g.
projectSecretCreate) against a project/group under that namespace. - Confirm the response has
errors: ["Secrets Manager access is restricted for this namespace."]andreason: "INELIGIBLE"/"TRIAL_EXPIRED"/ etc., with the payload fieldnull, and that no underlying service call happened. - With the flag disabled, confirm the mutation behaves exactly as before this MR (existing role/permission checks only).
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist.