目的
AWS CodeCommitのカスタマーマネージドポリシーを参考に、AWS CDKで個人開発した内容を記事とします。
下記を満たす実装を目指します。
- 指定した IP アドレス範囲から接続するユーザーにリポジトリへのアクセスを許可する
- ブランチに対するアクションを許可または拒否する
何をつくるか
CodeCommitを利用可能な2つのユーザグループを作成し、下記制限を満たすカスタムIAMポリシーをアタッチします。
- 管理ユーザグループ:
- CodeCommitに対するFullAccess権限をもつが下記を制限する
- 接続元のIPアドレスを制限
- CodeCommitに対するFullAccess権限をもつが下記を制限する
- 一般ユーザグループ:
- CodeCommitに対するPowerUser権限をもつが下記を制限する
- 接続元のIPアドレスを制限
- MASTERブランチへのプッシュおよびマージを拒否
- CodeCommitに対するPowerUser権限をもつが下記を制限する
動作環境
$ python -V
Python 3.8.10
$ cdk --version
2.95.1
$ cat requirements.txt
aws-cdk.core==1.204.0
aws-cdk.aws-iam==1.204.0
設計とディレクトリ構造
ベースとなるポリシーは公式サイトから取得し、jsonファイルとしてCDK内でLoadする設計としました。このポリシーを基礎としてカスタムIAMポリシーを実装しました。
$ tree
.
├── app.py
├── cdk.json
├── custom_iam_policy.py
├── json
│ ├── PolicyBasedOnAWSCodeCommitFullAccess.json
│ └── PolicyBasedOnAWSCodeCommitPowerUser.json
├── requirements.txt
接続元のIP制限
両グループ共通して接続元のIPアドレスの制限を実装したく、CDK内で読み込むjsonファイル内でConditionブロックを作成しました。
またResourceブロックの初期値はブランクとし、操作対象とするリポジトリの情報をCDKプログラム実行時に引数として渡せる実装としました。
"Statement": [
{
"Effect": "Allow",
"Action": [
"codecommit:*"
],
"Resource": "",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"制限するIPアドレス:XXXXXXXXXXXX"
]
}
}
},
...
]
MASTERブランチへのプッシュ/マージを拒否
一般ユーザグループに対してのみこの制限をアタッチしたく、下記のような実装を行っています。
# policyをアタッチ
# custom_policy:masterへのプッシュ・マージを拒否 一般のみ
custom_policy_deny_action = iam.Policy(
self,
id="id_custom_policy_deny_action_for_master_branch",
policy_name="CustomPolicyDenyActionForMasterBranch",
groups=[user_group],# 一般ユーザグループを指定
statements=[
iam.PolicyStatement(
effect=iam.Effect.DENY,
actions=[
"codecommit:GitPush",
"codecommit:DeleteBranch",
"codecommit:PutFile",
"codecommit:Merge*",
],
resources = [repository_arn], # 対象のリポジトリarn
conditions={
"StringEqualsIfExists": {
"codecommit:References": [
"refs/heads/main",
"refs/heads/master",
]
},
"Null": {
"codecommit:References": "false"
}
}
)
]
)
カスタムIAMポリシーの挙動確認結果
接続元IPアドレスの制限は、両グループとも期待通りの結果となりました。
$ git pull
fatal: unable to access 'https://git-codecommitXXXXXXXXX': The requested URL returned error: 403
一般ユーザ向けのマスターブランチへのプッシュを拒否するポリシーの挙動も期待通りでした。
$ git push origin master:master
To https://git-codecommitXXXXXXXXX
! [remote rejected] master -> master (You don't have permission to push changes to this branch.)
error: failed to push some refs to 'https://git-codecommitXXXXXXXXX'
開発してみて
IaCのよさについて、個人的には再現性・再利用性が魅力だと感じています。
- コードさえあれば誰でも同じ環境を構築可能
- 今回のケースでは、対象とするリポジトリを動的に変更可能な設計とすることで、同じような権限を他のリポジトリにも適用可能
最後に
IP制限やマスターブランチへのPush/Mergeの拒否といった制限はよくあるケースだと思います。
この記事がどれほど小さくとも、どなたかのお役に立てれば嬉しいです。