
ORAS (OCI Registry As Storage) permet de stocker n’importe quel fichier dans une registry OCI : configurations, charts Helm, SBOM, signatures, binaires. Cet outil CLI léger fonctionne sans Docker ni Podman et s’intègre parfaitement dans les pipelines CI/CD. Projet CNCF Sandbox soutenu par Microsoft, AWS et Red Hat.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Installer ORAS (v1.3.0) sur Linux ou macOS
- Pousser et tirer des artefacts vers/depuis une registry OCI
- Attacher des artefacts (SBOM, signatures) à des images existantes
- Utiliser backup/restore pour sauvegarder vos artefacts localement
- Intégrer dans CI/CD (GitHub Actions, GitLab CI)
Qu’est-ce qu’ORAS ?
Section intitulée « Qu’est-ce qu’ORAS ? »Le problème : stocker plus que des images
Section intitulée « Le problème : stocker plus que des images »Traditionnellement, les registries de conteneurs (Docker Hub, GitHub Container Registry, Azure Container Registry, etc.) ont été conçues pour stocker des images Docker. Mais de nombreuses équipes ont commencé à “détourner” ces registries pour stocker d’autres types de fichiers :
- Fichiers de configuration : nginx.conf, application.yaml
- Charts Helm : packages d’applications Kubernetes
- SBOM : inventaires de composants logiciels pour la sécurité
- Signatures et attestations : preuves cryptographiques de sécurité
- Binaires : exécutables, bibliothèques
- Documentation : manuels, API specs (OpenAPI, Swagger)
Le problème ? Il fallait créer des images Docker “artificielles” pour stocker ces fichiers, ce qui était maladroit et créait de la confusion.
La solution : Les artefacts OCI
Section intitulée « La solution : Les artefacts OCI »La spécification OCI (Open Container Initiative) a évolué avec OCI Artifacts et OCI 1.1+ pour supporter officiellement le stockage d’artefacts génériques, au-delà des seules images de conteneurs. Les registries conformes à cette spécification peuvent désormais stocker n’importe quel type de fichier de manière native.
ORAS (OCI Registry As Storage) est un outil CLI qui implémente cette spécification. Il permet de manipuler facilement ces artefacts OCI sans avoir besoin de Docker ou Podman. ORAS est un projet CNCF Sandbox (Cloud Native Computing Foundation), soutenu par Microsoft, AWS, Red Hat, et d’autres acteurs majeurs du cloud natif.
D’autres outils utilisent également la spécification OCI Artifacts : Helm (pour les charts), Cosign (pour les signatures), Syft (pour les SBOM), etc.
Comprendre OCI et les artefacts
Section intitulée « Comprendre OCI et les artefacts »L’Open Container Initiative (OCI) a défini des standards pour structurer et distribuer des contenus dans des registries. Ces standards, initialement conçus pour les images de conteneurs, supportent maintenant tout type de fichier.
Concepts clés :
-
Artefact OCI : fichier ou ensemble de fichiers stocké dans une registry avec un type de média spécifique (
application/vnd.oci.image.manifest.v1+jsonpour une image, types personnalisés pour d’autres contenus) -
Manifest : fichier JSON décrivant l’artefact (liste des fichiers/blobs, leur digest SHA256, taille, type de média, annotations)
-
Annotations : métadonnées clé-valeur ajoutées au manifest (date de création, auteurs, version, commit Git, etc.)
-
Digest : empreinte SHA256 immuable du contenu sous la forme
sha256:abc123.... Contrairement aux tags mutables (latest,v1.0), un digest référence toujours exactement le même contenu -
Attachements : artefacts liés entre eux (SBOM attaché à une image, signature attachée à une image, rapport de scan attaché à une image)
Pour approfondir ces concepts, consultez le guide OCI.
Installation d’ORAS
Section intitulée « Installation d’ORAS »Téléchargez le binaire v1.3.0 :
VERSION="1.3.0"curl -sLO "https://github.com/oras-project/oras/releases/download/v${VERSION}/oras_${VERSION}_linux_amd64.tar.gz"tar -xzf oras_${VERSION}_linux_amd64.tar.gzsudo mv oras /usr/local/bin/rm -f oras_${VERSION}_linux_amd64.tar.gz LICENSEbrew install orasVERSION="1.3.0"# Apple Siliconcurl -sLO "https://github.com/oras-project/oras/releases/download/v${VERSION}/oras_${VERSION}_darwin_arm64.tar.gz"tar -xzf oras_${VERSION}_darwin_arm64.tar.gzsudo mv oras /usr/local/bin/asdf plugin add orasasdf install oras 1.3.0asdf global oras 1.3.0Vérification de l’installation
Section intitulée « Vérification de l’installation »oras versionVersion: 1.3.0Go version: go1.25.0OS/Arch: linux/amd64Git commit: 40530fe4c68e5825b868cd874bd46fc0cdd0f432Git tree state: cleanPremiers pas avec ORAS
Section intitulée « Premiers pas avec ORAS »Préparer des fichiers de test
Section intitulée « Préparer des fichiers de test »Pour illustrer le fonctionnement d’ORAS, créons quelques fichiers d’exemple dans
/tmp :
cd /tmpmkdir oras-democd oras-demo
# Créer un fichier de configuration Nginxcat > nginx.conf << 'EOF'# Configuration Nginx pour ORASserver { listen 80; server_name example.com; root /var/www/html;
location / { try_files $uri $uri/ =404; }}EOF
# Créer un fichier READMEcat > README.md << 'EOF'# Guide ORAS Demo
Ce dépôt démontre le stockage d'artefacts avec ORAS.
## Contenu- nginx.conf : configuration du serveur web- README.md : cette documentationEOF
# Vérifier les fichiers créésls -lhRésultat attendu :
total 8,0K-rw-rw-r-- 1 user user 180 déc. 19 12:00 nginx.conf-rw-rw-r-- 1 user user 140 déc. 19 12:00 README.mdPousser des artefacts dans une registry
Section intitulée « Pousser des artefacts dans une registry »S’authentifier à une registry
Section intitulée « S’authentifier à une registry »Avant de pousser des artefacts, vous devez vous authentifier auprès de la registry. ORAS supporte les mêmes mécanismes d’authentification que Docker.
Pour vous connecter à une registry Harbor :
oras login harbor.example.com -u votre_usernamePassword:Login SucceededLes identifiants sont stockés dans ~/.docker/config.json (même emplacement que
Docker).
Stocker un artefact simple
Section intitulée « Stocker un artefact simple »La commande push envoie un ou plusieurs fichiers vers une registry. Voici la
syntaxe de base :
oras push [options] <registry>/<repository>:<tag> <fichier1> <fichier2> ...Exemples :
-
Pousser un seul fichier
Fenêtre de terminal cd /tmp/oras-demooras push ghcr.io/votre-username/config/nginx:v1.0 nginx.confExplication de la commande :
oras push: commande pour envoyer des artefactsghcr.io/votre-username/config/nginx:v1.0: référence complèteghcr.io: registry (GitHub Container Registry)votre-username: votre organisation/utilisateurconfig/nginx: nom du repository (chemin virtuel)v1.0: tag (version)
nginx.conf: fichier à pousser
Sortie attendue :
Uploading df5e6c1d0a3b nginx.confUploaded df5e6c1d0a3b nginx.confPushed [registry] ghcr.io/votre-username/config/nginx:v1.0Digest: sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5fLe digest est l’empreinte SHA256 unique de votre artefact. Il permet de référencer précisément cette version, même si le tag change.
-
Pousser plusieurs fichiers
Fenêtre de terminal oras push ghcr.io/votre-username/config/nginx:v1.1 \nginx.conf \README.mdLes deux fichiers sont uploadés et associés au même manifest.
-
Spécifier un type de média personnalisé
Par défaut, ORAS utilise le type
application/vnd.oci.image.layer.v1.tarpour les fichiers. Vous pouvez spécifier un type personnalisé :Fenêtre de terminal oras push ghcr.io/votre-username/config/nginx:v1.2 \nginx.conf:application/vnd.example.nginx.conf \README.md:text/markdownLe format est :
<fichier>:<type-de-média> -
Ajouter des annotations
Les annotations sont des métadonnées ajoutées au manifest pour documenter l’artefact :
Fenêtre de terminal oras push ghcr.io/votre-username/config/nginx:v1.3 \--annotation "org.opencontainers.image.created=$(date -Iseconds)" \--annotation "org.opencontainers.image.authors=votre-nom" \--annotation "org.opencontainers.image.description=Configuration Nginx pour prod" \--annotation "environment=production" \nginx.conf README.mdCes annotations seront visibles dans le manifest et peuvent être utilisées pour filtrer ou rechercher des artefacts.
Pousser vers une registry locale ou privée
Section intitulée « Pousser vers une registry locale ou privée »Cas particuliers :
-
Registry locale non sécurisée (HTTP)
Si vous testez avec une registry locale (par exemple,
localhost:5000), utilisez l’option--plain-http:Fenêtre de terminal oras push --plain-http localhost:5000/config/nginx:v1 nginx.conf -
Registry avec certificat auto-signé
Pour une registry avec un certificat SSL auto-signé, utilisez
--insecure:Fenêtre de terminal oras push --insecure myregistry.local:5000/config/nginx:v1 nginx.conf
Tirer des artefacts depuis une registry
Section intitulée « Tirer des artefacts depuis une registry »Télécharger un artefact
Section intitulée « Télécharger un artefact »La commande pull télécharge les fichiers d’un artefact dans le répertoire
courant :
# Créer un répertoire pour le testmkdir -p /tmp/oras-test-pullcd /tmp/oras-test-pull
# Tirer l'artefactoras pull ghcr.io/votre-username/config/nginx:v1.3Sortie attendue :
Downloading df5e6c1d0a3b nginx.confDownloaded df5e6c1d0a3b nginx.confDownloading a8f3d2e1b4c5 README.mdDownloaded a8f3d2e1b4c5 README.mdPulled [registry] ghcr.io/votre-username/config/nginx:v1.3Digest: sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5fVérifiez que les fichiers ont été téléchargés :
ls -lhTirer vers un répertoire spécifique
Section intitulée « Tirer vers un répertoire spécifique »Par défaut, oras pull télécharge dans le répertoire courant. Pour spécifier un
autre emplacement, utilisez l’option --output ou -o :
oras pull -o /tmp/mon-config ghcr.io/votre-username/config/nginx:v1.3Tirer par digest (immuable)
Section intitulée « Tirer par digest (immuable) »Pour garantir que vous récupérez exactement la version attendue, utilisez le digest au lieu du tag :
oras pull ghcr.io/votre-username/config/nginx@sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5fLe digest est immuable : contrairement aux tags qui peuvent être réassignés, un digest référence toujours le même contenu.
Tirer avec une plateforme spécifique
Section intitulée « Tirer avec une plateforme spécifique »Si l’artefact est multi-plateforme (par exemple, binaires compilés pour différentes architectures), spécifiez la plateforme :
oras pull --platform linux/arm64 ghcr.io/votre-username/binaries/app:v2.0Explorer les artefacts
Section intitulée « Explorer les artefacts »Récupérer le manifest
Section intitulée « Récupérer le manifest »Le manifest est le fichier JSON qui décrit l’artefact. Pour le visualiser :
oras manifest fetch ghcr.io/votre-username/config/nginx:v1.3 --prettyExemple de sortie :
{ "schemaVersion": 2, "mediaType": "application/vnd.oci.image.manifest.v1+json", "artifactType": "application/vnd.unknown.artifact.v1", "config": { "mediaType": "application/vnd.oci.empty.v1+json", "digest": "sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a", "size": 2, "data": "e30=" }, "layers": [ { "mediaType": "application/vnd.oci.image.layer.v1.tar", "digest": "sha256:df5e6c1d0a3b7e8c2f4a5b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d9e", "size": 180, "annotations": { "org.opencontainers.image.title": "nginx.conf" } }, { "mediaType": "application/vnd.oci.image.layer.v1.tar", "digest": "sha256:a8f3d2e1b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e", "size": 140, "annotations": { "org.opencontainers.image.title": "README.md" } } ], "annotations": { "org.opencontainers.image.created": "2025-12-19T12:00:00Z", "org.opencontainers.image.authors": "votre-nom", "org.opencontainers.image.description": "Configuration Nginx pour prod", "environment": "production" }}Explication du manifest :
config: métadonnées de configuration (souvent vide pour les artefacts génériques)layers: liste des fichiers (chaque fichier est un “layer”)digest: empreinte SHA256 du fichiersize: taille en octetsannotations.org.opencontainers.image.title: nom du fichier
annotations: métadonnées globales de l’artefact
Récupérer uniquement le descriptor
Section intitulée « Récupérer uniquement le descriptor »Le descriptor est une version condensée du manifest qui contient uniquement le type de média, le digest et la taille :
oras manifest fetch ghcr.io/votre-username/config/nginx:v1.3 --descriptorSortie :
{ "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5f", "size": 1247}Utile pour vérifier rapidement l’existence d’un artefact sans télécharger le manifest complet.
Exemple avec une image publique
Section intitulée « Exemple avec une image publique »Testons avec l’image Alpine sur Docker Hub pour voir comment ORAS interagit avec des images de conteneurs classiques :
oras manifest fetch docker.io/library/alpine:latest --descriptorSortie :
{ "mediaType": "application/vnd.oci.image.index.v1+json", "digest": "sha256:865b95f46d98cf867a156fe4a135ad3fe50d2056aa3f25ed31662dff6da4eb62", "size": 9218}On voit que mediaType est un index (multi-plateforme). Affichons le
manifest complet :
oras manifest fetch docker.io/library/alpine:latest --pretty | head -50Cela affiche toutes les plateformes disponibles (amd64, arm64, arm/v6, etc.) avec leurs annotations respectives.
Attacher des artefacts (références)
Section intitulée « Attacher des artefacts (références) »L’une des fonctionnalités les plus puissantes d’ORAS est la capacité d’attacher des artefacts à d’autres artefacts. Cela crée une relation parent-enfant.
Cas d’usage des attachements
Section intitulée « Cas d’usage des attachements »- Signature : attacher une signature Cosign à une image
- SBOM : attacher un inventaire de composants (Syft) à une image
- Scan de vulnérabilités : attacher un rapport Trivy/Grype à une image
- Attestation : attacher une preuve de build reproductible (SLSA)
- Documentation : attacher les release notes à une version
Attacher un fichier à un artefact existant
Section intitulée « Attacher un fichier à un artefact existant »Imaginons que vous avez déjà pushé une configuration Nginx (nginx:v1.3) et que
vous voulez y attacher un rapport d’audit de sécurité.
Étapes :
-
Créer le rapport d’audit
Fenêtre de terminal cd /tmp/oras-democat > security-audit.json << 'EOF'{"scannedAt": "2025-12-19T12:00:00Z","tool": "trivy","version": "0.50.0","vulnerabilities": {"critical": 0,"high": 0,"medium": 2,"low": 5},"status": "passed"}EOF -
Attacher le rapport à la configuration
Fenêtre de terminal oras attach \--artifact-type application/vnd.example.security.audit.v1+json \--annotation "scanned-by=trivy" \--annotation "scan-date=2025-12-19" \ghcr.io/votre-username/config/nginx:v1.3 \security-audit.jsonExplication :
--artifact-type: type personnalisé pour le rapport d’audit--annotation: métadonnées sur le scanghcr.io/votre-username/config/nginx:v1.3: artefact parent (la config Nginx)security-audit.json: fichier à attacher
Sortie :
Uploading a1b2c3d4e5f6 security-audit.jsonUploaded a1b2c3d4e5f6 security-audit.jsonAttached to [registry] ghcr.io/votre-username/config/nginx:v1.3Digest: sha256:8e7d6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7L’artefact attaché a son propre digest et n’est pas tagué. Il est référencé uniquement via son lien avec l’artefact parent.
Découvrir les artefacts attachés
Section intitulée « Découvrir les artefacts attachés »Pour lister tous les artefacts attachés à un artefact parent, utilisez oras discover :
oras discover ghcr.io/votre-username/config/nginx:v1.3Sortie en arbre :
ghcr.io/votre-username/config/nginx:v1.3└── application/vnd.example.security.audit.v1+json └── sha256:8e7d6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7Filtrer par type d’artefact
Section intitulée « Filtrer par type d’artefact »Si vous avez plusieurs types d’artefacts attachés (SBOM, signature, scan), filtrez par type :
oras discover \ --artifact-type application/vnd.example.security.audit.v1+json \ ghcr.io/votre-username/config/nginx:v1.3Afficher en format JSON
Section intitulée « Afficher en format JSON »Pour une sortie structurée exploitable par des scripts :
oras discover --format json ghcr.io/votre-username/config/nginx:v1.3:::caution[Format tableau déprécié] Le format --format table est déprécié et
sera supprimé dans une future version. Préférez le format JSON ou la sortie par
défaut en arbre. :::
Copier des artefacts entre registries
Section intitulée « Copier des artefacts entre registries »ORAS permet de copier des artefacts d’une registry à une autre, utile pour :
- Migrer vers une nouvelle registry
- Répliquer des artefacts entre régions (cloud)
- Créer des mirrors locaux
Copier un artefact simple
Section intitulée « Copier un artefact simple »oras copy \ ghcr.io/votre-username/config/nginx:v1.3 \ myregistry.azurecr.io/config/nginx:v1.3ORAS copie :
- Le manifest
- Tous les layers (fichiers)
- Les annotations
Copier avec tous les artefacts attachés
Section intitulée « Copier avec tous les artefacts attachés »Par défaut, oras copy ne copie pas les artefacts attachés (signatures,
SBOM, etc.). Pour les inclure, ajoutez -r (ou --recursive) :
oras copy -r \ ghcr.io/votre-username/config/nginx:v1.3 \ myregistry.azurecr.io/config/nginx:v1.3Maintenant, le rapport d’audit attaché sera également copié vers la registry de destination.
Taguer des artefacts
Section intitulée « Taguer des artefacts »Contrairement à Docker, ORAS n’a pas de commande tag dédiée. Pour ajouter un
nouveau tag à un artefact existant, il faut pousser le même manifest avec un
nouveau tag.
Méthode 1 : Pousser à nouveau le manifest
Section intitulée « Méthode 1 : Pousser à nouveau le manifest »# Récupérer le manifestoras manifest fetch ghcr.io/votre-username/config/nginx:v1.3 > manifest.json
# Pousser avec un nouveau tagoras manifest push \ ghcr.io/votre-username/config/nginx:latest \ manifest.jsonMéthode 2 : Utiliser oras copy
Section intitulée « Méthode 2 : Utiliser oras copy »Plus simple :
oras copy \ ghcr.io/votre-username/config/nginx:v1.3 \ ghcr.io/votre-username/config/nginx:latestLes deux tags (v1.3 et latest) pointent maintenant vers le même digest.
:::note[Registry locale] Pour une registry locale non sécurisée (HTTP), utilisez
les options --from-plain-http et --to-plain-http :
oras copy --from-plain-http --to-plain-http \ localhost:5000/config/nginx:v1.3 \ localhost:5000/config/nginx:latest:::
Supprimer des artefacts
Section intitulée « Supprimer des artefacts »Supprimer par tag
Section intitulée « Supprimer par tag »oras manifest delete ghcr.io/votre-username/config/nginx:v1.0⚠️ Attention : supprimer un tag ne supprime pas les layers (fichiers) sous-jacents. Si d’autres artefacts référencent ces layers, ils restent accessibles.
Supprimer par digest
Section intitulée « Supprimer par digest »Pour supprimer définitivement un artefact (et potentiellement ses layers si non-référencés) :
oras manifest delete ghcr.io/votre-username/config/nginx@sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5fGarbage collection
Section intitulée « Garbage collection »La suppression effective des layers orphelins dépend de la garbage
collection de la registry. La plupart des registries cloud (ACR, GCR, GHCR)
ont des politiques automatiques, mais pour une registry auto-hébergée (comme
distribution/distribution), vous devez exécuter manuellement :
registry garbage-collect /etc/docker/registry/config.ymlCas d’usage pratiques
Section intitulée « Cas d’usage pratiques »1. Versionner les configurations Kubernetes
Section intitulée « 1. Versionner les configurations Kubernetes »Au lieu de gérer les configurations dans Git uniquement, vous pouvez les versionner dans une registry OCI :
# Pousser les manifests Kubernetesoras push ghcr.io/mon-org/k8s-configs/frontend:v2.5.0 \ --annotation "git-commit=a1b2c3d" \ --annotation "deployed-by=ci-pipeline" \ deployment.yaml service.yaml ingress.yaml
# Déployer depuis la registryoras pull ghcr.io/mon-org/k8s-configs/frontend:v2.5.0kubectl apply -f .Avantages :
- Versioning atomique (toute la config en un seul artefact)
- Référence immuable (digest)
- Métadonnées riches (annotations)
2. Stocker les SBOM avec les images
Section intitulée « 2. Stocker les SBOM avec les images »Utilisez Syft pour générer un SBOM et attachez-le à l’image :
# Générer le SBOMsyft ghcr.io/mon-org/app:v1.0 -o spdx-json > sbom.spdx.json
# Attacher le SBOM à l'imageoras attach \ --artifact-type application/spdx+json \ --annotation "tool=syft" \ --annotation "format=spdx" \ ghcr.io/mon-org/app:v1.0 \ sbom.spdx.json
# Vérifieroras discover ghcr.io/mon-org/app:v1.0Maintenant, chaque image a son SBOM associé, accessible via oras discover.
3. Distribuer des binaires multi-plateformes
Section intitulée « 3. Distribuer des binaires multi-plateformes »ORAS supporte les artefacts multi-plateformes (comme les images Docker multi-arch) :
# Pousser pour Linux AMD64oras push --artifact-platform linux/amd64 \ ghcr.io/mon-org/cli:v3.0 \ app-linux-amd64
# Pousser pour Linux ARM64oras push --artifact-platform linux/arm64 \ ghcr.io/mon-org/cli:v3.0 \ app-linux-arm64
# Tirer selon la plateformeoras pull --platform linux/arm64 ghcr.io/mon-org/cli:v3.0Le bon binaire est téléchargé automatiquement selon la plateforme spécifiée.
4. Pipeline CI/CD : résultats de tests
Section intitulée « 4. Pipeline CI/CD : résultats de tests »Stockez les rapports de tests dans la registry pour les associer à chaque build :
# Après l'exécution des testsoras attach \ --artifact-type application/vnd.example.test.report.v1+json \ --annotation "test-suite=integration" \ --annotation "passed=152" \ --annotation "failed=0" \ ghcr.io/mon-org/app:build-${CI_COMMIT_SHA} \ test-report.json coverage.htmlLes développeurs peuvent récupérer les rapports de tests associés à n’importe quel commit :
oras discover ghcr.io/mon-org/app:build-a1b2c3doras pull ghcr.io/mon-org/app@sha256:... # digest du rapportIntégration dans les Pipelines CI/CD
Section intitulée « Intégration dans les Pipelines CI/CD »stages: - build - security - publish
variables: IMAGE_NAME: $CI_REGISTRY_IMAGE/app:$CI_COMMIT_SHA
build: stage: build script: - docker build -t $IMAGE_NAME . - docker push $IMAGE_NAME
security-scan: stage: security image: aquasec/trivy:latest script: - trivy image --format json -o trivy-report.json $IMAGE_NAME - oras attach --artifact-type application/vnd.aquasec.trivy.report.v1+json --annotation "scanned-at=$(date -Iseconds)" $IMAGE_NAME trivy-report.json artifacts: reports: container_scanning: trivy-report.json
publish-sbom: stage: publish image: anchore/syft:latest script: - syft $IMAGE_NAME -o spdx-json > sbom.spdx.json - oras attach --artifact-type application/spdx+json $IMAGE_NAME sbom.spdx.jsonname: Build and Publish Artifacts
on: push: branches: [main]
jobs: build: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4
- name: Login to GHCR uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Build image run: | docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} . docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
- name: Install ORAS run: | VERSION="1.3.0" curl -LO "https://github.com/oras-project/oras/releases/download/v${VERSION}/oras_${VERSION}_linux_amd64.tar.gz" tar -xzf oras_${VERSION}_linux_amd64.tar.gz sudo mv oras /usr/local/bin/
- name: Generate and attach SBOM run: | # Installer Syft curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# Générer SBOM syft ghcr.io/${{ github.repository }}:${{ github.sha }} \ -o spdx-json > sbom.spdx.json
# Attacher à l'image oras attach \ --artifact-type application/spdx+json \ --annotation "github.sha=${{ github.sha }}" \ --annotation "github.workflow=${{ github.workflow }}" \ ghcr.io/${{ github.repository }}:${{ github.sha }} \ sbom.spdx.jsonBonnes pratiques
Section intitulée « Bonnes pratiques »1. Utilisez des digests pour la production
Section intitulée « 1. Utilisez des digests pour la production »Les tags sont mutables (peuvent être réassignés). Pour garantir la reproductibilité, utilisez toujours des digests en production :
❌ Mauvais :
oras pull ghcr.io/mon-org/config:latest✅ Bon :
oras pull ghcr.io/mon-org/config@sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5f2. Documentez avec des annotations
Section intitulée « 2. Documentez avec des annotations »Ajoutez toujours des annotations pour documenter vos artefacts :
oras push ghcr.io/mon-org/config/app:v1.0 \ --annotation "org.opencontainers.image.created=$(date -Iseconds)" \ --annotation "org.opencontainers.image.authors=team-platform@example.com" \ --annotation "org.opencontainers.image.source=https://github.com/mon-org/configs" \ --annotation "org.opencontainers.image.version=v1.0" \ --annotation "org.opencontainers.image.revision=$GIT_COMMIT" \ --annotation "environment=production" \ config.yaml3. Définissez des types d’artefacts personnalisés
Section intitulée « 3. Définissez des types d’artefacts personnalisés »Ne laissez pas tous vos artefacts avec application/vnd.unknown.artifact.v1.
Définissez des types spécifiques :
# SBOM--artifact-type application/spdx+json
# Configuration Helm--artifact-type application/vnd.cncf.helm.config.v1+json
# Rapport de scan--artifact-type application/vnd.aquasec.trivy.report.v1+json
# Signature Cosign--artifact-type application/vnd.dev.cosign.simplesigning.v1+json4. Automatisez le nettoyage
Section intitulée « 4. Automatisez le nettoyage »Configurez des politiques de rétention pour éviter l’accumulation d’artefacts obsolètes :
- GHCR : Package settings → Retention policy
- ACR : Retention policies (days)
- GCR : Lifecycle policies
5. Utilisez le cache local
Section intitulée « 5. Utilisez le cache local »ORAS supporte un cache local pour accélérer les pulls répétés :
export ORAS_CACHE=~/.oras/cacheoras pull ghcr.io/mon-org/config:v1.0 # Mise en cacheoras pull ghcr.io/mon-org/config:v1.0 # Depuis le cache (rapide)Dépannage
Section intitulée « Dépannage »Erreur : “connection refused”
Section intitulée « Erreur : “connection refused” »Error: Head "http://localhost:5000/v2/...": dial tcp 127.0.0.1:5000: connect: connection refusedSolution : La registry n’est pas démarrée. Pour une registry locale :
docker run -d -p 5000:5000 --name registry registry:2Puis ajoutez --plain-http :
oras push --plain-http localhost:5000/test:v1 fichier.txtErreur : “unauthorized”
Section intitulée « Erreur : “unauthorized” »Error: HEAD https://ghcr.io/v2/user/repo/manifests/v1: unauthorized: authentication requiredSolution : Vous devez vous authentifier :
echo $GITHUB_TOKEN | oras login ghcr.io -u username --password-stdinErreur : “unsupported media type”
Section intitulée « Erreur : “unsupported media type” »Certaines registries anciennes ne supportent pas tous les types de médias OCI.
Solution : Utilisez --image-spec v1.0 pour forcer le format Docker v2 :
oras push --image-spec v1.0 registry.example.com/repo:v1 fichier.txtPerformances lentes
Section intitulée « Performances lentes »Solution : Ajustez le niveau de concurrence :
oras pull --concurrency 10 ghcr.io/mon-org/config:v1.0Sauvegarder et restaurer des artefacts (v1.3.0)
Section intitulée « Sauvegarder et restaurer des artefacts (v1.3.0) »La version 1.3.0 introduit deux nouvelles commandes pour sauvegarder vos artefacts localement au format OCI Image Layout.
Sauvegarder un artefact
Section intitulée « Sauvegarder un artefact »# Sauvegarder vers un répertoireoras backup --output ./backup-dir ghcr.io/mon-org/config:v1.0
# Sauvegarder vers une archive taroras backup --output backup.tar ghcr.io/mon-org/config:v1.0
# Inclure les artefacts attachés (SBOM, signatures)oras backup --output ./backup-dir --include-referrers ghcr.io/mon-org/config:v1.0
# Sauvegarder plusieurs tagsoras backup --output ./backup-dir ghcr.io/mon-org/config:v1.0,v1.1,v1.2Restaurer vers une registry
Section intitulée « Restaurer vers une registry »# Restaurer depuis un répertoireoras restore --from ./backup-dir ghcr.io/mon-org/config:v1.0
# Restaurer depuis une archive taroras restore --from backup.tar ghcr.io/mon-org/config:v1.0Cas d’usage :
- Disaster recovery : sauvegardes régulières des artefacts critiques
- Migration : déplacer des artefacts entre environnements déconnectés
- Archivage : conserver des versions pour conformité réglementaire
À retenir
Section intitulée « À retenir »- ORAS stocke n’importe quel fichier dans une registry OCI sans Docker
- Quatre opérations principales :
push,pull,attach,discover - Les attachements créent des graphes d’artefacts (SBOM → image)
- Les annotations documentent les artefacts avec des métadonnées
backup/restore(v1.3.0) permettent les sauvegardes locales- Utilisez les digests (immuables) plutôt que les tags en production
Prochaines étapes
Section intitulée « Prochaines étapes »Plus d’infos
Section intitulée « Plus d’infos »- Site officiel ORAS
- Documentation officielle
- GitHub ORAS
- Spécification OCI Artifacts
- Registries compatibles
Questions fréquentes
Section intitulée « Questions fréquentes »ORAS vs Docker
Docker est conçu pour les images conteneurs uniquement. ORAS manipule tout type d'artefact dans une registry OCI.| Aspect | Docker | ORAS |
|---|---|---|
| Type de contenu | Images conteneurs | Tout artefact (fichiers, SBOM, signatures) |
| Démon requis | Oui | Non |
| Media types | Fixés | Personnalisables |
| Cas d'usage | Build/run containers | Supply chain, config, artefacts |
Installation de ORAS
# Binaire GitHub (Linux)
VERSION="1.3.0"
curl -LO "https://github.com/oras-project/oras/releases/download/v${VERSION}/oras_${VERSION}_linux_amd64.tar.gz"
tar -xzf oras_${VERSION}_linux_amd64.tar.gz
sudo mv oras /usr/local/bin/
Autres options :- Homebrew :
brew install oras - asdf-vm :
asdf plugin add oras && asdf install oras 1.3.0 - Docker :
docker run -it ghcr.io/oras-project/oras:v1.3.0 help
Push de fichiers
# Fichier simple
oras push ghcr.io/user/config:v1 config.yaml
# Avec media type explicite
oras push ghcr.io/user/config:v1 config.yaml:application/vnd.config.yaml
# Plusieurs fichiers
oras push ghcr.io/user/bundle:v1 \
config.yaml:application/vnd.config \
README.md:text/markdown
Le media type aide les outils à identifier et traiter correctement le contenu.Attacher des artefacts
# Attacher un SBOM
oras attach ghcr.io/user/app:v1 \
--artifact-type application/spdx+json \
sbom.spdx.json
# Attacher une signature Cosign
oras attach ghcr.io/user/app:v1 \
--artifact-type application/vnd.dev.cosign.signature.v1+json \
signature.json
# Lister les artefacts attachés
oras discover ghcr.io/user/app:v1
Le --artifact-type est obligatoire pour attach.Pull d'artefacts
# Pull dans le répertoire courant
oras pull ghcr.io/user/config:v1
# Spécifier un dossier de destination
oras pull ghcr.io/user/config:v1 -o ./downloads/
# Pull d'un artefact attaché (par digest)
oras pull ghcr.io/user/app@sha256:abc123...
ORAS crée les fichiers avec leurs noms d'origine.Backup et Restore (v1.3.0+)
# Sauvegarder un artefact
oras backup ghcr.io/user/config:v1 -o backup-config.tar
# Restaurer vers une autre registry
oras restore backup-config.tar registry.local/config:v1
Cas d'usage :- Migrations entre registries
- Backups hors-ligne
- Environnements air-gapped
- Archivage de versions critiques
Intégration CI/CD
GitHub Actions :- name: Install ORAS
run: |
VERSION=1.3.0
curl -LO "https://github.com/oras-project/oras/releases/download/v${VERSION}/oras_${VERSION}_linux_amd64.tar.gz"
tar -xzf oras_${VERSION}_linux_amd64.tar.gz
sudo mv oras /usr/local/bin/
- name: Push config
run: |
echo ${{ secrets.GITHUB_TOKEN }} | oras login ghcr.io -u ${{ github.actor }} --password-stdin
oras push ghcr.io/${{ github.repository }}/config:${{ github.sha }} config.yaml
GitLab CI :image: ghcr.io/oras-project/oras:v1.3.0
Annotations OCI
# Annotations au push
oras push ghcr.io/user/config:v1 config.yaml \
--annotation org.opencontainers.image.authors="DevOps Team" \
--annotation org.opencontainers.image.version="1.0.0" \
--annotation custom.build.date="2026-01-23"
# Annotations au attach
oras attach ghcr.io/user/app:v1 \
--artifact-type application/spdx+json \
--annotation org.opencontainers.image.created="2026-01-23" \
sbom.json
Les annotations sont stockées dans le manifest OCI.Digest vs Tag
# Obtenir le digest
oras manifest fetch ghcr.io/user/config:v1 --descriptor | jq -r '.digest'
# Référencer par digest (immuable)
oras pull ghcr.io/user/config@sha256:abc123...
| Aspect | Tag | Digest |
|---|---|---|
| Mutable | Oui | Non |
| Reproductible | Non | Oui |
| Sécurité | Risque de remplacement | Garanti |
Registries compatibles
ORAS fonctionne avec toute registry OCI 1.1 :| Registry | Support ORAS | Referrers API |
|---|---|---|
| Harbor 2.9+ | ✅ | ✅ |
| GHCR | ✅ | ✅ |
| Azure ACR | ✅ | ✅ |
| AWS ECR | ✅ | Partiel |
| Google AR | ✅ | ✅ |
| Docker Hub | ✅ | ✅ |
| Quay.io | ✅ | ✅ |
| GitLab CR | ✅ | ✅ |
oras discover.