Help us understand the problem. What is going on with this article?

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

はじめに

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

lifull
日本最大級の不動産・住宅情報サイト「LIFULL HOME'S」を始め、人々の生活に寄り添う様々な情報サービス事業を展開しています。
https://lifull.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした