Service Catalog in GLPI 11: From Concept to Practice

In GLPI 11 the service catalog is native and has its own page (/ServiceCatalog). A technical guide to building a service end to end with form, access control and destination: the visibility trap that makes the catalog vanish, the decision matrix by scenario and the usage_count pruning query NexTool runs in support.

In GLPI 11 the service catalog stopped being a plugin and became part of the core - but what sinks most rollouts isn't a missing feature, it's a published form that no user can actually see. While supporting client GLPI environments, this is the first symptom to surface: "the catalog is empty" when, in the database, the forms exist and are active. This guide shows how to build a service end to end with the native features and how to diagnose the traps before the user complains.

In GLPI 11 the catalog is native - and has its own address

Up to GLPI 10, "service catalog" was a synonym for FormCreator. In GLPI 11 forms moved into the core and, along with them, came a real Service Catalog: a self-service page served by the /ServiceCatalog route, where the user browses services organized by category and opens the right form. Forms live under Administration > Forms, and each catalog service is a form with four pieces that must line up:

  • Form (glpi_forms_forms): the service itself, with name, description and category.
  • Questions (glpi_forms_questions): the fields the user fills in, with mandatory flags and conditions.
  • Access control (glpi_forms_accesscontrols_formaccesscontrols): who can see the service in the catalog.
  • Destination (glpi_forms_destinations_formdestinations): what gets created on submit - a ticket, a change or a problem.

Building a service end to end

Order matters. Skipping the Access control tab is the mistake that causes the most rework. For each service:

  1. Create the form and attach it to a lean category (two levels at most; glpi_forms_categories is a tree, and a deep tree becomes a maze).
  2. Add only the questions you will actually use in handling. A pretty field nobody reads on the ticket is friction for the user.
  3. Configure Access control: the AllowList strategy restricts the service to profiles, groups or users; DirectAccess generates a direct link (handy for an external vendor). Without an active access policy, the form does not appear in the catalog.
  4. Set the Destination: the FormDestinationTicket itemtype creates a ticket; FormDestinationChange and FormDestinationProblem also exist. In the destination you map the ITIL category, the assigned group and the requester of the generated item.
  5. Activate the form (is_active) and test it with a real self-service user, not with your administrator account.

The trap that makes the catalog "vanish"

In support, the recurring ticket is "I published the service and the user can't see it". In almost every case the cause is the same: the form has is_active = 1 but no active Access control policy. GLPI 11 treats visibility and publishing as separate things - publishing is not enough, you need at least one active AllowList or DirectAccess. And GLPI raises no warning: to the technician the form is "live", to the user the catalog is empty. This is the first query we run in a support onboarding, before discussing taxonomy:

-- PUBLISHED forms that do NOT appear in the self-service catalog:
-- they are active (is_active=1) but have NO active access policy.
-- They exist, count in the total and are invisible to the end user.
SELECT f.id, f.name, f.usage_count
FROM glpi_forms_forms f
LEFT JOIN glpi_forms_accesscontrols_formaccesscontrols ac
       ON ac.forms_forms_id = f.id
      AND ac.is_active = 1
WHERE f.is_active  = 1
  AND f.is_deleted = 0
  AND f.is_draft   = 0
  AND ac.id IS NULL
ORDER BY f.usage_count DESC;

One detail that only bites those who have actually migrated: when you bring FormCreator forms into the GLPI 11 core, FormCreator's per-profile visibility does not automatically become an AllowList. The form arrives active but with no access policy - that is, invisible. We have audited freshly migrated catalogs with dozens of services stuck in this limbo, with the client swearing "the migration lost the forms". It didn't: they were right there, just with nobody able to see them.

Client view vs technical view: where each one lives

The catalog has two layers and, in GLPI 11, they sit in different places on the form:

  • Client view lives in the Service catalog tab (title, friendly description, category, illustration) and in Access control (who sees it). It is what shows up at /ServiceCatalog.
  • Technical view lives in the Destination: ITIL category, technical group and requester of the generated ticket. The SLA does not live on the form - it is applied to the created ticket, by a business rule or by the ITIL category.

The common mistake here is trying to "set the SLA on the form". There is no such field: the form only creates the item; the ticket is what carries the deadline. The matrix we use to decide each service's configuration:

Catalog serviceAccess controlDestination (itemtype)Where the SLA comes from
Request VPN access (self-service)AllowList: Self-Service profileFormDestinationTicket + "Access" categoryBusiness rule on the category
Open a change request (technicians only)AllowList: Technician profileFormDestinationChangeChange workflow, not a ticket SLA
Form for an external vendorDirectAccess (link/token)FormDestinationTicket + vendor entityRule per entity
Service under constructionNone active-Invisible - by intent, never by oversight

Measure by usage, not by size

A good catalog is not a big catalog. Every GLPI 11 form has a native usage counter (usage_count), incremented on each submission - use it to prioritize and prune. A service nobody has triggered for months only bloats the menu and buries the ones that matter. The pruning query we run in our quarterly review cycle:

-- Pruning candidates: published over 90 days ago and never used.
-- A lean menu helps the user find the right service faster.
SELECT id, name, usage_count, date_creation
FROM glpi_forms_forms
WHERE is_active  = 1
  AND is_deleted = 0
  AND usage_count = 0
  AND date_creation < (NOW() - INTERVAL 90 DAY)
ORDER BY date_creation;

Start with the ten most requested services, use names the user understands ("Request a laptop", not "Asset provisioning") and review the catalog every quarter with usage_count in hand. That is how the catalog stops being a static storefront and becomes the real front door of the service desk.

Need to structure (or rescue) a service catalog in GLPI 11 with visibility under control and destinations mapped to your workflow? Explore NexTool's implementation projects.


This content was produced with the help of artificial intelligence and reviewed by the Nextool Solutions team.

Frequently Asked Questions

Yes. Forms moved into the core and there is a dedicated self-service page served by the /ServiceCatalog route. Each catalog service is a native form, with no dependency on FormCreator.

Almost always an active Access control policy is missing. In GLPI 11, publishing (is_active) and making visible are separate: without an active AllowList or DirectAccess, the form does not appear in the catalog. Run the query for forms without active access to find them all at once.

AllowList restricts the service to authenticated profiles, groups or users (internal self-service). DirectAccess generates a direct link, useful for someone outside GLPI such as an external vendor, optionally protected by a token.

No. The form creates a ticket (or change, or problem) and the SLA is applied to that item, by the ITIL category or a business rule. Map the correct category in the Destination and keep the SLA at the ticket layer.

Yes. The native destinations are FormDestinationTicket, FormDestinationChange and FormDestinationProblem, and a single form can have more than one destination, even conditional - for example, always create a ticket and, on certain answers, also a change.

No. FormCreator's per-profile visibility does not automatically become an AllowList in GLPI 11. The forms arrive active but with no access policy, i.e. invisible. Just add an active AllowList to each one.

Need help?