AWS IoT Coreで特定のトピックにのみpublishできるようにする

AWS IoT Coreで特定のトピックにのみpublishできるようにする

AWS IoT Coreを使ってみたのですが、ネットで情報を漁っていると意外と古い&ざっくりした情報が多く、トピックごとの権限を設定するのに少し詰まったので、備忘録として残しておきます。

AWS IoT Coreのリソース作成

まずはAWSのマネジメントコンソール上で、IoT Coreの設定を行っていきます。以下のサイトで詳しく書いてあったので、参考にしました。「AWS IoTにモノを登録」の段落の通り進めていけば設定完了です。

https://note.com/imaimai/n/n2646d75674b2

Publisherを作成(Node.js)

上記のIoT CoreにMQTTで5秒ごとにデータを送信するプログラムをNode.jsで記載しました。

const awsIot = require('aws-iot-device-sdk');

const device = awsIot.device({
  keyPath: './certs/xxx.pem',
  certPath: './certs/xxx.pem.crt',
  caPath: './certs/AmazonRootCA1.pem',
  clientId: 'test',
  host: 'xxx.iot.ap-northeast-1.amazonaws.com'
});

device.on('connect', function () {
  console.log('connect');
  setInterval(function () {
    const value = { name: "random name", age: Math.floor(Math.random() * 100) };
    device.publish('test', JSON.stringify(value));
  }, 5000);
});

keyPath、certPathの箇所はIoT Coreのリソース作成時に取得したファイルのパスを記載します。hostの箇所も、上記参考URLに確認の仕方が載っているのでそちらを記載します。
debice.publishの第一引数で設定している文字列(’test’)が送信先のトピックとなります。

トピックに送信されていることの確認

IoT Coreのサイドメニューにある”テスト”という項目をクリックすると、以下のような画面が開くので、”トピックのサブスクリプション”という箇所に、Node.jsのコードで指定したトピック名(test)を指定します。

あとは、”トピックのサブスクライブ”というボタンをクリックすればOK。上記のNode.jsのプログラムを起動していれば、以下のようにデータが表示されるはずです。

特定のトピックにしか送信できないようポリシーを変更する

現状の設定だと、証明書を持っていればどのトピックにでもデータを送信できるようになっているので、特定のトピックにしかデータを送信できないように証明書のポリシーを変更していきます。
証明書に紐づけたポリシーのドキュメントを以下のように設定すればOKです。(特定のクライアントからしか接続を受け付けない設定も混じってしまっています。)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Publish",
        "iot:Receive"
      ],
      "Resource": [
        "arn:aws:iot:ap-northeast-1:xxx:topic/test"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Connect"
      ],
      "Resource": [
        "arn:aws:iot:ap-northeast-1:xxx:client/test"
      ]
    }
  ]
}

xxxとなっている箇所は、自分のアカウント名に変更してください。