Backstage Service Catalog
Why we use Backstage
Section titled “Why we use Backstage”Backstage is our service catalog. It gives one place to answer the questions that otherwise mean digging through repositories, Slack threads and the memory of whoever built the project:
- What systems do we have, and who owns them?
- Where is each one deployed (Vercel, Cloudflare, etc.), and what is the production URL?
- What stack does it run on: framework, CMS, commerce platform, third-party APIs?
- Where do the logs go, which SLA tier applies, and which Busy/Jira project does it belong to?
Customer Support is the main audience. When a client gets in touch, CS needs to quickly find what the system is, where it runs, who to talk to and what agreement covers it, without having to ask a developer. A good catalog entry makes that possible. Developers benefit too: it is the quickest way to get oriented in a project you haven’t worked on before, or one you haven’t touched in a year.
The catalog is only useful if it is complete and correct. A product missing from Backstage, or one with outdated information, is a product CS can’t help with.
Principles
Section titled “Principles”- Every product we build and run has a
backstage.yamlin the root of its repository. - The entry is written for someone who has never opened the codebase. Write descriptions as plain-language explanations, not boilerplate.
- Everything in the file must be true for this repository. Products often share a stack, but they don’t share env var names, account IDs, space IDs or admin paths. Never copy these from a sibling project.
- Keep the file up to date. When you add a component, change hosting, or start using a new third-party API, update
backstage.yamlin the same PR.
What a catalog entry contains
Section titled “What a catalog entry contains”The file is multi-document YAML, with entities in this order:
- System: the product as a whole (exactly one per file).
- API: HTTP surfaces we expose that another component calls (e.g. an internal
/api/revalidateendpoint). - Component: what we build and deploy, such as a web app, worker, mobile app or studio.
- Resource: infrastructure we provision, such as queues, durable objects and KV namespaces.
Shared services like Vercel, Cloudflare, Storyblok, Centra and HyperDX live in the central try-backstage-catalog. Reference them by name (resource:tryhuset/vercel, tryhuset/storyblok-api). Don’t redefine them in your product file.
Information CS relies on
Section titled “Information CS relies on”Set these on the System so they show up on the Project card for every component:
| Field | What it tells CS |
|---|---|
spec.owner (group:default/<gh-team-slug>) |
Which team owns the product |
| Production link | The live site |
| Hosting link (Vercel / Cloudflare dashboard) | Where it is deployed |
| CMS / commerce admin links | Where the client manages content and products |
try.no/sla-tier, try.no/sla-agreement |
Which SLA applies. CS is the source of truth |
try.no/sla-client-domain |
The client’s production domain |
try.no/project-owner |
The PM / project owner |
busy.no/project-id, jira.com/project-key |
Where time is logged and issues are tracked |
try.no/log-drain |
Where to look for logs (e.g. HyperDX, Vercel) |
try.no/documentation |
External docs (Notion, Confluence, Storybook…) |
Default try.no/sla-tier to standard. Check with CS before setting anything else.
Relations that describe the stack
Section titled “Relations that describe the stack”The relations between entities are what make the catalog show how a system actually fits together:
consumesApis: who calls an API over HTTP. Use it for third-party APIs and for calls between our own components.providesApis: who exposes an API. Needs a matching API entity.dependsOn: platforms we run on and runtime bindings (hosting, queues, log drains). Not for HTTP.
Use one edge per relationship. If a component calls Storyblok over HTTP, that’s consumesApis: tryhuset/storyblok-api only. Don’t also add a dependsOn for it.
Getting started
Section titled “Getting started”- Use the Backstage agent skill to generate or update
backstage.yaml. It inspects the repository, follows the conventions above and asks for the values it can’t verify, such as the GitHub team, production URL and Centra admin path. - Review the generated file before merging. Pay particular attention to URLs, IDs and env var names, since mistakes there tend to get through review.
- Once merged, the product shows up in Backstage.
- See try-backstage-catalog for shared entities and examples.