Containers have become a standard deployment mechanism for modern .NET applications.
A typical application may move through several stages before reaching production:
Source Code
|
v
Build
|
v
Container Image
|
v
Container Registry
|
v
CI/CD Pipeline
|
v
Production
At every stage, there is an important question:
How can you prove that the container running in production is the same trusted artifact that was built by the expected publisher?
A container image digest can prove that a particular artifact has not changed since the digest was calculated. A digital signature adds another important property: it can associate that artifact with a trusted signing identity.
.NET 11 Preview 3 introduced signed official .NET container images. Microsoft announced that .NET container images are now signed, providing an additional supply-chain security signal for consumers of the official images.
This does not eliminate the need for dependency scanning, SBOMs, provenance, access controls, or runtime security. Instead, signing provides another layer in a broader software supply-chain security model.
What Does a Signed Container Image Mean?
A container image consists of metadata and filesystem layers identified by cryptographic digests.
A simplified representation is:
Container Image
|
+-- Manifest
|
+-- Configuration
|
+-- Layer 1
|
+-- Layer 2
|
+-- Layer 3
A signature binds the publisher's identity to the artifact descriptor, including its digest.
Conceptually:
Image Digest
|
v
Cryptographic Signature
|
v
Trusted Publisher Identity
When a consumer verifies the image, the verification process can establish:
The signature is cryptographically valid.
The signature corresponds to the artifact being consumed.
The signing identity is trusted according to the configured policy.
The artifact has not been modified since it was signed.
Microsoft's OCI artifact guidance describes signing as a way to establish both integrity and authenticity.
Why Container Signing Matters
Consider a normal container deployment:
Registry
|
v
Pull Image
|
v
Run Container
The registry may contain multiple tags:
myapp:latest
myapp:1.2
myapp:production
Tags are convenient, but they are mutable references.
A digest is more precise:
myapp@sha256:<digest>
Signing adds publisher identity to that immutable artifact reference.
The resulting trust model becomes:
Expected Publisher
|
v
Signed Artifact
|
v
Verified Digest
|
v
Deployment
This is significantly stronger than simply trusting a tag.
.NET 11 Official Container Images
Microsoft announced signed .NET container images as part of .NET 11 Preview 3.
Official .NET container images are available in different variants for runtime, ASP.NET Core, SDK, operating system, architecture, and other characteristics. Microsoft documents a tagging scheme based on the target framework, operating system, architecture, image type, and image variant.
A typical .NET application might use:
FROM mcr.microsoft.com/dotnet/aspnet:11.0 AS base
WORKDIR /app
EXPOSE 8080
and then:
FROM mcr.microsoft.com/dotnet/sdk:11.0 AS build
WORKDIR /src
COPY . .
RUN dotnet restore
RUN dotnet publish \
-c Release \
-o /app/publish \
--no-restore
The final stage can copy the published application into the runtime image:
FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyApplication.dll"]
The signing of Microsoft's official image is useful when that image is used as a trusted base layer, but your resulting application image still needs its own supply-chain controls.
Signing the Base Image Is Not Enough
This distinction is important.
Suppose your Dockerfile contains:
FROM mcr.microsoft.com/dotnet/aspnet:11.0
The official base image may be signed.
Your application image is then built on top of it:
Microsoft Signed Base Image
|
v
Your Application Files
|
v
Your Container Image
The resulting application image is a different artifact.
Therefore, organizations should consider signing their own final images as part of their CI/CD pipeline.
The trust chain should look more like:
Trusted Base Image
|
v
Controlled Build
|
v
Application Image
|
v
Organization Signature
|
v
Registry
|
v
Deployment Verification
OCI Signatures and Notation
The Notary Project provides tooling for signing and verifying OCI artifacts.
Notation is the command-line tool used to perform these operations.
Microsoft's current Azure Container Registry documentation describes Notation as a tool for signing and verifying OCI artifacts, including container images.
The workflow is conceptually:
Build Image
|
v
Push Image
|
v
Sign Image
|
v
Push Signature
|
v
Verify Before Deployment
This separates image creation from artifact trust.
Sign an Image With Notation
Suppose an image has already been pushed to a registry:
myregistry.example.com/orders-api:1.0
Notation can sign the image:
notation sign \
myregistry.example.com/orders-api:1.0
The exact command depends on the configured signing key provider.
In a real organization, the signing key should not simply be stored as a plaintext file on a developer workstation.
Microsoft documents integrations with signing services such as Azure Key Vault and Azure Artifact Signing.
Why Key Management Matters
The security of a signed image depends heavily on the protection of the signing identity.
Consider:
Private Signing Key
|
v
Image Signature
|
v
Trusted Deployment
If an attacker obtains the signing credential, they may be able to produce artifacts that appear to originate from a trusted publisher.
Therefore:
Protect private signing keys.
Avoid storing long-lived keys in source repositories.
Restrict who can sign.
Audit signing operations.
Rotate credentials according to organizational policy.
Separate development and production signing identities.
Azure Artifact Signing provides an alternative to managing certificate lifecycle directly through Azure Key Vault and uses short-lived certificates with a managed signing experience.
Verify a Signed Image
Signing is useful only if consumers actually verify the signature.
Notation supports verification:
notation verify \
myregistry.example.com/orders-api@sha256:<digest>
Microsoft's documentation demonstrates verification using a trust policy and trust store.
The verification process can be represented as:
Image
|
v
Find Signature
|
v
Validate Signature
|
v
Validate Certificate / Identity
|
v
Evaluate Trust Policy
|
+---- Trusted ----> Continue
|
+---- Untrusted --> Block
This is where signing becomes an enforceable security control rather than simply metadata attached to an image.
Trust Policies Are Critical
A signature can be mathematically valid while still coming from an identity your organization does not trust.
For example:
Image
|
+-- Valid signature
|
+-- Signer = UnknownDeveloper
Cryptographically valid does not automatically mean authorized.
A trust policy defines which identities are trusted for specific registry scopes.
A simplified policy concept looks like:
{
"version": "1.0",
"trustPolicies": [
{
"name": "production-images",
"registryScopes": [
"myregistry.example.com/orders"
],
"signatureVerification": {
"level": "strict"
},
"trustedIdentities": [
"expected-publisher"
]
}
]
}
The exact trust-store and identity configuration depends on the signing system.
Microsoft's Notation examples use trust policies to associate registry scopes with trust stores and trusted identities.
Verify by Digest, Not Just by Tag
Consider:
orders-api:production
A tag can move from one image digest to another.
For stronger deployment controls, use a digest:
orders-api@sha256:abc123...
Then verify the signature against that exact artifact.
A useful deployment pipeline is:
Build
|
v
Push
|
v
Resolve Digest
|
v
Sign Digest
|
v
Verify Digest
|
v
Deploy Digest
This prevents the deployment stage from accidentally resolving a mutable tag to a different image.
Integrating Signing Into CI/CD
A practical pipeline can be structured as follows:
Source
|
v
Build
|
v
Unit Tests
|
v
Security Scans
|
v
Container Build
|
v
Push
|
v
Sign
|
v
Verify
|
v
Deploy
The signing operation should occur after the final image has been built and pushed.
The deployment stage should verify the signature rather than assuming that the previous pipeline step was successful.
This creates a second security boundary:
Build Pipeline
|
v
Signed Artifact
|
v
Deployment Policy
|
v
Production
Example Azure DevOps Workflow
Microsoft provides an Azure DevOps Notation task that can sign and verify OCI artifacts in an Azure Pipeline.
A conceptual pipeline might contain:
steps:
- script: |
docker build \
-t $(REGISTRY)/orders-api:$(Build.BuildId) \
.
displayName: Build container
- script: |
docker push \
$(REGISTRY)/orders-api:$(Build.BuildId)
displayName: Push container
- task: Notation@0
inputs:
command: 'sign'
artifactRefs: '$(IMAGE)'
displayName: Sign container
- task: Notation@0
inputs:
command: 'verify'
artifactRefs: '$(IMAGE)'
trustPolicy: '.pipeline/trustpolicy.json'
trustStore: '.pipeline/truststore/'
displayName: Verify container
The exact task configuration depends on the selected signing provider and pipeline environment.
Microsoft's documented Azure DevOps workflow builds and pushes the image, signs it, and then supports verification through a configured trust policy and trust store.
GitHub Actions
The same concept can be implemented in GitHub Actions.
Microsoft documents a workflow using Notation and Artifact Signing that builds an image, pushes it to Azure Container Registry, signs it, and stores the resulting signature in the registry.
A conceptual workflow is:
name: Build and Sign
on:
push:
jobs:
container:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: |
docker build \
-t ${{ env.IMAGE }}:${{ github.sha }} \
.
- name: Push image
run: |
docker push \
${{ env.IMAGE }}:${{ github.sha }}
- name: Sign image
run: |
notation sign ${{ env.IMAGE }}@${{ env.DIGEST }}
The authentication and signing-provider configuration should be implemented using the identity and secret-management mechanisms supported by the chosen platform.
Do not place private signing keys directly in the workflow source.
Verify at Deployment Time
One of the strongest patterns is to make signature verification a deployment requirement.
Consider Kubernetes:
Registry
|
v
Image Request
|
v
Signature Verification
|
+---- Valid ----> Deployment
|
+---- Invalid --> Rejected
Microsoft documents using Ratify with Azure Policy to verify container image signatures in Azure Kubernetes Service.
This moves verification from an advisory CI/CD step to an enforcement point closer to production.
The exact enforcement architecture depends on the Kubernetes environment and policy stack.
Build a Chain of Trust
A mature container supply chain should verify more than one property.
For example:
Source
|
v
Controlled Build
|
+-----------+-----------+
| |
v v
SBOM Provenance
| |
+-----------+-----------+
|
v
Container Image
|
v
Signature
|
v
Registry
|
v
Deployment Policy
Container signing provides authenticity and integrity for the artifact.
SBOMs provide visibility into components.
Build provenance can provide information about how an artifact was produced.
Vulnerability scanning identifies known security issues.
None of these mechanisms replaces the others.
Signing vs Hashing vs Scanning
| Control | Primary Purpose | Answers |
|---|---|---|
| Digest | Artifact integrity reference | Did this artifact change? |
| Signature | Integrity + publisher identity | Who signed this artifact? |
| Vulnerability scan | Known vulnerability detection | Does it contain known issues? |
| SBOM | Component visibility | What is inside it? |
| Provenance | Build traceability | How was it produced? |
| Runtime policy | Deployment enforcement | Is this artifact allowed to run? |
A secure supply chain generally combines several of these controls.
Common Mistakes
Signing Only the Base Image
A signed Microsoft base image does not automatically make your application image trusted.
Sign your final application artifact as well.
Signing Mutable Tags Without Tracking Digests
Always know which digest was actually signed.
Storing Signing Keys in Source Control
Private signing credentials should never be committed to a Git repository.
Verifying Signatures Only in CI
If deployment can bypass the verification stage, the security control may be bypassed.
Where practical, enforce verification at the deployment boundary.
Trusting Any Valid Signature
A valid signature from an untrusted identity should not automatically authorize deployment.
Trust policy matters.
Treating Signing as Vulnerability Scanning
A perfectly signed image can still contain a vulnerable dependency.
Signing establishes provenance-related trust properties; it does not prove that the software is vulnerability-free.
Troubleshooting Signature Verification
Verification Fails With an Unknown Signer
Check the configured trust store and trust policy.
The certificate may be valid but not trusted by the verifier.
The Image Was Rebuilt and Verification Fails
That can be expected.
A rebuilt image normally has a different digest and therefore needs its own signature.
The Tag Works but the Digest Does Not
Check whether the tag points to the same digest that was signed.
Avoid using mutable tags as the security identity of an artifact.
The Image Is Signed but Deployment Still Succeeds After Verification Is Removed
That is expected if verification is only a CI step.
Signing does not automatically enforce deployment policy.
Add an admission or deployment-time verification mechanism where appropriate.
Testing a Supply Chain
A useful security test suite should include both successful and failed scenarios.
Valid image
|
+-- Valid signature
+-- Trusted identity
+-- Expected registry
|
+----> Deploy
Tampered image
|
+-- Invalid signature
|
+----> Reject
Untrusted signer
|
+-- Valid cryptographic signature
+-- Wrong identity
|
+----> Reject
Unsigned image
|
+----> Reject
Wrong digest
|
+----> Reject
These tests demonstrate that the policy actually enforces the intended trust model.
Best Practices
Sign Immutable Artifacts
Prefer digest-based references for security-sensitive deployment.
Keep Signing Separate From Building
The identity that builds an artifact does not necessarily need unrestricted signing privileges.
Protect Signing Identities
Use a managed key or signing service where appropriate.
Verify Before Production
Do not rely solely on the registry to tell you that an artifact is trusted.
Enforce Verification
Make deployment fail when required signatures are missing or invalid.
Maintain a Trust Policy
Define exactly which publishers are trusted for which repositories.
Combine Controls
Use signing together with:
SBOMs
Vulnerability scanning
Provenance
Dependency controls
Access control
Runtime policies
Frequently Asked Questions
Are all .NET container images signed?
Microsoft announced signed .NET container images beginning with .NET 11 Preview 3. The exact image and version should still be verified against the official image and release documentation being consumed.
Does a signed image guarantee that it is secure?
No.
A signature provides authenticity and integrity information. It does not prove that the image contains no vulnerabilities or malicious application logic.
Can I sign my own .NET container image?
Yes.
OCI-compatible tooling such as Notation can sign container images, and Microsoft documents integrations with signing systems including Azure Key Vault and Artifact Signing.
Should I verify the image in CI/CD?
Yes.
CI/CD verification is useful, but production environments should also consider enforcing signature policies at deployment time.
Why use a digest if the image is signed?
The digest identifies the exact artifact.
A tag such as latest can point to different artifacts over time. A digest provides a stable reference to the specific image being verified.
Conclusion
Signed container images provide an important building block for modern software supply-chain security.
For .NET developers, the introduction of signatures for official .NET container images provides stronger trust information when consuming Microsoft-provided base images.
But a secure supply chain requires more than trusting the base image.
A stronger architecture is:
Official Trusted Base
|
v
Controlled Build
|
v
Application Image
|
v
SBOM + Security Checks
|
v
Organization Signature
|
v
Registry
|
v
Digest Verification
|
v
Deployment Policy
|
v
Production
The key principle is:
Build trust into the artifact lifecycle, then enforce that trust at deployment time.
Container signing answers an important question—whether an artifact is associated with a trusted publisher and has remained intact—but it should operate alongside vulnerability scanning, SBOMs, provenance, identity controls, and runtime policies.
For teams building .NET applications in containers, that combination turns a simple image-push workflow into a more verifiable software supply chain.

Join the conversation! Your thoughts help the community grow.