Back to articles
Technology Insight

Building Enterprise Developer Platforms with Backstage, Score, and Crossplane

August 21, 2026

Building Enterprise Internal Developer Platforms with Backstage, Score, and Crossplane

Modern enterprise engineering organizations face severe developer cognitive overload. As cloud-native architectures grow in complexity across AWS, GCP, and Azure, software engineers are routinely required to navigate Kubernetes manifests, Terraform configurations, IAM policies, and cloud-vendor-specific APIs just to deploy a basic microservice with a managed database. The solution is an Internal Developer Platform (IDP) that abstracts lower-level infrastructure, enforces platform governance, and provides Golden Paths for self-service capability.

This article details the architecture and implementation of a next-generation Enterprise IDP built on three foundational pillars:

  • Backstage: The developer portal frontend, software catalog, and template scaffolding engine.
  • Score: A cloud-agnostic workload specification standard that decouples application requirements from target environment implementations.
  • Crossplane: A Kubernetes-native control plane engine that translates high-level infrastructure claims into enterprise-ready multi-cloud resources.

Architecture Overview

The IDP architecture separates concerns into clear layers: UI/Discovery (Backstage), Developer Specification (Score), Infrastructure Orchestration (Crossplane), and Deployment Control (GitOps with ArgoCD/Flux).

+-----------------------------------------------------------------------------------+
|                                DEVELOPER PORTAL                                   |
|   +---------------------------------------------------------------------------+   |
|   | Backstage (Software Catalog, Scaffolder, Technical Documentation)         |   |
|   +---------------------------------------------------------------------------+   |
+------------------------------------------+----------------------------------------+
                                           |
                                 Scaffolds Repo & Specs
                                           v
+-----------------------------------------------------------------------------------+
|                            DEVELOPER WORKLOAD SPEC                                |
|   +---------------------------------------------------------------------------+   |
|   | Score Spec (score.yaml) -> score-k8s / score-compose                      |   |
|   +---------------------------------------------------------------------------+   |
+------------------------------------------+----------------------------------------+
                                           |
                                Generates Manifests / Claims
                                           v
+-----------------------------------------------------------------------------------+
|                           GITOPS & CONTROL PLANE ENGINE                           |
|   +------------------------------------+  +-----------------------------------+   |
|   | GitOps Repository (ArgoCD / Flux)  |  | Crossplane Universal Control Plane |   |
|   +------------------------------------+  +-----------------------------------+   |
+------------------------------------------+----------------------------------------+
                                           |
                            Provisions Managed Resources
                                           v
+-----------------------------------------------------------------------------------+
|                          MULTI-CLOUD INFRASTRUCTURE                               |
|   +----------------------+   +-----------------------+   +--------------------+   |
|   | AWS (RDS, EKS, S3)   |   | GCP (CloudSQL, GKE)   |   | Azure (Database)   |
|   +----------------------+   +-----------------------+   +--------------------+   |
+-----------------------------------------------------------------------------------+

Component 1: Universal Control Plane with Crossplane

Crossplane turns Kubernetes clusters into universal control planes. Platform engineers define custom abstractions called Composite Resource Definitions (XRDs) and bind them to cloud implementations via Compositions. Developers consume these abstractions without knowing cloud vendor specifics.

Defining a CompositeResourceDefinition (XRD)

Below is an enterprise XRD defining a standard managed database resource claim (XPostgreSQLInstance):

apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: xpostgresqlinstances.database.platform.enterprise.io
spec:
  group: database.platform.enterprise.io
  names:
    kind: XPostgreSQLInstance
    plural: xpostgresqlinstances
  claimNames:
    kind: PostgreSQLInstance
    plural: postgresqlinstances
  versions:
  - name: v1alpha1
    served: true
    referenceable: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              parameters:
                type: object
                properties:
                  storageGB:
                    type: integer
                    default: 20
                  databaseName:
                    type: string
                  engineVersion:
                    type: string
                    default: "15"
                required:
                - databaseName
            required:
            - parameters

AWS RDS Infrastructure Composition

Platform engineers implement the XRD for specific cloud providers using a Crossplane Composition. The manifest below routes requests to AWS RDS with encrypted storage and Automated Backup configurations:

apiVersion: apiextensions.crossplane.io/v1
kind: Composition
metadata:
  name: rds-postgres-production
  labels:
    provider: aws
    environment: production
spec:
  compositeTypeRef:
    apiVersion: database.platform.enterprise.io/v1alpha1
    kind: XPostgreSQLInstance
  resources:
  - name: rds-instance
    base:
      apiVersion: rds.aws.upbound.io/v1beta1
      kind: Instance
      spec:
        forProvider:
          region: us-west-2
          instanceClass: db.t4g.medium
          allocatedStorage: 20
          engine: postgres
          skipFinalSnapshot: true
          storageEncrypted: true
          publiclyAccessible: false
    patches:
    - type: FromCompositeFieldPath
      fromFieldPath: spec.parameters.storageGB
      toFieldPath: spec.forProvider.allocatedStorage
    - type: FromCompositeFieldPath
      fromFieldPath: spec.parameters.engineVersion
      toFieldPath: spec.forProvider.engineVersion

Component 2: Developer Workload Specification with Score

While Crossplane manages infrastructure resources, Score (score.dev) provides a clean, platform-agnostic developer specification standard. Instead of writing verbose Kubernetes deployment YAMLs or Helm values, developers describe what their application needs to run in a score.yaml file.

apiVersion: score.dev/v1b1
metadata:
  name: payment-service
containers:
  web:
    image: 123456789012.dkr.ecr.us-west-2.amazonaws.com/payment-service:v2.1.0
    variables:
      DB_HOST: "${resources.db.host}"
      DB_PORT: "${resources.db.port}"
      DB_NAME: "${resources.db.name}"
      DB_USER: "${resources.db.username}"
      DB_PASSWORD: "${resources.db.password}"
resources:
  db:
    type: postgres
    params:
      extensions:
        - uuid-ossp

During automated CI/CD pipeline execution, the score-k8s CLI tool transforms this platform-agnostic definition into native Kubernetes resources and Crossplane Claims (`PostgreSQLInstance`), binding parameters automatically.

Component 3: Backstage Orchestration & Scaffolder Templates

Backstage serves as the entry point for software developers. Through Backstage Software Templates, engineers can spin up a new repository containing the application code, `score.yaml` specification, and GitOps integration files in seconds.

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: enterprise-java-service
  title: Java Microservice with Managed Database
  description: Scaffolds a Production-Ready Spring Boot Service integrated with Crossplane & Score
spec:
  owner: platform-team
  type: service
  parameters:
    - title: Service Details
      required:
        - name
        - owner
      properties:
        name:
          title: Service Name
          type: string
          pattern: '^[a-z0-9-]+$'
        owner:
          title: Owner Team
          type: string
          ui:field: OwnerPicker
    - title: Database Requirements
      properties:
        enableDatabase:
          title: Provision Cloud Database?
          type: boolean
          default: true
        storageGB:
          title: Database Storage (GB)
          type: integer
          default: 20
  steps:
    - id: fetch-template
      name: Fetch Base Skeleton
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          owner: ${{ parameters.owner }}
          enableDatabase: ${{ parameters.enableDatabase }}
          storageGB: ${{ parameters.storageGB }}

    - id: publish-github
      name: Publish to GitHub
      action: publish:github
      input:
        allowedHosts: ['github.com']
        repoUrl: 'github.com?repo=${{ parameters.name }}&owner=enterprise-org'

    - id: register-catalog
      name: Register Component in Backstage
      action: catalog:register
      input:
        catalogInfoUrl: 'https://github.com/enterprise-org/${{ parameters.name }}/blob/main/catalog-info.yaml'

End-to-End Execution Flow

The operational workflow proceeds through four seamlessly integrated steps:

  1. Self-Service Request: A developer selects the template in Backstage, specifies required storage, and clicks generate.
  2. Repository Scaffolding: Backstage generates the service codebase, injects `score.yaml`, and creates the Crossplane Claim manifest in the GitOps infrastructure repository.
  3. Control Plane Synchronization: ArgoCD synchronizes the GitOps repository with the control plane cluster. Crossplane interceptors read the `PostgreSQLInstance` claim, match the appropriate `Composition`, and provision an AWS RDS instance.
  4. Dynamic Secret & Endpoint Binding: Crossplane writes generated credentials directly to Kubernetes Secrets. The `score-k8s` operator mounts these secrets as environment variables inside the running workload pod.

Enterprise Governance and Day-2 Operations

Building an enterprise-ready IDP requires addressing security, governance, and drift management:

  • RBAC & Identity Federation: Implement OIDC bridging via Keycloak or Okta. Developers only hold permissions to write Score files or request claims within their team namespace. Crossplane operators run under privileged cloud IAM roles via AWS IRSA or GCP Workload Identity.
  • Secret Management Integration: Never store raw database passwords inside Kubernetes secret objects permanently. Integrate External Secrets Operator (ESO) with HashiCorp Vault or AWS Secrets Manager to automatically sync Crossplane-generated credentials.
  • Policy Enforcement: Use Kyverno or Open Policy Agent (OPA) to validate Crossplane Compositions and Score files prior to deployment, enforcing encryption, tagging standards, and resource limits.

By pairing Backstage for developer experience, Score for workload abstraction, and Crossplane for multi-cloud infrastructure orchestration, enterprises achieve full developer self-service while enforcing rigid platform security and governance standards.