Cet article vous montre comment écrire des stratégies IAM (Identity and Access Management, le service de gestion des identités et des accès d’AWS) qui encadrent l’accès de votre équipe aux dépôts CodeCommit. CodeCommit n’offre aucun écran de réglages pour la protection de branche, donc chaque garde-fou passe par une stratégie IAM. L’équipe tombe alors dans l’un des deux pièges, accorder codecommit:* à tout le monde ou écrire une stratégie par développeur qui ne survit pas à la prochaine embauche. La réponse courte est d’étendre les permissions par étiquette de dépôt plutôt que par identifiant de ressource, et d’ajouter un refus explicite sur les branches protégées comme main. Vous repartirez avec trois stratégies, une de lecture, une d’écriture par escouade et une de refus, qui couvrent un nouveau dépôt dès qu’il porte les bonnes étiquettes.
Ce qui se passe
L’autorisation CodeCommit passe entièrement par IAM. Il n’y a pas de rôles « propriétaire », « mainteneur » ou « rédacteur » dans CodeCommit lui-même — ces concepts viennent des principaux IAM (utilisateurs ou rôles) et des actions que leurs stratégies attachées autorisent. Les actions pertinentes se divisent en trois familles :
- Lectures au niveau dépôt :
codecommit:GitPull,codecommit:GetRepository,codecommit:ListBranches,codecommit:GetCommit, et les lectures liées aux PR (codecommit:GetPullRequest,codecommit:ListPullRequests). - Écritures au niveau dépôt :
codecommit:GitPush,codecommit:CreatePullRequest,codecommit:MergePullRequest*,codecommit:UpdatePullRequestStatus. - Admin au niveau dépôt :
codecommit:CreateRepository,codecommit:DeleteRepository,codecommit:PutRepositoryTriggers,codecommit:UpdateRepositoryDescription.
Le contrôle au niveau branche est la partie que les équipes manquent. CodeCommit livre une clé de condition — codecommit:References — qui vous permet d’étendre codecommit:GitPush à des refs spécifiques. Combinez ça avec un Deny pour le force-push (codecommit:References évalue par rapport à la ref destination ; la condition aws:ResourceTag vous laisse étendre par dépôt) et vous obtenez la protection de branche équivalente à GitHub sans outillage externe.
Le motif fragile dans lequel les équipes tombent est d’identifier les dépôts par ARN dans chaque stratégie. Quand le nombre de dépôts dépasse la dizaine, les stratégies deviennent ingérables. Le motif durable est le marquage — chaque dépôt porte un tag Squad et un tag Tier, et les stratégies s’étendent sur ces tags via aws:ResourceTag. Nouveau dépôt, bons tags, aucun changement de stratégie.
Comment vérifier
Vérifiez l’état actuel des permissions effectives de n’importe quel développeur avant de changer quoi que ce soit :
# Quelles actions cet utilisateur peut-il réellement effectuer sur ce dépôt ?
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/developer-alice \
--action-names \
codecommit:GitPush \
codecommit:GitPull \
codecommit:DeleteRepository \
codecommit:DeleteBranch \
--resource-arns arn:aws:codecommit:us-east-1:123456789012:my-repo \
--output table
Le simulateur renvoie allowed ou implicitDeny pour chaque action, avec la ligne de stratégie correspondante. Exécutez-le avant chaque changement de stratégie et ré-exécutez après — si le diff n’est pas celui attendu, la stratégie est cassée.
Pour énumérer chaque principal qui a actuellement une permission CodeCommit contre n’importe quel dépôt :
aws iam get-account-authorization-details \
--query 'Policies[?DefaultVersion.Document.Statement[?Action[?contains(@, `codecommit`) == `true`]]].{Policy:PolicyName,Arn:Arn}' \
--output table
La liste devrait être courte — une poignée de stratégies attachées à des groupes, pas des dizaines de stratégies inline sur des utilisateurs individuels. Si elle est longue, le travail de nettoyage précède les nouvelles stratégies.
Vérifiez que la discipline de marquage est en place :
aws codecommit list-repositories --query 'repositories[].repositoryName' --output text | \
while read r; do
tags=$(aws codecommit list-tags-for-resource \
--resource-arn "arn:aws:codecommit:us-east-1:123456789012:$r" \
--query 'tags' --output json)
echo "$r: $tags"
done
Les dépôts sans tags Squad et Tier tomberont en dehors des stratégies étendues par tag — ils ont besoin de tags appliqués avant que les stratégies les protègent.
La correction
Le motif utilise trois stratégies : une stratégie de lecture attachée largement, une stratégie d’écriture attachée à des groupes spécifiques à chaque escouade, et une stratégie de refus qui surcharge tout pour les refs protégées.
- Marquer chaque dépôt. Établissez deux tags obligatoires :
Squad(quelle équipe le possède) etTier(prod,staging,internal). Appliquez-les avec une stratégie de tag ou un script à la création — les dépôts créés sans tags sont hors de portée des protections.
aws codecommit tag-resource \
--resource-arn arn:aws:codecommit:us-east-1:123456789012:payments-api \
--tags Squad=payments,Tier=prod
- Attacher une stratégie de lecture étendue par tag au groupe ingénierie. Tout le monde obtient la lecture sur chaque dépôt prod et internal ; les dépôts staging sont ouverts par défaut. Voici la stratégie :
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadAllRepos",
"Effect": "Allow",
"Action": [
"codecommit:GitPull",
"codecommit:GetRepository",
"codecommit:ListBranches",
"codecommit:GetCommit",
"codecommit:GetPullRequest",
"codecommit:ListPullRequests",
"codecommit:GetCommentsForPullRequest",
"codecommit:GetDifferences",
"codecommit:GetBlob",
"codecommit:GetFile",
"codecommit:GetFolder"
],
"Resource": "*"
}
]
}
Le Resource: "*" est intentionnel — la lecture sur le code source à cette échelle est rarement le bit sensible. Si un dépôt porte des secrets, il ne devrait pas (c’est une correction séparée), et si un dépôt porte de la PI sensible au niveau lecture, ce dépôt réclame une stratégie séparée qui étend la lecture à l’escouade propriétaire.
- Attacher une stratégie d’écriture étendue par tag à chaque groupe d’escouade. Les membres de l’escouade peuvent pousser sur les dépôts que leur escouade possède. La condition utilise
aws:ResourceTagcontre le tagSquad:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "WriteOwnSquadRepos",
"Effect": "Allow",
"Action": [
"codecommit:GitPush",
"codecommit:CreatePullRequest",
"codecommit:CreateCommit",
"codecommit:CreateBranch",
"codecommit:MergePullRequestByFastForward",
"codecommit:MergePullRequestBySquash",
"codecommit:MergePullRequestByThreeWay",
"codecommit:PostCommentForPullRequest",
"codecommit:UpdatePullRequestStatus"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Squad": "payments"
}
}
}
]
}
Même stratégie pour chaque escouade, la valeur Squad permutée. Le nouveau dépôt marqué Squad=payments est automatiquement modifiable en écriture par l’escouade payments et aucune autre.
- Refuser le force-push et la suppression de ref sur les refs protégées. C’est la stratégie qui vous donne la protection de branche équivalente à GitHub sur
main:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyForcePushToMain",
"Effect": "Deny",
"Action": "codecommit:GitPush",
"Resource": "*",
"Condition": {
"StringEqualsIfExists": {
"codecommit:References": ["refs/heads/main"]
},
"Bool": {
"codecommit:References": "true"
},
"Null": {
"codecommit:References": "false"
}
}
},
{
"Sid": "DenyDeletionOfProtectedRefs",
"Effect": "Deny",
"Action": [
"codecommit:DeleteBranch",
"codecommit:DeleteRepository"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/Tier": "prod"
}
}
}
]
}
Le Deny sur codecommit:GitPush contre refs/heads/main bloque entièrement les push directs sur main. Le seul chemin vers main devient une PR fusionnée. Combinez ça avec les modèles de règles d’approbation et vous avez le garde-fou complet : les développeurs ne peuvent pas pousser sur main, seule la fusion d’une PR approuvée le peut.
- Fournir un rôle bris-de-glace séparément. La stratégie de refus s’applique aux développeurs ; si un release manager doit pousser un hotfix directement sur
mainpendant une panne, il assume un rôle bris-de-glace étendu séparément qui n’est pas soumis au refus. Auditez les appelssts:AssumeRolevers ce rôle agressivement — c’est le contournement et il doit rester rare.
Deux règles que nous tenons :
Tester les stratégies de refus avec un principal non-admin. La sortie du simulateur de stratégies d’un admin IAM est trompeuse — les admins ont iam:* qui peut masquer des refus de façon subtile. Exécutez le simulateur contre le rôle développeur, pas le rôle admin.
Marquer le dépôt avant le premier push. Appliquer les tags après que le dépôt soit en usage signifie qu’il y a une fenêtre où les protections ne s’appliquent pas et où un force-push pourrait atterrir. Le premier commit arrive après les tags.
Le bon jeu de stratégies pour une organisation à 30 développeurs et 50 dépôts est de trois stratégies (lecture, écriture par-escouade, refus sur refs protégées) plus un rôle bris-de-glace. C’est toute l’empreinte. N’en ajoutez d’autres que quand la sensibilité d’un dépôt spécifique justifie un cas particulier.
Stack Harbor opère CodePipeline + CodeCommit (et les variantes GitHub sur AWS) dans le cadre de l’onboarding Gestion AWS et des Environnements infogérés en continu. Si votre IAM CodeCommit a dérivé vers des stratégies inline par utilisateur qui ne survivent plus au roulement, commencez par une consultation d’infrastructure.