Android アプリを開発していく中で、シークレットキーなどの秘匿情報をプロジェクトで扱うことがあるかと思います。
例えば Qiita API を使った Android アプリを開発する場合、アクセストークンを発行するためには POST /api/v2/access_tokens を実行する必要がありますが、この時リクエストパラメータに client_id
と client_secret
が必要になります。
これらのパラメータは Qiita のアプリケーション ページからアプリケーションを登録することによって発行できますが、このような秘匿すべきパラメータを、以下のような条件で Android プロジェクトで扱うための設定について考えます。
- 漏洩防止のため Git のバージョン管理には含めない
- BuildConfig のフィールドとして、これらのパラメータをプログラムから参照できるようにする
今回は以下の3つの方法について紹介したいと思います。
- gradle.properties を使う
- 環境変数として設定する
- secrets-gradle-plugin を使う
1. gradle.properties を使う
一つ目の方法は gradle.properties
を使う方法です。
gradle.properties の作成
gradle.propeties
を以下のように作成し、~/.gradle/gradle.properties
に配置します。
QIITA_CLIENT_ID=xxxxxxxxxxxxxxxxxx
QIITA_CLIENT_SECRET=xxxxxxxxxxxxxxxxxx
build.gradle への設定
そして Android プロジェクトの app/build.gradle
で以下のように設定します。
...
android {
...
defaultConfig {
...
buildConfigField "String", "QIITA_CLIENT_ID", "\"${project.properties['QIITA_CLIENT_ID']}\""
buildConfigField "String", "QIITA_CLIENT_SECRET", "\"${project.properties['QIITA_CLIENT_SECRET']}\""
}
...
}
Gradle で project.properties['QIITA_CLIENT_ID']
のようにして、gradle.properties
に設定した値を取得することができます。
これでプログラムから BuildConfig.QIITA_CLIENT_ID
、BuildConfig.QIITA_CLIENT_SECRET
として設定した値を参照することができます。
CI でのビルド
もし CI でビルドするのであれば、必要なパラメータを CI で環境変数として設定しておいて、ビルドを実行する前に一度以下のコマンドを実行して gradle.properties
を作成しておく必要があります。
(以下の例では CI で環境変数 QIITA_CLIENT_ID
と QIITA_CLIENT_SECRET
が設定されているものとします)
cat <<EOF > ~/.gradle/gradle.properties
QIITA_CLIENT_ID=$QIITA_CLIENT_ID
QIITA_CLIENT_ID=$QIITA_CLIENT_SECRET
EOF
もしくは、ビルド時に -P
オプションを指定することによってパラメータを渡すことも可能です。
(以下の例でも環境変数 QIITA_CLIENT_ID
と QIITA_CLIENT_SECRET
が設定されているものとします)
./gradlew assembleRelease -PQIITA_CLIENT_ID=$QIITA_CLIENT_ID -PQIITA_CLIENT_SECRET=$QIITA_CLIENT_SECRET
2. 環境変数として設定する
先ほど紹介したように CI でビルドする際に環境変数として設定する必要があるのであれば、ローカルで開発する際にも環境変数で設定してしまう方法もあります。
環境変数への設定
OS や使用しているシェルによって設定方法は異なるかと思いますが、私の場合は Mac で zsh を使用しているので ~/.zshrc
に以下の設定を追記します。
export QIITA_CLIENT_ID=xxxxxxxxxxxxxxxxxx
export QIITA_CLIENT_SECRET=xxxxxxxxxxxxxxxxxx
direnv を使って環境変数を設定する
余談ですが Unix 系の OS であれば direnv を使うのがオススメです。
これを使うことによって、指定したディレクトリ以下に対して環境変数が適用されるようになります。
また ~/.zshrc
に環境変数を設定する必要がないため、プロジェクトごとにいくつか設定が必要な場合でも ~/.zshrc
に追加していく必要がなくなります。
導入方法や使い方については、こちらの記事 などが参考になるかと思います。
build.gradle への設定
そして Android プロジェクトの app/build.gradle
で以下のように設定します。
...
android {
...
defaultConfig {
...
buildConfigField "String", "QIITA_CLIENT_ID", "\"${System.getenv('QIITA_CLIENT_ID')}\""
buildConfigField "String", "QIITA_CLIENT_SECRET", "\"${System.getenv('QIITA_CLIENT_SECRET')}\""
}
...
}
環境変数の場合は System.getenv('QIITA_CLIENT_ID')
のようにして環境変数を取得できます。
CI でのビルド
CI 側に環境変数を設定しておくだけで OK です。
3. secrets-gradle-plugin を使う
google/secrets-gradle-plugin という Gradle プラグインを使うことによって、local.properties
などに設定されているプロパティを BuildConfig
のフィールドに設定してくれます。
設定はとても簡単で、まずは app/build.gradle
に以下のようにプラグインを導入します。
plugins {
...
id 'com.google.secrets_gradle_plugin' version '0.6'
}
そして、local.properties
に以下のように設定を追記します。
QIITA_CLIENT_ID=xxxxxxxxxxxxxxxxxx
QIITA_CLIENT_SECRET=xxxxxxxxxxxxxxxxxx
この状態でビルドを行うとプログラムから BuildConfig.QIITA_CLIENT_ID
、BuildConfig.QIITA_CLIENT_SECRET
として設定した値を参照することができるようになります。
また、このプラグインを使うことによって、設定した値が AndroidManifest.xml
内でも参照できるようになります。
その他に local.properties
以外にも設定ファイルを指定することができたり、指定したキーを無視するなどのオプションが設定できるようなので ドキュメント を参照してみてください。
CI でのビルド
local.properties
のファイルがあればよいので、ビルドを実行する前に以下のコマンドでファイルを作成する必要があります。
(以下の例では CI で環境変数 QIITA_CLIENT_ID
と QIITA_CLIENT_SECRET
が設定されているものとします)
cat <<EOF > local.properties
QIITA_CLIENT_ID=$QIITA_CLIENT_ID
QIITA_CLIENT_ID=$QIITA_CLIENT_SECRET
EOF