【Transfer Family】カスタムIDプロパイダー利用時のSecrets Managerへ登録するシークレットの記述についてハマりどころを共有する

Transfer FamilyのカスタムIDプロパイダー利用時に、Secrets Managerへ登録するシークレットの各キーバリューの記述資料が少なく、実装にあたりそこそこハマってしまったので共有します。
2023.05.04

こんにちは、AWS事業本部コンサルティング部のこーへいです。

今回検証するTransfer FamilyのカスタムIDプロパイダー構成について

上記記事にて解説するカスタムIDプロパイダー構成と同様の形となります。

Transfer Family → API Gateway → Lambda → Secrets Managerの流れにてSecrets Managerに登録されているユーザー情報を認証に利用します。

結論

{
    "Password": "指定のパスワード",
    "PublicKey": "指定のSSH公開鍵",
    "Role": "arn:aws:iam::AWSアカウントID:role/IAMロール名",
    "HomeDirectoryDetails": "[{\"Entry\": \"/\", \"Target\": \"/{ファイルシステムID}/{指定のディレクトリ}\"}]",
    "AcceptedIPNetwork": "受け入れIPアドレス",
    "PosixProfile": {
        "Uid": "指定のUID",
        "Gid": "指定のGID",
        "SecondaryGids": ["指定のSGID1","指定のSGID2",...]
    }
}

書き方としては上記です。

今回の主なはまりどころは「HomeDirectoryDetails」「PosixProfile」の2箇所でした。

Secrets Manager登録方法の前提

Secrets Managerのシークレット値の登録方法は以下の2種類あります。

  • キー/値ペア
  • プレーンテキスト

基本的にはどちらの登録方法でも機能としては変わらないのですが、公式ドキュメントには「JSONをお勧めします」との記述があります。

これはプレーンテキスト(JSON)の記述が推奨される理由の1つに、キー/値ペアの登録ではネストを深くすることができないことが挙げられます。

論より証拠です。

まず上記のようなシンプルなプレーンテキストを用意します。

その後、表示を「プレーンテキスト」から「キー/値」に変更すると上記のように変換されます。
これはシンプルな記述であれば「プレーンテキスト」「キー/値」のどちらの登録方法にも対応していることを示します

一方で、ネストが深いプレーンテキストを記述すると。

表示を「キー/値」してもプレーンテキストから変換できない旨のエラーが表示されます。 このようにJSON記述のネストが深くなる場合、「キー/値」の登録方法が使用できないことがわかります。

つまりTransfer FamilyのドメインがEFSの場合、ネストが深くなる「PosixProfile」の項目がSecrets Managerへの記述に必要なので、プレーンテキストでの登録が必須となります

PosixProfile

プレーンテキストでの登録が必須を前提に「PosixProfile」はどのように登録すれば良いでしょう。

改めて以下のようになります。

    "PosixProfile": {
        "Uid": "指定のUID",
        "Gid": "指定のGID",
        "SecondaryGids": ["指定のSGID1","指定のSGID2",...]
    }

ここで間違ってはいけないことはSecondaryGidの記述に引っ張られてPosixProfileを配列にしないことです。

    "PosixProfile": [{
        "Uid": "指定のUID",
        "Gid": "指定のGID",
        "SecondaryGids": ["指定のSGID1","指定のSGID2",...]
    }]

JSONでは[]のあるなしでバリューのタイプが配列かオブジェクトかに変わってしまうため、「SecondaryGidsの値が[]で囲まれているから記述形式を統一しよう」などの雰囲気で[]を追加したりすることは厳禁です。

参考:今さら聞けないJSONとは?表記形式や使い方をサンプル付きで解説!

SecondaryGidsは複数のSGIDを指定できるので、[]で配列タイプにする必要があります。

HomeDirectoryDetails

一方、「HomeDirectoryDetails」では以下のようになります。

"HomeDirectoryDetails": "[{\"Entry\": \"/\", \"Target\": \"/{ファイルシステムID}/{指定のディレクトリ}\"}]"

こちらは上記のようになりますが、特徴となる点はバリュー値内部のダブルクォーテーションをスラッシュでエスケープすることです。

こちらは推測となりますが、Transfer Familyが受け取る値の仕様が原因と考えます。

[
    {
        "Entry": "/",
        "Target": "/{ファイルシステムID}/{指定のディレクトリ}"
    }
]

上記のようなネストを深くした構造ではなく、Transfer Familyは下記の値をまとまりとして読み込んでいるのでしょう。

{\"Entry\": \"/\", \"Target\": \"/{ファイルシステムID}/{指定のディレクトリ}\"}

実際にバリュー値としてAWS公式ドキュメントでも[{"Entry": "/", "Target": "/fs-faa1a123/jane"}]を指定しています。

実際に上記のように「キー/値」形式で登録し、表示をプレーンテキストに切り替えてみると、、、

ダブルクォーテーションがスラッシュでエスケープされている記述に変換されます。

まとめ

JSONでは細かいミスが沼に誘うことも多いです。

  • Secrets Managerでは基本的にプレーンテキスト記述の登録が便利
  • バリューのタイプが配列かオブジェクトのどちらであるか把握する
  • どのような値が渡し先に求められているか把握する

上記、自分のはまったポイントを意識し上手く実装できるよう頑張りましょう。