Skip to main content
Platform Engineering Golden Paths: Build Your First One in 6 Steps

Platform Engineering Golden Paths: Build Your First One in 6 Steps

KU
• 7 min read•0 views

A golden path is a template plus the defaults that make the right way the easy way. How to build the first one, service template, CI, deploy and observability, how to measure whether anyone uses it, and the two ways platform teams kill their own paths.

Key takeaways

  • A golden path is a supported, opinionated way to ship a common kind of service, a project template plus CI, deployment and observability defaults, documented and maintained by the platform team.
  • Build one for your most common service type first, keep it optional, and measure adoption by the share of new services that start from it.

A golden path is the supported, opinionated route for shipping one common kind of service: a project template wired to CI, deployment, and observability defaults, maintained by the platform team. The CNCF platforms white paper describes it as a bundle of a project template and documentation. Build the first one for your most common service type, and keep it optional.

Verified against

Backstage 1.56 (v1.56.2, released 2026-10-22 on GitHub), against the backstage.io software templates and writing-templates docs and the CNCF TAG App Delivery Platforms White Paper v1.0. Checked October 2026.

What a golden path is, and what it is not

The CNCF paper defines a platform as an integrated collection of capabilities, and its first attribute is that a platform exists to serve its users. A golden path is the smallest useful slice of that: one workflow, for one kind of service, done end to end.

It is not a mandate, a wiki page of recommendations, or a portal. A path you must use is a policy. A path that is only documentation is a suggestion. The thing that works is code that a developer runs once and gets a repo that builds, deploys and reports metrics on day one, with nothing filed in a ticket queue.

If you are still deciding whether you need a portal at all, our notes on running Backstage in practice cover the operating cost honestly. A golden path does not require Backstage; a cookiecutter repo and a reusable CI workflow are a perfectly good first version.

The 6 steps to the first path

  1. Pick the most common service shape. Count new services from the last year by type. Usually it is an HTTP API in your dominant language. Build for that, not for the hardest case.
  2. Write the skeleton repo. Dockerfile, health endpoint, structured logging, a test, a catalog-info.yaml, and a README that explains how to change each default.
  3. Wire CI by reference, not by copy. The template calls a shared reusable workflow pinned to a version, so you can fix the pipeline for every service without editing a hundred repos.
  4. Make deploy a default. A Helm chart or Kustomize base with sane requests, probes and a PodDisruptionBudget, deployed to a dev environment on first merge.
  5. Ship observability on. Metrics endpoint scraped, logs shipped, a dashboard and two SLO-based alerts generated from the service name.
  6. Publish it as a template. In Backstage, that is a Software Template that fetches the skeleton, publishes the repo and registers it in the catalog.

What the template looks like

Backstage templates use the scaffolder.backstage.io/v1beta3 API and chain built-in actions. This one is the whole first path:

YAML
# templates/http-service/template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: http-service
  title: HTTP service (golden path)
  description: Go HTTP API with CI, Kubernetes deploy and default dashboards
spec:
  owner: group:default/platform-team
  type: service
  parameters:
    - title: Service
      required: [name, owner]
      properties:
        name:
          type: string
          title: Service name
        owner:
          type: string
          title: Owning team
          ui:field: OwnerPicker
    - title: Repository
      required: [repoUrl]
      properties:
        repoUrl:
          type: string
          ui:field: RepoUrlPicker
          ui:options:
            allowedHosts: [github.com]
  steps:
    - id: fetchSkeleton
      name: Fetch skeleton
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          owner: ${{ parameters.owner }}
    - id: publish
      name: Publish repository
      action: publish:github
      input:
        repoUrl: ${{ parameters.repoUrl }}
        defaultBranch: main
    - id: register
      name: Register in catalog
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml
  output:
    links:
      - title: Repository
        url: ${{ steps.publish.output.remoteUrl }}
      - title: Open in catalog
        icon: catalog
        entityRef: ${{ steps.register.output.entityRef }}

The step IDs are camelCase on purpose. The Backstage docs recommend camelCase for action IDs because dashes break template expressions, and we apply the same rule to step IDs referenced as ${{ steps.publish.output... }}.

What goes in the box

DefaultWhat we shipWhat it saves a teamEscape hatch
CIReusable workflow pinned to a tagWriting and securing a pipelineAdd jobs after the shared ones
DeployHelm chart with requests, probes, PDBLearning chart structureOverride values per environment
ObservabilityMetrics, logs, dashboard, 2 SLO alertsA week of Grafana workAdd panels; keep the SLO alerts
SecurityImage scan, pinned base image, SBOMCompliance tickets laterExceptions recorded in the repo
Catalogcatalog-info.yaml with ownerOrphaned servicesNone; ownership is required

The escape hatch column matters most. Every default needs a documented way out, or teams fork the template on day two and you lose the ability to update them.

Measure adoption, not launches

The CNCF paper suggests measuring user satisfaction, for example with Net Promoter Score, active users and retention, and the four DORA metrics: deployment frequency, lead time for changes, time to restore and change failure rate. For a single golden path, we track three numbers:

  • Share of new services started from the template each quarter. This is the honest adoption metric.
  • Time from template run to first production deploy. If it is measured in days, a manual step is hiding in the path.
  • Template drift. How many services still run the current CI workflow version, which tells you whether updates actually reach people.
code
$ gh search code "uses: acme/platform-workflows/.github/workflows/service-ci.yml@" \
    --owner acme --json repository,textMatches

Count the pinned versions in the results, and you have a drift chart without buying anything.

The two failure modes

The mandated path. Leadership declares the path compulsory before it is good. Teams comply minimally, file exceptions, and complain in retros. Adoption numbers look great and mean nothing. If the path is better, teams pick it; if they do not, the share-of-new-services number tells you it is not better yet.

Ticket-ops behind a portal. The template button opens a form that creates a ticket, and a platform engineer runs the steps by hand. That is the old ticket queue with a nicer UI. If any step in the path needs a human, fix that step before adding a second path. Our post on Backstage catalog adoption covers how portals stall the same way.

Where this breaks

A golden path pays off when many teams build similar things. With three services, or a dozen that are all different, the maintenance outweighs the savings and a good README wins. Paths also rot: a template nobody owns ships last year's base image to every new service. Give each path a named owner and a version.

Questions people ask

What is a golden path in platform engineering?

A golden path is a supported, opinionated way to build and ship a common type of software, usually a project template with CI, deployment, observability and documentation already wired in. The CNCF platforms white paper calls this bundle of a template and documentation a golden path. It is optional by design: teams can leave it, but staying on it should be easier.

What is the difference between a golden path and a paved road?

In practice the terms mean the same thing: a well-supported default route through tooling. Some teams use "paved road" for the broader set of supported tools and "golden path" for a specific end-to-end workflow, such as creating a new HTTP service. The distinction matters less than keeping each one optional, owned and measured.

Do you need Backstage to build golden paths?

No. Backstage Software Templates are one good implementation, but a template repository, a scaffolding CLI, and a shared reusable CI workflow deliver the same path. Start there if you have fewer than a few dozen services. Add a portal when discoverability and the service catalog become the bottleneck, not before.

The call we'd make

Build one path, for your most common service, with CI, deploy and observability defaults and an escape hatch for each. Keep it optional and judge it by the share of new services that choose it. Do not build path number two until path one gets there without a single manual step.

Sources

Explore topics:CI/CDDevOps
React
Share this post
Cite this article
Plain text

Kiril Urbonas (2026). Platform Engineering Golden Paths: Build Your First One in 6 Steps. DevOpsNess. https://www.devopsness.com/blog/platform-engineering-golden-paths

Markdown

[Platform Engineering Golden Paths: Build Your First One in 6 Steps](https://www.devopsness.com/blog/platform-engineering-golden-paths) (Kiril Urbonas, DevOpsNess, 2026-10-31)

KU

Kiril Urbonas

AI Engineer

585 articles
View all articles by Kiril Urbonas

You might have missed

Evergreen posts worth revisiting.