🥧

Auth0のスクリプトとシークレットを自動デプロイする

2024/04/08に公開

Auth0ではCustom DatabaseのActionScriptsと、Actions(旧Pipeline/Rules/Hooks)という独自のスクリプトをJavaScriptで書いて独自の挙動を実現する機能があります。Auth0をカスタマイズするのに強力なツールです。

今回は、このスクリプトとスクリプトで利用するシークレット(秘匿情報・環境変数)を管理してGitHub Actionsでデプロイする方法を紹介します。

Auth0のデプロイツール a0deploy

Auth0が公式でサポートしているデプロイツール a0deploy を利用します。デプロイと名前がついていますが、実際にはインポート・エクスポートツールのようなものです。既存の設定をYAMLファイルにエクスポートできるので、他テナントへの移植も楽にできて便利です。

これを使うことで、スクリプトをGitHubで管理しつつ、マージされたらa0deployを使ってGitHub Actionsからデプロイを自動化することができます。

a0deployの設定

config.json
{
  "AUTH0_ALLOW_DELETE": false,
  "AUTH0_INCLUDED_ONLY": ["databases", "actions", "triggers"]
}
  • AUTH0_ALLOW_DELETEfalse にしておきます
    • true だと定義のないものが自動的に削除されます
    • 運用ルール次第ですが、安全な方に倒したいので false にしています
  • AUTH0_INCLUDED_ONLY でデプロイ対象をしぼりこみます
    • デプロイ対象をDatabaseとActions(FlowとLibrary)のみにしています
      • サービス名称と設定キー名が微妙に異なるの困る…
      • Flow === triggers / Library === actions
    • 逆に AUTH0_EXCLUDED で除外対象指定もできます

tennant.yamlの設定

tennant.yaml
databases:
  - name: sample
    options:
      configuration:
        SECRET_KEY_A: SECRET_VALUE
      customScripts:
        change_password: ./databases/sample/change_password.js
        create: ./databases/sample/create.js
        delete: ./databases/sample/delete.js
        get_user: ./databases/sample/get_user.js
        login: ./databases/sample/login.js
        verify: ./databases/sample/verify.js
actions:
  - name: sample-lib
    code: ./actions/sample-lib/code.js
    dependencies: []
    deployed: true
    runtime: node18-actions
    secrets:
      - SECRET_KEY_A: SECRET_VALUE
    status: built
    supported_triggers:
      - id: post-login
        version: v3
triggers:
  post-login:
    - action_name: sample-lib
      display_name: sample-lib
  • databases キーでDatabaseのActionScriptsと利用するシークレットの定義ができます
  • actions キーでActionsのLibraryのスクリプトと利用するシークレットの定義ができます
  • triggers キーでActionsのFlowを定義できます、定義した順に実行されます

秘匿情報をコード管理から外す

上記の設定でa0deployすることは可能ですが、このままだと秘匿情報をGit管理することになります。なるべく秘匿情報はコミットしないほうが良いので、秘匿情報を置き換えてデプロイするようにします。

a0deployにはキーワード置換機能があるのでこれを活用します。この機能は AUTH0_KEYWORD_REPLACE_MAPPINGS 環境変数にJSONをセットし、一致するキーをtenant.yamlファイルから探し出し、値に置き換えていってくれるものです。

例えば以下のようなtenant.yamlの場合

secrets:
  - SECRET_KEY_A: ##SECRET_KEY_A##

以下のように AUTH0_KEYWORD_REPLACE_MAPPINGS 環境変数にセットしてあげると

export AUTH0_KEYWORD_REPLACE_MAPPINGS='{
  "SECRET_KEY_A": "秘匿情報"
}'

デプロイ時に、良い感じに置き換えをしてくれます。

secrets:
  - SECRET_KEY_A: 秘匿情報

##キー名## 以外にも @@キー名@@ 記法もあります。詳しくは公式ドキュメントを参考にしてください。

以上を踏まえて前述したtenant.yamlのシークレットをコード管理から外すと以下の形になります。

tennant.yaml
databases:
  - name: sample
    options:
      configuration:
        SECRET_KEY_A: ##SECRET_KEY_A##
      customScripts:
        change_password: ./databases/sample/change_password.js
        create: ./databases/sample/create.js
        delete: ./databases/sample/delete.js
        get_user: ./databases/sample/get_user.js
        login: ./databases/sample/login.js
        verify: ./databases/sample/verify.js
actions:
  - name: sample-lib
    code: ./actions/sample-lib/code.js
    dependencies: []
    deployed: true
    runtime: node18-actions
    secrets:
      - SECRET_KEY_A: ##SECRET_KEY_A##
    status: built
    supported_triggers:
      - id: post-login
        version: v3
triggers:
  post-login:
    - action_name: sample-lib
      display_name: sample-lib

シークレットを管理する

tenent.yamlからシークレットを外したので、GitHub Actionsでデプロイする際に、どこかしらから取得する必要があります。今回はAWS SecretsManagerを利用します。GitHub自身のシークレット管理機能を使ってもよいのですが、複合することができず修正時に元データを知ることができないのでオススメはしません。

AWS SecretsManager


SecretsManagerに設定する値の例

a0deployには4つの環境変数が必要です。

  • AUTH0_DOMAIN
  • AUTH0_CLIENT_ID
  • AUTH0_CLIENT_SECRET
  • AUTH0_KEYWORD_REPLACE_MAPPINGS

クライアントIDとシークレットはデプロイ可能な権限を持つAuth0アプリケーションを作成して発行してください。

一点だけ注意するポイントがあります。AUTH0_KEYWORD_REPLACE_MAPPINGS に指定する値はJSON形式の文字列ですが、SecretsManagerに登録する際は シングルクォーテーションで囲ってください。 例えば以下のような形です。

// 本来登録したいJSONデータ
{ "FOO": "VALUE" }

// SecretsManagerに登録するデータ
'{ "FOO": "VALUE" }'

これは、下で紹介するGitHub Actions実行時にSecretsManagerを読み取り良い感じにパースをしてくれる aws-secretsmanager-get-secrets が、本来必要ない部分のパースまでしてしまうからです。ただの文字列だと認識させて、あとから余計なシングルクォーテーションを削除するという運用にしています。

もっといい方法があればそうしたい。

GitHub Actions

GitHub Actionsでa0deployをインストールし、AWS SecretsManagerから環境変数やシークレットを取得してセット、デプロイを実行するフローです。

./github/workflows/deploy.yml
name: Auth0 Script Deploy

on:
  push:
    branches:
      - release
      - staging
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: |-
      ${{
         github.ref_name == 'release' && 'production'
      || github.ref_name == 'staging' && 'staging'
      ||                                 'development'
      }}
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v3

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::${{ vars.AWS_ACCOUNT_ID }}:role/github-actions-oidc-role
          aws-region: ap-northeast-1

      - name: Get secrets from AWS Secrets Manager
        id: get-aws-secret
        uses: aws-actions/aws-secretsmanager-get-secrets@v2
        with:
          secret-ids: |
            ,auth0-deploy-keys
          parse-json-secrets: true

      - uses: actions/setup-node@v4
        with:
          node-version: 18

      - name: Install the auth0-deploy-cli
        run: npm install -g auth0-deploy-cli

      - name: Replace keywords
        run: echo "AUTH0_KEYWORD_REPLACE_MAPPINGS=${AUTH0_KEYWORD_REPLACE_MAPPINGS//\'/}" >> $GITHUB_ENV

      - name: Deploy to Auth0
        run: a0deploy import --config_file=config.json --input_file tenant.yaml
  • AWS_ACCOUNT_ID がプロダクション・開発環境で異なる場合があるので environment をブランチごとに切り替えています
  • GitHub ActionsからAWS SecretsManagerを呼び出すためにOIDCを設定しています
ムーザルちゃんねる

Discussion