> For the complete documentation index, see [llms.txt](https://stablebuild.gitbook.io/stablebuild-documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://stablebuild.gitbook.io/stablebuild-documentation/docs/fr/tutorials/protecting-your-keys-in-public-docker-containers.md).

# Protéger vos clés dans les conteneurs Docker publics

L'accès aux miroirs et aux caches de StableBuild est contrôlé par des clés d'API indiquées directement dans votre Dockerfile. Dans l'exemple ci-dessous, votre clé d'API est à la fois utilisée dans le `FROM` et définie comme `ARG`, que `sb-apt.sh` utilise pour s'authentifier auprès du dépôt de paquets.

```docker
FROM stablebuild-my-secret-api-key.dockermirror.stablebuild.com/ubuntu:focal-20231003

ARG SB_API_KEY=stablebuild-my-secret-api-key
ARG APT_PIN_DATE=2023-11-10T10:40:01Z

COPY ./sb-apt.sh /opt/sb-apt.sh
RUN bash /opt/sb-apt.sh load-apt-sources ubuntu

RUN apt update && apt install -y curl
```

Il est important de garder ces clés confidentielles, car elles servent à facturer le trafic de votre compte. Si vous constatez des pics de trafic inhabituels, consultez les journaux de consommation bruts pour vérifier qu'une clé n'a pas fuité. Vous pouvez renouveler vos clés via **Tableau de bord > Clés**.

### Retrouver ces clés dans votre image Docker

Indiquer les clés dans votre Dockerfile ne pose pas de problème si vous construisez des conteneurs Docker à usage interne, mais devient problématique si vous voulez les publier publiquement (sur Docker Hub ou sur un autre registre public). Quiconque télécharge le conteneur peut examiner les layers qui le composent, et votre clé d'API y figurera. De plus, le build peut écrire dans votre conteneur des fichiers contenant votre clé d'API. Dans l'exemple ci-dessus, par exemple, la clé est visible à la fois lors de l'inspection des layers et de façon persistante sur le système de fichiers.

Pour le vérifier, construisez d'abord le conteneur ci-dessus avec :

```
docker build -t unsecure-demo .
```

Puis inspectez les layers avec [dive](https://github.com/wagoodman/dive) pour constater que la clé est bien présente :

```
dive unsecure-demo
```

<figure><img src="https://3692775141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fq2rcaL74coCkWoi6NPK7%2Fuploads%2Fgit-blob-2754bad845c46433223f56f5cebf41634529d797%2Fimage.png?alt=media" alt=""><figcaption><p>Clé divulguée par les layers du conteneur (inspectés avec <code>dive</code>)</p></figcaption></figure>

Vous pouvez également retrouver la clé sur le système de fichiers. Lancez le conteneur avec un shell interactif :

```
docker run --rm -it unsecure-demo bash
```

Et vous constaterez que votre clé est conservée sur le disque :

```
grep -rio --exclude-dir={ece,pytorch,sys,proc} 'stablebuild-my-secret-api-key' /
find / -name "*stablebuild-my-secret-api-key*"
```

<figure><img src="https://3692775141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fq2rcaL74coCkWoi6NPK7%2Fuploads%2Fgit-blob-205b93b0e9ac5978fdf1807a8414cecfb73e0ee5%2Fimage%20(1).png?alt=media" alt=""><figcaption><p>Clé divulguée par des fichiers du conteneur</p></figcaption></figure>

### Protéger vos clés

Protégeons maintenant ces clés. D'abord, notre image de base. La ligne `FROM` :

```docker
FROM stablebuild-my-secret-api-key.dockermirror.stablebuild.com/ubuntu:focal-20231003
```

n'est divulguée ni dans les layers (visibles avec dive) ni sur le système de fichiers, mais elle figure dans les métadonnées de l'image. Pour y remédier, vous pouvez créer une image Docker multi-stage :

```docker
FROM stablebuild-my-secret-api-key.dockermirror.stablebuild.com/ubuntu:focal-20231003 AS base
FROM scratch
COPY --from=base / /
```

#### Empêcher la fuite de la clé par les layers

Attaquons-nous ensuite à la fuite de la clé par les layers :

```
ARG SB_API_KEY=stablebuild-my-secret-api-key
```

Plutôt que de coder la clé en dur, vous pouvez utiliser les [secrets de build Docker](/stablebuild-documentation/docs/fr/mirrors-and-caches/docker-mirror.md). Les secrets sont montés au moment du build et ne sont pas inclus dans l'image finale. Vous pouvez écrire ceci :

```docker
FROM stablebuild-my-secret-api-key.dockermirror.stablebuild.com/ubuntu:focal-20231003 AS base
FROM scratch
COPY --from=base / /

ARG APT_PIN_DATE=2023-11-10T10:40:01Z

COPY ./sb-apt.sh /opt/sb-apt.sh

# Monte le secret « sb-api-key » dans le fichier « /kaniko/sb-api-key.txt »
# Puis charge le contenu du fichier dans la variable d'environnement SB_API_KEY
RUN --mount=type=secret,id=sb-api-key,target=/kaniko/sb-api-key.txt \
    SB_API_KEY=$(cat /kaniko/sb-api-key.txt) bash /opt/sb-apt.sh load-apt-sources ubuntu

RUN apt update && apt install -y curl
```

Si vous construisez ce conteneur avec :

```
export SB_API_KEY=stablebuild-my-secret-api-key
docker build -t demo-build-secrets --secret id=sb-api-key,env=SB_API_KEY .
```

puis que vous inspectez de nouveau l'image avec dive :

```
dive demo-build-secrets
```

la clé codée en dur a disparu :

<figure><img src="https://3692775141-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fq2rcaL74coCkWoi6NPK7%2Fuploads%2Fgit-blob-98c12588612356bba96ca2f21018113073ce520b%2Fimage%20(2).png?alt=media" alt=""><figcaption><p>La clé n'est plus divulguée dans les layers de l'image Docker</p></figcaption></figure>

#### Empêcher la fuite de la clé sur le système de fichiers

Pour éviter de divulguer les clés via le système de fichiers, vous devez nettoyer tout fichier où la clé est conservée **dans la même étape** que celle où vous l'utilisez. Sinon, quelqu'un peut inspecter le système de fichiers au niveau d'un layer donné et récupérer votre clé par ce biais.

En inspectant le système de fichiers plus haut, nous avons constaté que la clé figure dans `/etc/apt/sources.list` (écrit par `sb-apt.sh`) et qu'elle apparaît dans le nom des fichiers présents dans `/var/lib/apt/lists/` (les fichiers de cache d'apt). Nous pouvons réécrire notre Dockerfile ainsi :

```docker
FROM stablebuild-my-secret-api-key.dockermirror.stablebuild.com/ubuntu:focal-20231003 AS base
FROM scratch
COPY --from=base / /

ARG APT_PIN_DATE=2023-11-10T10:40:01Z

COPY ./sb-apt.sh /opt/sb-apt.sh

# Sauvegarde le /etc/apt/sources.list d'origine (restauré plus loin)
RUN cp /etc/apt/sources.list /etc/apt/sources.list.bak

# 1. Monte le secret « sb-api-key » dans le fichier « /kaniko/sb-api-key.txt »
# 2. Charge le contenu du fichier dans la variable d'environnement SB_API_KEY, puis lance `sb-apt.sh`
#    pour charger les sources : cela crée « /etc/apt/sources.list » avec la clé sur le système de fichiers
# 3. Fait le apt update && apt install dans une seule commande run (pour que /etc/apt/sources.list ne soit pas conservé dans un layer)
# 4. Recopie le sources.list d'origine
# 5. Supprime les fichiers de cache d'apt qui contiennent la clé dans /var/lib/apt/lists/
RUN --mount=type=secret,id=sb-api-key,target=/kaniko/sb-api-key.txt \
    SB_API_KEY=$(cat /kaniko/sb-api-key.txt) bash /opt/sb-apt.sh load-apt-sources ubuntu && \
    apt update && \
    apt install -y curl && \
    cp /etc/apt/sources.list.bak /etc/apt/sources.list && \
    rm -r /var/lib/apt/lists/
```

Lorsque vous construisez ce conteneur avec :

```
export SB_API_KEY=stablebuild-my-secret-api-key
docker build -t demo-clean-fs --secret id=sb-api-key,env=SB_API_KEY .
```

puis que vous lancez le conteneur et fouillez le système de fichiers, il n'y a plus aucun résultat :

```bash
$ docker run --rm -it demo-clean-fs bash
root@012e063d3d45:/# grep -rio --exclude-dir={ece,pytorch,sys,proc} 'stablebuild-my-secret-api-key' /
# aucun résultat
root@012e063d3d45:/# find / -name "*stablebuild-my-secret-api-key*"
# aucun résultat
```

#### Vérification finale : inspecter l'image exportée

Pour une dernière vérification, nous pouvons exporter l'image complète sur le disque (avec tous ses layers et ses métadonnées) et y rechercher une dernière fois notre clé d'API :

```bash
$ mkdir -p out && \
    docker save -o out.tar demo-clean-fs && \
    mkdir -p out && \
    tar -xvf out.tar -C out/
    
$ cd out
$ grep stablebuild-my-secret-api-key -R .
# aucun résultat !
```

Parfait 🎉 ! Votre conteneur ne contient plus votre clé, et vous pouvez le publier en toute sécurité sur Docker Hub ou sur un autre registre public.

Ce qui précède fonctionne pour le dépôt de paquets Ubuntu ; si vous utilisez d'autres miroirs ou caches, il vous faudra inspecter manuellement les layers et le système de fichiers pour vous assurer qu'aucune clé ne fuite. Cela reste relativement simple avec dive et un shell interactif ouvert dans le conteneur.

### Utiliser des secrets de build avec Kaniko

Si vous utilisez Kaniko pour construire vos conteneurs, les secrets de build ne sont pas disponibles. Vous pouvez toutefois tirer parti du fait que le dossier `/kaniko` de votre système de fichiers est partagé entre le conteneur Kaniko et le processus de build. Vous pouvez donc écrire ceci dans votre Dockerfile :

```docker
RUN --mount=type=secret,id=sb-api-key,target=/kaniko/sb-api-key.txt \
    SB_API_KEY=$(cat /kaniko/sb-api-key.txt) bash /opt/sb-apt.sh load-apt-sources ubuntu
```

Ici, la cible `/kaniko/sb-api-key.txt` se trouve sur un système de fichiers partagé : il vous suffit donc d'écrire la clé à cet emplacement depuis le conteneur Kaniko, avant d'appeler `/kaniko/executor` :

```bash
echo -n "stablebuild-my-secret-api-key" > /kaniko/sb-api-key.txt && \
    /kaniko/executor --dockerfile=./Dockerfile ...
```

Vous pouvez le faire, par exemple, en définissant le point d'entrée du conteneur `gcr.io/kaniko-project/executor` sur `sh` et ses arguments sur `[ "-c", "echo -n 'stablebuild-my-secret-api-key' > /kaniko/sb-api-key.txt && /kaniko/executor --dockerfile=./Dockerfile" ]`.
