Your Artifact Repository May Be the Gap in Your Identity Perimeter
Your Artifact Repository May Be the Gap in Your Identity Perimeter
Most enterprise security teams have invested heavily in Entra ID Conditional Access, Intune compliance policies, and Defender for Endpoint integration. They've built layered identity controls that gate access to Exchange Online, SharePoint, Teams, and Azure resources. Then they ship a NuGet package to an internal feed authenticated with a 365-day personal access token stored in a .env file on a developer's laptop.
Why Artifact Repositories Fall Outside the Identity Control Plane
Entra ID Conditional Access policies evaluate sign-in events against a set of conditions: user identity, device compliance, location, risk score, and application. The enforcement boundary is the authentication event itself.
Artifact repositories break this model in three specific ways.
First, many artifact repository authentication flows use long-lived tokens—PATs, API keys, or service principal secrets—that are issued once and reused indefinitely. These tokens bypass interactive authentication entirely, which means Conditional Access never evaluates them. There is no sign-in event to intercept.
Second, the client tools that consume artifact feeds—dotnet restore, docker pull, npm install, pip install—are not registered as Entra ID-aware applications in most environments. They authenticate to the feed endpoint directly, not through the Microsoft identity platform. Even when Azure Artifacts or Azure Container Registry is the backend, the token exchange often happens at the service layer, not at the Entra ID layer.
Third, Intune device compliance is irrelevant to these flows. A build agent running on an unmanaged VM, a developer's personal machine, or a compromised CI runner can pull packages from your internal feed with a valid PAT regardless of whether that device is enrolled, compliant, or even domain-joined.
The identity perimeter you've built in Entra ID stops at the authentication event. Artifact repositories that accept long-lived tokens never generate that event—so your Conditional Access policies are structurally blind to them.
---
The Actual Attack Surface: What Adversaries Target
Understanding the threat model requires being specific about what an attacker gains from artifact repository access.
Read access to an internal feed exposes your proprietary packages, internal library versions, dependency graphs, and occasionally embedded secrets in package metadata or build scripts. This is reconnaissance at the software supply chain level.
Write access—or the ability to publish packages—enables dependency confusion attacks. An adversary who can publish a package with a name that shadows an internal package name can inject malicious code into your build pipeline. This doesn't require compromising your source control. It requires only a valid publish credential for your feed.
Registry access in a container environment is more severe. An attacker with push access to your internal container registry can replace a base image. Every downstream build that pulls FROM internal-registry.azurecr.io/base-ubuntu:latest without a digest pin will consume the poisoned image.
The credential that enables all of this is typically a PAT or service principal secret with no expiry enforcement, no rotation policy, and no audit trail connected to your SIEM.
---
Where Entra ID Controls Actually Reach—and Where They Stop
Azure Container Registry (ACR) and Azure Artifacts both support Entra ID authentication. This is the correct foundation, but it is not the same as having Conditional Access coverage.
ACR with Entra ID authentication allows you to assign RBAC roles (AcrPull, AcrPush, AcrDelete) to users, groups, and managed identities. When a user authenticates interactively using az acr login, that generates an Entra ID sign-in event that Conditional Access can evaluate. When a service principal authenticates using a client secret, it does not go through an interactive flow—Conditional Access policies scoped to service principals apply only if you've explicitly configured them under Workload Identity policies, which requires Entra ID P2 and is frequently not configured for DevOps service principals.
Azure Artifacts in Azure DevOps authenticates through Azure DevOps PATs or through the Azure DevOps OAuth flow. The OAuth flow is Entra ID-backed and will respect Conditional Access for interactive sessions. PATs are not. A PAT issued to a developer is valid for the duration set at creation, from any device, from any network, with no compliance check.
The gap is not that these services lack identity integration. The gap is that the non-interactive authentication paths—which are the dominant paths in automated pipelines—are structurally excluded from your existing Conditional Access enforcement.
---
Mapping the Governance Exposure Under SOC 2, ISO 27001, and FedRAMP
Auditors examining SOC 2 Type II, ISO 27001, and FedRAMP environments are increasingly asking specific questions about artifact repository access controls. The control families that apply are not ambiguous.
Under SOC 2 CC6.1 (Logical and Physical Access Controls), the requirement is that access to systems is restricted to authorized users. A PAT with no expiry, shared across a team, stored in a repository secret, does not satisfy this control. It cannot be attributed to a specific authorized user at a specific point in time.
Under ISO 27001 Annex A 8.2 (Privileged Access Rights), privileged access—including write access to artifact repositories—must be controlled, reviewed, and revoked when no longer needed. Without a credential inventory tied to identity, you cannot demonstrate this to an auditor.
Under FedRAMP IA-5 (Authenticator Management), authenticators must have defined lifetimes and rotation schedules. A PAT issued with a 365-day expiry and no automated rotation fails this control explicitly.
The practical problem is that most organizations have no centralized inventory of artifact repository credentials. They exist in Azure DevOps project settings, in GitHub Actions secrets, in .npmrc files, and in CI/CD environment variables—distributed, untracked, and outside the scope of any privileged access review.
---
Extending Identity Governance to the Artifact Layer
The path forward is not to replace your artifact infrastructure. It is to extend the identity control plane you already operate into the artifact authentication layer. This requires changes in three areas.
Managed Identity for pipeline authentication. Replace service principal secrets and PATs in CI/CD pipelines with managed identities where the compute supports it. Azure Pipelines agents running on Azure-hosted infrastructure can authenticate to ACR and Azure Artifacts using the pipeline's managed identity. This eliminates the credential entirely—there is no secret to rotate, leak, or expire.
For self-hosted agents on Azure VMs or Azure Kubernetes Service, assign a user-assigned managed identity and grant it the minimum required RBAC role on the target registry or feed.
$managedIdentityObjectId = (Get-AzUserAssignedIdentity `
-ResourceGroupName "rg-buildagents" `
-Name "mi-pipeline-agent").PrincipalId
$acrResourceId = (Get-AzContainerRegistry `
-ResourceGroupName "rg-artifacts" `
-Name "contosoacr").Id
New-AzRoleAssignment `
-ObjectId $managedIdentityObjectId `
-RoleDefinitionName "AcrPull" `
-Scope $acrResourceIdWorkload Identity Federation for external CI systems. For GitHub Actions, GitLab CI, or other external systems that cannot use Azure managed identities natively, configure Workload Identity Federation. This allows the external CI system to exchange a short-lived OIDC token for an Entra ID access token, with no stored secret on either side.
$appId = "<your-app-registration-id>"
$federatedCredentialParams = @{
name = "github-actions-contoso-repo"
issuer = "https://token.actions.githubusercontent.com"
subject = "repo:contoso-org/contoso-app:ref:refs/heads/main"
audiences = @("api://AzureADTokenExchange")
description = "GitHub Actions OIDC for contoso-app main branch"
}
New-AzADAppFederatedCredential `
-ApplicationObjectId (Get-AzADApplication -AppId $appId).Id `
@federatedCredentialParamsAudit log integration with Microsoft Sentinel. ACR and Azure Artifacts generate audit events that are not automatically ingested into your SIEM. Connect these sources explicitly.
For ACR, enable diagnostic settings to forward ContainerRegistryLoginEvents and ContainerRegistryRepositoryEvents to your Log Analytics workspace. Then query for anomalous access patterns:
// Detect ACR pull events from non-managed-identity principals
// Requires ACR diagnostic logs forwarded to Log Analytics
ContainerRegistryLoginEvents
| where TimeGenerated > ago(7d)
| where Identity !startswith "mi-" // exclude managed identity names
| where Identity !contains "@" // exclude interactive user UPNs
| where ResultType == "Succeeded"
| summarize PullCount = count(),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by Identity, CallerIPAddress, Repository
| where PullCount > 10
| order by PullCount descThis query surfaces service principals and anonymous-style identities pulling from your registry at volume—exactly the pattern that indicates a leaked PAT or an unmanaged service account operating outside your governance model.
---
Operational Controls That Reduce Credential Sprawl
Beyond the architectural changes, several operational controls directly reduce the attack surface without requiring infrastructure replacement.
Enforce PAT expiry at the organizational level. In Azure DevOps, organization administrators can set a maximum PAT lifetime. Set this to 30 days or fewer. This does not eliminate PATs, but it forces rotation and surfaces stale credentials when rotation fails.
Require approval workflows for feed publish permissions. In Azure Artifacts, separate the Reader and Contributor roles explicitly. Most consumers of an internal feed need only read access. Publish rights should be granted only to pipeline identities, not to individual developer accounts.
Implement digest pinning in container references. Replace FROM internal-registry.azurecr.io/base-ubuntu:latest with FROM internal-registry.azurecr.io/base-ubuntu@sha256:<digest> in all Dockerfiles. This eliminates the attack surface of a poisoned tag, because the digest is cryptographically bound to a specific image layer set. Automate digest updates through a controlled pipeline rather than allowing developers to reference mutable tags directly.
Run Defender for Containers on your ACR. Microsoft Defender for Containers scans images in ACR for known vulnerabilities and generates alerts in Defender for Cloud. This does not address the identity control gap directly, but it adds a detection layer for malicious packages that have already entered the registry.
---
Conditional Access for Workload Identities: The Missing Configuration
Entra ID Conditional Access for workload identities is available under Entra ID P2 and applies to service principals. Most organizations that have deployed Conditional Access for users have not extended it to service principals authenticating to Azure resources.
To create a Conditional Access policy scoped to service principals accessing ACR:
Navigate to Entra ID → Protection → Conditional Access → New Policy. Under Users, select Workload identities and target the specific service principals that have ACR RBAC assignments. Apply conditions for IP location—restrict authentication to your known build agent IP ranges or Azure datacenter IP ranges. Set the grant control to Block for all other locations.
This does not replace managed identity adoption, but it adds a compensating control for service principals that cannot yet be migrated. A service principal that authenticates from an unexpected IP—indicating a leaked secret being used externally—will be blocked before it can pull or push to your registry.
---
Final Thoughts
Artifact repositories are not a separate security problem. They are an extension of the same identity and access management problem you've already invested in solving—except the default configuration of every major artifact platform leaves the non-interactive authentication paths outside the scope of your existing controls.
The practical starting point is an inventory. Before you can govern artifact repository access, you need to know what credentials exist, where they are stored, what they can access, and when they expire. Most organizations cannot answer these questions today.
From that inventory, the migration path is clear: managed identities for Azure-hosted compute, Workload Identity Federation for external systems, Conditional Access policies scoped to workload identities for service principals that cannot be migrated immediately, and audit log integration to surface anomalous access in your SIEM.
The governance exposure under SOC 2, ISO 27001, and FedRAMP is real and auditors are catching up to it. The technical controls to close these gaps exist today within the Microsoft platform you already operate. The question is whether your artifact repositories are inside your identity governance model or adjacent to it—and adjacency is not protection.
---