体はドクペで出来ている

インフラ、Goの割合が多い技術ブログ

AWS CodeCommitのREADME.mdでなるべく簡便且つセキュアに画像を表示する

始めに

AWS CodeCommitはGitHub風味(?)のマネージドGitリポジトリを提供してくれますが、GitHubに比べいくつか痒いところに手が届かないポイントがあります。今回題材としたREADME.md内での画像埋め込み表示もその一つで、リポジトリ内に画像を含め相対パス参照( ![example.png](/images/example.png) のような指定)で表示させることができません。

どうするか

画像の置き場所

リポジトリ内を直接参照させることができない以上、外部のストレージを参照するしかありません。こういったファイルの配布にうってつけなのがS3です。

S3に画像ファイルをアップロードし、リポジトリの参照者がその画像を見られるようバケットポリシーを設定します。特定のアカウント全体が対象であれば下記のようなJSONになるでしょう。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::000011112222:root",
                    "arn:aws:iam::333344445555:root"
                ]
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::example-bucket/*"
        }
    ]
}

000011112222 という数字はアカウント番号です。その他のリソース指定方法についてはこちらをご覧下さい。

全世界に公開して問題無いならば "Principal": "*" と簡潔に設定することもできますが、事故の元なので止めた方が良いでしょう。

README.md 内での指定方法

単純に ![](https://s3-ap-northeast-1.amazonaws.com/example-bucket/example.png) といった形でファイルを参照すればOKです。

アップロードが面倒

これについてはぶっちゃけあまり良い方法が思いつきませんが、私はCI/CDフローの中でREADME.md用の画像フォルダをS3にアップロードするステップを挟むことでとりあえず解決しています。

ボツネタ

署名付きURLを発行する

S3にはクエリーパラメーターを使った時限アクセス許可の仕組みがあり aws s3 presign s3://example-bucket/example.jpg でURLを発行することができます(余談ですが --expires-in <sec> のオプションで制限時間を指定できます。デフォルトは3,600秒=1時間です)。

aws s3 presign s3://example-bucket/example.png
https://s3.amazonaws.com/example-bucket/example.png?AWSAccessKeyId=XXXXXXXXXXXXX&Expires=1534224101&Signature=%2Aqb4eAiuAGqoEy8U3VhytFkAI%2JxnD

しかしこれは最大の有効期限が7日間と短かったのでボツにしました。

まぁ無期限や、実質無期限(100年間、等)を指定できるとセキュリティ的に穴となってしまいますのでこれは妥当な仕様だと思います。

Base64エンコードしてMarkdownに直書する

THE 力技

全てのリソースがリポジトリ内に閉じているという意味でセキュリティ的には理想ですが、画像の更新が面倒ですしMarkdownを開くとエディターが固まったり、仮に開けても恐ろしく見通しが悪いという致命的な欠点がありますのでボツ。