さわらブログ

さわら(@xhiroga)の技術ブログ

書評 - AWSの薄い本Ⅱ アカウントセキュリティのベーシックセオリー

booth.pm

アップデートの早い AWS のアカウントセキュリティ界隈において、2020 年時点での最新がキャッチアップできる本でした。

個人的には以前から興味のあったテーマなので知っていることも多かったです。しかし、以下の 2 点を新たに知ることができたのが収穫でした。

  1. Organization と StackSets が連携できる。新たに Organization に加わったアカウントがあれば自動で StackSets の Stack を展開できるようになること。
  2. アカウントセキュリティの各種サービスと Security Hub の連携について。

以下、私の感想と見解。

Organization と StackSets の連携

第 5 章 CloudFormation を利⽤した構成管理で紹介されている AWS の機能です。

筆者の紹介通り、IAM との相性の良いサービスだと思いました。 私の関わっている案件では、同じスタックを複数の環境にデプロイするために CircleCI のワークフローを使っています。しかしながらこの運用、アカウントが増えるたびにワークフローを追加するのが辛かった。 Organization+StackSets をありがたく利用したいと考えています。

ただ、アカウント周りに関しては AWS SSO でも良いのかもしれませんね。 AWS CLIAWS CDK と SSO の相性を調べていないのでなんとも言えないのですが、より楽な方を選びたいものです。

IAM 以外で個人的に検討していたのが、AWS Config の管理です。 AWS Config はちょくちょくルールを追加したくなることが予想されたので、なんらかの方法で自動的に更新したいなと考えていました。 さて本件、ちょっと罠がありました。(2021 年 4 月時点) StackSets に登録している CFn テンプレートを更新するということは、StackSets 自体を CloudFormation のスタックで管理したくなりますよね?(ややこしい) ところが、CloudFormation の StackSets リソースは DELEGATED_ADMIN を使った SERVICE_MANAGED スタックセットの作成をサポートしていません。

ここで新しい概念、DELEGATED_ADMIN について。StackSets を複数アカウントに適用するには、Organization の親アカウントに登録する方法と、親アカウントが認めたアカウントに登録する方法があります。 後者が DELEGATED_ADMIN ですね。AWS が推奨する方法も後者です。 これは納得できて、Organization の親アカウントなんか SRE が普段使いするのに相応しくありません。

ところが CloudFormation は DELEGATED_ADMIN として SERVICE_MANAGED(Organization と連携している、という意味)の StackSets の作成に対応していないとのこと。 やるなら API 叩くことになるんですね。うーん。。。今後に期待です。

アカウントセキュリティの各種サービスと Security Hub の連携について

第 7 章 障害の検知と復旧の考え⽅で紹介されています。

この章の具体的な内容が役立ったというより、アカウントセキュリティの通知の複雑さについて共感できたのが嬉しかったです。

とはいえ、まずは Security Hub と GuardDuty, AWS Config の繋ぎこみをした方が良いという筆者の見解に同意です。 それで通知の具合が良くない時に個別の設定をすれば良いかなと。

まあ一番嬉しいのは Control Tower が AWS Config に加えて Guarduty, Security Hub の設定を全部やってくれることなんですけどね。

Control Tower と GuardDuty の連携については公式ブログがあったのでご参考まで。

Enabling Amazon GuardDuty in AWS Control Tower using Delegated Administrator

まとめ

知るべきことが多い上にアップデートが早いアカウントセキュリティについて日本語でまとめられた貴重な本でした。 サクッと読んで知らない知識を補完するだけでも価値はあると思うので、気になる方は読まれると良いのではないでしょうか。

GitHub / TwitterのID変更をLAPRASに連携する

TL;DR

  • その他のログイン手段を用意する
  • GitHub, Twitter側のOIDC連携を解除する
  • LAPRAS側の連携を解除し、再接続

Step by step

その他のログイン手段を用意する

例えばQiitaがオススメです。

f:id:hiroga_cc:20210426091333p:plain
Login by Qiita

GitHub, Twitter側のOIDC連携を解除する

GitHubのOIDC連携の解除

https://github.com/settings/applications

TwitterのOIDC連携の解除

https://twitter.com/settings/connected_apps

LAPRAS側の連携を解除し、再接続

×ボタンで連携解除。この時、ログイン手段がなくなるケースでは連携解除ができません。

f:id:hiroga_cc:20210426091639p:plain
×ボタンで連携解除

1PasswordでItem Historyが見られない → Vaultを移動するとItem Historyがリセットされるようです。

TL;DR

1PasswordのItem Historyは、Vaultを移動すると無効化されます。

support.1password.com

検証

移動前のItemには View Item History が表示されています。

f:id:hiroga_cc:20210421104315p:plain
移動前のItem

移動後、 View Item History が消えました。

f:id:hiroga_cc:20210421104732p:plain
移動後のItem

再び元のVaultに戻しても、 View Item History は消えたままです。

f:id:hiroga_cc:20210421104904p:plain
再移動後のItem

まとめ

Vaultを移動するとItem Historyはリセットされ、再び元のVaultに戻しても蘇りません。 重要な項目が消えてしまった際など、ついうっかりVaultを移動しないようにしましょう。 逆に言えば、Historyを削除したい時には便利かもしれませんね(リセットがどのような挙動か解明できたわけではないので、厳密な用途ではオススメしません)

Expo製のReact Nativeアプリで Firebase を設定したはずなのに `Unhandled Rejection (Error): Firebase JS Analytics SDK is not available` → config の階層が間違っているかも?

TL;DR

誤り

    "web": {
      "favicon": "******",
      "config": {
          "apiKey": "******",
          "authDomain": "******",
          "projectId": "******",
          "storageBucket": "******",
          "messagingSenderId": "******",
          "appId": "******",
          "measurementId": "******"
      }
    },

正解

    "web": {
      "favicon": "******",
      "config": {
        "firebase": {
          "apiKey": "******",
          "authDomain": "******",
          "projectId": "******",
          "storageBucket": "******",
          "messagingSenderId": "******",
          "appId": "******",
          "measurementId": "******"
        }
      }
    },

config の内側に firebase という階層も必要でした。

CircleCIでProjectのセットアップに失敗して Try Again → リポジトリの Deploy KeyとWebhookを見てみよう

TL;DR

CircleCIでリポジトリのセットアップ時、そのリポジトリに既にWebhookが登録されているとエラーになるらしい。
条件は不明だが、リポジトリの名前の変更が関係あるかも。

対策としては、CircleCI由来のデプロイキーとWebhookを全部消せばとりあえずOK。

f:id:hiroga_cc:20210317100205p:plain
{"message":"{"message":"Validation Failed","errors":[{"resource":"Hook","code":"custom","message":"Hook already exists on this repository"}],"documentation_url":"https://docs.github.com/rest/reference/repos#update-a-repository-webhook"}"}

{"message":"{\"message\":\"Validation Failed\",\"errors\":[{\"resource\":\"Hook\",\"code\":\"custom\",\"message\":\"Hook already exists on this repository\"}],\"documentation_url\":\"https://docs.github.com/rest/reference/repos#update-a-repository-webhook\"}"}

Contentful にコンテンツが追加されたらツイートする by IFTTT(ノーコード)

TL:DR

ContentfulでIFTTTが用意したWebhookを叩いてツイートします。 (Zapierの方が簡単ですが、個人開発ではWebhookが無料で利用できるIFTTTがオススメです)

手順

  1. IFTTTのワークフローを設定する
  2. ContentfulでWebhookを叩く

IFTTTのワークフローを設定する

特に難しいことはなく、IFTTTで Webhook → Twitterの連携を設定します。

f:id:hiroga_cc:20210207175234p:plain
If Maker Event "tweet", then Post a tweet

ツイートの文章はIFTTT側に入れないのがポイントです。
Contentful以外のサービスからもWebhook経由でツイートしたい場合があるのを見越して、ワークフローを他のサービスと共用にするためです(IFTTTの無料枠が3枠なので節約するに越したことはない)
要するに、IFTTTはあくまでTwitterに付随するWebhookとして使います。

f:id:hiroga_cc:20210207174938p:plain
webhook to tweet

2. ContentfulでWebhookを叩く

IFTTTのWebhookエンドポイントにクセがあるので注意です。 ポイントは2点。

  1. Webhookのエンドポイントはワークフローの画面ではなく、プロフィール > My Services > Webhookから確認する。
  2. ContentfulのContent Typeは application/json に設定する。
  3. ツイートの文面をContentfulのWebhook側に埋め込む。

Content Typeについて、Zapierの場合はデフォルトの "application/vnd.contentful.management.v1+json" でも受け付けてくれます。優しいですね。

ツイートの文面のPayloadはこんな感じです。
実験したところ改行コード(\n)はツイートにも反映されました。ありがたい。

{
  "value1": "{ /payload/fields/title/en-US }\n新しい記事を公開しました!"
}

それからWebhookの発火タイミングですが、ユースケース次第ではあるものの「記事が投稿された場合に発火」ならEntryの Publishだけにチェックすれば良さそうです。

f:id:hiroga_cc:20210207175633p:plain
Entry(おそらくContentの旧称)

デバッグ時には何度もコンテンツをPublishする必要がありますが、記事のステータスを Unpublish → Publish に切り替えれば何度でも投稿できます。楽ですね。

まとめ

TwitterにWebhookを生やす感覚でIFTTTを使っていこう、という話でした。

Google Apps Script GitHub アシスタント で Error [github assistant] undefined と表示される → Google Apps Script API をオンにしよう

TL;DR

Google Apps Script GitHub アシスタント で Pull に失敗し、かつ Error [github assistant] undefined を表示されている場合、Google Apps Script API がオンになっていない可能性があります。

chrome.google.com

設定からオンにしましょう。

詳細

以下の通り、エラーが表示されることがあります。

f:id:hiroga_cc:20210130174536p:plain
Error [github assistant] undefined

Developer Consoleでログを見てみると...

{
  "error": {
    "code": 403,
    "message": "User has not enabled the Apps Script API. Enable it by visiting https://script.google.com/home/usersettings then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.LocalizedMessage",
        "locale": "en-US",
        "message": "User has not enabled the Apps Script API. Enable it by visiting https://script.google.com/home/usersettings then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
      }
    ]
  }
}

ユーザーがApps Script APIを有効にしていません。https://script.google.com/home/usersettings にアクセスして有効化し、再試行してください。最近この API を有効にした場合は、アクションが当社のシステムに伝搬するまで数分待ってから再試行してください。

ということで、APIをオンにしたら無事動きました。