Safeguard Docs
Integrations

Azure Container Registry

Connect Azure Container Registry (ACR) to Safeguard. The roles and token permissions each credential needs, which credentials work, and step-by-step setup.

Availability

This integration is switched on per workspace. If you do not see the card under Integrations, ask your Safeguard contact.

What it does

The Azure Container Registry card connects Safeguard to the container images in an Azure Container Registry. Safeguard lists the registry's repositories and tags, and each image you select becomes a project that Safeguard scans for an SBOM and vulnerability findings. Scans are pinned to the image digest the tag points at when the scan starts, and the scan pulls the image with the credential you connect. Find the card under Integrations on the Project/Product tab.

Public vs private

PublicPrivate
What you enterAn Image URL, such as myregistry.azurecr.io/team/app:1.0The Login server and one of the credentials below
Credential neededNone. Anonymous pull must be turned on for the registry (Standard or Premium tier)Admin user, repository-scoped token or service principal
What you can selectThe images you add by URLEvery repository the credential can list, or the repositories you name

Supported auth methods

Method (dialog label)Use it whenNotes
Service principalRecommended for registries in Azure public cloud (*.azurecr.io)A Microsoft Entra ID app registration with a client secret. Safeguard exchanges it for a registry token
Admin user or token, with a repository-scoped tokenYou want access to named repositories onlyA token from Repository permissions > Tokens with its scope map. Tokens cannot list the registry, so you name the repositories
Admin user or token, with the admin userQuick setup on a registry you controlThe admin user has full push and pull rights to the whole registry; prefer the other two
Workload identityNot available yetShown in the dialog as Coming later

Permissions required

Safeguard only reads. It never pushes, deletes or untags images, and never changes registry settings, except the push webhook you add yourself (below).

Service principal

Role on the registryRequired?What Safeguard uses it for
AcrPull (registries in RBAC Registry Permissions mode)RequiredListing repositories and tags, reading manifests and pulling images for scans
Container Registry Repository Reader (registries in RBAC Registry + ABAC Repository Permissions mode)Required in that modeReading tags and manifests and pulling images
Container Registry Repository Catalog Lister (ABAC mode)OptionalListing every repository. Without it, name the repositories in Repositories

The token flow is Microsoft Entra client credentials for the scope https://containerregistry.azure.net/.default, then the registry's /oauth2/exchange and /oauth2/token endpoints. No Azure Resource Manager (control plane) role is used.

Least privilege: AcrPull on the one registry (or Container Registry Repository Reader, scoped with an ABAC condition to the repositories to scan).

Repository-scoped token

Scope map actionRequired?What Safeguard uses it for
content/read on each repositoryRequiredReading manifests and pulling images
metadata/read on each repositoryRequiredListing tags

Repository-scoped permissions cannot list the registry's catalog, so add each repository on its own line under Repositories. The token must be Enabled and its password not expired.

Admin user

SettingRequired?What it gives
Admin user enabled under Access keysRequired for this methodUsername is the registry name; either password works. It grants push and pull to every repository, more than Safeguard needs

Token types

Credential typeWorks?Notes
Service principal with AcrPullYes (recommended)Paste the client secret's Value, not its Secret ID
Repository-scoped token (content/read, metadata/read)YesName the repositories; it cannot list them
Admin userYes, not recommendedRegistry-wide push and pull
Token with a write scope map (content/write, content/delete, _repositories_push, _repositories_admin)Works, not recommendedSafeguard never writes
Managed identity or workload identity federationNot available yet
Azure China or Azure Government registries with a service principalNoThe service principal method supports *.azurecr.io only

Expiry: set a client secret or token password expiry of 90 days or less (Azure allows longer). Azure token passwords do not expire unless you set a date, so always set one.

What we never need: AcrPush, AcrDelete, Owner, Contributor, Container Registry Contributor and Data Access Configuration Administrator, or any role outside the registry.

Step-by-step setup

Create the credential in Azure

Service principal:

  1. In the Azure portal, open Microsoft Entra ID > App registrations > New registration, name it (for example safeguard-acr) and register it.
  2. Copy the Application (client) ID and Directory (tenant) ID from its overview.
  3. Under Certificates & secrets > Client secrets, add a secret with an expiry and copy its Value (shown once).
  4. Open your container registry, then Access control (IAM) > Add role assignment, choose AcrPull (or Container Registry Repository Reader) and assign it to the app.

Repository-scoped token:

  1. Open your container registry, then Repository permissions > Tokens > + Add.
  2. Under Scope map, choose Create new, add each repository with content/read and metadata/read, and create the token.
  3. Open the token, select password1, set an expiration date and Generate. Copy the password; Azure does not show it again.

Or with the Azure CLI

# Service principal with AcrPull on one registry
ACR_ID=$(az acr show --name <registry> --query id --output tsv)
az ad sp create-for-rbac --name safeguard-acr --role AcrPull --scopes "$ACR_ID" --years 1
# prints appId (client ID), password (client secret) and tenant

# Or a repository-scoped token
az acr token create --name safeguard --registry <registry> \
  --repository <team/app> content/read metadata/read
az acr token credential generate --name safeguard --registry <registry> \
  --expiration-in-days 90 --password1

# Public tab only: allow anonymous pull (Standard or Premium tier)
az acr update --name <registry> --anonymous-pull-enabled

Connect it in Safeguard

  1. Open Integrations and choose the Project/Product tab.
  2. Click Connect on the Azure Container Registry card.
  3. For public images, choose Public, enter a Name, paste an Image URL and click Add, then Next.
  4. For private images, choose Private, enter a Name and the Login server (for example myregistry.azurecr.io), then pick the Authentication method:
    • Service principal: Tenant (directory) ID, Client (application) ID and Client Secret;
    • Admin user or token: Username (the registry name or the token name) and Password, plus Repositories for a repository-scoped token.
  5. Click Verify Credentials. "Credentials verified." means the registry accepted them, with the number of repositories visible.
  6. Click Next, select repositories and tags, review, and choose a connect option (fast, progressive or deep scan).

Webhooks and triggers

Scan on push is optional. In the connection's Scan on push (optional) panel, Safeguard shows the Service URI (https://api.safeguard.sh/scm/api/v1/registry-webhooks/acr/<connection id>), the Header name X-Safeguard-Webhook-Token and its secret value, and an Azure CLI command:

az acr webhook create --registry <registry> --name safeguard<id> --actions push \
  --uri "<Service URI>" --headers "X-Safeguard-Webhook-Token=<secret>" --scope "<repository>:*"

The webhook's --scope decides which repositories and tags start a scan. Each push scans the pushed tag as the version <tag>-<first 12 characters of the digest>. Creating the webhook needs a role that can manage registry webhooks; Safeguard's own credential does not. Without a webhook, rescan on a schedule under Integrations > Scheduled.

What we read and store

  • Read: repository names, tags and manifest digests, and the images you select for scanning.
  • Stored: the connection's settings, the SBOM and findings of each scanned image with its digest, and the credential, which is encrypted at rest and never shown again after you save it.
  • Not stored: image layers. The image is read for the scan and not kept.
  • No customer data from this integration is sent to third-party LLMs.

Troubleshooting

Message you seeCauseFix
Enter an Azure Container Registry login server, such as myregistry.azurecr.io.The login server is not an ACR addressCopy it from Container registries > your registry > Overview > Login server
These credentials could not be verified.Wrong secret or password, a disabled token, an expired password, or a missing roleCheck the role assignment or the scope map, and paste the secret's Value
This token can't list repositories. Add the repositories it can pull under Repositories.A repository-scoped token was usedAdd one repository per line under Repositories
Add at least one repository to continue.A repository-scoped token with an empty Repositories fieldName the repositories the token can pull
This image could not be found, or the registry does not allow anonymous pull.Public tab on a registry without anonymous pull, or a wrong image URLTurn on anonymous pull, or use the Private tab
Azure error AADSTS53003A Conditional Access policy blocks the service principalExclude the service principal from that policy
Connection fails although the credential is rightThe registry allows only private endpoints, or its firewall blocks SafeguardAllow public network access for Safeguard, or use a registry Safeguard can reach

Rotation and disconnect

  • Rotate: create a new client secret or token password, find the connection under Project Configurations on the Project/Product tab, choose Update, enter the new value, verify and save, then delete the old secret or password in Azure.
  • Disconnect: choose Delete from the connection's menu under Project Configurations and confirm Delete configuration. Then remove the role assignment or delete the app registration or token, and delete the push webhook (az acr webhook delete --registry <registry> --name <webhook>).

Vendor references

On this page