Hey {{first name | there}}. Earlier today I put out a post on LinkedIn about how platform engineering can feel like stitching tools together, and where I go when I want to see what the rest of the ecosystem is actually doing.

In today's issue, I thought I'd expand on some other thoughts I have regarding platform engineering and tooling.

In today's Technical Notes:

  • Why most platform conversations start at the portal and stall at a catalog

  • How Port, Crossplane, and Kratix answer the same question from three different layers

  • Why the interface developers actually call is the platform, not the UI in front of it

📰 TECHNICAL NOTES: A Catalog is not a platform

If you have spent any time in this space, you have seen the default starting point: stand up Backstage, or something that looks like Backstage, fill the software catalog, add TechDocs, maybe a software template that scaffolds a repo.

That work is not useless. Discoverability is a real problem, and Spotify open-sourced Backstage because they had lived the "where does this service live and who owns it" failure mode at scale.

The mistake is treating that UI as the platform.

A portal that cannot provision, upgrade, or retire anything is a wiki with extra CSS. Developers will use it to look things up.

They will not use it to get a database, an environment, or a pipeline. Those requests still go to Slack, a ticket, or a Terraform repo only three people are allowed to touch.

The platform is the interface they actually call. A Kubernetes API. A Promise. A Crossplane claim. An MCP tool. Even a well-designed CLI. The portal is one client of that interface, not the interface itself.

Different answers to the same question

When an application team needs a capability, what do they talk to, and what happens after the request lands?

Port (and Backstage, Cortex, the rest of that category) sits at the top. 

Catalog, scorecards, ownership, self-service actions. Port is good at this, and the blog is worth reading if you are trying to make the estate visible.

A self-service action in a portal still has to call something. If that something is a GitHub Actions workflow that applies a Helm chart and then forgets the resource exists, you have a button, not a platform.

Crossplane sits at the bottom, closer to the metal. You define a CompositeResourceDefinition, which is a custom Kubernetes API, and a Composition that maps that API onto real cloud resources.

 An application team (or more often, a platform team on their behalf) applies a claim, and Crossplane reconciles it until the RDS instance, the VPC, and the IAM role actually exist. The important part is not "we use Crossplane." The important part is that the contract is an API with a schema, not a wiki page describing how to open a ticket.

A request for Postgres, three ways

Say a team needs Postgres.

In the portal-only world, they click "Request database." That click fires a pipeline. The pipeline succeeds, someone gets a connection string, and from that point the resource is theirs. No upgrade path, no policy refresh, no retirement.

Syntasso calls this the puppy-for-Christmas problem, and it is the right name. You clicked it, now you own it.

In the Crossplane world, they apply a claim (or the portal applies one on their behalf). The API is the thing. Composition decides whether that is RDS or a Helm chart on a shared cluster. Reconciliation is continuous, which is a different shape of promise than "the job went green."

In the Kratix world, they request a Promise. The Promise is allowed to be opinionated: prod vs dev, backup window, which cluster it lands on. Crossplane can still do the cloud plumbing. The portal can still be how humans find the form. Agents can call the same Promise. The contract does not change just because the client did.

If you only remember one thing: put the opinions in the API. The UI will change. The agent will show up. The pipeline syntax will get rewritten twice. The API is what you can version, test, and refuse to break.

Where this leaves you

If you are in the middle of a Backstage rollout, do not stop. Just be honest about what you are shipping. A catalog is a catalog. Pair it with an API that actually creates and looks after the thing, or you will spend the next year wondering why adoption died after the demo.

If you already have Crossplane or a pile of Terraform modules, the gap is usually not "we need more modules." It is that application teams still cannot call those modules without becoming infrastructure engineers. That is the layer Kratix-style Promises are for.

And if your current "platform" is a portal button wired to a pipeline, pick one capability (Postgres is fine) and write down the API you wish existed: inputs, defaults, who is allowed to request it, what happens on upgrade, what happens when nobody uses it. Then see whether your current stack can implement that API, or whether you have been decorating a ticket queue.

🌍IN THE ECOSYSTEM

  • Beyond the Platform Façade — Syntasso: the portals-and-pipelines antipattern, and why a button that fires a workflow is not the same as owning the lifecycle.

  • CNCF Platforms White Paper — still the cleanest split I have seen between portals, APIs, and the capabilities underneath. Worth rereading if your org uses "IDP" to mean three different things.

  • What the Heck is Backstage Anyway? — Spotify Engineering, from the people who created it. Useful as a reminder of what Backstage was for, and what it was never claimed to be.

  • Kratix and Crossplane — short and practical on how Promises sit in front of Compositions instead of replacing them.

  • Port's blog — if you want the portal-and-catalog side of this done well, including what they are doing with agents on top of the catalog.

⏱️UNTIL NEXT TIME

That's it for this issue. If your platform is still a catalog with a button that fires a pipeline, reply and tell me what sits behind that button.

Know an engineer wrestling with this? Share this link with them

Jubril Oyetunji
CTO, EverythingDevOps

HOW DID WE DO?

Login or Subscribe to participate