こんにちは。仕事でAWSの構築し、プライベートでAWSの研究と技術書の執筆をし、Amazonで本を売っているAmazon依存症の佐々木です。
今日は昔からあるものの、知名度が殆どないS3の署名付きURL(S3 Presigned URL)の仕組みの紹介を行います。また、Presigned URLはアクセスキーと密接な関係があります。それを知らないと思わぬ罠にハマります。
S3の署名付きURLについて
まずS3の署名付きURLとは、なんぞやという話からです。IAMユーザーやIAMインスタンスプロファイル、AWS Security Token Serviceなど、有効なセキュリティ認証情報を持つユーザーは署名付きURLを発行できます。
このURLを使うと、S3のオブジェクトをアップロードできたり、参照できたりします。また発行の際には、有効期限(デフォルト1時間、最大72時間)も指定できるのが便利です。私の知る限りで多いユースケースとしては、特定の人にURLを共有することでファイルの受け渡しをするといったものがあります。そんなものGoogle Driveを使えばいいじゃんという話もありますが、そのとおりです。ただGoogleドライブは2012年に始まったサービスですが、S3の署名付きURLは(たぶん)サービス開始当初の2006年から利用可能でした。
S3の署名付きURLの発行の仕方と署名の仕組みについて
S3の署名付きURLは、今だとCLIコマンドから発行できるので、非常に簡単に発行できます。IAMユーザーでs3 presign コマンドを叩くと署名付きURLが出てきます。
aws s3 presign s3://BucketName/ObjectName https://BucketName.s3.ap-northeast-1.amazonaws.com/ObjectName?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAXXXXXXXXXXXXXIJQ%2F20210403%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20210403T085551Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=dfae027d87785b713a78828d9200d8cfbb4214875901a4b5c0f115e2abe9e1df
目敏い人は気が付くかもしれませんが、URL中にCredentialというパラメータとアクセスキーっぽい文字列(一部XXXで伏せています)があります。
ついでにAWS SSOでログインしたユーザー(STSによる一時的なユーザー)で、署名付きURLを発行してみましょう。
https://BucketName.s3.ap-northeast-1.amazonaws.com/ObjectName?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIXXXXXXXXXXXXXXQAQ%2F20210403%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20210403T092237Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEIn%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDmFwLW5vcnRoZWFzdC0xIkYwRAIgFk6Y4HxsjnCx9PvQC5MrXP18FcuExnoPqeYJyLZ2J1MCIEqMYclGNfq0zipi3f91a7b72%2Fv2KEG34eH5KXyD7P9ZKv4CCNP%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQABoMMDIxMDEwNzQ2MTI5IgxWNn%2FOml5xfO7kWHwq0gKOGqV60spHLC26KofAg79vH5KXyD35la2ll7Usw1yaUhaevG6Jsa45RdWcItAxQoGU2R4Y4wKthtGxMbNJ91N3Q94CIBE2Pi9u5g0SPe1AgU4Fr0K4gJohJHnyLn8Iy6rvAGTDzSW7XY%2Bk3%2BxmzyGwLyfj0qeK6zxFpi4mVs8JVnJEnnuYfyLRVYsP8ZmCH%2FdjKphQ7DbqV9pE77DlIIPBAV%2FjARGtc3SiPSYPBwT%2FriOG8aI5R1p5AjDyak%2Bh3C8IPSRPibulbxECTyya%2F6AMBC%2BcRfDyg5L4nm5XF2MM1fD9tZUT0yVoMmESDYNNga1UhIM6mjd%2BxniXco7plUDV4WMp%2B2Yff7B8qgoCkod6lockMMhA6QaFJUaUuPSHlsv3zPEEWuKYk0CZU7dipkooyCJ3MyWgkZ5WemZ3HU0H5KXyD%2BPmprKdI73KMGPolXGSR%2FTDN56CDBjqnAe%2FcMmBx%2BCTTZ5jwm3dBEZc7IGHAxpioeMx9kFnSad7eirHZ5u8pFNOCzqlO0Q8vYBEgOpfPf%2BW0nJjLAeSinYn7h0cMd5QD9Htj7O4Mr9g91Rd7inO6CY%2FC7RJ9cwoXWQtPByBQ2YBZ1pYAR6pcSUu%2FvTmNpWJrHvO%2F8c%2ByfdpG%2BuoNcECpMsMvCKXPrk6mg2IDf9F%2FDzyBIakb93OFciFIIuYzh2AI&X-Amz-Signature=7943f3b301d7f3b098d2ef7f449c38bc34866b6debd5886c568754cfbe87e775
先程のURLに比べて非常に長くなっています。これは、一時トークンを含めて署名を発行する必要があるからです。
アクセスキーが無効になると、どうなるのか?
ここまでで、S3の署名付きURLが発行したユーザーのクレデンシャル(認証情報)と密接な関係があるのをご理解いただけたでしょう。そして、勘が鋭いあなたは、何をいいたいのかも気が付いているかもしれません。署名付きURLの有効期限内に、クレデンシャルの方が無効になったら、どうなるのでしょうか?答えは有効期限内に関わらず、署名付きURLは無効になります。 無効になるケースとして多いのは、STSの有効期限だと思います。STSの有効期限のデフォルトは12時間ですので、それに気が付かずに72時間有効な署名を作ったとしても、実際に使えるのは12時間以内です。それ以外のケースとしては、IAMユーザーのアクセスキーを無効化した場合です。私は普段使いのCLIは、AWS SSOからコンソール利用のための環境変数を取得し実行しています。IAMユーザーのアクセスキーは普段無効化しています。しかし、上記の制約を知っているので、一時的にIAMユーザーのアクセスキーを有効化しURLを発行し、またアクセスキーを無効化しました。その後、ドヤ顔でURLを配布し、ここからアクセスしてくださいと。その場合でも、署名付きURLは無効になります。
いにしえのAWS
ちなみに最初期のAWSは、IAMユーザーは存在せずルートアカウントのみ存在していました。そして、何をするにしてもアクセスキーとシークレットアクセスキーから、自分でこの手の署名を作っていく必要があり割と苦行のようなサービスでした。
AWS CLIができたのは、意外に新しく2012年くらいです。もともとPython SDKを使ったbotoというサービスがコミュニティ発で存在し、その後AWSに取り込まれました。CLIの前は、EC2などのサービスごとのCLIが幾つかあったという程度です
まとめ
一見有用に見えて、AWSの実運用では殆ど役に立たない豆知識でした。ただ、これを機会にS3の署名付きURLの存在を知っていただければ幸いです。たぶん生涯の中で3人くらいには役に立てればと願っています。