Après l’échec d’un pipeline, les équipes téléversent généralement l’intégralité des journaux, des pièces jointes de test et des bundles de résultats vers un espace de stockage partagé, afin qu’un autre ingénieur puisse reprendre l’analyse. Le véritable danger n’est pas la ligne bien visible TOKEN=, mais les arguments de commande affichés par le mode de débogage, les en-têtes de requête, les chemins temporaires de signature et les instantanés de l’environnement joints par le code de test. Lorsqu’un Mac dans le cloud exécute plusieurs tâches sur une longue période, ces données peuvent aussi se retrouver dans les caches et les archives. L’épuration des journaux doit donc intervenir à trois niveaux : à la source de la sortie, dans le pipeline et au niveau de la barrière de téléversement.
Commencer par cartographier le flux des journaux
Ne commencez pas par écrire une expression régulière censée couvrir tous les textes. Identifiez d’abord les points d’entrée des informations, les processus qu’elles traversent et leur emplacement de stockage final.
| Point d’entrée | Mode de fuite courant | Traitement prioritaire |
|---|---|---|
| Shell | set -x affiche les variables après expansion |
Désactiver le traçage avant les étapes sensibles |
| Arguments de commande | Les clés et jetons apparaissent directement dans les arguments du processus | Utiliser un fichier temporaire aux droits restreints ou l’entrée standard |
| Variables d’environnement | Les scripts de diagnostic affichent l’environnement complet | N’afficher qu’une liste d’autorisation |
| Tests | Les en-têtes de requête et données de compte sont enregistrés dans les pièces jointes | Centraliser le nettoyage dans la couche d’utilitaires de test |
| Bundles de résultats | Les captures d’écran, journaux d’activité et fichiers de diagnostic sont téléversés ensemble | Analyser après l’exportation et avant la publication |
L’épuration ne peut pas sécuriser de nouveau un secret déjà divulgué. Dès qu’il est confirmé qu’une valeur réelle a atteint un journal susceptible d’être partagé, arrêtez la publication de cet artefact et renouvelez le secret selon son type.
Sur le nœud OakVM, créez un répertoire distinct pour chaque tâche et limitez les droits de lecture et d’écriture à l’utilisateur courant. Séparez les journaux, les bundles de résultats et les fichiers en attente de téléversement afin de ne pas mélanger les fichiers analysés avec leurs originaux.
umask 077
run_id="$(date -u +%Y%m%dT%H%M%SZ)-$$"
root="$HOME/ci-runs/$run_id"
mkdir -p "$root/raw" "$root/safe" "$root/results"
Fermer les voies de fuite à la source
Ne pas placer de secrets dans les arguments
Les arguments d’un processus peuvent être lus par des outils de diagnostic, des rapports de plantage ou des scripts lancés par le même utilisateur. Lors de l’appel d’un script interne de téléversement, n’utilisez pas --token "$TOKEN". Il est plus sûr de faire lire au script un fichier temporaire doté des permissions 600, puis de supprimer immédiatement ce fichier. Si l’outil accepte l’entrée standard, le secret peut également être transmis de cette manière.
Le traçage du shell doit être désactivé par défaut. S’il est réellement nécessaire d’observer des commandes ordinaires, ne l’activez que pendant une courte séquence qui ne manipule aucune variable sensible, puis exécutez set +x avant de charger les identifiants. N’affichez jamais directement l’environnement complet ; remplacez ces informations de diagnostic par une liste d’autorisation :
printf 'PATH=%s
' "$PATH"
printf 'DEVELOPER_DIR=%s
' "$DEVELOPER_DIR"
xcodebuild -version
sw_vers
Les chemins doivent eux aussi être traités comme des données sensibles. Les noms d’utilisateur, noms de code des projets et répertoires temporaires de signature peuvent révéler la structure de l’équipe. Avant de publier un journal, remplacez le répertoire racine de travail par $WORKSPACE, tout en conservant les noms de fichiers et les numéros de ligne afin de préserver la valeur diagnostique du journal.
Construire un pipeline d’épuration qui conserve les échecs
Les remplacements doivent cibler en priorité les valeurs réelles des secrets, et non se limiter à des noms de champs tels que password ou secret. La recherche de mots-clés produit facilement des faux positifs et ne détecte pas les jetons sans libellé. Le filtre ci-dessous lit les valeurs à masquer depuis un fichier aux droits restreints, puis les remplace de la plus longue à la plus courte afin qu’une valeur courte ne perturbe pas la détection d’une valeur plus longue.
import os
import sys
from pathlib import Path
secret_file = Path(os.environ["REDACT_FILE"])
values = [
line.rstrip("
")
for line in secret_file.read_text(encoding="utf-8").splitlines()
if line.strip()
]
values.sort(key=len, reverse=True)
for line in sys.stdin:
for value in values:
line = line.replace(value, "[REDACTED]")
sys.stdout.write(line)
Lors de l’exécution du build, conservez le véritable code de sortie de xcodebuild. Si seul le processus tee situé à la fin du pipeline est pris en compte, un build en échec risque d’être signalé à tort comme réussi.
#!/bin/bash
set -o pipefail
set +x
REDACT_FILE="$root/secrets.txt" \
xcodebuild \
-workspace App.xcworkspace \
-scheme App \
-configuration Release \
-resultBundlePath "$root/results/App.xcresult" \
build 2>&1 |
python3 ci/redact.py |
tee "$root/safe/build.log"
statuses=("${PIPESTATUS[@]}")
exit "${statuses[0]}"
secrets.txt doit disposer des permissions 600 et être supprimé par le hook de sortie de la tâche. Les clés privées multilignes ne se prêtent pas à un remplacement ligne par ligne. Il faut empêcher leur affichage dès la source et n’ajouter au fichier de masquage que des identifiants stables susceptibles d’apparaître dans du texte.
Analyser les bundles de résultats et les pièces jointes de test
La validation des journaux texte ne signifie pas que l’intégralité de la tâche peut être téléversée. Les bundles de résultats peuvent contenir des captures d’écran de test, des pièces jointes relatives aux échecs, des journaux d’activité et des informations de diagnostic. Commencez par les copier dans un répertoire isolé, exportez uniquement les éléments qui doivent réellement être partagés, puis analysez le répertoire d’exportation. Ne publiez pas par défaut les bundles de résultats complets.
Utiliser deux catégories de règles pour réduire les faux positifs
La première catégorie de règles recherche les véritables valeurs secrètes de la tâche en cours et bloque immédiatement la publication en cas de correspondance. La seconde détecte les structures à haut risque, comme les en-têtes d’autorisation, les délimiteurs de clés privées, les URL contenant des identifiants et les longues chaînes ressemblant à des jetons. Toute correspondance avec une règle structurelle doit faire l’objet d’un contrôle manuel. Ne considérez pas automatiquement chaque occurrence de token comme une fuite, car ce mot peut également figurer dans des noms de fichiers source ou des descriptions de tests.
Le rapport d’analyse ne doit contenir que le chemin du fichier, le numéro de ligne et l’identifiant de la règle. Ne recopiez pas le contenu détecté dans le rapport, au risque de l’exposer une nouvelle fois. Pour les pièces jointes binaires, commencez par identifier le type de fichier. Les fichiers qui ne peuvent pas être analysés de façon sûre doivent être exclus par défaut des artefacts partagés, plutôt que d’être extraits avec strings puis publiés directement.
Faire de l’épuration une barrière de publication
Une barrière facile à maintenir comprend au minimum quatre états : le code de sortie du build, l’analyse des valeurs exactes, la vérification des règles structurelles et la liste d’autorisation des artefacts. Tant que l’un de ces contrôles n’est pas terminé, l’étape de téléversement ne doit pas démarrer.
À la fin de chaque tâche, vérifiez les points suivants :
- le répertoire des données brutes reste accessible uniquement à l’utilisateur courant ;
- aucun répertoire racine de travail, en-tête d’autorisation ou secret réel ne subsiste dans les journaux ;
- le bundle de résultats ne contient aucune capture d’écran superflue, réponse réseau ni aucun instantané de l’environnement ;
- le manifeste de téléversement ne contient que des journaux épurés, les rapports nécessaires et les pièces jointes explicitement sélectionnées ;
- le script de nettoyage supprime les fichiers de secrets sans effacer les copies sûres encore nécessaires à l’analyse.
Effectuez enfin un test inverse. Injectez un faux jeton réservé à cet usage dans une tâche temporaire, puis faites-le passer successivement par la sortie standard, la sortie d’erreur et une pièce jointe de test afin de vérifier que la barrière bloque la publication. Forcez ensuite le build à renvoyer un état différent de zéro et confirmez que le pipeline d’épuration ne transforme pas cet échec en réussite. Le dispositif de sécurisation des journaux ne fait réellement partie du processus d’ingénierie que lorsque ces deux catégories de tests réussissent.
Questions fréquentes
Un remplacement de texte juste avant le dépôt du journal suffit-il ?
Non. Une valeur peut déjà être présente dans la sortie du terminal, un fichier temporaire ou un bundle. Il faut d’abord désactiver les traces et éviter les secrets dans les arguments.
Comment conserver le véritable code de sortie de xcodebuild ?
Activez pipefail dans Bash et capturez PIPESTATUS[0] immédiatement après le pipeline. Le statut de tee ou du filtre ne doit pas devenir le résultat du build.
Quels artefacts faut-il contrôler en plus des journaux texte ?
Contrôlez les bundles de résultats, pièces jointes de test, archives de diagnostic, configurations exportées et rapports produits par les scripts internes.
Lancez votre prochain build sur un nœud physique dédié
Choisissez OakVM M4 ou OakVM M4 Pro et louez un Mac cloud non virtualisé à la journée, à la semaine, au mois ou au trimestre. La disponibilité réelle du nœud est indiquée en temps réel dans la console.