← Alle Beiträge

Software Bills of Delivery: Über SBOMs hinaus mit Component Models

Matthias Bruns · · 8 Min. Lesezeit
software-supply-chain component-model sbom artifact-management

Traditionelle Software Bills of Materials (SBOMs) bilden zwar das Fundament für Transparenz in Software-Supply-Chains, stoßen aber in den komplexen, verteilten Umgebungen von heute an ihre Grenzen. Während SBOMs Komponenten und Abhängigkeiten katalogisieren, versagen sie dabei, den kompletten Delivery-Lifecycle in cloud-nativen Architekturen zu verfolgen. Hier kommen Software Bills of Delivery und Component Models ins Spiel – ein umfassenderer Ansatz, der nicht nur verfolgt, was in Ihrer Software steckt, sondern wie sie sich durch Ihre gesamte Delivery-Pipeline bewegt.

Das SBOM-Fundament und seine Grenzen

Eine Software Bill of Materials ist eine formelle Aufzeichnung aller Software-Komponenten und Software-Abhängigkeiten, die in der Anwendungsentwicklung und -bereitstellung verwendet werden. Die National Telecommunications and Information Administration (NTIA) hat Grundanforderungen für SBOM-Erstellung und -Bereitstellung etabliert, wodurch sie zunehmend verpflichtend für Regierungsaufträge und Unternehmenssoftware werden.

SBOMs glänzen dabei, eine Momentaufnahme von Komponenten zur Build-Zeit zu liefern. Sie beantworten kritische Fragen wie “Welche Open-Source-Bibliotheken verwenden wir?” und “Haben wir bekannte Sicherheitslücken?” Aber sie haben Schwierigkeiten mit der dynamischen Natur moderner Software-Bereitstellung:

  • Statische Momentaufnahmen vs. dynamische Umgebungen: SBOMs erfassen eine zeitpunktbezogene Sicht, aber Container-Images, Serverless-Funktionen und Microservices ändern sich ständig
  • Begrenzte Artefakt-Verfolgung: Sie fokussieren sich auf Quellcode-Abhängigkeiten, übersehen aber Laufzeit-Artefakte, Konfigurationsdateien und Deployment-Metadaten
  • Deployment-Kontext-Lücken: SBOMs verfolgen nicht, wo Komponenten deployed sind, wie sie konfiguriert sind oder ihre Laufzeit-Beziehungen

Diese Einschränkungen werden kritisch, wenn Sie Hunderte von Microservices über mehrere Cluster hinweg verwalten, jeder mit eigenen Abhängigkeitsketten und Deployment-Mustern.

Component Models: Die nächste Evolution

Component Models gehen über traditionelle SBOMs hinaus, indem sie Software-Artefakte als erstklassige Entitäten mit umfangreichen Metadaten während ihres gesamten Lebenszyklus behandeln. Das Open Component Model (OCM) bietet eine praktische Lösung für die Bereitstellung von Software-Artefakten und stellt eine standardisierte Methode zur Beschreibung, Paketierung und zum Transport von Software-Komponenten mit ihrem kompletten Kontext bereit.

Im Gegensatz zu SBOMs verfolgen Component Models:

  • Artefakt-Herkunft: Komplette Build- und Deployment-Historie
  • Laufzeit-Abhängigkeiten: Nicht nur Compile-Zeit-Abhängigkeiten, sondern tatsächliche Laufzeit-Beziehungen
  • Konfigurations-Metadaten: Umgebungsspezifische Einstellungen und ihre Quellen
  • Delivery-Pipelines: Wie Komponenten sich durch CI/CD-Systeme bewegen
  • Deployment-Topologie: Wo Komponenten laufen und wie sie kommunizieren

Diese umfassende Verfolgung ermöglicht das, was wir “Software Bills of Delivery” nennen – lebende Dokumente, die sich mit Ihrer Software entwickeln, während sie durch Umgebungen wandert.

Software Bills of Delivery in der Praxis

Eine Software Bill of Delivery geht über die Auflistung von Komponenten hinaus und verfolgt die komplette Delivery-Reise. So sieht das in einer echten cloud-nativen Umgebung aus:

Mit OCM dient eine Component-Constructor-Datei als Bill of Delivery. Sie erfasst nicht nur, welche Artefakte existieren, sondern woher sie stammen und wie man auf sie zugreift. Das folgende Beispiel dient der Veranschaulichung — das vollständige Schema findet sich in der OCM-Component-Constructor-Referenz:

# component-constructor.yaml — illustratives Beispiel, vollständiges Schema auf ocm.software/docs
components:
  - name: github.com/company/user-service
    version: 2.1.3
    provider:
      name: company.com
    labels:
      - name: build.commit
        value: abc123def456
      - name: build.timestamp
        value: "2024-01-15T10:30:00Z"
      - name: build.pipeline
        value: github-actions
    resources:
      - name: container-image
        type: ociImage
        version: 2.1.3
        access:
          type: OCIImage/v1
          imageReference: registry.company.com/user-service:2.1.3
      - name: helm-chart
        type: helmChart
        version: 2.1.3
        access:
          type: Helm/v1
          helmRepository: registry.company.com
          helmChart: user-service-chart
          version: 2.1.3
    sources:
      - name: source
        type: git
        access:
          type: File/v1alpha1
          uri: https://github.com/company/user-service
    componentReferences:
      - name: postgres
        componentName: github.com/company/postgres
        version: "14.9"
      - name: redis
        componentName: github.com/company/redis
        version: "7.2"

Dieser Constructor erfasst Artefakte, ihre Quellen und Komponentenreferenzen – und bildet damit eine vollständige, maschinenlesbare Bill of Delivery, die OCM signieren, verifizieren und über Registries hinweg transferieren kann.

Component Models für Supply-Chain-Sicherheit implementieren

Moderne Software-Supply-Chain-Sicherheit erfordert die Verfolgung von Komponenten über ihren gesamten Lebenszyklus. So adressieren Component Models zentrale Sicherheitsbedenken:

Herkunfts-Verfolgung

Component Models bewahren kryptografische Beweise für Artefakt-Ursprünge:

type ComponentProvenance struct {
    BuildSystem   string            `json:"buildSystem"`
    SourceRepo    string            `json:"sourceRepo"`
    CommitHash    string            `json:"commitHash"`
    Builder       string            `json:"builder"`
    BuildTime     time.Time         `json:"buildTime"`
    Attestations  []Attestation     `json:"attestations"`
    Signatures    []Signature       `json:"signatures"`
}

type Attestation struct {
    Type      string    `json:"type"`      // "build", "test", "security-scan"
    Result    string    `json:"result"`    // "pass", "fail", "warning"
    Details   string    `json:"details"`
    Timestamp time.Time `json:"timestamp"`
    Verifier  string    `json:"verifier"`
}

Laufzeit-Abhängigkeits-Auflösung

Anders als statische SBOMs verfolgen Component Models tatsächliche Laufzeit-Abhängigkeiten:

# Laufzeit-Abhängigkeits-Erkennung
runtimeDependencies:
  discovered:
    - service: payment-api
      version: "1.4.2"
      protocol: https
      endpoint: payment-api.internal:443
      discoveredAt: "2024-01-15T16:50:00Z"
      
  declared:
    - service: user-db
      version: "14.9"
      protocol: postgresql
      endpoint: user-db.production:5432
      
  external:
    - service: stripe-api
      endpoint: api.stripe.com
      version: "2023-10-16"
      sla: "99.9%"

Schwachstellen-Korrelation

Component Models ermöglichen präzise Schwachstellen-Verfolgung über Deployments hinweg:

{
  "vulnerabilityReport": {
    "component": "user-service:2.1.3",
    "scanTime": "2024-01-15T17:00:00Z",
    "findings": [
      {
        "cve": "CVE-2024-0001",
        "severity": "high",
        "affectedArtifacts": [
          "container:user-service@sha256:8f8a8b8c8d8e8f"
        ],
        "deploymentImpact": [
          {
            "environment": "production",
            "instances": 5,
            "exposure": "internal-only",
            "mitigations": ["network-policy", "pod-security-policy"]
          }
        ]
      }
    ]
  }
}

Verteilte Systeme und Komponenten-Beziehungen

In verteilten Architekturen wird das Verständnis von Komponenten-Beziehungen entscheidend. Component Models bilden diese Beziehungen explizit ab:

Service-Mesh-Integration

componentRelationships:
  upstreamServices:
    - name: api-gateway
      traffic: "100%"
      protocol: http/2
      
  downstreamServices:
    - name: user-db
      queries: ["SELECT", "UPDATE", "INSERT"]
      connectionPool: 10
      
    - name: notification-service
      protocol: grpc
      async: true
      
  sidecarComponents:
    - name: envoy-proxy
      version: "1.28.0"
      config: istio-proxy-config
      
    - name: datadog-agent
      version: "7.49.0"
      config: monitoring-config

Cluster-übergreifende Abhängigkeiten

Moderne Anwendungen erstrecken sich über mehrere Cluster und Cloud-Provider. Component Models verfolgen diese verteilten Beziehungen:

crossClusterDependencies:
  - component: shared-cache
    cluster: us-west-2-cache
    endpoint: redis.shared.company.internal
    latency: "< 5ms"
    
  - component: analytics-pipeline
    cluster: data-processing
    protocol: kafka
    topics: ["user-events", "audit-logs"]
    
  - component: cdn
    provider: cloudflare
    endpoints: ["cdn.company.com"]
    cachePolicies: ["static-assets", "api-responses"]

Automatisierung und Tooling

Component Models glänzen bei der Integration in automatisierte Workflows. So implementieren Sie automatisierte Delivery-Verfolgung:

CI/CD-Integration

OCM verwendet eine component-constructor.yaml-Datei als Eingabe und den Befehl ocm add component-version, um sie in eine OCI-Registry zu pushen. Schlüssel für das Signieren werden über .ocmconfig konfiguriert, nicht als Flags übergeben.

#!/bin/bash
# Build-Pipeline-Integration
set -e

# Container-Image bauen und pushen
docker build -t registry.company.com/user-service:${BUILD_ID} .
docker push registry.company.com/user-service:${BUILD_ID}

# Component Constructor schreiben
cat > component-constructor.yaml <<EOF
components:
  - name: github.com/company/user-service
    version: ${BUILD_ID}
    provider:
      name: company.com
    labels:
      - name: build.commit
        value: ${GIT_COMMIT}
    resources:
      - name: container-image
        type: ociImage
        version: ${BUILD_ID}
        access:
          type: OCIImage/v1
          imageReference: registry.company.com/user-service:${BUILD_ID}
    sources:
      - name: source
        type: git
        access:
          type: File/v1alpha1
          uri: https://github.com/company/user-service
EOF

# Component Version zum OCM-Repository hinzufügen
ocm add component-version \
  --repository ${OCI_REGISTRY} \
  --constructor component-constructor.yaml

# Component Version signieren (Credentials in .ocmconfig konfiguriert)
ocm sign component-version \
  ${OCI_REGISTRY}//github.com/company/user-service:${BUILD_ID} \
  --signature company-signature

Laufzeit-Erkennung

Automatisierte Erkennung hält Component Models aktuell:

func discoverRuntimeDependencies(ctx context.Context, podName string) (*RuntimeDependencies, error) {
    // Netzwerk-Traffic-Analyse
    connections, err := analyzeNetworkConnections(podName)
    if err != nil {
        return nil, err
    }
    
    // Service-Mesh-Integration
    envoyConfig, err := getEnvoyConfiguration(podName)
    if err != nil {
        return nil, err
    }
    
    // DNS-Auflösungs-Verfolgung
    dnsQueries, err := analyzeDNSQueries(podName)
    if err != nil {
        return nil, err
    }
    
    return &RuntimeDependencies{
        NetworkConnections: connections,
        ServiceMeshRoutes:  envoyConfig.Routes,
        DNSResolutions:     dnsQueries,
        DiscoveredAt:       time.Now(),
    }, nil
}

Sicherheitsvorteile und Compliance

Component Models bieten bedeutende Sicherheitsvorteile gegenüber traditionellen SBOMs:

Compliance-Automatisierung

CISAs SBOM-Anforderungen fokussieren sich auf Transparenz, aber Component Models ermöglichen automatisierte Compliance-Prüfungen:

complianceChecks:
  - policy: "no-high-severity-vulnerabilities"
    status: "enforced"
    lastCheck: "2024-01-15T18:00:00Z"
    
  - policy: "signed-artifacts-only"
    status: "enforced"
    exceptions: []
    
  - policy: "approved-base-images"
    status: "warning"
    violations:
      - component: "legacy-service"
        reason: "using deprecated base image"

Erkennung von Supply-Chain-Angriffen

Component Models ermöglichen ausgeklügelte Angriffserkennung:

type SupplyChainAnomaly struct {
    Type        string    `json:"type"`
    Component   string    `json:"component"`
    Description string    `json:"description"`
    Severity    string    `json:"severity"`
    DetectedAt  time.Time `json:"detectedAt"`
}

func detectAnomalies(current, previous *ComponentModel) []SupplyChainAnomaly {
    var anomalies []SupplyChainAnomaly
    
    // Unerwartete Abhängigkeitsänderungen
    for _, dep := range current.Dependencies {
        if !containsDependency(previous.Dependencies, dep) {
            anomalies = append(anomalies, SupplyChainAnomaly{
                Type:        "unexpected-dependency",
                Component:   current.Name,
                Description: fmt.Sprintf("Neue Abhängigkeit hinzugefügt: %s", dep.Name),
                Severity:    "medium",
                DetectedAt:  time.Now(),
            })
        }
    }
    
    // Build-Umgebungsänderungen
    if current.BuildEnvironment.Builder != previous.BuildEnvironment.Builder {
        anomalies = append(anomalies, SupplyChainAnomaly{
            Type:        "builder-change",
            Component:   current.Name,
            Description: "Build-Umgebung geändert",
            Severity:    "high",
            DetectedAt:  time.Now(),
        })
    }
    
    return anomalies
}

Implementierungs-Roadmap

Der Übergang von SBOMs zu Component Models erfordert einen phasenweisen Ansatz:

Phase 1: SBOM-Erweiterung

Beginnen Sie damit, bestehende SBOMs mit Delivery-Metadaten anzureichern. Integrieren Sie SBOM-Generierung direkt in CI/CD-Pipelines und fügen Sie Deployment-Kontext hinzu.

Phase 2: Component-Model-Adoption

Implementieren Sie Component Descriptors neben SBOMs. Beginnen Sie mit der Verfolgung von Artefakt-Beziehungen und Deployment-Topologie.

Phase 3: Laufzeit-Integration

Deployen Sie Discovery-Agents, um Component Models automatisch mit Laufzeit-Abhängigkeiten und tatsächlichen Service-Beziehungen zu aktualisieren.

Phase 4: Erweiterte Analytik

Implementieren Sie Anomalie-Erkennung, Compliance-Automatisierung und prädiktive Sicherheitsanalyse basierend auf Component-Model-Daten.

Die Zukunft der Software-Supply-Chain-Transparenz

Software Bills of Delivery repräsentieren die Evolution von statischer Dokumentation zu dynamischen, lebenden Aufzeichnungen von Software-Komponenten und ihren Beziehungen. Durch die Implementierung von Component Models gewinnen Organisationen beispiellose Sichtbarkeit in ihre Software-Supply-Chains und ermöglichen proaktive Sicherheit, automatisierte Compliance und selbstbewusste Deployment-Praktiken.

Der Wandel von SBOMs zu umfassenden Component Models geht nicht nur um bessere Dokumentation – es geht darum, Software-Supply-Chains zu bauen, die transparent, sicher und resilient by Design sind. Da verteilte Systeme komplexer werden, wird diese Sichtbarkeitsebene essentiell für die Aufrechterhaltung von Sicherheit und operationeller Exzellenz.

Component Models bieten das Fundament für die nächste Generation von Software-Supply-Chain-Sicherheitstools und ermöglichen es Organisationen, von reaktivem Schwachstellen-Management zu proaktiver Risiko-Prävention überzugehen. Die Frage ist nicht, ob dieser Ansatz adoptiert werden sollte, sondern wie schnell Sie ihn implementieren können, um aufkommenden Bedrohungen und Compliance-Anforderungen voraus zu sein.

Lesebarkeit

Schriftgröße