How to Tell Which GitLab Issues Came From a Real Customer vs. an Internal Idea
You can't tell, not from the issue itself. GitLab's issue model has a title, a description, an assignee, labels, a milestone, and on paid tiers a weight and custom fields, but nothing called "source" or "customer." An issue filed because Acme Corp emailed in looks identical, structurally, to one an engineer opened after a Friday afternoon idea. Whatever tells them apart has to be something your team writes into the issue by convention, because GitLab isn't going to write it for you.
The honest answer to "how do I tell" is: check whichever of three places your team has agreed to put that information, if your team has agreed on one. A label, a custom field, or a line in the description. Most teams that get this working use one of the three consistently; most teams that don't get it working never picked one at all.
Why GitLab leaves this to you
GitLab has looked at this gap before and not closed it. Issue 8571, "Gathering user feedback in GitLab: Discovery," is GitLab's own product team scoping out how user feedback should flow into the tracker, and it's been open for years without becoming a shipped field. The closest thing to precedent from inside GitLab's own trackers is issues like gitlab-ui#2229, "Accessibility feedback from customer," where a reporter distinguishing a large customer's audit findings from GitLab's internal review just puts "from customer" in the title. That's the ad hoc pattern: whoever files the issue types the provenance into free text, if they remember to.
The reason this stays free text is that GitLab's issue is deliberately a generic unit of work. It's the same shape whether it comes from a support escalation, a sales call, a competitor's changelog, or someone's shower thought. Adding a first-class "customer" field would mean deciding what a customer even is across every kind of GitLab project, from an internal platform team's issues to a public open-source repo's, and GitLab has consistently left that decision to each team instead of making it for everyone.
Three ways to mark it, since GitLab won't
A label convention. The plain-tier version is a label like customer-reported, applied by hand at filing time, available on every GitLab plan including free. If you're on Premium or Ultimate, scoped labels let you go further with a source::customer / source::internal pair using the key::value syntax. Scoped labels are mutually exclusive by key, so an issue can't accidentally carry both source::customer and source::internal at once. Either version lives or dies on people remembering to apply it.
A custom field. Work item custom fields are a newer, Premium/Ultimate-only mechanism, configured at the group level, that give you a proper single-select field, "Source," with options like "Customer," "Internal," and "Support escalation." It's more structured than a label because it shows up as its own row on the issue rather than buried in a label list, and a group can carry up to fifty custom fields with up to ten assigned per work item type. Still filled in by a human at filing time, same as the label.
A line in the description. GitLab's description templates let you commit a .gitlab/issue_templates/Default.md file, or set a default template in project settings on Premium and Ultimate, that pre-fills every new issue with a "Reported by" line. This is the lowest-friction option on the free tier: the field is already there when someone opens a new issue, they just have to fill it in rather than remember to create it.
None of the three is better than the others in the abstract. The label is fastest to set up, the custom field is the most structured, and the template is the hardest to forget because it's already sitting in the box. What all three share is the same failure mode: they only work if the person filing the issue actually does the extra step.
How Tobias flagged it at Quillan Robotics
Quillan runs one GitLab group, quillan, with a firmware project for the arm's onboard software and a fleet-dashboard project for the web app operators use to monitor a site's arms. The picking arms those projects track are what warehouse operators use to pull inventory off shelves, and when one acts up in the field, the report lands with Tobias Kirwan, the on-call support engineer.
Quillan's convention is the label pair: source::customer and source::internal, scoped labels on their Premium plan. When a warehouse operator's ops lead emails support because an arm keeps dropping its grip calibration after a firmware update, Tobias files it like this:
firmware#241: Grip calibration resets after OTA update on arm firmware 4.2 Labels:
source::customer,priority::highDescription: Reported by Linh Duarte, ops lead at Northbay Fulfillment. Three arms at their Reno site lost calibration within an hour of the 4.2 push. Customer had to run manual recalibration on all three before their shift could resume.
Two days later, one of Quillan's own firmware engineers notices the same 4.2 build logs a spurious warning on startup and files firmware#243, no customer involved, tagged source::internal. Both issues sit in the same backlog, same board, same milestone. The label is the only thing that tells a reader which one has a warehouse operator waiting on it and which one doesn't.
The convention holds for as long as everyone applies it. It starts to slip the week a new hire files an issue without knowing the label pair exists, or Tobias is out and a teammate covering support forgets to tag one before a busy Monday. Nothing in GitLab enforces it. The label is a promise the team keeps to itself, not a rule GitLab checks.
Where the convention runs out
Even applied perfectly, hand-written source labels have a ceiling:
- They only capture who typed the issue, not who asked. If Tobias files the issue, the requester's name lives in a description line he wrote from memory or a support ticket he had open in another tab, not in a field GitLab understands as a person or an account.
- They don't survive the request being asked twice. If a second warehouse customer hits the same calibration bug next month, nothing connects their report to
firmware#241unless someone happens to remember it and links the two by hand. - They don't scale past whoever's disciplined. A label convention that one meticulous engineer maintains looks like a real system until that engineer goes on vacation, and then it's a label nobody's applying consistently anymore.
That third point is where hand conventions stop being enough, usually somewhere past a couple dozen customer-sourced issues a month spread across more than one project. At that point the fix isn't a better label scheme, it's a system that already knows where a request came from before anyone opens GitLab.
That's what Modem does. Modem's GitLab integration watches the projects you connect and attaches the originating person and company to every issue automatically, sourced from wherever the request actually came in, a support ticket, a Slack thread, a sales call transcript, whether or not anyone remembered to type it into a label. When Linh from Northbay emails in again about a different arm, Modem already knows she's asked before, so the second report lands connected to the first instead of starting a fresh, unlabeled source::internal-looking issue that nobody links back. We build Modem, so weigh that against the alternatives compared in the best tools for turning customer feedback into GitLab issues. For a team still under that couple-dozen-a-month threshold, the label convention above costs nothing and is worth setting up properly before reaching for anything more.
The smallest version you can start this week
Pick one mechanism, not all three. If you're on GitLab Free, commit a Default.md template with a "Reported by" line; it's already in the box the next time anyone opens a new issue. If you're on Premium or Ultimate, a source::customer / source::internal scoped label pair takes ten minutes to create and gets checked automatically by the mutual-exclusivity rule. Either way, write the one-sentence rule down somewhere the whole team will see it, and apply it to the very next issue you file. A convention nobody wrote down is a convention that dies with whoever remembers it. For the related question of what container a customer request should live in once you know it's real, see what's the actual difference between a GitLab epic and an issue for feature requests.
