Add Geo replication support for SupplyChain::Attestation
What does this MR do and why?
This MR implements Geo replication and verification support for Supply Chain Attestations—signed text files which represent build provenance, SBOM, etc. These are generated in the Rails backend, typically triggered by a pipeline.
What this MR does:
-
Adds Geo replication infrastructure for
SupplyChain::Attestation:- Creates
Geo::PackagesNugetSymbolRegistryto track replication state - Creates
Geo::PackagesNugetSymbolStateto track verification state - Implements
Geo::PackagesNugetSymbolReplicatorusing the blob replication strategy
- Creates
-
Enables verification of attestations:
- Adds checksum calculation and verification for symbol files
- Tracks verification state (pending, succeeded, failed)
- Supports both local and object storage locations
-
Supports selective sync:
- Symbols can be selectively synced by namespace (group/project)
- Symbols can be selectively synced by storage shard
- Respects object storage sync settings
-
Feature flags for safe rollout:
-
geo_supply_chain_attestation_replication- Controls replication functionality -
geo_supply_chain_attestation_checksumming- Controls verification on primary
-
How to set up and validate locally
Prerequisites
- Set up a local Geo environment with a primary and secondary node. Follow the Geo development setup guide.
Testing Replication
On the Primary Node:
-
Enable the feature flags in Rails console:
Feature.enable(:geo_supply_chain_attestation_replication) Feature.enable(:geo_supply_chain_attestation_force_primary_checksumming) -
Create an attestation file:
attestation = SupplyChain::Attestation.new( project: Project.find(1), build: Ci::Build.where(project_id: 1).take, predicate_kind: :provenance, predicate_type: "https://slsa.dev/provenance/v1", subject_digest: "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", file: File.open("/path/to/file.txt") ) attestation.save! -
Verify the symbol was created and verification started:
attestation.reload attestation.supply_chain_attestation_state # Should show verification_state as 'pending' or 'verification_succeeded'
On the Secondary Node:
-
Check that the registry entry was created:
Geo::SupplyChainAttestationRegistry.count # Should be > 0 registry = Geo::SupplyChainAttestationRegistry.last registry.supply_chain_attestation_id # Should match the symbol ID from primary -
Trigger replication:
Geo::SupplyChainAttestationReplicator.new(model_record_id: attestation.id).execute -
Verify the attestation file was replicated:
registry.reload registry.state # Should be 'synced' registry.verification_state # Should be 'verification_succeeded'
Related to #571772
Edited by Aaron Huntsman