LoginSignup
14
9

More than 3 years have passed since last update.

GitHub Actionsでビルドするコンテナ内でGitHubのprivate repositoryをセキュアに参照する

Posted at

はじめに

GitHub Actions、便利ですよね
ソースコードの変更後、いちいち手元でdocker buildしてpushなんてやってられないですし、
外部CIツールを新たに導入するよりは全部GitHub内で完結してたほうがシンプルです。

しかしながら別のprivate repositoryにある社内用ライブラリを持ってくるのが地味に面倒だったのでやり方を書きます

1行で

リポジトリsecretsにトークンを入れてBuild-time secretsでコンテナ内に注入

説明

認証方法

GitHub→GitHub内とは言え認証は必要です
httpsかsshで認証することになります
権限を細かく絞れるためトークンを介するhttps接続の方が良いと思います

https

下記記事のようにトークンを作成し、トークンを用いて認証します
この際、個人ユーザのトークンを利用するとアカウント削除時にトークンが使えなくなりそうなので、マシンユーザを作成してそちらでトークンを作成します。マシンユーザがcloneしたいリポジトリのread権限を持っている必要があります

Dockerfileのbuildで簡単にGithubのプライベートリポジトリをクローンする方法 - Qiita
https://qiita.com/Jah524/items/fa68f99c8b787f94b884

ssh

GitHubに登録してある公開鍵に対応する秘密鍵をコンテナ内に入れてしまえば接続はできます
ただユーザに許可されている全権限がついてしまうので、トークンを利用したほうがより安全ですね

Build-time secrets

リポジトリにトークンを直書きするのはもちろん、docker build--build-argに渡す方法も安全であるとは言えません
Build-time secretsという機能があるのでこちらを使いましょう

Docker Engine 18.09 から使える Build-time secrets を試してみた | はったりエンジニアの備忘録
https://blog.manabusakai.com/2018/12/docker-build-secret/

コンテナにsecretsを渡す

下記ドキュメントにrepo-tokenで渡すとあるので、そうすればいいのかと思ってしまいがちなのですが(1敗)、
この形で渡したトークンはActionsの中のcloneで使えるだけなので、コンテナに渡す場合は普通にenvを使います

GITHUB_TOKENでの認証 - GitHub ヘルプ
https://help.github.com/ja/actions/configuring-and-managing-workflows/authenticating-with-the-github_token

    steps:
    - uses: actions/labeler@v2
      with:
        repo-token: ${{ secrets.GITHUB_TOKEN }}

コード

事前にリポジトリのsecretsにMACHINE_USER_TOKENの名前でトークンを入れておきます
下記のようにファイルの形でコンテナにトークンを渡します

github_actions_ecr.yml
      - name: Build, tag, and push image to Amazon ECR
        id: build-image
        env:
          TOKEN: ${{ secrets.MACHINE_USER_TOKEN }}
        run: |
          echo $TOKEN >> .token
          DOCKER_BUILDKIT=1 docker build --secret id=token,src=.token \
            -t $ECR_REGISTRY/$ECR_REPOSITORY:latest \
            .
          rm .token
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest

Dockerfileの1行目にマジックコメントを入れます

# syntax = docker/dockerfile:1.0-experimental

Dockerfileでは下記のように受け取ります
pyproject.tomlにはssh形式でパスを入れておく想定で(どちらでもいいのですが手元で作業する分にはsshのほうが便利)
それを置換してトークンを入れています

COPY pyproject.toml .
RUN --mount=type=secret,id=token TOKEN=$(cat /run/secrets/token) \
  && sed -i "s/ssh:\/\/git@github.com/https:\/\/$TOKEN@github.com/g" pyproject.toml \
  && pip install . && rm pyproject.toml
pyproject.toml
[tool.poetry.dependencies]
<tool_name> = {git = "ssh://git@github.com/<org>/<repo>.git", tag = "1.0"}

GithubActionsのログにも秘匿化された状態で出力されています

#18 9.075 Collecting <tool_name>@ git+https://***@github.com/<略>

まとめ

Build-time secretsでクレデンシャルを安全に扱いましょう
https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information

14
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
9