Durante muchos años en arquitectura de software hemos hablado de:

  • CI/CD

  • DevSecOps

  • SBOM

  • supply chain security

  • SLSA

Pero hay una pregunta que durante demasiado tiempo ha quedado en segundo plano:

¿Cómo sabemos que el binario que estamos ejecutando es realmente el que generó nuestro pipeline?

No el código.

El binario final.

Ahí es donde entra Azure Artifact Signing.

El problema: confiar en binarios

Un pipeline moderno genera artefactos continuamente:

  • ejecutables

  • librerías

  • paquetes

  • contenedores

Ejemplo típico en .NET:

InventoryService.exe
InventoryService.dll
InventoryService.pdb

Esos archivos son artefactos de software.

Pero surge una cuestión crítica:

  • ¿quién generó ese binario?

  • ¿ha sido modificado?

  • ¿proviene de un pipeline legítimo?

La respuesta clásica es code signing.

Una firma criptográfica que permite verificar que el binario:

  1. proviene de una identidad concreta

  2. no ha sido modificado

  3. fue emitido por una autoridad confiable

Revisa este documento: https://learn.microsoft.com/en-us/azure/artifact-signing/how-to-signing-integrations

El problema del Code Signing tradicional

Históricamente firmar software implicaba:

  • comprar certificados

  • proteger claves privadas

  • tokens hardware

  • procesos manuales

  • renovación de certificados

En muchos equipos esto acababa así:

certificado.pfx
password.txt

La propuesta de Azure Artifact Signing

Azure Artifact Signing cambia el modelo:

la firma se convierte en un servicio gestionado en la nube

Las claves privadas se almacenan en HSM gestionados por Azure.

Los desarrolladores no gestionan certificados directamente.

El flujo se integra con el pipeline.

Arquitectura simplificada:

Developer Commit
        │
        ▼
CI/CD Pipeline
        │
        ▼
Artifact Signing (Azure)
        │
        ▼
Signed Artifact
        │
        ▼
Deployment

El resultado es un artefacto que contiene una identidad verificable.

Qué es exactamente un Artifact

Un artifact es el resultado de un build.

Ejemplos comunes:

Tecnología Artifact
.NET .dll, .exe
Docker imagen OCI
npm .tgz
NuGet .nupkg

Ejemplo real:

publish/InventoryService.exe

Ese ejecutable es el artifact que se firmará.

Ejemplo práctico en .NET

1. Crear la aplicación

dotnet new console -n SigningDemo
cd SigningDemo

Programa simple:

Console.WriteLine("Azure Artifact Signing Demo");

Compilamos:

dotnet publish -c Release -r win-x64

Se genera:

bin/Release/net8.0/win-x64/publish/SigningDemo.exe

Ese es el artifact.

Preparar Azure Artifact Signing

En Azure necesitamos tres elementos:

1. Artifact Signing Account

asign-demo

2. Identity validation

Ejemplo:

cp-public-code

Este profile define el certificado usado para firmar.

Metadata de firma

Azure necesita un pequeño archivo JSON que describe qué perfil usar.

metadata.json

{
  "Endpoint": "https://weu.codesigning.azure.net",
  "CodeSigningAccountName": "asign-demo",
  "CertificateProfileName": "cp-public-code",
  "CorrelationId": "build-demo"
}

Firma del ejecutable

Usamos SignTool + Azure CodeSigning library.

Ejemplo:

signtool sign `
 /v `
 /fd SHA256 `
 /tr http://timestamp.acs.microsoft.com `
 /td SHA256 `
 /dlib Azure.CodeSigning.Dlib.dll `
 /dmdf metadata.json `
 SigningDemo.exe

Qué ocurre aquí:

  1. SignTool calcula el hash del binario

  2. Azure Artifact Signing firma ese hash

  3. se adjunta una firma Authenticode al archivo

Resultado:

SigningDemo.exe (signed)

Verificar la firma

Podemos comprobarlo con:

signtool verify /pa SigningDemo.exe

Resultado esperado:

Successfully verified
Publisher: Your Organization

Windows ahora reconoce ese binario como software firmado.

Integración en CI/CD

Lo interesante aparece cuando esto se integra en el pipeline.

Ejemplo conceptual:

GitHub
   │
   ▼
GitHub Actions
   │
   ├ Build .NET
   ├ Generate SBOM
   ├ Artifact Signing
   │
   ▼
Signed Release

Ahora cada release tiene:

  • identidad verificable

  • timestamp

  • provenance del pipeline

Más allá de los ejecutables

Artifact Signing no se limita a .exe.

También puede aplicarse a:

  • paquetes NuGet

  • drivers

  • artefactos Windows

  • otros binarios distribuidos

Esto empieza a ser crítico en modelos modernos de seguridad.

Supply Chain Security

Los ataques recientes han demostrado algo importante:

El objetivo de los atacantes ya no es solo comprometer servidores.

El objetivo es comprometer pipelines.

Ejemplos conocidos:

  • SolarWinds

  • ataques a repositorios npm

  • supply chain malware

Si un atacante compromete el pipeline, el software generado puede parecer legítimo.

La firma añade una capa clave:

solo artefactos generados por identidades verificadas pueden ejecutarse

El detalle arquitectónico importante

Artifact Signing introduce algo que hasta ahora era difuso: la identidad del software.

No solo sabemos:

  • qué código hay

  • qué dependencias tiene

También sabemos:

  • qué organización lo firmó

  • qué pipeline lo generó

  • cuándo se creó

Esto permite construir controles como:

  • execution policies

  • Kubernetes admission control

  • software provenance

  • runtime verification

Hacia pipelines de confianza

El modelo que está emergiendo en muchas organizaciones es este:

Source Code
     │
     ▼
Build Pipeline
     │
     ▼
SBOM generation
     │
     ▼
Artifact Signing
     │
     ▼
Artifact Registry
     │
     ▼
Deployment

Cada paso añade confianza verificable.

Y para terminar

Durante años hemos tratado la seguridad del software como un problema de código.

Pero el verdadero punto crítico suele aparecer después del build.

La pregunta clave no es solo:

¿El código es seguro?

La pregunta real es:

¿Podemos confiar en el binario que estamos ejecutando?

Azure Artifact Signing intenta resolver precisamente eso.

No es simplemente una herramienta más.

Es un paso hacia algo más profundo:

software con identidad verificable.

Y en un mundo donde la supply chain del software es cada vez más compleja, eso empieza a ser absolutamente fundamental.