Aller au contenu

ORAS : stockez et distribuez vos artefacts dans des registries OCI

Mise à jour :

Logo ORAS

Les registries OCI ne servent plus uniquement à stocker des images de conteneurs. Vous pouvez désormais y stocker n’importe quel type d’artefact : fichiers de configuration, charts Helm, SBOM (Software Bill of Materials), signatures de sécurité, binaires, documentation… ORAS (OCI Registry As Storage) est l’outil de référence pour manipuler ces artefacts directement dans les registries OCI, sans avoir besoin d’installer Docker ou Podman.

Qu’est-ce qu’ORAS ?

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

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

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+json pour 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

Installation sur Linux avec ASDF

ASDF-VM est un gestionnaire de versions polyvalent qui peut être utilisé pour installer ORAS sur Linux.

Terminal window
asdf plugin add oras
asdf install oras latest
asdf global oras latest

Vérifiez l’installation :

Terminal window
asdf current oras
oras 1.3.0 /home/user/.tool-versions

Installation sur macOS avec Homebrew

Si vous utilisez macOS et préférez Homebrew pour gérer vos logiciels :

Terminal window
brew install oras

Installation manuelle (toutes plateformes)

Téléchargez le binaire depuis la page des releases GitHub :

Terminal window
# Linux AMD64
VERSION="1.3.0"
curl -LO "https://github.com/oras-project/oras/releases/download/v${VERSION}/oras_${VERSION}_linux_amd64.tar.gz"
mkdir -p oras-install/
tar -zxf oras_${VERSION}_*.tar.gz -C oras-install/
sudo mv oras-install/oras /usr/local/bin/
rm -rf oras_${VERSION}_*.tar.gz oras-install/

Vérification de l’installation

Une fois l’installation terminée, vérifiez qu’ORAS est correctement installé :

Terminal window
oras version

Vous devriez voir une sortie similaire à :

Version: 1.3.0
Go version: go1.25.0
OS/Arch: linux/amd64
Git commit: 40530fe4c68e5825b868cd874bd46fc0cdd0f432
Git tree state: clean

Premiers pas avec ORAS

Préparer des fichiers de test

Pour illustrer le fonctionnement d’ORAS, créons quelques fichiers d’exemple dans /tmp :

Terminal window
cd /tmp
mkdir oras-demo
cd oras-demo
# Créer un fichier de configuration Nginx
cat > nginx.conf << 'EOF'
# Configuration Nginx pour ORAS
server {
listen 80;
server_name example.com;
root /var/www/html;
location / {
try_files $uri $uri/ =404;
}
}
EOF
# Créer un fichier README
cat > 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 documentation
EOF
# Vérifier les fichiers créés
ls -lh

Ré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.md

Pousser des artefacts dans une registry

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 :

Terminal window
oras login harbor.example.com -u votre_username
Password:
Login Succeeded

Les identifiants sont stockés dans ~/.docker/config.json (même emplacement que Docker).

Stocker un artefact simple

La commande push envoie un ou plusieurs fichiers vers une registry. Voici la syntaxe de base :

Terminal window
oras push [options] <registry>/<repository>:<tag> <fichier1> <fichier2> ...

Exemples :

  1. Pousser un seul fichier

    Terminal window
    cd /tmp/oras-demo
    oras push ghcr.io/votre-username/config/nginx:v1.0 nginx.conf

    Explication de la commande :

    • oras push : commande pour envoyer des artefacts
    • ghcr.io/votre-username/config/nginx:v1.0 : référence complète
      • ghcr.io : registry (GitHub Container Registry)
      • votre-username : votre organisation/utilisateur
      • config/nginx : nom du repository (chemin virtuel)
      • v1.0 : tag (version)
    • nginx.conf : fichier à pousser

    Sortie attendue :

    Uploading df5e6c1d0a3b nginx.conf
    Uploaded df5e6c1d0a3b nginx.conf
    Pushed [registry] ghcr.io/votre-username/config/nginx:v1.0
    Digest: sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5f

    Le 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.

  2. Pousser plusieurs fichiers

    Terminal window
    oras push ghcr.io/votre-username/config/nginx:v1.1 \
    nginx.conf \
    README.md

    Les deux fichiers sont uploadés et associés au même manifest.

  3. Spécifier un type de média personnalisé

    Par défaut, ORAS utilise le type application/vnd.oci.image.layer.v1.tar pour les fichiers. Vous pouvez spécifier un type personnalisé :

    Terminal window
    oras push ghcr.io/votre-username/config/nginx:v1.2 \
    nginx.conf:application/vnd.example.nginx.conf \
    README.md:text/markdown

    Le format est : <fichier>:<type-de-média>

  4. Ajouter des annotations

    Les annotations sont des métadonnées ajoutées au manifest pour documenter l’artefact :

    Terminal window
    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.md

    Ces 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

Cas particuliers :

  1. Registry locale non sécurisée (HTTP)

    Si vous testez avec une registry locale (par exemple, localhost:5000), utilisez l’option --plain-http :

    Terminal window
    oras push --plain-http localhost:5000/config/nginx:v1 nginx.conf
  2. Registry avec certificat auto-signé

    Pour une registry avec un certificat SSL auto-signé, utilisez --insecure :

    Terminal window
    oras push --insecure myregistry.local:5000/config/nginx:v1 nginx.conf

Tirer des artefacts depuis une registry

Télécharger un artefact

La commande pull télécharge les fichiers d’un artefact dans le répertoire courant :

Terminal window
# Créer un répertoire pour le test
mkdir -p /tmp/oras-test-pull
cd /tmp/oras-test-pull
# Tirer l'artefact
oras pull ghcr.io/votre-username/config/nginx:v1.3

Sortie attendue :

Downloading df5e6c1d0a3b nginx.conf
Downloaded df5e6c1d0a3b nginx.conf
Downloading a8f3d2e1b4c5 README.md
Downloaded a8f3d2e1b4c5 README.md
Pulled [registry] ghcr.io/votre-username/config/nginx:v1.3
Digest: sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5f

Vérifiez que les fichiers ont été téléchargés :

Terminal window
ls -lh

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 :

Terminal window
oras pull -o /tmp/mon-config ghcr.io/votre-username/config/nginx:v1.3

Tirer par digest (immuable)

Pour garantir que vous récupérez exactement la version attendue, utilisez le digest au lieu du tag :

Terminal window
oras pull ghcr.io/votre-username/config/nginx@sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5f

Le 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

Si l’artefact est multi-plateforme (par exemple, binaires compilés pour différentes architectures), spécifiez la plateforme :

Terminal window
oras pull --platform linux/arm64 ghcr.io/votre-username/binaries/app:v2.0

Explorer les artefacts

Récupérer le manifest

Le manifest est le fichier JSON qui décrit l’artefact. Pour le visualiser :

Terminal window
oras manifest fetch ghcr.io/votre-username/config/nginx:v1.3 --pretty

Exemple 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 fichier
    • size : taille en octets
    • annotations.org.opencontainers.image.title : nom du fichier
  • annotations : métadonnées globales de l’artefact

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 :

Terminal window
oras manifest fetch ghcr.io/votre-username/config/nginx:v1.3 --descriptor

Sortie :

{
"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

Testons avec l’image Alpine sur Docker Hub pour voir comment ORAS interagit avec des images de conteneurs classiques :

Terminal window
oras manifest fetch docker.io/library/alpine:latest --descriptor

Sortie :

{
"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 :

Terminal window
oras manifest fetch docker.io/library/alpine:latest --pretty | head -50

Cela affiche toutes les plateformes disponibles (amd64, arm64, arm/v6, etc.) avec leurs annotations respectives.

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

  1. Signature : attacher une signature Cosign à une image
  2. SBOM : attacher un inventaire de composants (Syft) à une image
  3. Scan de vulnérabilités : attacher un rapport Trivy/Grype à une image
  4. Attestation : attacher une preuve de build reproductible (SLSA)
  5. Documentation : attacher les release notes à une version

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 :

  1. Créer le rapport d’audit

    Terminal window
    cd /tmp/oras-demo
    cat > 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
  2. Attacher le rapport à la configuration

    Terminal window
    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.json

    Explication :

  • --artifact-type : type personnalisé pour le rapport d’audit
  • --annotation : métadonnées sur le scan
  • ghcr.io/votre-username/config/nginx:v1.3 : artefact parent (la config Nginx)
  • security-audit.json : fichier à attacher

Sortie :

Uploading a1b2c3d4e5f6 security-audit.json
Uploaded a1b2c3d4e5f6 security-audit.json
Attached to [registry] ghcr.io/votre-username/config/nginx:v1.3
Digest: sha256:8e7d6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7

L’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

Pour lister tous les artefacts attachés à un artefact parent, utilisez oras discover :

Terminal window
oras discover ghcr.io/votre-username/config/nginx:v1.3

Sortie en arbre :

ghcr.io/votre-username/config/nginx:v1.3
└── application/vnd.example.security.audit.v1+json
└── sha256:8e7d6f5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b7

Filtrer par type d’artefact

Si vous avez plusieurs types d’artefacts attachés (SBOM, signature, scan), filtrez par type :

Terminal window
oras discover \
--artifact-type application/vnd.example.security.audit.v1+json \
ghcr.io/votre-username/config/nginx:v1.3

Afficher en format JSON

Pour une sortie structurée exploitable par des scripts :

Terminal window
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

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

Terminal window
oras copy \
ghcr.io/votre-username/config/nginx:v1.3 \
myregistry.azurecr.io/config/nginx:v1.3

ORAS copie :

  • Le manifest
  • Tous les layers (fichiers)
  • Les annotations

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) :

Terminal window
oras copy -r \
ghcr.io/votre-username/config/nginx:v1.3 \
myregistry.azurecr.io/config/nginx:v1.3

Maintenant, le rapport d’audit attaché sera également copié vers la registry de destination.

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

Terminal window
# Récupérer le manifest
oras manifest fetch ghcr.io/votre-username/config/nginx:v1.3 > manifest.json
# Pousser avec un nouveau tag
oras manifest push \
ghcr.io/votre-username/config/nginx:latest \
manifest.json

Méthode 2 : Utiliser oras copy

Plus simple :

Terminal window
oras copy \
ghcr.io/votre-username/config/nginx:v1.3 \
ghcr.io/votre-username/config/nginx:latest

Les 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 :

Terminal window
oras copy --from-plain-http --to-plain-http \
localhost:5000/config/nginx:v1.3 \
localhost:5000/config/nginx:latest

:::

Supprimer des artefacts

Supprimer par tag

Terminal window
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

Pour supprimer définitivement un artefact (et potentiellement ses layers si non-référencés) :

Terminal window
oras manifest delete ghcr.io/votre-username/config/nginx@sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5f

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 :

Terminal window
registry garbage-collect /etc/docker/registry/config.yml

Cas d’usage pratiques

1. Versionner les configurations Kubernetes

Au lieu de gérer les configurations dans Git uniquement, vous pouvez les versionner dans une registry OCI :

Terminal window
# Pousser les manifests Kubernetes
oras 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 registry
oras pull ghcr.io/mon-org/k8s-configs/frontend:v2.5.0
kubectl 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

Utilisez Syft pour générer un SBOM et attachez-le à l’image :

Terminal window
# Générer le SBOM
syft ghcr.io/mon-org/app:v1.0 -o spdx-json > sbom.spdx.json
# Attacher le SBOM à l'image
oras attach \
--artifact-type application/spdx+json \
--annotation "tool=syft" \
--annotation "format=spdx" \
ghcr.io/mon-org/app:v1.0 \
sbom.spdx.json
# Vérifier
oras discover ghcr.io/mon-org/app:v1.0

Maintenant, chaque image a son SBOM associé, accessible via oras discover.

3. Distribuer des binaires multi-plateformes

ORAS supporte les artefacts multi-plateformes (comme les images Docker multi-arch) :

Terminal window
# Pousser pour Linux AMD64
oras push --artifact-platform linux/amd64 \
ghcr.io/mon-org/cli:v3.0 \
app-linux-amd64
# Pousser pour Linux ARM64
oras push --artifact-platform linux/arm64 \
ghcr.io/mon-org/cli:v3.0 \
app-linux-arm64
# Tirer selon la plateforme
oras pull --platform linux/arm64 ghcr.io/mon-org/cli:v3.0

Le bon binaire est téléchargé automatiquement selon la plateforme spécifiée.

4. Pipeline CI/CD : résultats de tests

Stockez les rapports de tests dans la registry pour les associer à chaque build :

Terminal window
# Après l'exécution des tests
oras 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.html

Les développeurs peuvent récupérer les rapports de tests associés à n’importe quel commit :

Terminal window
oras discover ghcr.io/mon-org/app:build-a1b2c3d
oras pull ghcr.io/mon-org/app@sha256:... # digest du rapport

Intégration dans les Pipelines CI/CD

GitLab CI

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.json

GitHub Actions

name: 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.json

Bonnes pratiques

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 :

Terminal window
oras pull ghcr.io/mon-org/config:latest

Bon :

Terminal window
oras pull ghcr.io/mon-org/config@sha256:fc35b2696484ac4f8f2c6831efd541c64f91012fcadda5554ac64fc008802e5f

2. Documentez avec des annotations

Ajoutez toujours des annotations pour documenter vos artefacts :

Terminal window
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.yaml

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 :

Terminal window
# 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+json

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

ORAS supporte un cache local pour accélérer les pulls répétés :

Terminal window
export ORAS_CACHE=~/.oras/cache
oras pull ghcr.io/mon-org/config:v1.0 # Mise en cache
oras pull ghcr.io/mon-org/config:v1.0 # Depuis le cache (rapide)

Dépannage

Erreur : “connection refused”

Error: Head "http://localhost:5000/v2/...": dial tcp 127.0.0.1:5000: connect: connection refused

Solution : La registry n’est pas démarrée. Pour une registry locale :

Terminal window
docker run -d -p 5000:5000 --name registry registry:2

Puis ajoutez --plain-http :

Terminal window
oras push --plain-http localhost:5000/test:v1 fichier.txt

Erreur : “unauthorized”

Error: HEAD https://ghcr.io/v2/user/repo/manifests/v1: unauthorized: authentication required

Solution : Vous devez vous authentifier :

Terminal window
echo $GITHUB_TOKEN | oras login ghcr.io -u username --password-stdin

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 :

Terminal window
oras push --image-spec v1.0 registry.example.com/repo:v1 fichier.txt

Performances lentes

Solution : Ajustez le niveau de concurrence :

Terminal window
oras pull --concurrency 10 ghcr.io/mon-org/config:v1.0

Conclusion

ORAS transforme les registries OCI en systèmes de stockage universels pour n’importe quel type d’artefact. Sa simplicité (pas besoin de Docker/Podman), sa légèreté (binaire unique) et sa puissance (attachements, annotations, multi-plateforme) en font l’outil idéal pour distribuer et versionner des artefacts dans des environnements cloud-natifs.

Points clés à retenir :

  • Pas de Docker nécessaire : ORAS est un binaire autonome
  • Artefacts génériques : n’importe quel fichier peut être stocké dans une registry OCI
  • Attachements : créez des graphes d’artefacts (SBOM, signatures, scans)
  • Annotations : métadonnées riches pour documenter les artefacts
  • Intégration CI/CD : automatisez la publication et l’attachement d’artefacts
  • Multi-plateforme : distribuez des binaires pour différentes architectures

ORAS s’inscrit parfaitement dans une chaîne d’outils DevSecOps moderne, notamment avec Syft pour les SBOM, Trivy pour les scans, et Cosign pour les signatures.

Plus d’infos