Akatsuki Hackers Lab | 株式会社アカツキ(Akatsuki Inc.)

Akatsuki Hackers Labは株式会社アカツキが運営しています。

Redash を GCP の Workload Identity 連携に対応させた話

この記事は Akatsuki Games Advent Calendar 2023 の6日目の記事です。昨日はShuさんの Patch Your EC2 Instances Automatically using Systems Manager and Terraform でした。偶々ですが今日もある意味でセキュリティ運用を楽にするお話です。

Redash について

Redashは、BigQuery、Googleスプレッドシート、Athena、MySQL等、様々なデータソースからクエリした結果を可視化するダッシュボードを作成することができるオープンソースのツールです。
クエリパラメータという機能でクエリの一部に指定値を埋め込んで実行するといったことが非常に手軽にできるため、クエリの文法を知らない人にも簡単にデータ分析ができるようにしたりするのに活用しています。

Google のサービスを利用する際の認証方法

Redash のようなツールから Google のサービスへのアクセス時の認証方法としては、サービスアカウントキーが最も使用されることが多いでしょうか。ただし、サービスアカウントキーは機密データを守るためにも慎重に管理を行う必要があります。サービスアカウントキー管理のベストプラクティスのドキュメントには「可能であれば、認証のためのより安全な代替手段を選択してください」とまで書かれています。

Google のサービスには他にも様々な認証方法があります。

これらは、管理の手軽さとセキュリティを同時に向上させる良い機能だと思います。

しかしこれまで Redash は、Googleのサービスとの接続方法としてサービスアカウントキーにしか対応していませんでした。*1

そこで、Redash に Pull Request を送ってこれらの認証機能に対応させました。
本記事では、その内容や利用方法などを紹介します。

Pull Request の内容

Redash は元々、oauth2clientというライブラリをGoogleの認証に使用していましたが、これはかなり前に廃止されてメンテナンスも止まっているものでした。機能も限定的です。これをgoogle-authという現行の認証ライブラリに置き換えたというのがメインの内容です。

また、Redashが対応しているGoogleのサービスである BigQuery、Google スプレッドシート、Google Searchコンソール、Google Analytics のデータソース登録時に、サービスアカウントキーのアップロードをオプションとし、アップロードされなかった場合は Application Default Credentials (ADC) を使用するようにしました。
ADCの仕組みは以下に説明されていますが、これを利用することで前項で説明した様々な認証方法に対応させることができるようになっています。
アプリケーションのデフォルト認証情報の仕組み  |  Google Cloud

利用方法

まず、この機能はv10等の既存のリリースには含まれていないので、 Redash の開発ブランチを使用する必要があります。GitHub のmasterブランチや、Docker イメージ redash/redash:preview から取得してください。
以下では利用例が多いと思われる Docker を前提とします。

初めて利用する場合は、

docker compose run --rm server create_db

でDBの構築を行ってから docker compose up [-d] で起動します。

既存で v8 を利用している場合は、CHANGELOG のUpgradingの説明に従って docker-compose.yml を変更し、

docker compose run --rm server manage db upgrade

でデータベース移行が必要です。

GCE のメタデータを利用する場合、データソースを登録する際にサービスアカウントキーをアップロードしなければ自動的にメタデータが利用されるはずです。

AWS上でWorkload Identity を使用する場合には設定時に生成された構成JSONファイルが必要ですが、Redashにアップロードするのではなく、環境変数の GOOGLE_APPLICATION_CREDENTIALS でパスを指定するか、デフォルトの場所*2に配置するようにします。

参考までに、docker-compose.yml の例を示しておきます。

version: "2"
x-redash-service: &redash-service
  image: redash/redash:preview
  depends_on:
    - postgres
    - redis
  env_file: .env
  volumes:
    - ./config:/config  # ← 構成JSONファイルの共有用ディレクトリ
  restart: always
x-redash-environment: &redash-environment
  REDASH_REDIS_URL: "redis://redis:6379/0"
services:
  server:
    <<: *redash-service
    command: server
    environment:
      <<: *redash-environment
      REDASH_WEB_WORKERS: 4
  scheduler:
    <<: *redash-service
    command: scheduler
    environment:
      <<: *redash-environment
  worker:
    <<: *redash-service
    command: worker
    environment:
      <<: *redash-environment
      QUEUES: "periodic emails default"
      WORKERS_COUNT: 1
  scheduled_worker:
    <<: *redash-service
    command: worker
    environment:
      <<: *redash-environment
      QUEUES: "scheduled_queries,schemas"
      WORKERS_COUNT: 1
  adhoc_worker:
    <<: *redash-service
    command: worker
    environment:
      <<: *redash-environment
      QUEUES: "queries"
      WORKERS_COUNT: 2
  redis:
    image: redis:7-alpine
    restart: always
  postgres:
    image: pgautoupgrade/pgautoupgrade:15-alpine3.8
    env_file: .env
    volumes:
      - ./postgres-data:/var/lib/postgresql/data
    restart: always
  nginx:
    image: redash/nginx:latest
    ports:
      - "8000:80"
    depends_on:
      - server
    links:
      - server:redash
    restart: always

そして .env ファイルでシークレット等の環境変数を適切に設定します。この時に GOOGLE_APPLICATION_CREDENTIALS も設定できます。

GOOGLE_APPLICATION_CREDENTIALS=/config/google-auth-config.json
REDASH_COOKIE_SECRET=SampleSampleSampleSample
REDASH_DATABASE_URL=postgresql://postgres:aaaaaaaa@postgres/postgres
POSTGRES_PASSWORD=aaaaaaaa

まとめ

本記事では Redash で Google のサービスの認証に、サービスアカウントキーを使用するのを止め、GCEのメタデータや、GKE・AWS等のWorkload Identityに紐付いたサービスアカウントを使用できるようにした話を紹介しました。
ちなみにこの対応のために送った Pull Request は、送った数時間後には最初のコメントがもらえ、テスト方法に関する議論を経て3日後にはマージというスピード感で対応してもらえました。開発コミュニティがアクティブなのは良いですね。

*1: 厳密にはBigQuery + GCEのみ、専用のデータソース実装を使うことで対応させる方法はありましたが、煩雑な実装となっていました。

*2: ~/.config/gcloud/application_default_credentials.json