Platform Engineering skill for Codex
Golden paths first, the developer portal second. Codex treats an internal developer platform as a product: it quantifies the bottleneck first, designs one golden path that takes a new service to production without tickets, and only then picks a portal, Backstage or a lighter option. It writes catalog-info.yaml and Software Templates, plans how template fixes reach existing services, and defines adoption metrics.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- platform-engineering Installs to ~/.agents/skills/platform-engineering/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install platform-engineering The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project platform-engineering Installs to .agents/skills/platform-engineering/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/platform-engineering.zipunzip -o platform-engineering.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) platform-engineering PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $platform-engineering, or pick it from /skills.
You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.
What Codex reads before loading it
Designs and builds internal developer platforms as products - golden paths from repo template to production, self-service scaffolding, a software catalog with ownership, and a Backstage portal (catalog-info.yaml, Software Templates, TechDocs) or a lighter alternative - measured by adoption, lead time and onboarding time rather than tool count. Use when a team wants an IDP or developer portal, is evaluating Backstage, Port or Cortex, wants a service template with CI, deploy and observability built in, or developers wait on tickets to ops for routine infrastructure.
Use it when
- A team wants an internal developer platform or portal
- Evaluating Backstage against Port, Cortex or a lighter approach
- Developers wait on ops tickets for repos, databases or pipelines
- Service ownership and docs are scattered and unknown
Use something else when
- You need one Kubernetes deploy pipeline, not a platform: use argocd-gitops
- The task is a single reusable CI workflow: use github-actions-workflows
How to check the result
Someone outside the platform team takes a new service from template to production unaided, the entity appears in the catalog with the right owner, and a shared workflow update reaches an existing service via a version bump.
The mistake it prevents
Launching a Backstage portal before any golden path works end to end, so the portal only catalogues the existing inconsistency.
Done well means: the platform removes a measured bottleneck, the first golden path takes a new service to production with no tickets, teams adopt it because it is easier (not because it is mandated), and the platform team tracks adoption and friction like any product team tracks usage.
Start with the problem, not the portal
Interview or survey before building. Collect numbers where possible:
| Question | Signal that a platform helps |
|---|---|
| How long from “new service idea” to first production deploy? | Days to weeks, mostly waiting on other teams |
| How many tickets to ops/infra per month, and of which kinds? | Repetitive requests (new repo, DB, DNS, secrets, pipeline) |
| How many ways do teams deploy today? | More than two for the same kind of workload |
| How long until a new hire ships to production? | More than a week |
| Who owns each running service? | Nobody can answer quickly |
If the pain is one slow CI pipeline or one painful deploy, fix that directly and stop; not every organisation with 20 engineers needs an IDP. A platform team usually pays off once several product teams repeat the same infrastructure work.
Layers of a platform
Build bottom-up; a portal on top of chaos is a catalog of chaos.
| Layer | Contents | Usually already exists as |
|---|---|---|
| Infrastructure | Clusters, networks, managed databases, IAM | Terraform/OpenTofu, cloud accounts |
| Delivery | CI templates, GitOps, environments, preview envs | GitHub Actions reusable workflows, Argo CD |
| Golden paths | Templates wiring infra plus delivery plus observability for a workload type | Often missing: this is the product |
| Interfaces | CLI, portal, API, or plain repo templates | Backstage, Port, Cortex, a create-service CLI |
| Ownership and insight | Catalog, scorecards, docs | Spreadsheets, wiki pages |
Golden path design
A golden path is an opinionated, supported route for one workload type (for example “HTTP service in Go on Kubernetes” or “scheduled Python job”). It is paved, not walled: teams may leave it but then own the consequences.
Each path ships, working on day one:
- Repo template with build, test, lint, Dockerfile,
AGENTS.mddescribing the conventions - CI calling shared, versioned reusable workflows (not copy-pasted YAML)
- Deploy to dev automatically, to production through the standard GitOps flow
- Health endpoints, structured logging, metrics and tracing defaults wired in
- Ownership metadata (team, on-call, tier) in the catalog
- Secrets from the standard store; no secrets in templates
- Runbook and docs stub that renders in the portal
- Upgrade story: how existing services receive template improvements
The last item is where platforms rot. Prefer shared, versioned building blocks (reusable
CI workflows, base Helm charts, Terraform modules) over one-time code generation, so a fix
reaches every service with a version bump. Include AGENTS.md in templates so Codex and
other agents follow the same conventions as humans.
Portal: Backstage or not
| Option | Choose when | Cost |
|---|---|---|
| No portal yet: templates + CLI + README catalog | Under ~10 teams, first golden path not proven | Lowest; revisit later |
| Backstage (self-hosted) | Need deep customisation, own plugins, have 1 to 3 engineers to run it | A React/Node app you build, upgrade and secure |
| Managed Backstage (for example Roadie) | Want Backstage ecosystem without running it | Subscription; less low-level control |
| Port, Cortex, OpsLevel | Want catalog, scorecards and self-service actions quickly | Subscription; data model is theirs |
Backstage is a framework, not a product you install once. Budget ongoing engineering time for upgrades (frequent releases) and plugin maintenance before choosing it.
Backstage essentials
Catalog entry in each repo root:
# catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: payments-api
description: Card payments and refunds
annotations:
github.com/project-slug: acme/payments-api
backstage.io/techdocs-ref: dir:.
tags: [go, grpc]
spec:
type: service
lifecycle: production
owner: group:payments
system: checkout
providesApis: [payments-grpc]
dependsOn: [resource:payments-db]
Owners must be real Group entities synced from the identity provider (an org data
provider for GitHub, Entra ID or LDAP), or ownership drifts within months.
A Software Template that creates a repo from a skeleton and registers it:
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: go-http-service
title: Go HTTP service
spec:
owner: group:platform
type: service
parameters:
- title: Service
required: [name, owner]
properties:
name: { type: string, pattern: '^[a-z][a-z0-9-]{2,40}$' }
owner:
type: string
ui:field: OwnerPicker
ui:options: { catalogFilter: { kind: Group } }
steps:
- id: fetch
action: fetch:template
input:
url: ./skeleton
values: { name: '${{ parameters.name }}', owner: '${{ parameters.owner }}' }
- id: publish
action: publish:github
input:
repoUrl: github.com?owner=acme&repo=${{ parameters.name }}
defaultBranch: main
- id: register
action: catalog:register
input:
repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
catalogInfoPath: /catalog-info.yaml
output:
links:
- { title: Repository, url: '${{ steps.publish.output.remoteUrl }}' }
- TechDocs builds MkDocs sites from
docs/plusmkdocs.yml; build them in CI and publish to object storage rather than building on request in production. - Use the new backend system for plugins; check plugin compatibility with your Backstage release before upgrading.
- Running a template creates real repositories and cloud resources. When Codex tests a template, use a sandbox GitHub org or dry-run mode, and confirm with the user before any run that publishes.
Self-service infrastructure
- Expose infrastructure as reviewed, versioned modules or Crossplane compositions, called from templates. The developer picks “Postgres, small”; the module encodes backups, encryption, sizing and tags.
- Guardrails in policy (OPA/Kyverno, cloud org policies, CI checks), not in review queues.
- Every self-service action is auditable and reversible, with cost tags set automatically.
Measure the platform
| Metric | How |
|---|---|
| Time from template to first prod deploy | Timestamp of repo creation vs first prod deploy event |
| Adoption | Share of active services on a golden path or current template version |
| DORA metrics per team | Deployment frequency, lead time, change failure rate, time to restore |
| Ticket volume to platform team | By category, month over month |
| Developer satisfaction | Short quarterly survey (one ease question, one open question) |
| Catalog quality | Share of components with owner, tier, on-call, docs |
Use scorecards (production readiness, security baseline) as guidance with clear next steps, not as public shaming dashboards.
Anti-patterns
- Building the portal first, golden paths later.
- Mandating the platform before it is better than the status quo.
- A path that covers 90 percent of the setup and leaves the hard 10 percent (secrets, DNS, alerts) as tickets.
- Templates that generate code once and never update, leaving hundreds of forks.
- Platform team as gatekeeper: approvals for everything recreate the ticket queue.
- Abstracting the cloud so thoroughly that debugging requires the platform team.
Verification
- A developer outside the platform team creates a service from the template and reaches production without help; time it and record every question they asked.
catalog-info.yamlvalidates and the entity appears with correct owner and system.- A change to a shared workflow or chart reaches at least one existing service through a version bump, proving the upgrade story.
- Baseline metrics captured before launch so improvement can be shown.
Output: platform proposal
## Problem
New services take 12 working days to reach prod; 61% of infra tickets are repeat requests.
## First golden path
Go HTTP service on EKS: template, reusable CI v2, Argo CD app, OTel defaults, catalog entry.
## Interface
Backstage (self-hosted) in phase 2; phase 1 is a template repo + `create-service` CLI.
## Success measures (90 days)
Template-to-prod under 1 day; 50% of new services on the path; infra tickets -40%.
## Team and cost
2 platform engineers; Backstage hosting about $X/month; upgrade budget 20% of team time.
## Out of scope
Data pipelines, mobile apps (separate paths later). What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Platform Engineering"
short_description: "Golden paths first, the developer portal second"
default_prompt: "$platform-engineering Design a golden path for new Go services from template to production on our EKS setup" About this skill
Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.