【AWS IoT Core】デバイスメーカーとデバイス利用者の2者間で認証の役割分担はどう決めるか考えてみた(独自CAとAWS管理CA、証明書管理のメリット・デメリットを比較検討)

【AWS IoT Core】デバイスメーカーとデバイス利用者の2者間で認証の役割分担はどう決めるか考えてみた(独自CAとAWS管理CA、証明書管理のメリット・デメリットを比較検討)

Clock Icon2025.05.14

はじめに

こんにちは、コンサルティング部の神野です。

今回はIoTデバイスをAWS IoT Coreに接続する際の認証方式について、デバイスメーカーとデバイス利用者の二者がいた場合に導入する負担を考慮しながら、いくつかの選択肢を比較検討してみました。

この記事では、主に以下の3つの案について、それぞれのメリット・デメリット、そして「誰が何をやるのか?」という観点から深掘りしていきたいと思います。

  1. デバイスメーカー(または証明書発行の主体となる企業)が独自CAを構築し、デバイス証明書と秘密鍵を発行する案
  2. デバイスの利用者(またはサービス事業者)がAWS管理のCAを使用して、デバイス証明書と秘密鍵を発行する案
  3. (参考)外部のSaaSを利用する案

特に案3については、証明書発行・管理に関連する外部SaaSにも少し触れますが、これはあくまで参考情報として捉えてください。特定のサービスを推奨するものではありませんし、実際の要件への適合性やサポート体制については、各サービス提供元にご確認いただく必要があります。

それでは、早速確認してきます!

登場人物とシナリオについて

今回の話を進めるにあたって、登場する主な役割を整理しておきたいと思います。

  • デバイスメーカー

    • IoTデバイスを製造する企業。場合によっては、デバイスに組み込む証明書の発行主体にもなり得ます。ただし、自社でIoTプラットフォームを提供はしないとします。
  • デバイス利用者 / サービス事業者

    • 製造されたIoTデバイスを利用して、何らかのサービスを提供する企業や個人。デバイスをAWS IoT Coreに接続し、データを収集・活用します。

シナリオとしては、例えばデバイスメーカーA社が製造したデバイスを、サービス事業者B社が自社のAWS環境で利用する、といったケースを想像していただけると分かりやすいかもしれません。この場合、証明書の発行や管理をどちらの企業が担うのか、というのが重要なポイントになります。

認証方法についてはAWSが提供している下記資料が大変わかりやすいので、必要に応じてご参照ください。

https://pages.awscloud.com/rs/112-TZM-766/images/EV_iot-deepdive-aws2_Sep-2020.pdf

検討する認証方式の概要

改めて、今回比較検討する認証方式の概要です。

  • 案1: デバイスメーカーが独自CAで発行
    • デバイスメーカーがAWS Private CAなど独自の認証局(CA)を使用・管理し、デバイスごとの証明書と秘密鍵を発行します。
    • デバイス利用者は、提供された証明書と秘密鍵を使ってAWS IoT Coreに接続します。
  • 案2: デバイス利用者がAWS管理CAで発行
    • デバイスメーカーは証明書発行プロセスには関与せず、デバイス利用者自身がAWS IoT Coreの機能(AWS管理CA)を使って証明書と秘密鍵を発行・管理します。
  • 案3: 外部SaaS利用 (参考)
    • 証明書の発行・管理を、専門の外部SaaSプロバイダーに委託する方式です。

案1と案2の処理イメージと登場人物の整理フローは下記のようなイメージです。
(案3はあくまで参考意見なので含めておりません)

CleanShot 2025-05-12 at 17.58.20@2x

案1: デバイスメーカーが独自CAで証明書を発行するケースを深掘りしてみた

まずは、デバイスメーカーが中心となって証明書を発行する案です。この場合、デバイスメーカーがAWS Private CA (以下PCA) などを利用して独自の認証局(CA)を立て、そこから各デバイス向けの証明書と秘密鍵を発行するイメージですね。

作業範囲のイメージ

ざっくりとした作業範囲のイメージはこんな感じです。

CleanShot 2025-05-14 at 15.25.26@2x

証明書発行主体(デバイスメーカー)が独自CAを構築・管理し、証明書と秘密鍵を発行します。デバイス利用者(サービス事業者)は、提供された証明書と秘密鍵、そして発行主体のCA証明書を使って、自身のAWSアカウントのAWS IoT Coreにデバイスを接続します。

メリット

この方式のメリットとしては、以下のような点が考えられます。

  • 証明書の有効期限を柔軟にコントロール可能
    独自CAなので、証明書や秘密鍵の有効期限を自由に設定できます。AWS管理CAの場合、有効期限が2049年12月31日に固定されてしまうため、それ以上の長期利用を想定する場合は更新プロセスの検討が必須になりますが、独自CAならそのあたりも柔軟に対応できる可能性があります。
  • デバイス利用者の証明書管理負担軽減(の可能性)
    証明書発行主体が一括して証明書を発行することで、デバイス利用者側の証明書管理に関する手間を減らせるかもしれません。これは一種の付加価値として提供できる部分かなと思います。

デメリット

一方で、デメリットや考慮すべき点もいくつかあります。どれも重要な観点かと思います。

  • 関係者双方のAWSアカウントとマルチアカウント構成(もしくはそれに近しい環境)が前提
    この方式では、証明書発行主体デバイス利用者の両方がAWSアカウントを保有し、マルチアカウント構成で作業を分担する必要があります。そして、このマルチアカウント構成であるがゆえに、独自CAでの証明書・秘密鍵の発行が実質的に必須となります。
    • 証明書発行主体側の負担
      • 独自CAの管理(AWS Private CAの運用など)
      • 証明書・秘密鍵の作成・発行プロセスの構築・運用(後述するLambdaなどが必要になることも)
      • 発行プロセスの継続的なメンテナンス
      • 証明書関連のトラブル発生時の一次対応
    • デバイス利用者側の負担
      • 証明書発行主体から独自CAの証明書(CA証明書)を共有してもらい、自身のAWSアカウントのAWS IoT Coreに登録する作業
  • AWS Private CAのコスト
    AWS Private CAを利用する場合、月額400ドル(1CAあたり)の固定費に加えて、発行した証明書の数に応じた従量課金が発生します。このコストを製品価格などにどう転嫁するか、というビジネス的な検討も必要になりますね。
  • 証明書・秘密鍵のセキュアな受け渡し
    証明書発行主体は、発行したデバイス証明書と特に秘密鍵を、デバイス利用者にセキュアに受け渡す方法を確立する必要があります。あるいは、製造段階でデバイスに安全に書き込む仕組みも検討しなければなりません。ここは非常に重要なポイントです。
  • JITR (Just-in-Time Registration) の実装
    デバイスが初めてAWS IoT Coreに接続する際に、自動的にモノを登録したり、ポリシーをアタッチしたりするJITRのような仕組みを、デバイス利用者側のAWS環境で実装・運用する必要があります。

証明書・秘密鍵発行の具体的な実装イメージ

独自CAを使って証明書と秘密鍵を発行するプロセスは、具体的にどうなるのでしょうか。 現時点での実装イメージはこんな感じです。これはあくまで一例で、具体的な要件に合わせて調整が必要になります。下記は主に証明書発行主体が担当する処理のイメージですね。

CleanShot 2025-05-12 at 17.18.31@2x

AWSのマネージドサービスには、AWS Private CAのように「証明書を発行する」機能はありますが、「デバイス用の秘密鍵と公開鍵のペアを安全に生成し、その公開鍵を使ってPCAに証明書発行を依頼する」という一連の処理を自動で行う単一のマネージドサービスは、標準では提供されていません。(AWS IoT Coreにも証明書発行機能はありますが、マルチアカウント構成で独自CAを利用する場合は、この機能は直接利用できません)

そのため、図にあるようにAWS Lambdaのような「プログラムを実行できる環境」が必要になってくることが多いと思います。

この図の例では、Lambda関数が以下のような役割を担います。

  1. 秘密鍵と公開鍵のペアを生成します。 (例えば、OpenSSLなどの暗号ライブラリを利用)
  2. 生成した公開鍵を含むCSR (証明書署名リクエスト) を作成します。
  3. 作成したCSRをAWS Private CA (独自CA) に送信し、証明書の発行をリクエストします。
  4. PCAから発行された証明書を受け取ります。
  5. 生成した秘密鍵と、PCAから受け取った証明書を、安全な場所(図ではAmazon S3バケット)に保存します。

イメージではLambdaやS3を使用する前提としていますが、実際の要件や習熟度に合わせてコンピュート部分のアーキテクチャは検討いただくのがいいかと思います。

ちょっと深掘り1: なぜマルチアカウントだと独自CAが必要か?

「マルチアカウント構成だと独自CAが必要」と書きましたが、なぜでしょうか。
ちょっと例え話で説明してみたいと思います。

  1. AWS IoT Core は「会員制クラブ」みたいなもの
    まず、デバイス利用者のAWSアカウントにある「AWS IoT Core」を、セキュリティがしっかりした「会員制クラブ」だとイメージしてください。デバイスがこのクラブ(AWS IoT Core)に入る(接続する)ためには、有効な「会員証」(=デバイス証明書)を提示する必要があります。クラブの入り口には門番がいて、会員証が本物かチェックします。

  2. 会員証の「発行元」が超重要
    会員証(証明書)は、誰が発行したかが非常に重要です。クラブの門番は、「信頼できる発行元」からの会員証しか受け付けません。AWSには、大きく分けて2種類の発行元があります。

    • AWS管理CA
      AWSが各アカウント(クラブ)ごとに用意している、いわば「クラブ内部の受付」です。ここで発行される会員証(証明書)は、そのクラブ(アカウント)専用です。手軽ですが、他のクラブでは通用しません。

    • 独自CA (例:AWS Private CA)
      これは、自分で設立する「信頼できる身分証明書センター」のようなものです。ここで発行した身分証明書(証明書)は、事前に他のクラブに「このセンターが発行した証明書は信頼できますよ」と登録しておけば、複数のクラブで通用します。

  3. マルチアカウント構成での問題点
    案1の構成では、証明書発行主体(アカウントA)が証明書を発行し、デバイスはその証明書を持ってデバイス利用者(アカウントB)のAWS IoT Coreに接続しようとします。 もし証明書発行主体が、自身のアカウントAのAWS管理CAで証明書を発行したとします。デバイスがその証明書をアカウントBのAWS IoT Core(門番)に見せても、「これはアカウントA専用の証明書ですね。うち(アカウントB)では使えません」と拒否されてしまいます。アカウントが違うため、アカウントBのAWS IoT CoreはアカウントAのAWS管理CAが発行した証明書を信頼できないのです。

  4. 独自CAが解決策になる理由
    そこで登場するのが「独自CA」です。
    証明書発行主体(アカウントA)は、AWS Private CAを使って独自CAを設立します。次に、デバイス利用者(アカウントB)は、自身のAWS IoT Coreに、「証明書発行主体の独自CAは信頼できる」と登録します。こうすることで、証明書発行主体が独自CAで発行したデバイス証明書をデバイスが持ってアカウントBのAWS IoT Coreに接続しようとすると、「ああ、事前に登録された信頼できるCAが発行した証明書ですね。どうぞ」と、受け付けてくれるようになります。

つまり、複数のAWSアカウント間でデバイス認証を行う必要がある場合、アカウントをまたいで信頼される「共通の認証局(CA)」が必要になり、その役割をAWS Private CAで作る「独自CA」が果たしてくれるという理解です。

ちょっと深掘り2: JITRって何?なぜ案1で必要なの?

案1のデメリットとして「JITRなどのデバイス登録スキームをデバイス利用者側の環境で実装する必要がある」と書きました。この「JITR」とは何でしょうか?

JITRの基本

JITR(Just-in-Time Registration)は「ジャストインタイム登録」の略で、デバイスが初めて接続した時に自動的にシステムに登録する仕組みです。事前に一つ一つのデバイスを手作業で登録する必要がなくなるため、大量のデバイスを扱う場合に非常に便利です。

案1でJITRが必要な理由

会員制クラブの例で続けると、

  1. デバイスメーカー(アカウントA)が独自CAで発行した「会員証」(デバイス証明書)を持って、デバイスがデバイス利用者(アカウントB)のAWS IoT Coreに接続します。
  2. AWS IoT Coreは「この証明書は信頼できる発行元のもの」と確認できますが、一つ問題があります。この「信頼できる証明書を持った人」が、まだクラブの会員リストに登録されていない状態です。
  3. JITRの役割は、この「会員リストへの登録作業」を自動的に行うことです。
    • 未登録だけど信頼できるCA発行の証明書で接続試行があると、AWS IoT Coreが特別なイベント通知を発行
    • このイベントをトリガーにLambda関数が起動
    • Lambda関数が「モノの登録」「ポリシーのアタッチ」「証明書の有効化」などを自動実行

案1におけるJITRの実装責任

案1では、デバイスメーカーは証明書を発行するところまでが役割で、その先のデバイス登録の仕組み(JITR)はデバイス利用者自身が自分のAWSアカウント内に実装・設定する必要があります
つまり、案1を採用する場合、デバイス利用者は単にデバイスメーカーから証明書を受け取るだけでなく、自身のAWS環境でJITRの仕組みを構築する負担も考慮する必要があります。

案2: デバイス利用者がAWS管理CAで証明書を発行するケースを深掘りしてみた

次に、デバイスの利用者さん(またはサービス事業者さん)が主体となって、AWS管理のCAを利用して証明書を発行する「案2」について見ていきましょう。

作業範囲のイメージ

この場合の作業範囲のイメージはこんな感じです。

CleanShot 2025-05-14 at 15.26.27@2x

デバイスメーカーは証明書発行プロセスには直接関与しません。デバイス利用者自身が、自分のAWSアカウント内でAWS IoT Coreの機能(AWS管理CA)を使ってデバイス証明書と秘密鍵を発行し、デバイスをAWS IoT Coreに接続します。 この場合、AWSアカウントはデバイス利用者さんのみで完結するシングルアカウント構成となるため、高価な独自CAを用意する必要がなく、AWS管理CAを利用できるのが大きな特徴です。

もちろんデバイス利用者はAWS管理のCAではなく独自CAを使うことももちろん可能です。
今回は案1と対比するために、わかりやすくAWS管理のCAを使用することを前提としています。

メリット

この方式の主なメリットは以下の通りです。

  • デバイスメーカー側の負担・コストが低い
    デバイスメーカーはAWSアカウントの保有や証明書発行作業が不要になるため、責任範囲が明確になり、負担が大幅に軽減されます。これは大きなメリットかと思います。
  • デバイス利用者側のコスト削減とシンプルさ
    デバイス利用者のAWSアカウント内で全てが完結するため、独自CAの管理コスト(月額$400~)が不要になります。構成もシンプルに保てます。
  • 柔軟な発行方法
    AWS CloudShellなどを使った簡易的なスクリプトで証明書・秘密鍵を一括発行することも可能ですし、デバイス固有の証明書を事前に払い出す必要がない、フリートプロビジョニングというスケーラブルな仕組みを利用することもできます。

デメリット

一方で、デメリットとしては以下のような点が挙げられます。

  • デバイス利用者側の作業負担 デバイス利用者自身が、証明書の発行やデバイス登録のプロセス(CloudShellスクリプトの管理、またはフリートプロビジョニングのテンプレート作成・IAM設定・デバイス側ロジックの実装など)を構築・管理・運用する必要があります。

  • 証明書の有効期限が固定 AWS管理CAを使用する場合、発行される証明書の有効期限が2049年12月31日に固定されてしまいます。もしデバイスの期待寿命がこれを超える場合は、デバイス利用者側で証明書のローテーション(更新)メカニズムを設計・実装・運用する必要が出てきます。(AWS IoT Device Managementなどを活用すれば実現可能ですが、デバイス側の対応も必要になります。)

実装イメージ

デバイス利用者が主体となり、自身のAWSアカウント内でデバイスの認証情報(証明書・秘密鍵)を発行・管理します。具体的な方法としては、主に以下の2つの選択肢が考えられます。

  1. 手動またはスクリプトによる発行
    AWSマネジメントコンソールやAWS CLI、あるいは後述するAWS CloudShellを用いたスクリプトを使って、必要な数の証明書・秘密鍵を発行・管理します。

  2. 大規模・自動化向けのフリートプロビジョニング
    AWS IoT Core フリートプロビジョニングを利用します。これは、デバイスが初めてクラウドに接続する際に、自動的に証明書の発行、モノの登録、ポリシーのアタッチなどを行う仕組みです。大量生産時のオンボーディングプロセスを大幅に効率化・自動化できる強力な機能ですね。

どちらの方法を選ぶかは、デバイスの生産規模、デバイス利用者さんの技術力、自動化の要件などによって変わってくると思います。フリートプロビジョニングは初期設定が少し複雑ですが、長期的な運用負荷とスケーラビリティを考えると、非常に魅力的な選択肢と言えるでしょう。

1. CloudShellでスクリプトを実行する場合

CloudShellを使って証明書を発行・管理するイメージです。一括で発行する簡便さのためにCloudShellを使って発行する想定をしておりますが、案1でも述べたようなLambdaなどでもいいかと思います。
CleanShot 2025-05-12 at 17.28.19@2x

2. フリートプロビジョニングの場合

フリートプロビジョニングを利用する場合のイメージです。
こちらもCloudShellを使う想定をしておりますが、案1でも述べたようなLambdaなどでもいいかと思います。
CleanShot 2025-05-12 at 17.29.47@2x

フリートプロビジョニングは非常に強力なんですが、プロビジョニングテンプレートの作成やデバイス側の対応など、CloudShellスクリプトに比べると初期設定や実装の難易度は少し上がります。ここでは「スケーラブルでセキュアな自動化方法もあるんだな」という選択肢として捉えていただければと思います。

ちょっと深掘り4: CloudShellでスクリプトを実行する場合とフリートプロビジョニングってどんなもの?

案2で出てきた「CloudShellで実行するスクリプト」と「フリートプロビジョニング」、もう少し詳しく見てみましょう。

AWS CloudShellを用いたスクリプト実行

AWS CloudShellとは?
CloudShellは、AWSマネジメントコンソールから直接起動できる、ブラウザベースのコマンドライン環境です。特別なソフトウェアのインストールや設定なしに、AWS CLIなどのコマンドをすぐに実行できます。

どんなスクリプトか
記載したサンプルスクリプトは、案2のシナリオで、デバイス利用者が自身のAWSアカウント内で、多数のIoTデバイス用の「秘密鍵」と「証明書」を効率的に作成・登録・保管するための自動化スクリプトの一例です。 具体的には、指定した数の証明書とキーペアをaws iot create-keys-and-certificateコマンドで生成し、それらをS3バケットに保存するような処理を行います。モノの作成や証明書とモノの紐付けもオプションで実行できます。

CloudShellで実行するメリット (案2の場合)

  • 手軽さ
    デバイス利用者は特別な開発環境を用意する必要がありません。
  • 自動化
    大量発行を効率化し、手作業によるミスを減らせます。
  • AWS連携
    AWS CLIがプリインストールされているので、AWSサービスとの連携が簡単です。

注意点

  • 秘密鍵の管理
    スクリプトで生成・保存される秘密鍵は、S3のアクセス権限を最小限に絞るなど、厳重に管理する必要があります。デバイスへの安全な書き込み方法も別途確立が必要です。

  • S3バケットの準備
    事前に適切な権限設定を持つS3バケットを作成しておく必要があります。

  • エラー処理
    サンプルスクリプトは基本的なエラーチェックしか含まれていないことが多いので、本番利用ではより堅牢なエラーハンドリングを実装しましょう。

このスクリプトは、案2における証明書発行を効率化するための一つの具体的な手段ですね。 以下に、雰囲気を感じてもらうためのスクリプトイメージを記載しました。これはあくまでサンプルであり、実際の利用には十分な検証とカスタマイズが必要です。

スクリプトのサンプル
スクリプトのサンプル
#!/bin/bash

# --- 設定項目 ---
NUM_CERTIFICATES=10       # 発行する証明書の数
S3_BUCKET="your-iot-certificates-bucket" # 証明書を保管するS3バケット名 (事前に作成)
S3_PREFIX="certificates"  # S3バケット内のプレフィックス (例: certificates/device-001/)
THING_NAME_PREFIX="my-device-" # モノの名前のプレフィックス (例: my-device-001)
REGION="ap-northeast-1"   # AWSリージョン

# --- スクリプト本体 ---
set -e # エラーが発生したらスクリプトを終了

echo "Starting certificate provisioning..."
echo "Number of certificates to create: ${NUM_CERTIFICATES}"
echo "Target S3 Bucket: s3://${S3_BUCKET}/${S3_PREFIX}"
echo "Thing name prefix: ${THING_NAME_PREFIX}"
echo "Region: ${REGION}"

# 一時作業ディレクトリ作成
WORK_DIR=$(mktemp -d)
echo "Working directory: ${WORK_DIR}"
cd "${WORK_DIR}"

for i in $(seq 1 ${NUM_CERTIFICATES})
do
  DEVICE_ID=$(printf "%s%03d" "${THING_NAME_PREFIX}" "${i}")
  echo "----------------------------------------"
  echo "Processing device: ${DEVICE_ID}"

  # 1. モノを作成 (存在しない場合 - オプション)
  # aws iot create-thing --thing-name "${DEVICE_ID}" --region "${REGION}" > /dev/null || echo "Thing ${DEVICE_ID} already exists or failed to create."

  # 2. キーペアと証明書を作成 & 有効化
  echo "Creating keys and certificate for ${DEVICE_ID}..."
  OUTPUT=$(aws iot create-keys-and-certificate \\
            --set-as-active \\
            --region "${REGION}" \\
            --output json)

  if [ $? -ne 0 ]; then
    echo "ERROR: Failed to create keys and certificate for ${DEVICE_ID}. Skipping."
    continue # エラーが発生したら次のループへ
  fi

  CERT_ARN=$(echo "${OUTPUT}" | jq -r '.certificateArn')
  CERT_ID=$(echo "${OUTPUT}" | jq -r '.certificateId')
  CERT_PEM=$(echo "${OUTPUT}" | jq -r '.certificatePem')
  KEY_PAIR_PUBLIC=$(echo "${OUTPUT}" | jq -r '.keyPair.PublicKey')
  KEY_PAIR_PRIVATE=$(echo "${OUTPUT}" | jq -r '.keyPair.PrivateKey') # ★★★ 秘密鍵 ★★★

  echo "Certificate ID: ${CERT_ID}"
  echo "Certificate ARN: ${CERT_ARN}"

  # ファイルに保存
  CERT_FILE="${DEVICE_ID}_${CERT_ID}_cert.pem"
  PUB_KEY_FILE="${DEVICE_ID}_${CERT_ID}_pub.key"
  PRV_KEY_FILE="${DEVICE_ID}_${CERT_ID}_prv.key" # ★★★ 秘密鍵ファイル ★★★

  echo "${CERT_PEM}" > "${CERT_FILE}"
  echo "${KEY_PAIR_PUBLIC}" > "${PUB_KEY_FILE}"
  echo "${KEY_PAIR_PRIVATE}" > "${PRV_KEY_FILE}"
  echo "Files created locally: ${CERT_FILE}, ${PUB_KEY_FILE}, ${PRV_KEY_FILE}"

  # 3. 証明書をモノにアタッチ (オプション - モノを作成した場合)
  # echo "Attaching certificate ${CERT_ARN} to thing ${DEVICE_ID}..."
  # aws iot attach-thing-principal \\
  #  --thing-name "${DEVICE_ID}" \\
  #  --principal "${CERT_ARN}" \\
  #  --region "${REGION}"
  # if [ $? -ne 0 ]; then
  #  echo "WARNING: Failed to attach certificate to thing ${DEVICE_ID}."
  # fi

  # 4. S3にアップロード (SSE-S3で暗号化)
  S3_DEVICE_PATH="${S3_PREFIX}/${DEVICE_ID}"
  echo "Uploading files to s3://${S3_BUCKET}/${S3_DEVICE_PATH}/ ..."

  aws s3 cp "${CERT_FILE}" "s3://${S3_BUCKET}/${S3_DEVICE_PATH}/${CERT_FILE}" --sse AES256
  aws s3 cp "${PUB_KEY_FILE}" "s3://${S3_BUCKET}/${S3_DEVICE_PATH}/${PUB_KEY_FILE}" --sse AES256
  aws s3 cp "${PRV_KEY_FILE}" "s3://${S3_BUCKET}/${S3_DEVICE_PATH}/${PRV_KEY_FILE}" --sse AES256 # ★★★ 秘密鍵の保護は最重要 ★★★

  if [ $? -ne 0 ]; then
    echo "ERROR: Failed to upload files to S3 for ${DEVICE_ID}. Check permissions and bucket settings."
    # エラー処理
    continue
  fi

  echo "Successfully processed ${DEVICE_ID}."

  # レート制限回避のための待機 (必要に応じて調整)
  sleep 0.5
done

# 一時作業ディレクトリ削除
echo "Cleaning up working directory: ${WORK_DIR}"
rm -rf "${WORK_DIR}"

echo "----------------------------------------"
echo "Certificate provisioning finished."

AWS IoT Core フリートプロビジョニング

よりスケーラブルでセキュアな方法として、AWS IoT Coreのフリートプロビジョニング機能があります。

フリートプロビジョニングとは?

デバイスが初めてAWS IoT Coreに接続するタイミングで、必要なリソース(デバイス証明書、モノ、ポリシー)を自動的にプロビジョニング(準備・設定)する仕組みです。 事前に個別のデバイス証明書を作成・配布する必要がなく、共通の「クレーム(初期登録用)証明書」を使ってデバイスを起動させるだけで、オンボーディングプロセスが完了するといった便利な機能です。

主な構成要素

プロビジョニングテンプレートやクレーム証明書、さらに一部ロジックも必要な箇所があるかと思います。

  • プロビジョニングテンプレート
    デバイス登録時に実行される処理(モノの作成、ポリシーのアタッチなど)を定義したJSON(yaml)形式のテンプレート。

  • クレーム証明書
    全ての未登録デバイスが、初回接続時に自身を認証するために使用する共通の証明書。プロビジョニング目的のみに使用し、権限は最小限にします。デバイス利用者が事前に作成し、製造プロセスでデバイスに書き込みます。

  • デバイス側のロジック
    デバイスは、クレーム証明書を使ってAWS IoT Coreに接続し、プロビジョニングを要求します。成功したら、新しく発行されたデバイス固有の証明書を受け取り、保存します。

フリートプロビジョニングの簡単な流れ

簡単な流れを下記にまとめてみました。自動でプロビジョニングできるようのはメリットですね!

  1. 【準備】デバイス利用者が、プロビジョニング用のIAMロール、プロビジョニングテンプレート、クレーム証明書を作成・登録します。
  2. 【製造】(デバイス利用者 or 製造委託先)が、デバイスに共通のクレーム証明書と秘密鍵を書き込みます。
  3. 【初回起動】デバイスが、クレーム証明書を使用してAWS IoT Coreのプロビジョニング用エンドポイントに接続します。
  4. 【自動処理】AWS IoT Coreが、クレーム証明書を検証し、プロビジョニングテンプレートに基づき、新しいデバイス固有証明書の発行、モノの登録、ポリシーのアタッチなどを行います。そして、新しいデバイス固有証明書をデバイスに返します。
  5. 【登録完了】デバイスが、新しいデバイス固有証明書と秘密鍵を受け取り、セキュアストレージに保存します。以降はこの新しい証明書でAWS IoT Coreに接続します。

メリット・デメリットも整理してみました。やはりスケーラビリティに長がある手法で、その分若干の導入コストもありますね。

メリット

  • スケーラビリティ
    大量のデバイスのオンボーディングに非常に強いです。
  • 自動化
    製造ラインや初回起動プロセスに組み込みやすいです。
  • セキュリティ
    デバイス固有証明書の事前配布が不要なため、製造段階での漏洩リスクを低減できます。

デメリット/考慮事項

  • 初期設定の複雑さ
    プロビジョニングテンプレート作成、IAMロール設定、デバイス側ロジック実装など、CloudShellスクリプトよりは初期設定の手間がかかります。

  • デバイス側の実装
    初回接続、証明書受信・保存、証明書の切り替えといったロジックをデバイス側に実装する必要があります。

CloudShellスクリプトは手軽な選択肢ですが、より大規模で自動化されたセキュアな運用を目指すなら、フリートプロビジョニングは非常に強力な選択肢になると思います。

案3: 外部SaaSを利用するケースについて(参考情報)

最後に、参考情報として外部のSaaSを利用する案についても少し触れておきます。 証明書の発行・管理機能を提供する外部サービスも存在します。例えば、GMOグローバルサイン様のIoTデバイスセキュリティサービスなどが挙げられます。

https://jp.globalsign.com/internet-of-things/

メリット

  • 証明書・秘密鍵の発行処理などを外部の専門SaaSに移譲できる可能性がある

デメリット

  • AWS IoT Coreとの連携を含め、今回の要件に具体的にどうフィットするのか、実現可能かどうかは詳細な確認が必要です。料金体系も問い合わせてみないと分からないことが多いと思います。

  • SaaS側が秘密鍵を生成・保持するような場合、自社のセキュリティポリシーや要件に準拠できるかの確認が非常に重要になります。

  • 当然ながら、外部サービスへの依存が発生します。

この案は、あくまで「こういう選択肢もあるかもしれない」という程度で、今回は深くは掘り下げません。もし検討される場合は、サービス提供元へ直接問い合わせて、機能、料金、セキュリティ要件とのすり合わせなどをしっかり確認することが不可欠です。

各認証方式を比較してみた

さて、ここまで2つの案を見てきましたが、ここで一度、それぞれの特徴を整理して比較してみたいと思います。 「誰が何をやるのか」「主なメリット・デメリット」「コスト感」「導入のしやすさ」といった観点でまとめてみました。(案3は不明瞭な箇所が多く、比較の土台に乗らない可能性が高いため除外しました)

比較項目 案1: 証明書発行主体 独自CA (AWS Private CA) 案2: デバイス利用者 AWS管理CA
認証方式概要 証明書発行主体が独自CAを構築・管理し、証明書/鍵を発行。デバイス利用者が利用。 デバイス利用者が自身のAWSアカウント内でAWS管理CAを使い、証明書/鍵を発行・管理。
主な作業主体 証明書発行主体: CA管理、発行システム構築・保守
デバイス利用者: CA登録、JITR実装
デバイス利用者: 証明書発行・管理、デバイス登録プロセス構築・運用
主なメリット - 証明書有効期限の柔軟な設定が可能
- デバイス利用者は発行作業不要(CA登録・JITR設定は必要)
- 証明書発行主体の負担・コストなし
- 低コスト (CA維持費不要)
- シンプル (AWS内で完結) - フリートプロビジョニングによる自動化・スケーラビリティも可能
主なデメリット - 高コスト (PCA月額$400~ + 従量課金 + システム保守費)
- 複雑な構成 (マルチアカウント連携)
- 証明書発行主体の継続的な運用負荷
- 鍵の安全な受け渡しが課題
- デバイス利用者のJITR実装・CA登録が必要
- デバイス利用者の証明書発行・管理作業が必要
- 証明書有効期限が2049年末固定 (以降利用には更新対応が必要)
- フリートプロビジョニング利用時は初期設定・実装が必要
コスト感 高い (初期・運用ともに) 低い (AWS利用料のみ、CA固定費なし)
導入しやすさ 難しい (技術的複雑さ、関係者調整) 比較的易しい (AWS標準機能ベース、デバイス利用者主体)
セキュリティ考慮点 - 独自CAの適切な管理・運用
- 秘密鍵の安全な生成・保管・受け渡し - JITR実装のセキュリティ
- デバイス利用者による秘密鍵の厳重な管理 (S3アクセス制御等)
- 証明書ローテーションの計画 (2049年以降)
- フリートプロビジョニング利用時の共通クレーム証明書管理
推奨度 (個人的な評価) △ (コスト・複雑さが若干大きい) ◎ (現実的、低コスト、シンプルで始めやすい)

こうして比較してみると、それぞれの案に一長一短があることがよく分かります。

考察: どの方式を選ぶべきか?

さて、これらの比較を踏まえて、どの方式を選ぶのが良いのでしょうか。これは一概には言えないのですが、いくつかの観点から考えてみたいと思います。

まず、シンプルさ、低コスト、そしてデバイスメーカー側の負担軽減を最優先するならば、案2(デバイス利用者がAWS管理CAを利用する方式) が最も現実的で導入しやすい選択肢ではないかな、と個人的には思います。 デバイス利用者側での証明書管理作業は発生しますが、AWSの標準機能(CloudShellスクリプトやフリートプロビジョニング)で対応可能ですし、AWS Private CAのような高価な固定費がかからないのは大きな魅力です。構成もシンプルに保てます。

一方で、どうしても証明書の有効期限を2049年以降も柔軟にコントロールしたい、あるいはデバイス利用者が一切の証明書管理作業を避けたい(ただしCA登録やJITR設定は必要になりますが)という強い要件がある場合は、案1(証明書発行主体が独自CAを管理する方式) も検討の余地はあるかもしれません。しかし、その場合はコストとシステム全体の複雑性が増大することを念頭におく必要があるかと思います。特に、証明書発行主体となるデバイスメーカーの継続的な運用負荷はかかる可能性があります。

案3(外部SaaS)については、現時点では不確定要素が多いため、積極的な推奨は難しいかな、という印象です。もちろん、特定の要件にぴったりハマるサービスが見つかれば、それはそれで良い選択肢になり得るとは思います。

結局のところ、「これが絶対!」という答えはなく、関係する企業の役割分担、技術力、コスト許容度、セキュリティ要件、デバイスのライフサイクルなどを総合的に考慮して、最適な方式を選択していくことになるのだと思います。

おわりに

今回は、IoTデバイスをAWS IoT Coreに接続する際の認証方式について、いくつかの案を比較検討してみました。

  • 案1 (デバイスメーカー独自CA): 柔軟性は高いが、コストと複雑性が課題。マルチアカウント構成が前提。
  • 案2 (デバイス利用者AWS管理CA): シンプルかつ低コスト。デバイスメーカーの負担も少ない。ただし有効期限は2049年末。
  • 案3 (外部SaaS): 要件次第ではあり得るが、詳細確認が必須。

限定的なシナリオでもこんなにも考える観点があって難しいですよね。

まずはいろいろな選択肢があることを知り、それぞれのメリット・デメリットを理解した上で、自分たちのプロジェクトに最適な方法を見つけていくことだと思います。その過程で、この記事が少しでもお役に立てば嬉しいです。

こういった技術選定は、たたき台を作って、関係者間で意見を出し合い、要件の整理を行い修正を繰り返していくことで、最終的に目指すアーキテクチャを実現できるようになるのかなと思います!

最後までお読みいただき、ありがとうございました!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.