はじめに
こんにちは!三宅です! やっと杉の花粉が落ち着いてきて安心しています。
さて、外部ベンダーに自社 AWS アカウントの AWS CodeArtifact へアクセスしてもらう必要が出てきました。 ベンダーがライブラリをプッシュしたり、こちらがそれを取得したりするケースです。
「どうやってアクセスを提供するのがいいんだろう?」と思い、考えられる方法を調べて比較してみました。
結論から言うと、今回は AWS IAM Identity Center(SSO)を使う方法を採用しました。 この記事では、4 つのアクセス方法を比較した上で、採用した方法の概要を紹介します。
外部ベンダーに CodeArtifact へのアクセスをどう提供するか悩んでいる方の参考になれば幸いです。
前提条件
- AWS CodeArtifact は、AWS が提供するフルマネージドのソフトウェアアーティファクトリポジトリサービスです
- npm、pip、Maven などのパッケージマネージャーと連携し、パッケージを管理できます
- 今回の要件は以下の通りです
- 外部ベンダーが、自社 AWS アカウントの CodeArtifact リポジトリにパッケージをプッシュ/プルする
- 最小権限の原則で運用したい
- AWS Organizations を使用した環境がある
考えられるアクセス方法
外部ベンダーに CodeArtifact へのアクセスを提供する方法として、以下の 4 つが考えられます。
1. IAM ユーザー(アクセスキー)
ベンダー専用の AWS Identity and Access Management (IAM) ユーザーを作成し、アクセスキーとシークレットキーを発行して渡す方法です。
最もシンプルですが、長期的な認証情報を外部に渡すことになるため、認証情報の漏洩、不正な共有、盗難といった不必要なリスクが発生します。
2. IAM ロール(クロスアカウント スイッチロール)
ベンダーが持つ AWS アカウントの IAM ロールから、自社アカウントの IAM ロールにスイッチロール(AssumeRole)する方法です。
一時的な認証情報を使えますが、ベンダー側に AWS アカウントが必要です。
また、対象アカウントの IAM ロールの信頼ポリシーにベンダーのアカウント情報(アカウント ID やロール ARN)を直書きする必要があり、ベンダーのアクセスが不要になった際に、信頼ポリシーからこれらの情報を削除する運用も手間になります。
3. IAM Identity Center(SSO)
AWS IAM Identity Center でベンダー用の SSO ユーザーを作成し、許可セットを割り当てる方法です。
一時的な認証情報でアクセスでき、ユーザーのライフサイクル管理もしやすいです。
今回はこの方法を採用しました。 詳しい設定手順は後述します。
4. CodeArtifact リソースポリシー
CodeArtifact のドメインポリシーとリポジトリポリシーの両方を設定し、ベンダーの AWS アカウントからのクロスアカウントアクセスを許可する方法です。
CodeArtifact 側の設定で完結しますが、ベンダー側にも AWS アカウントが必要です。
また、ドメインポリシーにベンダーのアカウント情報(アカウント ID やロール ARN)を直書きする必要があり、ベンダーのアクセスが不要になった際に、リソースポリシーからこれらの情報を削除する運用も手間になります。
比較表
| 検討案 | セキュリティ | 運用管理 | 総合評価 | 実装内容 | 備考 |
|---|---|---|---|---|---|
| 1. IAM ユーザー(アクセスキー) | × | △ | × | IAM ユーザーを作成しアクセスキーを発行 | 導入は簡単だが、長期認証情報の管理リスクがあり非推奨 |
| 2. IAM ロール(スイッチロール) | ◎ | ○ | ○ | 対象アカウントに IAM ロールを作成し、外部アカウントからスイッチロール | 一時的な認証情報で安全性が高い。ただしベンダー側に AWS アカウントが必要で、対象アカウントの信頼ポリシーにアカウント情報の直書きが必要 |
| 3. IAM Identity Center(SSO)【採用】 | ◎ | ◎ | ◎ | IAM Identity Center でユーザーを作成し、許可セットを割り当てる | 一時的な認証情報・MFA 対応・ユーザー単位の管理が可能。ベンダー側に AWS アカウント不要。ただし AWS Organizations の利用が前提 |
| 4. CodeArtifact リソースポリシー | ○ | △ | △ | CodeArtifact のポリシーに外部アカウント情報を直接記述してアクセスを許可 | CodeArtifact 側の設定で完結する。ただしベンダー側に AWS アカウントが必要で、ポリシーにアカウント情報の直書きが必要 |
比較のポイント
大きな分岐点は 「ベンダーが AWS アカウントを持っているかどうか」 です。
- ベンダーが AWS アカウントを持っていない場合: IAM ユーザーか IAM Identity Center の 2 択になります
- ベンダーが AWS アカウントを持っている場合: クロスアカウント スイッチロールや CodeArtifact リソースポリシーも選択肢に入ります
今回はベンダーの AWS アカウント有無に依存しない構成を前提とし、AWS アカウントが不要な IAM ユーザーと IAM Identity Center の 2 つに絞りました。
その上で、一時的な認証情報を使える点とユーザーのライフサイクル管理がしやすい点を重視し、IAM Identity Center を採用しました。
IAM Identity Center(SSO)で外部ベンダーに CodeArtifact へのアクセスを提供する方法
構成の概要
ベンダーのローカル環境 ↓ aws sso login IAM Identity Center(管理アカウント) ↓ 許可セット(CodeArtifact 読み取り専用 or 読み書き) 対象の AWS アカウントの CodeArtifact
ベンダーには IAM Identity Center のユーザーアカウントを発行し、SSO 経由で対象の AWS アカウントの CodeArtifact にアクセスしてもらいます。
事前準備(AWS コンソール側)
1. カスタム許可セットを作成する
参考: 許可セットの概念
IAM Identity Center コンソール > [マルチアカウントのアクセス許可] > [許可セット] > [許可セットを作成] から、以下のように設定します。
- 許可セットのタイプ: カスタム許可セット
- インラインポリシーに以下を設定する
このポリシーでは、以下の権限を付与しています。
| Sid | 権限の内容 |
|---|---|
AllowAuthToken |
CodeArtifact の認証トークンを取得する(aws codeartifact get-authorization-token に必要) |
AllowBearerTokenOnlyForCodeArtifact |
CodeArtifact 用のベアラートークンを取得する(pip や npm での認証に必要) |
AllowReadAccessToSpecificDomainAndRepo |
指定したドメイン・リポジトリの情報参照とパッケージの読み取り |
Resource には特定のドメインとリポジトリの ARN を指定しているため、ドメインの情報(リポジトリ一覧など)は参照できますが、パッケージの読み取りは指定したリポジトリに限定されます。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAuthToken", "Effect": "Allow", "Action": "codeartifact:GetAuthorizationToken", "Resource": "*" }, { "Sid": "AllowBearerTokenOnlyForCodeArtifact", "Effect": "Allow", "Action": "sts:GetServiceBearerToken", "Resource": "*", "Condition": { "StringEquals": { "sts:AWSServiceName": "codeartifact.amazonaws.com" } } }, { "Sid": "AllowReadAccessToSpecificDomainAndRepo", "Effect": "Allow", "Action": [ "codeartifact:List*", "codeartifact:Describe*", "codeartifact:Get*", "codeartifact:ReadFromRepository" ], "Resource": [ "arn:aws:codeartifact:<リージョン>:<アカウントID>:domain/<ドメイン名>", "arn:aws:codeartifact:<リージョン>:<アカウントID>:repository/<ドメイン名>/<リポジトリ名>", "arn:aws:codeartifact:<リージョン>:<アカウントID>:package/<ドメイン名>/<リポジトリ名>/*" ] } ] }
ベンダーにパッケージのプッシュも許可する場合は、AllowReadAccessToSpecificDomainAndRepo の Action に以下を追加します。
codeartifact:PublishPackageVersioncodeartifact:PutPackageMetadata
許可セット名は CodeArtifactReadOnly などわかりやすい名前にしておきます。
セッション時間の変更
参考: セッション期間の設定
許可セットのセッション時間はデフォルトで 1 時間ですが、最大 12 時間まで延長できます。
IAM Identity Center コンソール > [マルチアカウントのアクセス許可] > [許可セット] > 対象の許可セットを選択 > [一般設定] > [編集]
ベンダーの作業時間に合わせて調整すると、頻繁な再ログインを避けられます。
2. ユーザー / グループを作成する
参考: IAM Identity Center クイックスタート
IAM Identity Center コンソール > [ユーザー] > [ユーザーの追加] から、以下のように設定します。
- [ユーザー名]、[E メールアドレス]、[名]、[姓]、[表示名] を入力
- [パスワード] — 「このユーザーにパスワード設定の手順を記載した E メールを送信(推奨)」 を選択
- グループを作成してユーザーを追加する(例:
codeartifact-readonly-group)
グループにまとめておくと、ベンダーの追加・削除が楽になります。
3. 対象の AWS アカウントに割り当てる
参考: ユーザーの割り当て
IAM Identity Center コンソール > [マルチアカウントのアクセス許可] > [AWS アカウント] から、以下の手順で割り当てます。
- 対象の AWS アカウントのチェックボックスをオンにする
- [ユーザーまたはグループを割り当て] を選択する
- [グループ] タブで作成したグループを選択し、[次へ] を選択する
- 作成した許可セット(例:
CodeArtifactReadOnly)を選択し、[次へ] を選択する - 内容を確認して [送信] を選択する
ベンダー側の設定(初回のみ)
4. aws configure sso を実行する
参考: AWS CLI の SSO 設定
ベンダーには以下のコマンドを実行してもらいます。
aws configure sso
プロンプトに以下を入力します。
SSO session name: <任意のセッション名> SSO start URL: https://<ポータルURL>.awsapps.com/start SSO region: ap-northeast-1 SSO registration scopes: sso:account:access
ブラウザが自動的に開くので、IAM Identity Center にログインします。
ログイン後、CLI に戻って続きを入力します。
# 表示されたアカウント一覧から対象の AWS アカウントを選択 # 表示されたロール一覧から CodeArtifactReadOnly を選択 Default client Region: ap-northeast-1 CLI default output format: json Profile name: <任意のプロファイル名>
設定後、~/.aws/config に以下のようなプロファイルが保存されます。
[profile <プロファイル名>] sso_session = <セッション名> sso_account_id = <対象の AWS アカウントID> sso_role_name = CodeArtifactReadOnly region = ap-northeast-1 output = json [sso-session <セッション名>] sso_start_url = https://<ポータルURL>.awsapps.com/start sso_region = ap-northeast-1 sso_registration_scopes = sso:account:access
日常の使い方
5. SSO ログイン(セッション切れのときだけ)
aws sso login --profile <プロファイル名>
セッションが有効な間(設定した時間、最大 12 時間)は再ログイン不要です。
6. CodeArtifact の認証トークンを取得してパッケージを操作する
SSO ログイン後、通常の CodeArtifact コマンドが使えます。
# 認証トークンの取得(pip/npm 等で使用) aws codeartifact get-authorization-token \ --domain <ドメイン名> \ --query authorizationToken \ --output text \ --profile <プロファイル名>
まとめ
外部ベンダーに AWS CodeArtifact へのアクセスを提供する方法として、4 つのアプローチを比較しました。
ベンダーが AWS アカウントを持っているかが最初の分岐点ですが、特に IAM ユーザー方式は以下の理由で非推奨と判断しました。
- 長期認証情報のローテーションが必要
- 認証情報の共有・漏洩・盗難リスクがある
一方、IAM Identity Center(SSO)方式は以下が可能なため、より安全かつ運用しやすいと判断しました。
- 一時的な認証情報
- MFA の強制が可能
- ユーザー単位で権限を管理でき、ベンダーの追加・無効化も容易
ベンダーが AWS アカウントを持っている場合でも、運用のシンプルさやユーザー単位の管理を重視するなら IAM Identity Center を選ぶケースが多いと考えています。
AWS Organizations の環境があるなら、ぜひ検討してみてください。
参考リンク
- AWS CodeArtifact ユーザーガイド
- AWS IAM Identity Center ユーザーガイド
- CodeArtifact のドメインポリシー
- IAM Identity Center の許可セット
- Beyond IAM access keys: Modern authentication approaches for AWS — AWS Security Blog