# Trois tortues suffisent peut-être : des clés SSH liées au matériel sur macOS

> La sécurité ne se termine jamais sur une racine de confiance inconditionnelle ; elle s'arrête là où la couche suivante cesse d'être rentable. Pour les clés SSH sur un Mac, trois couches suffisent, et l'une d'elles est déjà dans votre portable.

Source: https://www.bluewise.fr/fr/three-turtles-might-be-enough  
Author: Marc Morel  
Published: 2026-05-04  
Category: Engineering

## Des tortues jusqu'en bas

Une vieille histoire raconte une conférence d'astronomie. Alors que l'orateur termine d'expliquer que la Terre tourne autour du Soleil, une vieille dame dans l'assistance objecte poliment : le monde, dit-elle, est une assiette plate posée sur le dos d'une tortue géante. Quand on lui demande sur quoi repose la tortue, elle n'hésite pas. « Ce sont des tortues jusqu'en bas. »

Les ingénieurs sécurité connaissent bien cette réponse. Un secret est protégé par un mot de passe, le mot de passe par un coffre, le coffre par une session, la session par un appareil, et l'appareil par celui qui l'a provisionné. Chaque protection repose sur une autre, et la question « qu'est-ce qui protège *ça* ? » n'aboutit jamais à une réponse finale et inconditionnelle.

La question utile n'est donc pas de savoir où se trouve la dernière tortue. Il n'y en a pas. C'est **de combien de tortues avons-nous besoin avant que la suivante ne vaille plus le coup**. Pour les clés SSH sur un Mac, la réponse est trois.

## Le problème de la première tortue que la plupart d'entre nous utilisent

La plupart des développeurs s'authentifient encore sur GitHub avec une clé privée stockée dans un fichier : `~/.ssh/id_ed25519`, souvent sans passphrase, parfois copiée d'une machine à l'autre, occasionnellement commitée par accident dans un dépôt de dotfiles.

Ce fichier est lisible par tous les processus qui tournent sous votre compte utilisateur. Une dépendance malveillante dans un script de build, une extension d'éditeur compromise ou un outil en ligne de commande vérolé n'a besoin d'aucun exploit pour la voler : il suffit de lire un fichier et de l'envoyer quelque part. Une fois copiée, la clé fonctionne depuis n'importe quelle machine au monde, silencieusement, jusqu'à ce que quelqu'un s'en aperçoive et la révoque. Une passphrase n'aide que tant que la clé est chiffrée au repos. Un agent qui garde la clé déchiffrée toute la journée offre le même matériel à tout ce qui peut parler à son socket.

La faiblesse n'est pas la cryptographie. C'est que le secret est **portable**. Tout ce qui peut le lire peut devenir vous.

## Trois tortues

Une conception saine de l'identité SSH d'un développeur nécessite trois couches, chacune répondant à une question différente.

**Tortue un : la clé ne peut pas quitter l'appareil.** La clé privée est générée à l'intérieur d'un matériel dédié et n'existe jamais en mémoire principale, sur disque ou dans une sauvegarde. Un malware peut demander au matériel de signer quelque chose, mais il ne peut pas emporter la clé pour l'utiliser ailleurs. Cela transforme un problème de *vol* en un problème d'*usage abusif sur cette machine*, ce qui est considérablement plus restreint.

**Tortue deux : chaque usage requiert un humain.** Chaque signature exige un acte explicite de la personne au clavier : une empreinte digitale, pas une session en cache. Un malware qui demande au matériel de signer déclenche une invite que l'utilisateur n'attendait pas. L'usage silencieux devient un usage visible.

**Tortue trois : la partie de confiance peut révoquer.** GitHub ne détient que la clé publique. Si le portable est perdu, volé ou mis au rebut, retirer cette clé publique du compte met fin à l'identité immédiatement. La durée de vie de la clé est liée à celle de l'appareil, et le service garde le dernier mot.

Une quatrième tortue est toujours disponible : une chaîne de démarrage durcie, un appareil attesté, un jeton matériel dans un coffre-fort. Chacune ajoute du coût et de la friction, et chacune protège contre un attaquant qui a déjà vaincu les trois premières. Pour la plupart des équipes d'ingénierie, trois couches bien choisies ferment les chemins d'attaque réalistes, et la quatrième est là où l'effort cesse d'être rentable.

## La Secure Enclave est la tortue un, et Touch ID la tortue deux

Chaque Mac Apple Silicon, ainsi que les Mac Intel dotés d'une puce T2, contient une **Secure Enclave** : un coprocesseur isolé avec sa propre mémoire et son propre firmware, conçu pour que les clés générées à l'intérieur ne puissent pas être extraites, même par le système d'exploitation. Touch ID y est relié directement. L'enclave peut exiger une empreinte vérifiée avant d'effectuer une opération avec une clé donnée.

Jusqu'à récemment, utiliser l'enclave pour SSH impliquait des agents tiers comme Secretive, qui reste un choix solide sur les versions plus anciennes de macOS. Depuis macOS Tahoe, le système fournit les briques nativement :

- `sc_auth` crée des identités adossées à la Secure Enclave via CryptoTokenKit.
- `/usr/lib/ssh-keychain.dylib` implémente l'interface *security key provider* d'OpenSSH, la même interface qu'OpenSSH utilise pour les jetons FIDO2 comme une YubiKey. Pour OpenSSH, le Mac ressemble simplement à une clé de sécurité matérielle intégrée.

Le type de clé obtenu est `sk-ecdsa-sha2-nistp256@openssh.com`, que GitHub accepte à la fois pour l'authentification et la signature de commits.

## La mise en place pour GitHub

**1. Créer l'identité dans la Secure Enclave.** Le type de clé `p-256-ne` signifie que la clé est générée dans l'enclave et n'est pas exportable. `-t bio` exige Touch ID à chaque usage.

```bash
sc_auth create-ctk-identity -l github -k p-256-ne -t bio
sc_auth list-ctk-identities -t ssh      # vérifier que l'identité existe
```

Évitez la variante exportable `p-256`. Elle chiffre la clé *avec* l'enclave au lieu de la générer *dans* l'enclave, ce qui revient à renoncer à la tortue un.

**2. Récupérer le handle de la clé pour OpenSSH.**

```bash
cd ~/.ssh
ssh-keygen -w /usr/lib/ssh-keychain.dylib -K -N ""
mv id_ecdsa_sk_rk     id_github_enclave
mv id_ecdsa_sk_rk.pub id_github_enclave.pub
```

Le fichier « privé » ainsi écrit n'est pas la clé privée. C'est une référence vers la clé détenue par l'enclave, et elle est inutile sur toute autre machine. Conservez-le quand même ; OpenSSH en a besoin pour adresser la clé.

**3. Enregistrer la clé publique sur GitHub.** Ajoutez `id_github_enclave.pub` dans *Settings → SSH and GPG keys* comme clé d'authentification, ou avec la CLI GitHub :

```bash
gh ssh-key add ~/.ssh/id_github_enclave.pub --title "MacBook enclave $(date +%Y-%m)"
```

**4. Faire pointer OpenSSH vers l'enclave.** Dans `~/.ssh/config` :

```
Host github.com
  User git
  IdentityFile ~/.ssh/id_github_enclave
  IdentitiesOnly yes
  SecurityKeyProvider /usr/lib/ssh-keychain.dylib
```

`IdentitiesOnly` empêche SSH de proposer toute autre clé qu'il trouverait. `SecurityKeyProvider` lui indique de demander la signature à l'enclave.

**5. Tester.**

```bash
ssh -T git@github.com
```

Touch ID devrait vous solliciter, et GitHub devrait vous saluer par votre nom d'utilisateur. À partir de là, chaque `git fetch`, `pull` et `push` en SSH demande votre empreinte.

**6. Optionnel : signer les commits avec le même matériel.** Exportez le provider pour que tous les outils OpenSSH le trouvent, y compris le `ssh-keygen` que Git appelle pour signer. Puis configurez Git :

```bash
echo 'export SSH_SK_PROVIDER=/usr/lib/ssh-keychain.dylib' >> ~/.zprofile

git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_github_enclave.pub
git config --global commit.gpgsign true
```

Ajoutez la même clé publique une seconde fois sur GitHub, en tant que clé de *signature*. Vos commits apparaissent alors comme vérifiés, et chaque signature porte la même garantie que vos connexions : elle a été faite sur ce Mac, par quelqu'un avec ce doigt.

## L'exploiter sans regrets

Lier la clé au matériel change quelques habitudes :

- **Prévoir la perte avant qu'elle n'arrive.** Une clé qui ne peut pas quitter l'appareil meurt avec lui. Enregistrez une seconde clé liée au matériel : l'enclave d'un autre Mac, ou un jeton FIDO2 rangé en lieu sûr. Révoquez l'ancienne clé le jour où une machine est perdue ou retirée.
- **S'attendre à une invite par signature.** Les scripts qui ouvrent de nombreuses connexions SSH solliciteront de nombreuses fois. Regroupez les opérations, ou réutilisez une connexion authentifiée avec `ControlMaster auto` et un `ControlPersist` court dans le bloc `github.com`. Le multiplexage assouplit légèrement la tortue deux : des processus locaux peuvent emprunter la connexion ouverte jusqu'à son expiration, donc gardez une fenêtre courte.
- **Vérifier que l'enclave est vraiment dans la boucle.** Dans une machine virtuelle sans enclave, l'outillage peut tout de même créer une identité. Créez les clés sur le Mac physique, et vérifiez que Touch ID sollicite réellement avant de faire confiance à la configuration.
- **Garder les anciennes clés honnêtes.** Une fois la clé de l'enclave fonctionnelle, supprimez les clés fichier de GitHub et de `~/.ssh`. Une clé forte à côté d'une clé faible n'est pas plus forte que la faible.

## Ce qui change

La vieille dame de l'histoire n'avait pas tort : chaque fondation repose sur quelque chose. L'erreur serait d'en conclure qu'on ne peut faire confiance à rien tant que la dernière tortue n'a pas été trouvée. L'ingénierie de sécurité, c'est l'art de choisir où s'arrêter, délibérément, et de savoir pourquoi.

Pour les identités SSH, trois couches font le travail :

- une clé qui ne peut pas quitter le matériel ;
- une empreinte pour chaque usage ;
- un service qui peut révoquer en un clic.

Chacune ferme un chemin que les autres laissent ouvert, et toutes les trois existent déjà sur le portable devant vous.
