Self-service Billing Account access for Group Owners (.com only)
[[_TOC_]] # Problem GitLab group Owners on .com who are not already a Billing Account Manager are unable to manage their group's subscription in the Customers Portal because **being a group Owner does not automatically grant Billing Account membership**. When these users try to access the Customers Portal from within their Group /billings page on gitlab.com, they see no subscriptions and in some cases hit **404 pages** - with no explanation and no self-service path to resolve it. There is currently **no workaround available to affected users**; they are fully blocked. This gap is becoming increasingly visible with the **recent rollout of GitLab Credits**, which is driving more group owners to visit the GitLab Credits Dashboard in the Customers Portal - only to be met with a broken experience. ## Impacted Customers Any GitLab group Owner (.com) who has not been specifically invited to be a Billing Account Manager - regardless of when or how they became a group Owner. The full scale of impact is not yet quantified, but the recent support tickets suggest this is a real and growing pain point. To better understand the scope, it would be valuable to look at how many group Owners exist per group on average - any group with more than one Owner has potential exposure to this problem, since only one (the original purchaser or invitee) is likely to be a Billing Account Manager. Reported examples within the last few days: * https://gitlab.slack.com/archives/C08RA9HRZ97/p1771513642046609 * https://gitlab.zendesk.com/agent/tickets/697072 * https://gitlab.zendesk.com/agent/tickets/696360 * https://gitlab.zendesk.com/agent/tickets/692973 * https://gitlab.zendesk.com/agent/tickets/697000 * https://gitlab.zendesk.com/agent/tickets/696906 ## Note about Self-Managed This issue is scoped to .com only. For .com, the Customers Portal can verify group ownership directly via the GitLab.com API, making it feasible to identify when a logged-in user is an Owner of a namespace linked to a Billing Account. Self-Managed is a fundamentally different problem - ownership information is stored on the customer's own instance and is not accessible to the Customers Portal, so a different technical approach is required. That problem is tracked separately in https://gitlab.com/gitlab-org/customers-gitlab-com/-/work_items/16224. # Proposed Solutions These are presented iteratively so we can deliver value at each step. Note that Option 2 has a partial dependency on https://gitlab.com/groups/gitlab-org/-/epics/8986+ for a specific cohort: group Owners who have previously purchased an add-on (e.g., Compute Minutes or Storage) for that same group, which created a separate Billing Account for them. Until https://gitlab.com/groups/gitlab-org/-/epics/8986 is complete, a user can only be a member of one Billing Account, so this cohort would not be fully served by Option 2. ## [Iteration 1 - Better error state / explainer](https://gitlab.com/gitlab-org/customers-gitlab-com/-/issues/16245) (immediate, low effort) Replace the blank/404 experience with a **clear, actionable message** when a logged-in user has no billing account membership. * Tell the user _why_ they see no subscriptions * Explain what a Billing Account is and how access works * Point them toward a next step (e.g., contact the Billing Account Manager, or submit a request) **Value:** Reduces confusion and support tickets immediately, even before self-service exists. Low risk, low effort. ## Iteration 2 - Self-service access request flow (medium effort) Allow a group Owner to **request membership** of the Billing Account linked to their namespace(s): 1. Detect namespaces the user owns via the existing [`list_service.rb`](https://gitlab.com/gitlab-org/customers-gitlab-com/-/blob/main/app/services/gitlab/namespaces/list_service.rb#L65) 2. Resolve the linked Billing Account via [`namespace.base_order.billing_account`](https://gitlab.com/gitlab-org/customers-gitlab-com/-/blob/main/app/models/gitlab/namespace.rb#L140) 3. Surface a **"Request access"** action in the UI 4. **Notify the existing Billing Account Manager(s) by email** to approve or deny the request 5. Upon approval, grant the requestor Billing Account membership **Approval is always required** from an existing Billing Account Manager - access is never auto-granted. This keeps the security model clean and ensures the BAM retains control over who can manage their subscription. **Edge cases to handle:** * User owns namespaces linked to **multiple billing accounts** - until https://gitlab.com/groups/gitlab-org/-/work_items/8986 is complete, surface a clear message that only one billing account membership can be held at a time, and let the user choose which to request * **Billing Account Manager is unreachable** (e.g., they have left the company or no longer have access to that email) - needs a defined fallback path (see Open Questions) **Value:** Unblocks the majority of affected users with a self-service path, reduces support burden significantly. ## Iteration 3 - Auto-grant Billing Account membership based on namespace ownership (longer term) Explore **automatically provisioning** Billing Account membership when a user is a verified group Owner, removing the need for a manual request/approval flow entirely. * Could be triggered at Customers Portal login, or when group ownership is granted on GitLab.com * Would need careful design around security/trust (e.g., should auto-grant be immediate or require confirmation?) * Fully dependent on Epic &8986 if a user owns namespaces across multiple billing accounts **Value:** Eliminates the problem at the root. Best long-term UX, but requires more design and cross-team coordination. ## Open Questions 1. **Unreachable Billing Account Manager:** There is always at least one BAM on a Billing Account, but they may have left the company or lost access to that email. What is the fallback in this case? Most likely routing to GitLab Support. 2. **Request expiry:** Invitations to Billing Account Managers currently expire after 7 days - should access requests follow the same logic? If so, what happens upon expiry - auto-deny, or escalate? 3. **Priority vs. Epic https://gitlab.com/groups/gitlab-org/-/work_items/8986 :** Should Option 2 ship with the single-billing-account constraint as a known limitation, or should we wait for https://gitlab.com/groups/gitlab-org/-/work_items/8986 before building the request flow? 4. **Quantifying impact:** How many group Owners exist per group on average? Any group with more than one Owner has potential exposure to this problem. This data would help validate the business case and prioritization.
epic