Il m'arrive souvent de devoir accéder à des ressources AWS (S3, SQS, etc.) depuis une application qui tourne sur Google Cloud. Comme l'usage des clés d'accès et des clés secrètes est — à juste titre — considéré comme une mauvaise pratique, j'ai fini par développer Janus : un petit outil qui permet d'assumer un rôle AWS depuis une instance Google Cloud Compute Engine associée à un compte de service.
Pourquoi Janus ? Parce que dans la mythologie romaine, Janus, dieu à deux visages, présidait aux portes et aux passages. L'analogie m'a paru bien tomber ;-)
Alors, qu'est-ce que Janus, exactement ? Un petit bout de code que vous exécutez sur votre propre instance Google Cloud Compute Engine et qui vous permet d'assumer un rôle AWS sans recourir aux clés AWS IAM.
Pourquoi utiliser Janus ?
Imaginons que vous deviez récupérer un fichier privé dans un bucket S3 depuis une instance ou un conteneur qui tourne sur Google Cloud. Pour télécharger ce fichier, il vous faut vous authentifier auprès d'AWS IAM.
Plusieurs options d'authentification existent. La plus sûre consiste à associer un rôle IAM à une instance, mais cela n'est possible qu'avec une instance EC2 (c'est-à-dire une instance qui tourne sur l'infrastructure AWS).
Avec une instance Google Cloud, les options sont plus limitées : la plupart des utilisateurs choisissent donc de générer des clés d'accès AWS IAM (souvent avec des permissions plus larges que nécessaire) et de les stocker en dur dans le code.
Cela représente un risque de sécurité considérable : votre clé peut fuiter. Une fois la clé compromise, quiconque y a accès peut accéder à votre compte AWS. Les conséquences vont de la fuite de données au préjudice financier pour votre entreprise. Le scénario le plus innocent que j'ai pu observer : des pirates qui montent des serveurs de minage de cryptomonnaies, ou qui chiffrent les données et les sauvegardes du compte avant d'exiger une rançon pour les restituer.
Comment, dès lors, établir une connexion sécurisée entre GCP et des ressources AWS sans clés codées en dur ?
Janus contourne ces limites en vous permettant d'assumer un rôle via une Google Web Identity sur une machine GCP Compute Engine, à la manière d'un rôle IAM avec EC2. Janus demande à AWS une clé temporaire valable une heure.
Comment mettre en œuvre Janus
À titre d'exemple, je vais montrer comment accorder un accès en lecture seule à un bucket AWS S3, que j'utiliserai ensuite depuis mon instance Google Compute.
- Connectez-vous à votre console GCP et choisissez IAM & Admin dans le menu de navigation à gauche. Cliquez ensuite sur Service Accounts, puis sur +CREATE SERVICE ACCOUNT.

2. Donnez un nom à votre compte de service et ajoutez une description détaillée (c'est toujours une bonne pratique). Cliquez ensuite sur le bouton CREATE.

3. Cliquez ensuite sur la zone Role et sélectionnez Service Account → Service Account Token Creator.
Plus simple : tapez Token dans la barre de recherche Type to filter.

4. Une page Grant users access to this service account (optional) s'affiche. Lorsqu'elle apparaît, cliquez sur DONE.
5. Cliquez sur le nom du compte de service et copiez l'Unique ID.

6. Connectez-vous à votre compte AWS et accédez à IAM console → Roles → Create role.

7. Pour la trusted entity, sélectionnez Web identity → Google comme Identity provider, puis collez l'Unique ID du compte de service GCP dans le champ Audience. Cliquez ensuite sur Next: Permissions.

8. Attribuez les permissions au rôle. Pour cette démonstration, nous utiliserons AmazonS3ReadOnlyAccess. Cliquez sur Next: Tags.

9. L'étape des tags est facultative ; nous la passons pour cette démonstration. Cliquez sur Next: Review.
10. Donnez un nom et une description détaillée au rôle, puis cliquez sur Create role.

11. Le rôle est prêt à l'emploi. Cliquez et copiez le Role ARN ; il servira à l'étape suivante.

12. Retournez sur la console GCP et créez une nouvelle instance VM Compute Engine.

Faites défiler jusqu'à la section Identity and API access et remplacez le Compute Engine default service account par le compte de service créé à l'étape 5.

13. AWS et GCP sont maintenant configurés et nous pouvons assumer un rôle AWS depuis GCP : il nous faut désormais un outil ou un peu de code pour exécuter la procédure avec la Web Identity de Google. C'est précisément ce qui a motivé la création de Janus.
Janus renvoie des identifiants AWS temporaires à tous les SDK AWS pris en charge ainsi qu'à l'AWS CLI.
Pour mettre en place Janus, il suffit d'exécuter les commandes suivantes en tant qu'utilisateur root :
$ apt install python3-pip awscli
$ pip3 install boto3 requests
$ wget https://raw.githubusercontent.com/doitintl/janus/master/janus.py -O /usr/local/bin/janus
$ chmod 555 /usr/local/bin/janus
Pour exécuter Janus avec le rôle IAM souhaité, ajoutez le nom du Role ARN AWS copié à l'étape 10.
/usr/local/bin/janus arn:aws:iam::123456789012:role/s3-ro-from-gcp
14. Créez un nouveau profil dans le fichier /.aws/credentials ( est un raccourci vers le répertoire personnel de l'utilisateur). Le SDK AWS s'appuie sur les profils définis dans ce fichier pour finaliser l'authentification auprès d'AWS.
Si le fichier n'existe pas, créez-le :
$ mkdir ~/.aws
$ touch ~/.aws/credentials
Modifiez le fichier credentials et ajoutez un profil (le profil par défaut s'appelle default). Vous pouvez disposer de plusieurs profils ; pour cette démonstration, nous allons créer un nouveau profil par défaut :
credential_process = /usr/local/bin/janus arn:aws:iam::123456789012:role/s3-ro-from-gcp
15. Et voilà ! Vous pouvez désormais utiliser AWS depuis votre instance GCP.
À titre d'exemple, je vais copier un fichier nommé hello.txt depuis mon bucket S3 AWS via l'AWS CLI :

Comment ça fonctionne ?
- Chaque fois que l'AWS SDK ou l'AWS CLI a besoin d'accéder à AWS, il recherche le profil par défaut dans :
/.aws/credentials sur Mac, Linux et Unix. ( est un raccourci vers le répertoire personnel)
ou
C:\Users\USERNAME\.aws\credentials sur Windows.
- Il exécute alors Janus avec le nom du rôle AWS à assumer.
- Janus demande un jeton JWT au serveur de métadonnées de Compute Engine, puis assume un rôle auprès d'AWS avec le nom du rôle AWS.
- AWS vérifie que le jeton JWT correspond aux paramètres du rôle AWS et renvoie une clé d'accès temporaire :

- Avec cette clé d'accès temporaire, nous pouvons accéder à AWS et appeler les API au nom du rôle AWS.
Comment savoir quelle instance accède à mon compte AWS ?
À des fins de traçabilité, Janus assume le rôle avec un nom de session personnalisé, sous la forme project-id.instance-name.
Si AWS CloudTrail est activé sur votre compte, vous pouvez filtrer tous les événements AssumeRoleWithWebIdentity et suivre chaque appel d'API effectué.

L'événement contient :
- L'IP source de la machine GCP.
- Le username — l'unique id du compte de service GCP.
- Le session name du rôle — l'id du projet et le nom de l'instance.
- Le nom du rôle assumé.
À partir de la clé d'accès, nous pouvons retrouver toutes les actions exécutées par l'instance.