Aller au contenu
English
Cloud medium

Lab fil rouge sécurité : une application qui lit un secret, et rien d'autre

Mesuré live le ·fr-par·scw 2.62.0

65 min de lecture

Le moindre privilège ne se prouve pas par ce qui marche, il se prouve par ce qui est refusé. Ce lab de synthèse assemble tout le volet en un seul scénario : un projet dédié qui sert de frontière, une application IAM avec sa politique et une clé qui expire, un secret qu'elle doit lire, une clé de chiffrement qu'elle doit utiliser, et l'Audit Trail qui raconte ce qu'elle a tenté. Vous vérifierez que le chemin nominal fonctionne, puis vous ferez volontairement échouer la même clé sur ce qui déborde de sa politique. Vous finirez par un démontage complet, y compris d'un objet que Scaleway a créé sans vous le dire.

  • Poser un projet, une application, une politique et une clé qui expire.
  • Choisir le jeu de permissions qui autorise vraiment la lecture d'une valeur.
  • Prouver le moindre privilège par deux refus exacts.
  • Lire dans l'Audit Trail ce que l'application a tenté, refus compris.
  • Détruire dans l'ordre, y compris ce que Scaleway a créé pour vous.

Que va coûter ce lab, et pendant combien de temps ?

Section intitulée « Que va coûter ce lab, et pendant combien de temps ? »

Presque rien, et c'est ce qui en fait un bon terrain de répétition. IAM, les projets et l'Audit Trail sont gratuits. Secret Manager et Key Manager se facturent au secret, à la clé et à l'appel, pour des montants de l'ordre du centime sur une session d'une heure.

Le seul poste qui compte, si vous ajoutez l'étape facultative sur les listes filtrées, est l'Instance que vous créerez quelques minutes. Comptez une session de quarante minutes, largement sous le centime pour les briques de sécurité.

Étape 1 : pourquoi commencer par un projet dédié ?

Section intitulée « Étape 1 : pourquoi commencer par un projet dédié ? »

Parce qu'une politique IAM a besoin d'une frontière, et que le projet est la seule qui existe. Les jeux de permissions de Secret Manager et de Key Manager ont tous une portée projects : sans projet séparé, « limiter » une application revient à lui ouvrir tout votre compte.

  1. Créez le projet qui servira de périmètre.

    Fenêtre de terminal
    PROJ=$(scw account project create name=capstone-secu -o json | jq -r .id)
    scw account project list -o json

    La sortie doit afficher deux projets : le vôtre et celui-ci.

  2. Créez l'application, c'est-à-dire l'identité non humaine.

    Fenêtre de terminal
    APP=$(scw iam application create name=capstone-app -o json | jq -r .id)
    scw iam application get "$APP" -o json

    La sortie doit afficher le nom et un id.

Quel jeu de permissions autorise vraiment à lire un secret ?

Section intitulée « Quel jeu de permissions autorise vraiment à lire un secret ? »

SecretManagerSecretAccess, et surtout pas SecretManagerReadOnly. C'est le piège central de ce lab, et son nom le rend invisible : « ReadOnly » laisse croire qu'il donne la lecture, alors qu'il ne donne que la lecture des métadonnées, pas de la valeur.

Mesuré le 11 septembre 2026 avec scw 2.62.0 : une politique portant SecretManagerReadOnly échoue à lire la valeur du secret avec

scaleway-sdk-go: insufficient permissions: access secret

La liste des jeux disponibles répond elle-même à la question, et c'est le bon réflexe plutôt que de deviner :

Fenêtre de terminal
scw iam permission-set list -o json

La sortie doit contenir SecretManagerSecretAccess, décrit « Retrieve the plaintext value of secret versions ». La formulation est explicite là où le nom ne l'était pas.

Lisez ce tableau par la colonne Besoin : partez de ce que votre application doit faire, jamais du nom de jeu qui vous paraît le plus proche.

BesoinJeu à choisirPourquoi pas l'autre
Lister les secrets et voir leurs versionsSecretManagerReadOnlyil s'arrête aux métadonnées
Lire la valeur d'une versionSecretManagerSecretAccessseul jeu décrit « Retrieve the plaintext value »
Créer un secret ou une versionSecretManagerSecretCreatelire n'implique jamais écrire
Tout faire, suppression compriseSecretManagerFullAccessà réserver à un humain, pas à une chaîne d'intégration

La leçon dépasse Secret Manager. Un nom de jeu de permissions est un libellé commercial, pas un contrat : la description est la seule source, et elle se lit avant d'écrire la politique. Cette page a coûté une passe de lab entière pour l'apprendre.

  1. Créez la politique, limitée au projet et aux trois jeux nécessaires.

    Fenêtre de terminal
    POL=$(scw iam policy create name=capstone-pol application-id="$APP" \
    rules.0.project-ids.0="$PROJ" \
    rules.0.permission-set-names.0=SecretManagerSecretAccess \
    rules.0.permission-set-names.1=KeyManagerKeyEncrypt \
    rules.0.permission-set-names.2=KeyManagerKeyDecrypt \
    -o json | jq -r .id)
    scw iam policy get "$POL" -o json

    La sortie doit afficher la règle avec le project_ids attendu.

  2. Créez la clé d'API, avec une date d'expiration.

    Fenêtre de terminal
    EXP=$(date -u -d '+2 hours' +%Y-%m-%dT%H:%M:%SZ)
    scw iam api-key create application-id="$APP" expires-at="$EXP" -o json > cle.json
    AK=$(jq -r .access_key cle.json)
    SK=$(jq -r .secret_key cle.json)
    ORG=$(scw config get default-organization-id)

    La sortie affiche access_key et secret_key. La partie secrète n'est montrée qu'une fois : notez-la immédiatement.

Ces deux ressources se créent avec votre profil, celui de l'Organisation : l'application n'a pas le droit de les créer, et c'est voulu.

Fenêtre de terminal
SECRET=$(scw secret secret create name=capstone-secret \
project-id="$PROJ" region=fr-par -o json | jq -r .id)
printf 'mot-de-passe-du-capstone' > /tmp/val.txt
scw secret version create secret-id="$SECRET" data=@/tmp/val.txt region=fr-par -o json
KEY=$(scw keymanager key create name=capstone-key project-id="$PROJ" \
region=fr-par usage.symmetric-encryption=aes_256_gcm -o json | jq -r .id)

La sortie de la version doit afficher "revision":1 et "status":"enabled".

Étape 4 : la clé restreinte fait-elle son travail ?

Section intitulée « Étape 4 : la clé restreinte fait-elle son travail ? »

C'est le chemin nominal, et il doit réussir avant qu'on s'intéresse aux refus. Une politique qui ne laisse rien passer n'est pas du moindre privilège, c'est une panne.

La clé restreinte s'utilise par variables d'environnement, sans jamais toucher votre configuration :

Fenêtre de terminal
env SCW_ACCESS_KEY="$AK" SCW_SECRET_KEY="$SK" \
SCW_DEFAULT_PROJECT_ID="$PROJ" SCW_DEFAULT_ORGANIZATION_ID="$ORG" \
scw secret version access secret-id="$SECRET" revision=latest region=fr-par -o json

La sortie doit ressembler à ceci, relevée le 11 septembre 2026 :

{"secret_id":"6cc5b648-…","revision":1,"data":"bW90LWRlLXBhc3NlLWR1LWNhcHN0b25l","type":"opaque"}

La valeur revient encodée en base64, comme partout dans Secret Manager. Elle se décode en mot-de-passe-du-capstone :

Fenêtre de terminal
echo "bW90LWRlLXBhc3NlLWR1LWNhcHN0b25l" | base64 -d

Étape 5 : prouver le moindre privilège par le refus

Section intitulée « Étape 5 : prouver le moindre privilège par le refus »

Une autorisation qui réussit ne prouve rien sur ce qui est interdit. Il faut tenter ce qui doit échouer, et lire le message.

Fenêtre de terminal
env SCW_ACCESS_KEY="$AK" SCW_SECRET_KEY="$SK" \
scw secret secret create name=interdit project-id="$PROJ" region=fr-par
env SCW_ACCESS_KEY="$AK" SCW_SECRET_KEY="$SK" \
scw keymanager key delete key-id="$KEY" region=fr-par

Les deux sorties doivent afficher un refus explicite :

scaleway-sdk-go: insufficient permissions: create secret
scaleway-sdk-go: insufficient permissions: delete key

Ces deux lignes sont le vrai livrable de ce lab. Elles disent que la clé posée dans une chaîne d'intégration ne peut pas créer de secret, ni détruire la clé de chiffrement, même si elle fuite.

Il nomme l'application, et il enregistre aussi ce qu'elle n'a pas eu le droit de faire. C'est ce qui permet de repérer une clé qui cherche à déborder de son périmètre.

Fenêtre de terminal
scw audit-trail event list region=fr-par -o json

Sur le lab, deux événements portaient l'identifiant de l'application comme principal : CreateSecret et DeleteKey. Les deux avaient été refusés. Une tentative bloquée laisse donc une trace, et c'est exactement le signal qu'une supervision doit remonter.

L'Audit Trail est asynchrone : comptez une vingtaine de secondes avant qu'un événement apparaisse. Un script qui interroge immédiatement après l'action ne trouvera rien et conclura à tort.

Le tableau ci-dessous est le vrai résumé du lab : il dit quel objet bloque la suppression de quel autre, et chaque ligne a été provoquée volontairement.

Vous supprimezCe qui bloqueMessage exactL'ordre correct
le projettout ce qu'il contient encoreresource is still in use, all resources are not deletedvider le projet d'abord
un secret protégésa propre protectioncannot delete a protected secretsecret unprotect puis delete
une clé Key Manager protégéesa protectionmême famille de messagekey unprotect puis delete
le projet, alors qu'il paraît videle groupe de sécurité par défaut créé par Scalewaymessage générique, aucune mention du groupesupprimer le groupe à la main
l'applicationrien : elle part même avec sa politiqueaucunsupprimer quand même la politique, sinon elle reste
  1. Libérez les protections, puis supprimez secret et clé.

    Fenêtre de terminal
    scw secret secret unprotect secret-id="$SECRET" region=fr-par
    scw secret secret delete secret-id="$SECRET" region=fr-par
    scw keymanager key unprotect key-id="$KEY" region=fr-par
    scw keymanager key delete key-id="$KEY" region=fr-par
  2. Supprimez la clé d'API, la politique, puis l'application.

    Fenêtre de terminal
    scw iam api-key delete access-key="$AK"
    scw iam policy delete policy-id="$POL"
    scw iam application delete application-id="$APP"
  3. Supprimez le projet, en nommant l'argument.

    Fenêtre de terminal
    scw account project delete project-id="$PROJ"

    La sortie doit afficher Project has been successfully deleted.

  4. Vérifiez le retour à zéro sur chaque famille, avec une clé qui voit tout.

    Fenêtre de terminal
    scw iam application list -o json
    scw secret secret list region=fr-par -o json
    scw keymanager key list region=fr-par -o json
    scw account project list -o json

    Les trois premières doivent être vides, la dernière ne doit plus contenir que vos projets habituels.

  • Le chemin nominal fonctionne : une clé ne portant que trois jeux de permissions lit la valeur d'un secret et chiffre une donnée, sans aucun autre droit.
  • Le moindre privilège tient, et se lit dans deux refus : insufficient permissions: create secret et insufficient permissions: delete key.
  • Un nom de jeu de permissions ment : SecretManagerReadOnly ne lit pas les valeurs, SecretManagerSecretAccess le fait, et seule la description le dit.
  • Key Manager échoue en silence sur du texte brut, renvoyant un chiffré vide sans erreur ni code de retour non nul.
  • Une liste vide n'est pas une preuve : la clé restreinte reçoit [] là où la clé de l'Organisation voit une Instance, et seul un accès direct révèle le refus.
  • Une tentative refusée est journalisée, avec l'application comme auteur, une vingtaine de secondes après coup.
  • Scaleway crée un objet que vous n'avez pas demandé, le groupe de sécurité par défaut, et il bloque la suppression du projet sans jamais se nommer.

Ces valeurs encadrent ce que vous venez de construire. Elles se relèvent toutes en lecture, sans rien créer.

LimiteValeurSource
Portée des jeux Secret Manager et Key Managerprojects, sans exceptionscw iam permission-set list, 2.62.0, 2026-09-11
Jeux Key Manager distincts10, dont Encrypt, Decrypt, Sign, Verify, Wrap, Unwrapscw iam permission-set list
Jeux Secret Manager distincts7, dont SecretAccess séparé de ReadOnlyscw iam permission-set list
Expiration des clés d'APIimposée par les réglages de l'Organisationscw iam security-settings get
Délai d'apparition dans l'Audit Trailenviron 20 secondesmesuré en lab le 2026-09-11
Encodage des valeurs de secret et de plaintextbase64 dans les deux sensaide du CLI et sorties du lab

Security : que peut faire votre clé si elle fuite ?

Section intitulée « Security : que peut faire votre clé si elle fuite ? »

La question clé : si la clé posée dans votre chaîne d'intégration se retrouve dans un dépôt public, quel est le pire scénario ?

Ici, la réponse est bornée et vérifiée : lire un secret et chiffrer, dans un seul projet, pendant deux heures. Elle ne peut ni créer, ni supprimer, ni voir les autres produits.

La discipline : écrire la politique en partant de ce qu'on accepte de perdre, puis prouver les refus, parce qu'une politique non testée est une intention.

Operational Excellence : sauriez-vous dire ce que cette clé a tenté ?

Section intitulée « Operational Excellence : sauriez-vous dire ce que cette clé a tenté ? »

La question clé : disposez-vous d'une trace des actions refusées, et pas seulement des actions réussies ?

L'Audit Trail enregistre les deux, avec l'application comme auteur. Une clé qui tente régulièrement ce qu'elle n'a pas le droit de faire est soit mal configurée, soit compromise.

La discipline : surveiller les refus autant que les réussites, et se rappeler qu'un délai d'une vingtaine de secondes sépare l'action de sa trace.

Cost Optimization : que reste-t-il après un lab de sécurité ?

Section intitulée « Cost Optimization : que reste-t-il après un lab de sécurité ? »

La question clé : un projet supprimé emporte-t-il tout ce qu'il contenait ?

Non : il refuse de partir tant qu'il reste quoi que ce soit, y compris un objet que vous n'avez jamais créé. Les briques de ce lab coûtent peu, mais un projet fantôme masque des ressources qui, elles, peuvent coûter.

La discipline : vérifier le retour à zéro avec une clé qui voit tout, et traiter un refus de suppression de projet comme l'indice qu'il reste une ressource à trouver.

Chacun de ces messages a été provoqué volontairement le 11 septembre 2026 avec scw 2.62.0.

SymptômeCauseSolution
organization security settings require an expiration date for API keysla clé est créée sans expires-atajouter expires-at au format RFC 3339
insufficient permissions: access secret malgré SecretManagerReadOnlyce jeu ne donne que les métadonnéesutiliser SecretManagerSecretAccess
Un ciphertext vide, sans aucune erreurplaintext doit être en base64plaintext="$(printf '…' | base64)"
Invalid argument '<uuid>': arg name must only contain lowercase letters…un positionnel sur un argument optionnelnommer l'argument : project-id=<id>
resource is still in use, all resources are not deletedle projet contient encore une ressourcechercher le groupe de sécurité par défaut
cannot delete a protected secretla protection est activesecret unprotect avant delete
Une liste vide avec une clé restreinteIAM filtre le résultat au lieu de refuservérifier avec une clé qui voit tout

Ces cinq erreurs se ressemblent : elles concluent d'une absence de message que tout va bien, alors que le silence ne prouve rien.

AntipatternConséquenceDiscipline
Choisir un jeu de permissions sur son nomReadOnly ne lit pas les valeurs, l'application échoue en productionlire la description renvoyée par permission-set list
Tester une politique uniquement sur ce qui doit marcherce qui est interdit n'a jamais été vérifiétenter au moins deux actions qui doivent échouer
Vérifier un compte vide avec une clé restreintela liste filtrée fait croire au retour à zérocontrôler avec une clé qui voit tout
Chiffrer sans relire le ciphertextla donnée n'est pas chiffrée, et rien ne le signaleéchouer explicitement si le chiffré est vide
Créer des clés d'API sans expirationune clé fuitée reste valable indéfinimentimposer l'expiration au niveau de l'Organisation

Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

  • Le projet est la seule frontière d'une politique IAM : tous les jeux Secret Manager et Key Manager ont la portée projects.
  • SecretManagerSecretAccess lit la valeur d'un secret, SecretManagerReadOnly ne lit que les métadonnées, et seul le champ description le dit.
  • expires-at est imposé par les réglages de sécurité de l'Organisation : sans lui, la création de clé est refusée.
  • Les valeurs de Secret Manager reviennent en base64, et keymanager key encrypt en attend en entrée.
  • Un chiffrement sur du texte brut renvoie un ciphertext vide sans erreur : le contrôler est la seule parade.
  • Le moindre privilège se prouve par un refus : insufficient permissions: create secret vaut mieux que n'importe quelle capture d'écran.
  • Une liste vide obtenue avec une clé restreinte ne prouve rien : IAM filtre les listes et ne refuse explicitement que les accès directs.
  • L'Audit Trail journalise les tentatives refusées et nomme l'application, environ vingt secondes après coup.
  • Le groupe de sécurité par défaut, créé par Scaleway, bloque la suppression du projet sans jamais apparaître dans le message d'erreur.
  • scw account project delete veut project-id= : le CLI n'accepte un positionnel que pour un argument obligatoire.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn