Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@

# Vally/vally - Name of product

ignore-words-list = numer,wit,aks,edn,ser,ois,gir,rouge,categor,aline,ative,afterall,deques,dateA,dateB,TE,FillIn,alle,vai,LOD,InOut,pixelX,aNULL,Wee,Sherif,queston,extenions,Vertexes,nin,FO,CAF,Parth,ans,gud,Vally,vally
# ACI - Azure Container Instances abbreviation

ignore-words-list = numer,wit,aks,edn,ser,ois,gir,rouge,categor,aline,ative,afterall,deques,dateA,dateB,TE,FillIn,alle,vai,LOD,InOut,pixelX,aNULL,Wee,Sherif,queston,extenions,Vertexes,nin,FO,CAF,Parth,ans,gud,Vally,vally,ACI

# Skip certain files and directories
# *.tm7 - MTM DataContract exports; embedded base64 icon blobs trigger false positives
Expand Down
1 change: 1 addition & 0 deletions docs/README.skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ See [CONTRIBUTING.md](../CONTRIBUTING.md#adding-skills) for guidelines on how to
| [aws-well-architected-review](../skills/aws-well-architected-review/SKILL.md)<br />`gh skills install github/awesome-copilot aws-well-architected-review` | Perform an AWS Well-Architected Framework review of the current workload IaC and architecture, generating findings and GitHub issues for improvements. | None |
| [az-cost-optimize](../skills/az-cost-optimize/SKILL.md)<br />`gh skills install github/awesome-copilot az-cost-optimize` | Analyze Azure resources used in the app (IaC files and/or resources in a target rg) and optimize costs - creating GitHub issues for identified optimizations. | None |
| [azure-architecture-autopilot](../skills/azure-architecture-autopilot/SKILL.md)<br />`gh skills install github/awesome-copilot azure-architecture-autopilot` | Design Azure infrastructure using natural language, or analyze existing Azure resources to auto-generate architecture diagrams, refine them through conversation, and deploy with Bicep.<br />When to use this skill: - "Create X on Azure", "Set up a RAG architecture" (new design) - "Analyze my current Azure infrastructure", "Draw a diagram for rg-xxx" (existing analysis) - "Foundry is slow", "I want to reduce costs", "Strengthen security" (natural language modification) - Azure resource deployment, Bicep template generation, IaC code generation - Microsoft Foundry, AI Search, OpenAI, Fabric, ADLS Gen2, Databricks, and all Azure services | `.gitignore`<br />`assets/06-architecture-diagram.png`<br />`assets/07-azure-portal-resources.png`<br />`assets/08-deployment-succeeded.png`<br />`references/ai-data.md`<br />`references/architecture-guidance-sources.md`<br />`references/azure-common-patterns.md`<br />`references/azure-dynamic-sources.md`<br />`references/bicep-generator.md`<br />`references/bicep-reviewer.md`<br />`references/phase0-scanner.md`<br />`references/phase1-advisor.md`<br />`references/phase4-deployer.md`<br />`references/service-gotchas.md`<br />`scripts/cli.py`<br />`scripts/generator.py`<br />`scripts/icons.py` |
| [azure-container-registry-cli](../skills/azure-container-registry-cli/SKILL.md)<br />`gh skills install github/awesome-copilot azure-container-registry-cli` | Manage Azure Container Registry via the az acr CLI including registries, images, cloud builds, ACR Tasks, authentication, tokens, geo-replication, and networking. Use when working with ACR, az acr commands, pushing/importing/purging container images in Azure, or when the user mentions Azure Container Registry. | `references/auth-and-security.md`<br />`references/build-and-tasks.md`<br />`references/images-and-artifacts.md`<br />`references/networking-and-geo.md` |
| [azure-deployment-preflight](../skills/azure-deployment-preflight/SKILL.md)<br />`gh skills install github/awesome-copilot azure-deployment-preflight` | Performs comprehensive preflight validation of Bicep deployments to Azure, including template syntax validation, what-if analysis, and permission checks. Use this skill before any deployment to Azure to preview changes, identify potential issues, and ensure the deployment will succeed. Activate when users mention deploying to Azure, validating Bicep files, checking deployment permissions, previewing infrastructure changes, running what-if, or preparing for azd provision. | `references/ERROR-HANDLING.md`<br />`references/REPORT-TEMPLATE.md`<br />`references/VALIDATION-COMMANDS.md` |
| [azure-devops-cli](../skills/azure-devops-cli/SKILL.md)<br />`gh skills install github/awesome-copilot azure-devops-cli` | Manage Azure DevOps resources via CLI including projects, repos, pipelines, builds, pull requests, work items, artifacts, and service endpoints. Use when working with Azure DevOps, az commands, devops automation, CI/CD, or when user mentions Azure DevOps CLI. | `references/advanced-usage.md`<br />`references/boards-and-iterations.md`<br />`references/long-comments-on-windows.md`<br />`references/org-and-security.md`<br />`references/pipelines-and-builds.md`<br />`references/repos-and-prs.md`<br />`references/variables-and-agents.md`<br />`references/workflows-and-patterns.md` |
| [azure-pricing](../skills/azure-pricing/SKILL.md)<br />`gh skills install github/awesome-copilot azure-pricing` | Fetches real-time Azure retail pricing using the Azure Retail Prices API (prices.azure.com) and estimates Copilot Studio agent credit consumption. Use when the user asks about the cost of any Azure service, wants to compare SKU prices, needs pricing data for a cost estimate, mentions Azure pricing, Azure costs, Azure billing, or asks about Copilot Studio pricing, Copilot Credits, or agent usage estimation. Covers compute, storage, networking, databases, AI, Copilot Studio, and all other Azure service families. | `references/COPILOT-STUDIO-RATES.md`<br />`references/COST-ESTIMATOR.md`<br />`references/REGIONS.md`<br />`references/SERVICE-NAMES.md` |
Expand Down
90 changes: 90 additions & 0 deletions skills/azure-container-registry-cli/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
name: azure-container-registry-cli
description: 'Manage Azure Container Registry via the az acr CLI including registries, images, cloud builds, ACR Tasks, authentication, tokens, geo-replication, and networking. Use when working with ACR, az acr commands, pushing/importing/purging container images in Azure, or when the user mentions Azure Container Registry.'
---

# Azure Container Registry CLI

Manage Azure Container Registry (ACR) resources using the `az acr` command group of the Azure CLI.

**CLI:** `az acr` ships with core Azure CLI — no extension required (the `acrtransfer` extension is only needed for export/import pipelines).

## Prerequisites

```bash
# Install Azure CLI
brew install azure-cli # macOS
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash # Linux
winget install Microsoft.AzureCLI # Windows

# Sign in and select subscription
az login
az account set --subscription {subscription-id}
```

## Quick Start

```bash
# Create a registry (SKU: Basic | Standard | Premium)
az acr create --resource-group {rg} --name {registry} --sku Standard

# Authenticate Docker/Podman against the registry
az acr login --name {registry}

# Build and push in the cloud — no local Docker needed
az acr build --registry {registry} --image app:v1 .

# Copy an image from another registry without pull/push
az acr import --name {registry} --source mcr.microsoft.com/hello-world:latest

# List repositories and tags
az acr repository list --name {registry} --output table
az acr repository show-tags --name {registry} --repository app --orderby time_desc

# Diagnose registry connectivity and configuration
az acr check-health --name {registry} --yes
```

## Key Principles

- **Prefer `az acr build` / ACR Tasks** over local `docker build` + `docker push`: builds run in Azure, work without a local daemon, and integrate with triggers.
- **Prefer `az acr import`** to move images between registries: it is server-side, faster, and requires no local storage.
- **Never enable the admin user for production** — use Microsoft Entra identities (RBAC roles `AcrPull`/`AcrPush`, or `Container Registry Repository Reader`/`Writer` on ABAC-enabled registries), repository-scoped tokens, or managed identities.
- **Premium-only features**: geo-replication, private endpoints, retention policies, connected registries, agent pools. (Repository-scoped tokens work in all tiers; zone redundancy is automatic in all tiers in supported regions.)

## CLI Structure

```
az acr
├── create / delete / list / show / update # Registry lifecycle
├── login # Docker credential helper (or --expose-token)
├── check-health / check-name / show-usage # Diagnostics & quota
├── build # Cloud image build (quick task)
├── run # Run a command / multi-step task once
├── task # ACR Tasks (triggers, timers, logs, runs)
├── agentpool # Dedicated task agent pools (Premium)
├── import # Server-side image copy into the registry
├── repository # List/show/delete/untag repos & tags, lock images
├── manifest # Manifest metadata, delete, OCI referrers
├── credential # Admin user credentials (avoid in production)
├── token / scope-map # Repository-scoped tokens (Premium)
├── replication # Geo-replication (Premium)
├── network-rule # IP network rules
├── private-endpoint-connection # Private Link approvals
├── config # content-trust, retention, soft-delete, ...
├── cache / credential-set # Artifact cache (pull-through cache) rules
├── webhook # Push/delete event webhooks
├── connected-registry # On-premises / IoT connected registries
└── export-pipeline / import-pipeline / pipeline-run # acrtransfer extension
```

## Reference Files

Read the relevant reference file based on the user's task. Each file contains complete command syntax and examples for its domain.

| File | When to read | Covers |
|---|---|---|
| `references/auth-and-security.md` | Login failures, permissions, CI/CD or AKS pull access | `az acr login` (incl. `--expose-token`), Entra RBAC roles, service principals, managed identities, `--attach-acr` for AKS, repository-scoped tokens & scope maps, admin user, content trust |
| `references/build-and-tasks.md` | Building images in Azure, automation, CI triggers | `az acr build`, `az acr run`, multi-step task YAML, `az acr task` (git/base-image/timer triggers, logs, runs), agent pools |
| `references/images-and-artifacts.md` | Managing repos, tags, cleanup, storage costs | `az acr import`, repository & manifest commands, untag vs delete, purge (`acr purge`), image locking, retention policy, soft delete, artifact cache, `show-usage` |
| `references/networking-and-geo.md` | Multi-region, private access, edge scenarios | Geo-replication, zone redundancy, private endpoints, network rules, dedicated data endpoints, connected registries, registry transfer pipelines |
174 changes: 174 additions & 0 deletions skills/azure-container-registry-cli/references/auth-and-security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# Authentication & Security

## Table of Contents
- [Individual Login](#individual-login)
- [Microsoft Entra RBAC Roles](#microsoft-entra-rbac-roles)
- [Service Principals](#service-principals)
- [Managed Identities](#managed-identities)
- [AKS Integration](#aks-integration)
- [Repository-Scoped Tokens](#repository-scoped-tokens)
- [Admin User](#admin-user)
- [Content Trust](#content-trust)

---

## Individual Login

```bash
# Standard login — wires Docker/Podman credentials via your az login identity
az acr login --name {registry}

# Without a Docker daemon: get an Entra access token and pipe it to docker login
LOGIN_SERVER=$(az acr show --name {registry} --query loginServer --output tsv)
az acr login --name {registry} --expose-token --query accessToken --output tsv | \
docker login $LOGIN_SERVER --username 00000000-0000-0000-0000-000000000000 --password-stdin
```

Notes:
- `az acr login` tokens are valid for 3 hours; re-run on expiry.
- Resolve the login server with `az acr show --name {registry} --query loginServer --output tsv` rather than hardcoding it: it is usually `{registry}.azurecr.io`, but sovereign clouds use other suffixes and registries with a domain name label scope get a hash suffix.

## Microsoft Entra RBAC Roles

The applicable data-plane roles depend on the registry's **role assignment permissions mode** — check it first:

```bash
az acr show --name {registry} --query roleAssignmentMode --output tsv
# LegacyRegistryPermissions -> use AcrPull/AcrPush/AcrDelete
# AbacRepositoryPermissions -> use Container Registry Repository Reader/Writer/Contributor
```

**Legacy mode (RBAC Registry Permissions):**

| Role | Permissions |
|---|---|
| `AcrPull` | Pull images |
| `AcrPush` | Pull + push images |
| `AcrDelete` | Delete images |
| `AcrImageSigner` | Sign images (content trust) |
| `Contributor`/`Owner` | Full control-plane management + push/pull |
Comment thread
AClerbois marked this conversation as resolved.

**ABAC-enabled mode (RBAC Registry + ABAC Repository Permissions):** `AcrPull`/`AcrPush`/`AcrDelete` are **not honored**, and `Owner`/`Contributor`/`Reader` grant control-plane only. Use instead:

| Role | Permissions |
|---|---|
| `Container Registry Repository Reader` | Read images, tags, metadata (add ABAC conditions to scope to repositories) |
| `Container Registry Repository Writer` | Read + write/update |
| `Container Registry Repository Contributor` | Read + write + delete |
| `Container Registry Repository Catalog Lister` | List repositories — assign only when the identity must enumerate the catalog (e.g., `az acr repository list`); not needed for pull/push of known repositories |

```bash
# Get the registry resource ID
ACR_ID=$(az acr show --name {registry} --query id --output tsv)

# Grant pull access to a user, group, service principal, or managed identity
az role assignment create --assignee {principal-id} --scope $ACR_ID --role AcrPull

# List who has access
az role assignment list --scope $ACR_ID --output table
```

## Service Principals

For CI/CD systems that cannot use OIDC/managed identity:

```bash
# Create an SP scoped to pull only
ACR_ID=$(az acr show --name {registry} --query id --output tsv)
az ad sp create-for-rbac --name {sp-name} --scopes $ACR_ID --role AcrPull

# Docker login with the SP — pipe the secret via stdin, never pass it as an argument
# (printf with a quoted variable preserves whitespace/glob characters exactly)
printf '%s' "$SP_PASSWORD" | docker login $LOGIN_SERVER --username {appId} --password-stdin
```

Prefer federated credentials (OIDC) over SP passwords in GitHub Actions / Azure DevOps when possible.

## Managed Identities

For Azure compute (VM, App Service, Container Apps, Functions):

```bash
# Assign a system-assigned identity and grant it pull
az vm identity assign --name {vm} --resource-group {rg}
PRINCIPAL_ID=$(az vm show --name {vm} --resource-group {rg} --query identity.principalId --output tsv)
az role assignment create --assignee $PRINCIPAL_ID --scope $ACR_ID --role AcrPull
```

App Service / Container Apps then pull with `--assign-identity` + `--acr-identity` style flags of their own CLIs — no registry password needed.

## AKS Integration

```bash
# Attach at cluster creation
az aks create --name {cluster} --resource-group {rg} --attach-acr {registry}

# Attach/detach an existing cluster (grants AcrPull to the kubelet identity)
az aks update --name {cluster} --resource-group {rg} --attach-acr {registry}
Comment thread
AClerbois marked this conversation as resolved.
az aks update --name {cluster} --resource-group {rg} --detach-acr {registry}

# Validate the cluster can reach the registry
az aks check-acr --name {cluster} --resource-group {rg} --acr {registry}.azurecr.io
```

`--attach-acr` requires Owner or User Access Administrator on the registry. Cross-subscription attach works by passing the full ACR resource ID.

⚠️ `--attach-acr` assigns `AcrPull`, which is **not honored on ABAC-enabled registries** (`roleAssignmentMode` = `AbacRepositoryPermissions`). For those, assign the ABAC roles to the kubelet identity manually:

```bash
ACR_ID=$(az acr show --name {registry} --query id --output tsv)
KUBELET_ID=$(az aks show --name {cluster} --resource-group {rg} \
--query identityProfile.kubeletidentity.objectId --output tsv)
az role assignment create --assignee $KUBELET_ID --scope $ACR_ID \
--role "Container Registry Repository Reader"
# "Container Registry Repository Catalog Lister" is NOT needed for pulls —
# only add it if the identity must list repositories
```

## Repository-Scoped Tokens

Available in all service tiers. Fine-grained, non-Entra credentials (e.g., external partners, IoT devices):

```bash
# 1. Create a scope map (actions: content/read, content/write, content/delete, metadata/read, metadata/write)
az acr scope-map create --name {scope-map} --registry {registry} \
--repository app content/read metadata/read \
--description "Pull-only access to app"

# 2. Create a token bound to the scope map
az acr token create --name {token} --registry {registry} --scope-map {scope-map}

# 3. Generate/rotate passwords (up to 2, optional expiry)
az acr token credential generate --name {token} --registry {registry} --password1 --expiration-in-days 30

# Login with the token — pipe the password via stdin, never pass it as an argument
printf '%s' "$TOKEN_PWD" | docker login $LOGIN_SERVER --username {token} --password-stdin

# Disable or delete
az acr token update --name {token} --registry {registry} --status disabled
az acr token delete --name {token} --registry {registry} --yes
```

## Admin User

Single account, full push/pull on the whole registry, not auditable per user — **keep disabled in production**:

```bash
az acr update --name {registry} --admin-enabled false # recommended
az acr credential show --name {registry} # view username/passwords (if enabled)
az acr credential renew --name {registry} --password-name password2 # rotate
```

Legitimate uses: quick local tests, services that only accept username/password and cannot use tokens.

## Content Trust (deprecated)

Docker Content Trust (DCT) is being retired: **since May 31, 2026 it cannot be enabled on new registries** (or on registries that never enabled it), and it will be removed entirely on March 31, 2028. Do not set up DCT — sign images with **Notation (Notary Project)** and store signatures as OCI artifacts instead; see "Transition from Docker Content Trust to Notary Project" in the ACR docs.

```bash
# Registries with legacy DCT only — inspect or disable the existing configuration
az acr config content-trust show --registry {registry}
az acr config content-trust update --registry {registry} --status disabled
```

Legacy DCT signers needed `AcrImageSigner` in addition to `AcrPush`.
Loading
Loading