Open Component Model: Software Bills of Delivery für Cloud-Native Anwendungen erstellen
Die Software-Supply-Chain ist zu einem kritischen Angriffsvektor geworden: 62% der Unternehmen erlebten 2023 einen Angriff auf ihre Software-Supply-Chain, so der State of Software Supply Chain Security Report. Herkömmliche Ansätze zur Verfolgung von Abhängigkeiten und Deployment-Artefakten greifen in Cloud-Native-Umgebungen zu kurz, wo sich Anwendungen über mehrere Repositories, Container-Images und Laufzeitkonfigurationen erstrecken. Das Open Component Model (OCM) schließt diese Lücke, indem es einen standardisierten Ansatz zur Erstellung von Software Bills of Delivery (SBOD) bietet, die das vollständige Bild dessen erfassen, was deployed wird.
Im Gegensatz zu Software Bills of Materials (SBOM), die sich auf Code-Abhängigkeiten konzentrieren, verfolgen Software Bills of Delivery die tatsächlichen Artefakte und Konfigurationen, die in Produktionsumgebungen gelangen. Diese Unterscheidung ist wichtig, wenn Sie nicht nur verstehen müssen, welcher Code geschrieben wurde, sondern was tatsächlich deployed wurde, wie es konfiguriert war und woher es stammt.
Das Open Component Model verstehen
Das Open Component Model ist ein offener Standard, der Software Bills of Delivery in einem technologieagnostischen, maschinenlesbaren Format beschreibt. OCM fokussiert sich speziell auf die Software-Artefakte, die für Software-Produkte ausgeliefert werden müssen, und bietet vollständige Sichtbarkeit und Kontrolle über die gesamte Supply-Chain bei gleichzeitiger Vereinfachung von Compliance-Prüfungen, Sicherheitsscans und Deployments.
Das Modell behandelt Software-Komponenten als erstklassige Entitäten, die versioniert, signiert und zwischen verschiedenen Umgebungen und Repositories transportiert werden können. Dieser Ansatz ermöglicht es Organisationen, nicht nur den Quellcode zu verfolgen, sondern die komplette Delivery-Pipeline einschließlich Build-Artefakten, Container-Images, Helm-Charts und Konfigurationsdateien.
Zentrale Konzepte
Components repräsentieren logische Software-Einheiten, die unabhängig versioniert und deployed werden können. Eine Komponente kann ein Microservice, eine Bibliothek oder ein kompletter Anwendungsstack sein.
Resources sind die tatsächlichen Artefakte, die einer Komponente zugeordnet sind - Container-Images, Binärdateien, Dokumentation oder Konfigurationsdateien. Jede Resource hat einen Typ, eine Version und eine Zugriffsmethode.
Sources verfolgen den Ursprung von Komponenten und verlinken zurück zu Source-Repositories, Build-Systemen oder anderen Komponenten. Dies schafft eine nachvollziehbare Spur von der Quelle bis zum Deployment.
References stellen Beziehungen zwischen Komponenten her und ermöglichen komplexe Abhängigkeitsgraphen bei gleichzeitiger Wahrung klarer Eigentumsgrenzen.
OCM für Multi-Repository-Tracking einrichten
Lassen Sie uns die Implementierung von OCM in einem realistischen Szenario durchgehen, in dem Sie Microservices über mehrere Repositories verteilt haben, jeder mit eigenen Build-Pipelines.
Installieren Sie zunächst das OCM CLI-Tool:
# OCM CLI herunterladen und installieren
curl -L https://github.com/open-component-model/ocm/releases/latest/download/ocm-linux-amd64.tar.gz | tar xz
sudo mv ocm /usr/local/bin/
Erstellen Sie einen Component-Descriptor für Ihren ersten Microservice. Diese YAML-Datei definiert die Komponente und ihre Resources:
# component-descriptor.yaml für user-service
apiVersion: ocm.software/v3alpha1
kind: ComponentVersion
metadata:
name: acme.com/user-service
version: v1.2.3
provider:
name: acme.com
spec:
repositoryContexts:
- type: OCIRegistry
baseUrl: registry.acme.com/ocm
sources:
- name: user-service-source
type: git
version: v1.2.3
access:
type: github
repoUrl: https://github.com/acme/user-service
ref: v1.2.3
resources:
- name: user-service-image
type: ociImage
version: v1.2.3
relation: local
access:
type: ociRegistry
imageReference: registry.acme.com/user-service:v1.2.3
- name: helm-chart
type: helmChart
version: v1.2.3
relation: local
access:
type: ociRegistry
imageReference: registry.acme.com/charts/user-service:v1.2.3
- name: config
type: yaml
version: v1.2.3
relation: local
access:
type: github
repoUrl: https://github.com/acme/user-service-config
ref: v1.2.3
path: production.yaml
OCM in CI/CD-Pipelines integrieren
Die wahre Stärke von OCM zeigt sich bei der Integration in Ihre Build- und Deployment-Pipelines. Hier erfahren Sie, wie Sie einen GitHub Actions-Workflow modifizieren, um Component-Descriptors zu generieren und zu veröffentlichen:
# .github/workflows/build-and-publish.yml
name: Build and Publish Component
on:
push:
tags: ['v*']
jobs:
build-and-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push image
uses: docker/build-push-action@v5
with:
push: true
tags: registry.acme.com/user-service:${{ github.ref_name }}
- name: Install OCM CLI
run: |
curl -L https://github.com/open-component-model/ocm/releases/latest/download/ocm-linux-amd64.tar.gz | tar xz
sudo mv ocm /usr/local/bin/
- name: Generate component descriptor
run: |
envsubst < component-descriptor.template.yaml > component-descriptor.yaml
env:
VERSION: ${{ github.ref_name }}
IMAGE_DIGEST: ${{ steps.build.outputs.digest }}
COMMIT_SHA: ${{ github.sha }}
- name: Create and push component version
run: |
ocm create componentversion \
--file component-descriptor.yaml \
--provider acme.com
ocm transfer componentversion \
component-descriptor.yaml \
registry.acme.com/ocm
Für Multi-Repository-Szenarien erstellen Sie einen separaten Workflow, der Komponenten zu einer übergeordneten Komponente aggregiert, die Ihre komplette Anwendung repräsentiert:
# Anwendungsebenen-Component-Descriptor
apiVersion: ocm.software/v3alpha1
kind: ComponentVersion
metadata:
name: acme.com/ecommerce-platform
version: v2.1.0
provider:
name: acme.com
spec:
repositoryContexts:
- type: OCIRegistry
baseUrl: registry.acme.com/ocm
componentReferences:
- name: user-service
componentName: acme.com/user-service
version: v1.2.3
- name: order-service
componentName: acme.com/order-service
version: v2.0.1
- name: payment-service
componentName: acme.com/payment-service
version: v1.5.2
resources:
- name: deployment-manifest
type: yaml
version: v2.1.0
relation: local
access:
type: github
repoUrl: https://github.com/acme/platform-deployment
ref: v2.1.0
path: kubernetes/
Laufzeitkonfigurationen erfassen
Eine der Stärken von OCM ist die Verfolgung nicht nur von Build-Artefakten, sondern auch von Laufzeitkonfigurationen, die das Verhalten von Software in der Produktion beeinflussen. Dazu gehören Umgebungsvariablen, Feature-Flags und Infrastrukturkonfigurationen.
Erstellen Sie einen Resource-Typ für Laufzeitkonfigurationen:
resources:
- name: runtime-config
type: json
version: v1.2.3
relation: local
access:
type: inline
data: |
{
"environment": "production",
"features": {
"new_checkout_flow": true,
"enhanced_security": true
},
"scaling": {
"min_replicas": 3,
"max_replicas": 10,
"cpu_threshold": 70
},
"database": {
"connection_pool_size": 20,
"timeout_seconds": 30
}
}
Für Kubernetes-Deployments erfassen Sie die tatsächlich deployten Manifeste:
# Deployed-Konfiguration extrahieren und zur Komponente hinzufügen
kubectl get deployment user-service -o yaml > deployed-config.yaml
# Als Resource zum Component-Descriptor hinzufügen
ocm add resource component-descriptor.yaml \
--name deployed-config \
--type yaml \
--version v1.2.3 \
--inputFilePath deployed-config.yaml
Supply-Chain-Security implementieren
OCM bietet mehrere Mechanismen zur Gewährleistung der Supply-Chain-Sicherheit. Digitale Signaturen verifizieren die Authentizität von Komponenten, während Policy-Enforcement das Deployment nicht autorisierter oder verwundbarer Komponenten verhindert.
Komponenten signieren
Signieren Sie Component-Versionen mit OCMs eingebauten Signierungsfähigkeiten:
# Signierungsschlüssel generieren
ocm create rsakeypair acme-signing-key
# Component-Version signieren
ocm sign componentversion \
--signature acme-signature \
--private-key acme-signing-key.priv \
registry.acme.com/ocm//acme.com/user-service:v1.2.3
Policy-Enforcement
Erstellen Sie Richtlinien, die Komponenten vor dem Deployment validieren:
# policy.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: ocm-policy
data:
policy.rego: |
package ocm.policy
# Alle Komponenten müssen signiert sein
deny[msg] {
not input.signatures
msg := "Component must be signed"
}
# Komponenten müssen aus vertrauenswürdigen Quellen stammen
deny[msg] {
input.sources[_].access.repoUrl
not startswith(input.sources[_].access.repoUrl, "https://github.com/acme/")
msg := "Component must originate from trusted repository"
}
# Aktuelle Versionen erforderlich
deny[msg] {
version_age_days := days_since_version(input.metadata.version)
version_age_days > 90
msg := sprintf("Component version %s is too old (%d days)", [input.metadata.version, version_age_days])
}
Integrieren Sie Policy-Validierung in Ihre Deployment-Pipeline:
# Komponente vor Deployment gegen Policy validieren
ocm verify componentversion \
--policy policy.yaml \
registry.acme.com/ocm//acme.com/user-service:v1.2.3
Abfragen und Reporting
OCM ermöglicht ausgeklügelte Abfragen Ihrer Software-Supply-Chain. Extrahieren Sie Abhängigkeitsgraphen, identifizieren Sie verwundbare Komponenten und generieren Sie Compliance-Reports.
Abfrage aller Komponenten, die ein bestimmtes Base-Image verwenden:
# Alle Komponenten finden, die ubuntu:20.04 verwenden
ocm query components \
--repo registry.acme.com/ocm \
--filter 'resources[?type==`ociImage`].access.imageReference | [?contains(@, `ubuntu:20.04`)]'
Vollständige Bill of Delivery für eine Anwendung generieren:
# Kompletten Abhängigkeitsbaum extrahieren
ocm tree componentversion \
--repo registry.acme.com/ocm \
acme.com/ecommerce-platform:v2.1.0 \
--output json > supply-chain-report.json
Benutzerdefinierte Reports mit der OCM API erstellen:
// Go-Beispiel für die Generierung benutzerdefinierter Reports
package main
import (
"context"
"fmt"
"github.com/open-component-model/ocm/pkg/contexts/ocm"
"github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ocireg"
)
func generateSupplyChainReport(componentName, version string) error {
ctx := ocm.New()
defer ctx.Finalize()
repo, err := ocireg.NewRepository(ctx, "registry.acme.com/ocm")
if err != nil {
return err
}
cv, err := repo.LookupComponentVersion(componentName, version)
if err != nil {
return err
}
// Component-Referenzen rekursiv durchlaufen
refs := cv.GetComponentReferences()
for _, ref := range refs {
fmt.Printf("Dependency: %s@%s\n", ref.GetComponentName(), ref.GetVersion())
// Referenzierte Komponente abrufen und auf Schwachstellen prüfen
refCV, err := repo.LookupComponentVersion(ref.GetComponentName(), ref.GetVersion())
if err != nil {
continue
}
// Sicherheitsmetadaten extrahieren
resources := refCV.GetResources()
for _, res := range resources {
if res.Meta().GetType() == "ociImage" {
fmt.Printf(" Image: %s\n", res.Meta().GetName())
// Hier Integration mit Vulnerability-Scanner
}
}
}
return nil
}
Best Practices für Produktions-Deployment
Automatisierte Component-Generierung: Erstellen Sie niemals manuell Component-Descriptors. Integrieren Sie die Generierung in Ihre CI/CD-Pipelines, um Konsistenz und Genauigkeit zu gewährleisten.
Alles versionieren: Berücksichtigen Sie nicht nur Anwendungsversionen, sondern auch Versionen von Build-Tools, Base-Images und Deployment-Konfigurationen. Dies ermöglicht die präzise Reproduktion jedes Deployments.
Progressive Validierung implementieren: Beginnen Sie mit grundlegendem Component-Tracking und fügen Sie schrittweise Signierung, Policy-Enforcement und Vulnerability-Scanning hinzu, während Ihre Prozesse reifen.
Klare Verantwortlichkeiten etablieren: Definieren Sie, welche Teams für die Wartung von Component-Descriptors für geteilte Abhängigkeiten und Infrastruktur-Komponenten verantwortlich sind.
Supply-Chain-Drift überwachen: Auditieren Sie regelmäßig deployete Komponenten gegen ihre Descriptors, um nicht autorisierte Änderungen oder Konfigurationsdrift zu identifizieren.
Die Open Component Model-Spezifikation bietet die Grundlage für umfassende Sichtbarkeit der Software-Supply-Chain. Durch die Implementierung von OCM in Ihrer Multi-Repository-Umgebung gewinnen Sie die Transparenz, die für die Sicherung und Auditierung Ihrer Cloud-Native-Anwendungen erforderlich ist, bei gleichzeitiger Beibehaltung der Flexibilität zur Weiterentwicklung Ihrer Architektur.
OCM verwandelt Supply-Chain-Sicherheit von einer Compliance-Checkbox in eine strategische Fähigkeit, die zuversichtliche, schnelle Software-Auslieferung ermöglicht. Die Investition in die Implementierung umfassender Component-Verfolgung zahlt sich durch reduzierte Sicherheitsvorfälle, schnellere Incident-Response und vereinfachtes Compliance-Reporting aus.