Immutable tags
ECR, ACR, and Artifact Registry all support immutable tag enforcement to prevent tag overwrite attacks
OIDC auth
All three cloud providers support OIDC-based pipeline authentication -- eliminates static registry credentials in CI/CD
Digest pinning
Referencing images by SHA-256 digest instead of tag prevents supply chain attacks that overwrite a mutable tag
Binary Authorization
GCP policy enforcement that blocks deployment of images without required attestations from Container Analysis or custom signers

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

Container registries are the distribution point for every containerized workload your organization runs. An image that is pushed with a malicious layer, pulled from an unscanned source, or authenticated via a leaked static credential represents a supply chain risk that bypasses application security controls entirely -- the malicious code runs inside what looks like a legitimate container. The controls that matter are: restricting who can push and pull, enforcing image scanning before deployment, preventing tag mutation, signing images to guarantee provenance, and eliminating static credentials from CI/CD pipeline registry authentication. This guide covers each control for AWS ECR, Azure ACR, and GCP Artifact Registry.

AWS ECR: Scanning, Immutable Tags, and Access Policy

ECR is the AWS-native container registry with native integration into Inspector v2 for vulnerability scanning. Security hardening focuses on preventing public repository exposure, enabling continuous scanning, locking down cross-account access, and enforcing tag immutability.

Enable Inspector v2 for enhanced image scanning

ECR basic scanning uses an open-source scanner for OS packages only. Inspector v2 provides enhanced scanning with programming language package CVE detection, continuous re-scanning as new CVEs are published, and integration with ECR to surface findings in the ECR console. Enable Inspector v2 in each region and configure ECR to use enhanced scanning under Registry settings.

Enforce immutable image tags

Enable image tag immutability on all ECR repositories via the console or CLI: aws ecr put-image-tag-mutability --repository-name my-app --image-tag-mutability IMMUTABLE. This prevents any push from overwriting an existing tag, eliminating the attack vector where a legitimate tag is replaced with a malicious image.

Block public access and apply repository policies

Ensure no ECR repositories are configured as public unless explicitly required. For cross-account pull access, apply a repository resource policy granting only the specific IAM role in the target account the ecr:GetDownloadUrlForLayer, ecr:BatchGetImage, and ecr:BatchCheckLayerAvailability actions. Do not use wildcard principals in repository policies.

Enforce lifecycle policies to remove unscanned images

ECR lifecycle policies can automatically expire images older than a threshold or images that have not been tagged. Create a policy that removes untagged images after 7 days and images failing Inspector findings above HIGH severity. This prevents the registry from accumulating vulnerable old images that might be pulled if a version pin is loosened.

Azure ACR: Private Endpoints, Managed Identity, and Notation Signing

Azure Container Registry supports geo-replication, private endpoint connectivity, managed identity-based pull access, and image signing via Notation with Azure Key Vault. The most important controls are eliminating admin user access, using private endpoints instead of public registry access, and signing images with AKV-backed certificates.

Disable the admin user

ACR has a built-in admin user account that provides username/password credentials for registry access. Disable it immediately: az acr update --name myregistry --admin-enabled false. All access should be via Entra ID identities with the AcrPull or AcrPush role assigned, not via static admin credentials.

Configure private endpoints for registry access

Deploy an Azure Private Endpoint for the registry and disable public network access (az acr update --name myregistry --public-network-enabled false). Registry operations from AKS clusters and pipeline agents route through the private endpoint over the VNet rather than the public internet, eliminating exposure to internet-based attacks.

Use managed identity for AKS pull access

Attach the AKS cluster's managed identity to the registry with the AcrPull role: az role assignment create --assignee <kubelet-identity-client-id> --role AcrPull --scope /subscriptions/.../registries/myregistry. This eliminates the imagePullSecrets pattern that requires storing registry credentials in Kubernetes secrets.

Sign images with Notation and Azure Key Vault

Use the notation CLI with the AKV plugin to sign images using certificates stored in Azure Key Vault. The signing key never leaves AKV. Verification is enforced via Ratify running as an admission controller in AKS, which validates the Notation signature on every pod admission. Unsigned images are blocked from running.

Configure webhook notifications for push events

ACR webhooks can notify a security monitoring endpoint on every image push. Configure a webhook pointing to a Lambda function or Azure Function that calls the registry API to check for new Inspector or Security Center findings and alerts the security team if a newly pushed image has critical vulnerabilities.

Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

GCP Artifact Registry: IAM, VPC-SC, and Binary Authorization

GCP replaced Google Container Registry (gcr.io) with Artifact Registry as the recommended container registry. Artifact Registry uses GCP IAM for access control and integrates with Container Analysis for vulnerability scanning and Binary Authorization for deployment enforcement.

Apply least-privilege IAM roles

Use roles/artifactregistry.reader for pull-only access and roles/artifactregistry.writer for push access. Avoid roles/artifactregistry.admin except for the pipeline service account that manages the registry itself. Grant roles at the repository level, not the project level, to scope access to specific registries.

Include the registry in a VPC Service Controls perimeter

Add Artifact Registry to a VPC-SC perimeter to prevent exfiltration of images by compromised service account credentials from outside the defined network boundary. Pipeline agents running outside GCP need to be added to the perimeter's access policy via their external IP range or OIDC identity.

Enable Container Analysis scanning and vulnerability notifications

Enable Container Analysis in the GCP project. Container Analysis automatically scans images pushed to Artifact Registry and re-scans them as new CVEs are published. Configure Pub/Sub notifications on the Container Analysis note so that new HIGH or CRITICAL findings trigger an alert to your security team.

Configure Binary Authorization policy

Create a Binary Authorization policy requiring attestations from your Container Analysis vulnerability scan and your CI build signer before any image can be deployed to GKE or Cloud Run. Set the default rule to 'DENY_ALL' and add per-image allow rules or attestation requirements. This enforces that only scanned, signed images from your CI pipeline run in production.

Image Signing with cosign and Digest Pinning

Image signing and digest pinning are the two controls that guarantee the image you built is the image that runs in production. They operate at different layers -- signing proves provenance, digest pinning prevents accidental or malicious tag drift -- and both should be applied.

Sign images in CI using cosign with keyless signing

In GitHub Actions, cosign's keyless signing uses the runner's OIDC identity to obtain a Sigstore Fulcio certificate and sign the image. The signature and certificate are stored in the registry alongside the image and logged in the Rekor transparency log. No long-lived signing key is stored in CI secrets. Run: cosign sign --yes myregistry/myapp@sha256:<digest> as a post-build step.

Verify signatures in the pull pipeline before deployment

Before deploying an image, verify its cosign signature: cosign verify --certificate-identity=https://github.com/myorg/myrepo/.github/workflows/build.yml@refs/heads/main --certificate-oidc-issuer=https://token.actions.githubusercontent.com myregistry/myapp@sha256:<digest>. Integrate this verification step into your deployment pipeline and fail the deployment if verification does not succeed.

Pin all image references to digests

In Kubernetes manifests, Helm values, and pipeline pull steps, reference images by digest: image: myregistry/myapp@sha256:abc123... rather than by tag. Digest references are immutable -- the same digest always resolves to the same image bytes. Use a tool like crane digest or docker buildx imagetools inspect to retrieve the digest after a build and inject it into deployment manifests.

OIDC-Based Registry Authentication in CI/CD Pipelines

Static registry credentials stored in pipeline secrets are a persistent source of credential exposure. All three cloud providers support OIDC-based authentication from CI/CD platforms that eliminates the need to store any registry password.

GitHub Actions to ECR via AWS OIDC

Configure an IAM OIDC identity provider for GitHub Actions and create an IAM role with ECR pull/push permissions and a trust policy restricted to the specific repository and branch. In the workflow, use aws-actions/configure-aws-credentials@v4 with role-to-assume, then call aws ecr get-login-password to obtain a short-lived registry token. No AWS credentials are stored in GitHub secrets.

GitHub Actions to ACR via federated identity

Create an Entra ID app registration with a federated identity credential pointing to the GitHub Actions OIDC issuer and specific repository. Assign AcrPush on the registry to the app registration. In the workflow, use azure/login@v2 with client-id and tenant-id (no client-secret), then az acr login to obtain a registry token. Credentials are exchanged at runtime via OIDC.

GitHub Actions to Artifact Registry via Workload Identity Federation

Configure a GCP Workload Identity Pool and Provider for GitHub Actions. Create a service account with Artifact Registry writer permissions and bind the GitHub Actions identity to it. In the workflow, use google-github-actions/auth@v2 with workload_identity_provider and service_account, then docker login to the Artifact Registry endpoint. No GCP service account key is stored in GitHub.

The bottom line

Container registry security requires controls at every layer of the image lifecycle: scan on push and continuously for new CVEs, enforce immutable tags to prevent tag overwrite attacks, use private endpoints or VPC-SC to prevent public registry exposure, sign images in CI using cosign or Notation so signatures can be verified at deploy time, pin all production image references to digests, and eliminate static registry credentials from CI/CD pipelines by migrating to OIDC-based authentication on all three cloud platforms. Binary Authorization on GKE enforces that only attested images run in production and is the strongest deploy-time control available.

Frequently asked questions

What is the difference between image tag and image digest, and why does it matter for security?

An image tag like 'myapp:latest' is a mutable pointer that can be reassigned to a different image at any time. A digest like 'myapp@sha256:abc123...' is an immutable cryptographic hash of the image manifest -- it will always refer to exactly the same image content. Pinning Kubernetes manifests and pipeline pull steps to digest references prevents tag-based supply chain attacks where a legitimate tag is overwritten with a malicious image.

How does immutable tag enforcement work in ECR?

Enabling image tag immutability on an ECR repository prevents any push from overwriting an existing tag. Once 'myapp:1.2.3' is pushed, that tag cannot be reassigned to a different image digest. Attempts to push with the same tag return an error. This eliminates the attack vector where an attacker with push access overwrites a legitimate release tag with a malicious image.

What is the difference between cosign and notation for image signing?

Cosign (part of the Sigstore project) signs OCI images using either keyless signing tied to an OIDC identity (a GitHub Actions runner identity, for example) or traditional key-based signing. Notation (CNCF project, used by Azure's AKV signing integration) uses X.509 certificates stored in a key management service and produces OCI reference-type signatures. Both produce signatures stored in the same registry alongside the image. The choice typically follows the cloud provider: cosign integrates naturally with Sigstore's keyless model in GitHub Actions; notation integrates with Azure Key Vault for ACR signing.

What is Binary Authorization and how does it relate to GCR?

Binary Authorization is a GCP policy enforcement service that requires container images deployed to GKE, Cloud Run, or GCE to have attestations from specified authorities before deployment is allowed. Attestations are cryptographic signatures indicating an image passed a specific check -- a Vulnerability Scanning attestation from Container Analysis, a QA sign-off, or a security team sign-off. Binary Authorization enforces these attestations at deploy time, preventing images without required attestations from running even if they are present in the registry.

How should CI/CD pipelines authenticate to container registries without static credentials?

All three cloud providers support OIDC-based authentication for CI/CD pipelines. GitHub Actions can assume an AWS IAM role via OIDC, authenticate to an Azure service principal via federated identity, or impersonate a GCP service account via Workload Identity Federation. The pipeline receives a short-lived token rather than a stored secret. For ECR this means the pipeline calls 'aws ecr get-login-password' using temporary STS credentials from the assumed role. No registry password is stored in the pipeline configuration.

What is an ECR repository policy and how does it differ from IAM policy?

An ECR repository policy is a resource-based policy attached directly to the repository that controls access to that specific repository. IAM policies attached to users, roles, or groups are identity-based and can also grant ECR access. Both must allow an action for cross-account access to work. Repository policies are the primary mechanism for granting cross-account access -- you attach a repository policy that allows a role from another account to pull from the repository, without needing IAM changes in the target account.

How does VPC Service Controls protect GCP Artifact Registry?

VPC Service Controls (VPC-SC) creates a security perimeter around GCP services including Artifact Registry. When a registry is inside a perimeter, API calls to it from outside the perimeter (from the internet or from GCP projects not in the perimeter) are blocked regardless of IAM permissions. This prevents data exfiltration: even if an attacker obtains valid service account credentials, they cannot pull images from outside the defined perimeter. Access from CI/CD pipelines outside GCP requires the pipeline's source IP or identity to be in the perimeter's access policy.

Sources & references

  1. AWS ECR: Image scanning
  2. Azure ACR: Content trust and image signing with Notation
  3. GCP: Binary Authorization overview
  4. Sigstore: cosign documentation

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.