Manage OCI Artifacts and Supply Chain Artifacts with ORAS
Azure container registry (ACR) helps you manage both the Open container initiative (OCI) artifacts and supply chain artifacts. This article guides you how to use ACR for managing OCI artifacts and supply chain artifacts effectively. Learn to store, manage, and retrieve both OCI artifacts and a graph of supply chain artifacts, including signatures, software bill of materials (SBOM), security scan results, and other types.
This article is divided into two main sections:
Prerequisites
- Azure container registry - Create a container registry in your Azure subscription. For example, use the Azure portal or the Azure CLI.
- Azure CLI - Version
2.29.1
or later is required. See Install Azure CLI for installation and/or upgrade. - ORAS CLI - Version
v1.1.0
or later version is required. See: ORAS installation. - Docker (Optional) - To complete the walkthrough, a container image is referenced.
You can use Docker installed locally to build and push a container image, or use
acr build
to build remotely in Azure.
While Docker Desktop isn't required, theoras
cli utilizes the Docker desktop credential store for storing credentials. If Docker Desktop is installed, it must be running fororas login
.
Configure the registry
To configure your environment for easy command execution, follow these steps:
- Set the
ACR_NAME
variable to your registry name. - Set the
REGISTRY
variable to$ACR_NAME.azurecr.io
. - Set the
REPO
variable to your repository name. - Set the
TAG
variable to your desired tag. - Set the
IMAGE
variable to$REGISTRY/${REPO}:$TAG
.
Set environment variables
Configure a registry name, login credentials, a repository name, and tag to push and pull artifacts. The following example uses the net-monitor
repository name and v1
tag. Replace with your own repository name and tag.
ACR_NAME=myregistry
REGISTRY=$ACR_NAME.azurecr.io
REPO=net-monitor
TAG=v1
IMAGE=$REGISTRY/${REPO}:$TAG
Sign in to a registry
Authenticate with the ACR, for allowing you to pull and push container images.
az login
az acr login -n $REGISTRY
If Docker isn't available, you can utilize the AD token provided for authentication. Authenticate with your individual Microsoft Entra identity using an AD token. Always use "000..." for the USER_NAME
as the token is parsed through the PASSWORD
variable.
# Login to Azure
az login
Sign in with ORAS
Provide the credentials to oras login
.
oras login $REGISTRY \
--username $USER_NAME \
--password $PASSWORD
This setup enables you to seamlessly push and pull artifacts to and from your Azure Container Registry. Adjust the variables as needed for your specific configuration.
Push and Pull OCI Artifacts with ORAS
You can use an Azure container registry to store and manage Open Container Initiative (OCI) artifacts as well as Docker and OCI container images.
To demonstrate this capability, this section shows how to use the OCI Registry as Storage (ORAS) CLI to push and pull OCI artifacts to/from an Azure container registry. You can manage various OCI artifacts in an Azure container registry using different command-line tools appropriate to each artifact.
Note
ACR and ORAS support multiple authentication options for users and system automation. This article uses individual identity, using an Azure token. For more authentication options see Authenticate with an Azure container registry.
Push an artifact
A single file artifact that has no subject
parent can be anything from a container image, a helm chart, a readme file for the repository. Reference artifacts can be anything from a signature, software bill of materials, scan reports, or other evolving types. Reference artifacts, described in Attach, push, and pull supply chain artifacts are artifacts that refer to another artifact.
Push a Single-File Artifact
For this example, create content that represents a markdown file:
echo 'Readme Content' > readme.md
The following step pushes the readme.md
file to <myregistry>.azurecr.io/samples/artifact:readme
.
- The registry is identified with the fully qualified registry name
<myregistry>.azurecr.io
(all lowercase), followed by the namespace and repo:/samples/artifact
. - The artifact is tagged
:readme
, to identify it uniquely from other artifacts listed in the repo (:latest, :v1, :v1.0.1
). - Setting
--artifact-type readme/example
differentiates the artifact from a container image, which usesapplication/vnd.oci.image.config.v1+json
. - The
./readme.md
identifies the file uploaded, and the:application/markdown
represents the IANAmediaType
of the file.
For more information, see OCI Artifact Authors Guidance.
Use the oras push
command to push the file to your registry.
Linux, WSL2 or macOS
oras push $REGISTRY/samples/artifact:readme \
--artifact-type readme/example \
./readme.md:application/markdown
Windows
.\oras.exe push $REGISTRY/samples/artifact:readme ^
--artifact-type readme/example ^
.\readme.md:application/markdown
Output for a successful push is similar to the following output:
Uploading 2fdeac43552b readme.md
Uploaded 2fdeac43552b readme.md
Pushed <myregistry>.azurecr.io/samples/artifact:readme
Digest: sha256:e2d60d1b171f08bd10e2ed171d56092e39c7bac1
aec5d9dcf7748dd702682d53
Push a multi-file artifact
When OCI artifacts are pushed to a registry with ORAS, each file reference is pushed as a blob. To push separate blobs, reference the files individually, or collection of files by referencing a directory.
For more information how to push a collection of files, see Pushing artifacts with multiple files.
Create some documentation for the repository:
echo 'Readme Content' > readme.md
mkdir details/
echo 'Detailed Content' > details/readme-details.md
echo 'More detailed Content' > details/readme-more-details.md
Push the multi-file artifact:
Linux, WSL2 or macOS
oras push $REGISTRY/samples/artifact:readme \
--artifact-type readme/example\
./readme.md:application/markdown\
./details
Windows
.\oras.exe push $REGISTRY/samples/artifact:readme ^
--artifact-type readme/example ^
.\readme.md:application/markdown ^
.\details
Discover the manifest
To view the manifest created as a result of oras push
, use oras manifest fetch
:
oras manifest fetch --pretty $REGISTRY/samples/artifact:readme
The output is similar to:
{
"mediaType": "application/vnd.oci.artifact.manifest.v1+json",
"artifactType": "readme/example",
"blobs": [
{
"mediaType": "application/markdown",
"digest": "sha256:2fdeac43552b71eb9db534137714c7bad86b53a93c56ca96d4850c9b41b777fc",
"size": 15,
"annotations": {
"org.opencontainers.image.title": "readme.md"
}
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:0d6c7434a34f6854f971487621426332e6c0fda08040b9e6cc8a93f354cee0b1",
"size": 189,
"annotations": {
"io.deis.oras.content.digest": "sha256:11eceb2e7ac3183ec9109003a7389468ec73ad5ceaec0c4edad0c1b664c5593a",
"io.deis.oras.content.unpack": "true",
"org.opencontainers.image.title": "details"
}
}
],
"annotations": {
"org.opencontainers.artifact.created": "2023-01-10T14:44:06Z"
}
}
Pull an artifact
Create a clean directory for downloading.
mkdir ./download
Run the oras pull
command to pull the artifact from your registry.
oras pull -o ./download $REGISTRY/samples/artifact:readme
View the pulled files
tree ./download
Remove the artifact (optional)
To remove the artifact from your registry, use the oras manifest delete
command.
oras manifest delete $REGISTRY/samples/artifact:readme
Attach, push, and pull supply chain artifacts with ORAS
To demonstrate this capability, this article shows how to use the OCI Registry as Storage (ORAS) CLI to push
, discover
, and pull
a graph of supply chain artifacts to an Azure container registry.
Storing individual (subject) OCI Artifacts are covered in Push and pull OCI artifacts.
To store a graph of artifacts, a reference to a subject
artifact is defined using the OCI image manifest, which is part of the prerelease OCI 1.1 Distribution specification.
Push a container image
To associate a graph of artifacts with a container image using the Azure CLI:
You can build and push a container image, or skip this step if $IMAGE
references an existing image in the registry.
az acr build -r $ACR_NAME -t $IMAGE https://github.com/wabbit-networks/net-monitor.git#main
Attaching a Signature
echo '{"artifact": "'${IMAGE}'", "signature": "jayden hancock"}' > signature.json
Attach a signature to the registry, as a reference to the container image
The oras attach
command creates a reference between the file (./signature.json
) to the $IMAGE
. The --artifact-type
provides for differentiating artifacts, similar to file extensions that enable different file types. One or more files can be attached by specifying [file]:[mediaType]
.
oras attach $IMAGE \
--artifact-type signature/example \
./signature.json:application/json
For more information on oras attach, see ORAS documentation.
Attach a multi-file artifact as a reference
When OCI artifacts are pushed to a registry with ORAS, each file reference is pushed as a blob. To push separate blobs, reference the files individually, or collection of files by referencing a directory.
For more information how to push a collection of files, see Pushing artifacts with multiple files.
Discovering artifact references
The OCI v1.1 Specification defines a referrers API for discovering references to a subject
artifact. The oras discover
command can show the list of references to the container image.
Using oras discover
, view the graph of artifacts now stored in the registry.
oras discover -o tree $IMAGE
The output shows the beginning of a graph of artifacts, where the signature and docs are viewed as children of the container image.
myregistry.azurecr.io/net-monitor:v1
├── signature/example
│ └── sha256:555ea91f39e7fb30c06f3b7aa483663f067f2950dcb...
└── readme/example
└── sha256:1a118663d1085e229ff1b2d4d89b5f6d67911f22e55...
Creating Artifacts graphs
The OCI v1.1 Specification enables deep graphs, enabling signed software bill of materials (SBOM) and other artifact types.
Here's how to create and attach an SBOM to the registry:
Create a sample SBOM
echo '{"version": "0.0.0.0", "artifact": "'${IMAGE}'", "contents": "good"}' > sbom.json
Attach a sample SBOM to the image in the registry
Linux, WSL2 or macOS
oras attach $IMAGE \
--artifact-type sbom/example \
./sbom.json:application/json
Windows
.\oras.exe attach $IMAGE ^
--artifact-type sbom/example ^
./sbom.json:application/json
Sign the SBOM
Important
Microsoft recommends using a secure crypto signing tool, like Notation to sign the image and generate a signature for signing SBOMs.
Artifacts that are pushed as references, typically don't have tags as they're considered part of the subject
artifact. To push a signature to an artifact that is a child of another artifact, use the oras discover
with --artifact-type
filtering to find the digest. This example uses a simple JSON signature for demonstration purposes.
SBOM_DIGEST=$(oras discover -o json \
--artifact-type sbom/example \
$IMAGE | jq -r ".manifests[0].digest")
Create a signature of an SBOM.
echo '{"artifact": "'$IMAGE@$SBOM_DIGEST'", "signature": "jayden hancock"}' > sbom-signature.json
Attach the SBOM signature
oras attach $IMAGE@$SBOM_DIGEST \
--artifact-type 'signature/example' \
./sbom-signature.json:application/json
View the graph
oras discover -o tree $IMAGE
Generates the following output:
myregistry.azurecr.io/net-monitor:v1
├── sbom/example
│ └── sha256:4f1843833c029ecf0524bc214a0df9a5787409fd27bed2160d83f8cc39fedef5
│ └── signature/example
│ └── sha256:3c43b8cb0c941ec165c9f33f197d7f75980a292400d340f1a51c6b325764aa93
├── readme/example
│ └── sha256:5fafd40589e2c980e2864a78818bff51ee641119cf96ebb0d5be83f42aa215af
└── signature/example
└── sha256:00da2c1c3ceea087b16e70c3f4e80dbce6f5b7625d6c8308ad095f7d3f6107b5
Promoting the Artifact Graph
A typical DevOps workflow promotes artifacts from dev through staging, to the production environment. Secure supply chain workflows promote public content to privately secured environments. In either case you want to promote the signatures, SBOMs, scan results, and other related artifact with the subject artifact to have a complete graph of dependencies.
Using the oras copy
command, you can promote a filtered graph of artifacts across registries.
Copy the net-monitor:v1
image, and related artifacts to sample-staging/net-monitor:v1
:
TARGET_REPO=$REGISTRY/sample-staging/$REPO
oras copy -r $IMAGE $TARGET_REPO:$TAG
The output of oras copy
:
Copying 6bdea3cdc730 sbom-signature.json
Copying 78e159e81c6b sbom.json
Copied 6bdea3cdc730 sbom-signature.json
Copied 78e159e81c6b sbom.json
Copying 7cf1385c7f4d signature.json
Copied 7cf1385c7f4d signature.json
Copying 3e797ecd0697 details
Copying 2fdeac43552b readme.md
Copied 3e797ecd0697 details
Copied 2fdeac43552b readme.md
Copied demo42.myregistry.io/net-monitor:v1 => myregistry.azurecr.io/sample-staging/net-monitor:v1
Digest: sha256:ff858b2ea3cdf4373cba65d2ca6bcede4da1d620503a547cab5916614080c763
Discover the promoted artifact graph
oras discover -o tree $TARGET_REPO:$TAG
Output of oras discover
:
myregistry.azurecr.io/sample-staging/net-monitor:v1
├── sbom/example
│ └── sha256:4f1843833c029ecf0524bc214a0df9a5787409fd27bed2160d83f8cc39fedef5
│ └── signature/example
│ └── sha256:3c43b8cb0c941ec165c9f33f197d7f75980a292400d340f1a51c6b325764aa93
├── readme/example
│ └── sha256:5fafd40589e2c980e2864a78818bff51ee641119cf96ebb0d5be83f42aa215af
└── signature/example
└── sha256:00da2c1c3ceea087b16e70c3f4e80dbce6f5b7625d6c8308ad095f7d3f6107b5
Pulling Referenced Artifacts
To pull a specific referenced artifact, the digest of reference is discovered with the oras discover
command:
DOC_DIGEST=$(oras discover -o json \
--artifact-type 'readme/example' \
$TARGET_REPO:$TAG | jq -r ".manifests[0].digest")
Create a clean directory for downloading
mkdir ./download
Pull the docs into the download directory
oras pull -o ./download $TARGET_REPO@$DOC_DIGEST
View the docs
tree ./download
The output of tree
:
./download
├── details
│ ├── readme-details.md
│ └── readme-more-details.md
└── readme.md
View the repository and tag listing
ORAS enables artifact graphs to be pushed, discovered, pulled, and copied without having to assign tags. It also enables a tag listing to focus on the artifacts users think about, as opposed to the signatures and SBOMs that are associated with the container images, helm charts, and other artifacts.
View a list of tags
oras repo tags $REGISTRY/$REPO
Deleting all artifacts in the graph
Support for the OCI v1.1 Specification enables deleting the graph of artifacts associated with the subject artifact. Use the oras manifest delete
command to delete the graph of artifacts (signature, SBOM, and the signature of the SBOM).
oras manifest delete -f $REGISTRY/$REPO:$TAG
oras manifest delete -f $REGISTRY/sample-staging/$REPO:$TAG
You can view the list of manifests to confirm the deletion of the subject artifact, and all related artifacts leaving a clean environment.
az acr manifest list-metadata \
--name $REPO \
--registry $ACR_NAME -o jsonc
Output:
2023-01-10 18:38:45.366387 Error: repository "net-monitor" is not found.
Summary
In this article, you learned how to use Azure Container Registry to store, manage, and retrieve both OCI artifacts and supply chain artifacts. You used ORAS CLI to push and pull artifacts to/from an Azure Container Registry. You also discovered the manifest of the pushed artifacts and viewed the graph of artifacts attached to the container image.
Next steps
- Learn about Artifact References, associating signatures, software bill of materials and other reference types.
- Learn more about the ORAS Project, including how to configure a manifest for an artifact.
- Visit the OCI Artifacts repo for reference information about new artifact types.