aws login で default プロファイルを “使えなくした” はなし

記事タイトルとURLをコピーする

神奈川県からこんにちは、アプリケーションサービス部の千葉です。

以前、AWS CLI/SDK認証の新時代:aws login で変わる開発体験 という記事を書きました。
ブラウザ認証だけで一時認証情報が自動セットされる、あの aws login です。
あれからすっかり aws login で生活しているのですが、しばらく使ううちに、ひとつ「これは事故るな」と思う瞬間がありました。

今回はその話と、それを「使わないように気をつける」のではなく 「使えなくした」 んです。ってポストです。

便利になった、その裏で

aws login はとても便利なのですが、私の手元には複数プロジェクトの開発用アカウントプロファイルが並んでいます。
日常的にこれらを行ったり来たりしています。

ここで aws login のプロファイル解決順を思い出してみます。AWS CLI 共通のルールで、

--profile フラグ  →  環境変数 AWS_PROFILE  →  default

の順に解決されます。つまり --profile を付け忘れ、AWS_PROFILE も設定していなければ default に適用される ということです。

私の ~/.aws/config には [default] がいます。
そして default が指している先は、付け忘れたときに一番入ってほしくないアカウントだったりするわけです。

flowchart TD
    A["aws login(--profile 付け忘れ)"] --> B{プロファイル解決}
    B -->|--profile なし| C[環境変数 AWS_PROFILE]
    C -->|未設定 / default| D["default プロファイル"]
    D --> E["意図しないアカウントに<br/>認証情報がセットされる"]
    E --> F["気づかず deploy / delete …💥"]

頭では別アカウントだと分かっているつもりなのに、手癖で aws login と打鍵してしまう。
aws login は何食わぬ顔で default のブラウザ認証を済ませてくれる。
そのまま cdk deploy まで突き進む——。
まだやらかしてはいませんが「オレはいつかヤルぞ」と確信できる程度には、ヒヤッとしました。

※ 事故防止の目的(だと思います)で、AWSコンソールでアカウントNoの確認をするようになっています。が、それでも『オレはいつかヤル』と思ってます

「使わないようにする」では足りない

ここで普通に思いつくのは「default を使わないように気をつける」です。--profile を必ず付ける、という運用ルールにする。

でも、ルールは破られます。
正確には、疲れているときや急いでいるときに限って破られます
--profile の付け忘れというのは、まさにそういうときに起きます。
「気をつける」で防げるなら、世の中の事故はとっくに絶滅しているはずなのです。

課題:

  • 付け忘れは「気をつける」で防げる類のミスではない(注意力は枯渇する)
  • default が存在する限り、無指定の aws login はいつでも成立してしまう
  • 一番危ないアカウントへの動線が、一番打ちやすいコマンドに割り当たっている

つまり私が欲しかったのは「default を使わない自分」ではなく default を使えない仕組み」 でした。
規律ではなく、ガードレールです。
落ちてはいけない崖にガードレールを立てたかったんです。

aws login 側に “禁止” 設定は無い

まず期待したのは、aws login の設定で default を禁止できないか、でした。が、結論から言うと ありません

  • aws login は AWS CLI v2 ネイティブのコマンドですが、「特定プロファイルを禁止する」ようなオプションや設定キーは用意されていません
  • ~/.aws/config から [default] を消すという手もありますが、それでも無指定の login はエラーにならず、対話的にセッション選択を促すだけ。ブロックにはなりません

AWS CLI 側で防止できないなら、その手前——シェルで塞ぐしかありません。

シェルのラッパーで “使えなくする”

私のシェルは zsh なので、~/.zshrcaws 関数を一枚かぶせました。
aws login のときだけ前段でプロファイルを検査し、default 行きになる呼び出しを弾きます。login 以外のサブコマンドには一切触りません。

# aws login で default プロファイルを使わせない(明示的な --profile を必須にする)
# login 以外のサブコマンドには影響しない。
aws() {
  if [[ "$1" == "login" ]]; then
    # --profile=default / --profile default を明示的に禁止
    local prev="" arg
    for arg in "$@"; do
      if [[ "$arg" == "--profile=default" ]] || [[ "$prev" == "--profile" && "$arg" == "default" ]]; then
        print -u2 "aws login: default プロファイルは使えません。default 以外の --profile を指定してください。"
        return 1
      fi
      prev="$arg"
    done
    # --profile 無指定 かつ AWS_PROFILE が未設定/default なら拒否
    if [[ "$*" != *"--profile"* && ( -z "$AWS_PROFILE" || "$AWS_PROFILE" == "default" ) ]]; then
      print -u2 "aws login: --profile を指定してください(例: aws login --profile dev)。"
      return 1
    fi
  fi
  command aws "$@"
}

やっていることは単純です。

  • aws login のときだけ介入する
  • --profile default / --profile=default明示的な default 指定 を弾く
  • --profile 無指定で、かつ AWS_PROFILE が未設定か default暗黙の default 行き を弾く
  • それ以外(aws login --profile devaws s3 ls など)は command aws でそのまま素通し
flowchart TD
    A["aws login ..."] --> B{default に行く?}
    B -->|"--profile 明示あり<br/>かつ default 以外"| P["command aws へ素通し ✅"]
    B -->|"無指定 / AWS_PROFILE=default<br/>/ --profile default"| R["return 1 で拒否 🚧"]
    R --> M["『--profile を指定してください』"]

ちゃんと弾けるか確認する

仕組みを入れたら、ちゃんと効くかは確認するのが優秀なエンジニアの条件です。代表的なパターンを確認してきました。

コマンド 結果
aws login(無指定) 🚧 ブロック
aws login --profile default 🚧 ブロック
aws login --profile=default 🚧 ブロック
AWS_PROFILE=default aws login 🚧 ブロック
aws login --profile dev ✅ 通過
AWS_PROFILE=dev aws login ✅ 通過
aws sts get-caller-identity(login 以外) ✅ 通過(影響なし)

狙いどおり、default に行く経路だけがすべて塞がれ、明示的にプロファイルを指定したときと、login 以外のコマンドはまったく影響を受けません。

ガードレールが “効く範囲” について

これは完璧なガードレールではありません。

  • 効くのは 対話シェル経由で aws を叩いたとき だけです。スクリプト内で command aws や絶対パスの /usr/local/bin/aws を呼ぶ経路、CI のような別環境 には効きません
  • そもそも悪意ある回避を防ぐものでもありません

やっつけたいのは「悪意」ではなく 「うっかり」 なので、これでも目的の大半は果たせます。
でも、さっき自分で書いた穴——「スクリプトや SDK には効かない」——がやっぱり気になる。
cdk deploy の裏で認証情報を解決する SDK や、無指定の aws s3 ls は、ラッパーをすり抜けて default に吸い込まれ得るわけです。
なら、もう一段。もっと根っこに、二本目のガードレールを立てます。

ダメ押し:~/.aws/config から [default] を消す

ラッパーが守れるのは「対話シェル経由の login」だけ。
スクリプトや CI、cdk deploy の裏で動く SDK には届きません。
彼らが見ているのは、もっと根っこの プロファイル解決そのもの だからです。

なので、根っこから断つことにします。~/.aws/config から [default] を消してしまう。

-[default]
-region=ap-northeast-1
-login_session = arn:aws:sts::xxxxxxxxxxxx:assumed-role/.../you
-
 [profile dev]
 ...

こうすると、--profileAWS_PROFILE も無いコマンドは、default に黙って当たる」のではなく「認証情報が見つからず即エラー」 になります。
しかもこれは login に限りません。aws s3 lscdk deploy も、無指定なら等しく止まります。

ただし、これが成立するには前提があります。

前提:

  • ~/.aws/credentials に静的な [default](長期キー)が無いこと
    aws login に切り替えたタイミング にファイルごと捨てました
  • シェルに AWS_ACCESS_KEY_IDAWS_PROFILE を export していないこと
    → 当然つかってない

要は「default の認証情報を供給する別経路が存在しない」状態であること。
私の環境はどちらも満たしていたので、[default] を消した瞬間、無指定 = 即停止になりました。

確かめてみます。

$ aws sts get-caller-identity
aws: [ERROR]: An error occurred (NoCredentials): Unable to locate credentials.
You can configure credentials by running "aws login".

$ aws sts get-caller-identity --profile dev
{ ...正しく dev の Identity が返る... }

無指定はピシャリと閉じ --profile dev はちゃんと通る。狙いどおりです!

ついでに、未来の自分がうっかり書き戻さないよう、消した跡地にコメントだけ残しておきました。

# [default] は意図的に置かない。
# 無指定の操作を「default に黙って当たる」のではなく
# 「認証情報なしで即エラー」にして、--profile の明示を強制するため。復活させないこと。

ラッパーと [default] 削除は、役割が違います。

シェルラッパー [default] 削除
守備範囲 aws login だけ 全コマンド + SDK / CDK
効く場所 対話シェルのみ スクリプト・絶対パス呼びでも効く
役割 気づかせて止める 手前のガードレール そもそも持たせない 最終ガードレール

一番打ちやすいミスを手前で気づかせて止めるガードレールと、その奥でそもそも通さないガードレール。
どちらも「予防的ガードレール」です。同じ種類を、二重に立てます。

「AI に壊された」も、たぶん根っこは同じ

最近、テック系のニュースやブログを見ていると「AI に仕事をやらせたら ◯◯ が吹き飛んだ」みたいな投稿が増えてきました。
過激なタイトルでアクセスを稼ぎたい、という側面もあるのかもしれません。
でも中身を読んでみると、多くの場合は 生成 AI に必要以上の権限を渡していた とか、
今回のように トラブルの原因になりそうな仕様に対策を打っていなかった ことが、本質的な問題のように感じています。

人間も --profile を付け忘れます。生成 AI も悪気なく default に当たりにいきます。
どちらも「気をつける」「ちゃんとお願いする」では止まりません。
止めるのは、いつだって仕組み——ガードレールの側です。

裏を返せば、今日 aws login に立てたガードレールは、そのまま AI エージェントに作業を任せるときのガードレール でもあります。
「壊さないでね」とお願いするのではなく「壊せない環境」を渡す。
やることは、まったく同じです。

まとめ:「使わない」と「使えない」は違う

最後に Before / After で整理します。

観点 Before(使わないようにする) After(使えなくする)
防御の主体 自分の注意力 仕組み(シェル)
付け忘れたとき default に入ってしまう その場で return 1、入れない
再現性 疲れていると破れる いつでも同じ挙動
守備範囲 自分が見ている画面だけ シェルも SDK も CDK も
直すべき場所 自分の心がけ ~/.zshrc~/.aws/config の数行

default を使わないようにしよう」と心に誓うことでは何も解決しません。
誓いは疲労で溶けます。

一方「default を使えないようにする」は、二度と同じことを考えなくてよくなります。
判断を仕組みに委任した ぶんだけ頭が軽くなります。

aws login を複数アカウントで利用している方は、ぜひご自身の手元にも 二重のガードレール(ラッパー+[default] 削除) を設定してください。
パラメータを付け忘れた未来のアナタが、きっと今日のアナタに感謝するんじゃないかな。と

それでは、よい aws login ライフを。

千葉 哲也 (執筆記事の一覧)

アプリケーションサービス部

コーヒーゼリーが好きです。