s3url: S3 の署名付き URL を一発で発行するコマンドを作った

S3 オブジェクトの署名付き URL を一発で発行できるコマンドラインツール s3url を作ったのでご紹介です。

github.com

下のような感じで、S3 オブジェクトのパスを与えると5分間誰でもアクセスできる URL が即座に発行されるコマンドです。

$ s3url s3://my-bucket/foo.key
https://my-bucket.s3-ap-northeast-1.amazonaws.com/foo.key?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA***************************%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20160923T010227Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=****************************************************************

S3 署名付き URL とは、指定したオブジェクトに対する「一定期間有効な」「誰でもダウンロード可能となる」URL のことです。詳しくはドキュメントを御覧ください。

docs.aws.amazon.com

インストール

Mac ユーザであれば Homebrew 経由でインストール可能です。dtan4/dtan4 tap にレシピがあります。

$ brew tap dtan4/dtan4
$ brew install s3url

その他の OS をお使いの方は、GitHub Releases からバイナリをダウンロードしてください。

使い方

引数に S3 オブジェクトの URL を与えることで、一時的に誰でもそのオブジェクトをダウンロード可能になる署名付き URL が表示されます。デフォルトだと5分間有効となっています。5分過ぎるとアクセスできなくなります。

$ s3url s3://my-bucket/foo.key
https://my-bucket.s3-ap-northeast-1.amazonaws.com/foo.key?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA***************************%2Fap-northeast-1%2Fs3%2Faws4_request&X-Amz-Date=20160923T010227Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=****************************************************************

オブジェクトのは https://s3:// で始まる URL、または -b, -k オプションでそれぞれ指定することができます。

-d オプションを与えることで、秒単位で有効期間を指定することができます。

# 10分間有効
$ s3url s3://my-bucket/foo.key -d 600

--upload オプションでローカルファイルのパスを指定すれば、そのファイルを S3 へアップロードした後に URL を発行します。自分のマシンにあるファイルを他人へ渡すような場合に、アップロードを他の手段でしなくてよくなるので便利です。

# カレントディレクトリの foo.key を s3://my-bucket/foo.key にアップロードして URL 発行
$ s3url s3://my-bucket/foo.key --upload foo.key

なお、ここで発行された URL は期限付きとは言え誰でもアクセスできる URL です。なので、ファイルの機密性が高い場合は URL をパブリックな場所で公開してはいけません。チャットツールの private channel とかで必要な人だけと共有しましょう。

Why

チームで開発していると、他の人とファイルのやり取りをすることがそれなりにあるでしょう。で、他人に見られても問題ないファイルであればどこで共有しようといいでしょう。しかし、クレデンシャルファイル (e.g. AWS Management Console から落とせる IAM user の Access Key ID, Secret Access Key を書いた CSV) のような他人に見られちゃマズいファイルを共有するには、何らかのセキュアな方法を取らないといけません。

  • AirDrop
    • Mac に限定される、更にいうと Mac のバージョンもある程度限定される
    • Bluetooth で検知できる範囲にいないといけないので、リモート勤務とかだと使えない
  • Dropbox やチャットツールで直接共有
    • 他人にファイルを見られる可能性がある
    • ファイルを消し忘れて、相手が引き続きアクセスできる状態が保たれてセキュリティ上よくない
  • USB メモリ
    • 手間がかかって面倒、使いたいときに限って見つからない

そんな中で S3 と署名付き URL 使うのは便利だと思っています。

  • バケットやオブジェクトに対して細かくアクセスルールを決められる
  • URL なのでどんな環境でもだいたい送れる
  • 署名付き URL は指定した時間経つと無効化される

先述した IAM クレデンシャルの場合は、Ops チームのみ読み書きできるバケットを作成した上でそこに CSV を置き、相手には s3url で発行した URL を private chat で渡す運用にできます。

あとは機能的な why があります。公式ドキュメントや s3url のコードをみたらわかるんですけど、署名付き URL って AWS CLI で生成できないし API も1コールで生成できないんですよね…。Management Console でもいいけど。なので、この辺のやり取りを全部ひっくるめてワンコマンドでできたら便利かなー、というので作られたのが s3url なのです。

おわりに

最近作った s3url の紹介をしました。s3url、自分のチームを中心にそれなりに使われています。

同じ機能を持ちかつ s3url と名のつくツールは既にいくつかあったので例によって他の名前を考えたのですが、いいのが思いつかず…。そこで既存の見てみると、どれも LL 上の実装で言語ランタイムをインストールしないといけないやつでした。これはバイナリ置くだけで実行できるコマンドラインツール作れば、名前が被っていようと他を駆逐できるのでは…という目論見で、あえて s3url と名付けて Go で実装 & プラットフォームごとのバイナリを一括配布する形にしました。

Issue, Pull Request お待ちしています :octocat: