はじめに
- 今回はAmazon Cognitoを使ったGrafanaのOAuth認証の設定手順について解説していきます。また、Grafana roleのマッピングやTeamのマッピングについても少し解説しようと思います。
- 動作環境
- Grafana v9.3.1
Cognitoユーザープールの作成
まずCognitoユーザープールの作成と設定を行います。
Cognitoの画面を開き、「ユーザープールを作成」をクリックします。
サインインエクスペリエンスを設定
サインインオプションで「ユーザー名」と「Eメール」を選択し、ユーザー名の要件で「ユーザーが任意のユーザー名でサインインすることを許可」と「ユーザー名の大文字と小文字を区別する」を選択します。
セキュリティ要件を設定
demoのためデフォルトのパスワードポリシーとMFAなしを選択します。ユーザーアカウントの復旧もデフォルトのままにします。
※本番環境では強力なパスワードポリシーとMFA必須をおすすめします。
サインアップエクスペリエンスを設定
ユーザーの作成はすべてCognitoユーザープールで実施したいので、セルフサービスのサインアップの「自己登録」を外します。それ以外の設定はデフォルトのままです。
必須の属性に「追加の必須属性」として「name」を追加します。
メッセージ配信を設定
Eメールの設定で「CognitoでEメールを送信」を選択します。大規模なシステムの場合はSESでのメール送信の方が向いているかと思います。
アプリケーションを統合
「ユーザープール名」を入力します。 Cognitoのホストされたログインページを使うため、「CognitoのホストされたUIを使用」を選択します。
「Cognitoドメイン」に任意のドメイン名を入力します。このURLは後ほどのGrafana設定で使います
。
サードパーティのアプリケーションであるGrafanaを使うため、アプリケーションタイプで「その他」を選択します。「アプリケーションクライアント名」を入力し、「クライアントのシークレットを生成する」を選択します。
「許可されているコールバックURL」に「Grafanaのホスト/login/generic_oauth
」を入力します。今回はlocalhostでGrafanaを起動する予定なので、以下のURLになります。
http://localhost:3000/login/generic_oauth
高度なアプリケーションクライアントの設定を開き、「認証フロー」に以下の認証フローを追加します。
- ALLOW_ADMIN_USER_PASSWORD_AUTH
- ALLOW_USER_PASSWORD_AUTH
「OpenID接続スコープ」で以下のスコープを指定します。(「電話番号」は今回使わないので、外します) - aws.cognito.signin.user.admin
- OpenID
- Profile
クライアントIDとクライアントのシークレットの確認
上記手順で作成したCognitoユーザープールを開き、「アプリケーションの統合」タブをクリックします。
アプリケーションクライアントに関する情報欄に表示された「クライアントID」と「クライアントシークレット」をメモしておきます。後ほどのGrafana設定で使います。
ユーザーの作成
Grafanaにログインするユーザーを作成します。上記手順で作成したCognitoユーザープールを開き、「ユーザーを作成」をクリックします。
「ユーザー名」と「Eメールアドレス」を入力します。仮パスワードを設定し、ユーザーを作成します。demoなのでEメール招待は送信しないようにします。
Grafanaの設定
grafana.iniの作成
ローカルPCの任意の場所に「grafana.ini」というファイルを作成し、以下の情報を記載します。client_id、client_secret、auth_url、token_url、api_urlは適宜変更してください。
[auth.generic_oauth]
enabled = true
name = OAuth
client_id = <クライアントID>
client_secret = <クライアントシークレット>
scopes = email profile aws.cognito.signin.user.admin openid
auth_url = https://<Cognitoドメイン>.auth.<AWSリージョン>.amazoncognito.com/oauth2/authorize
token_url = https://<Cognitoドメイン>.auth.<AWSリージョン>.amazoncognito.com/oauth2/token
api_url = https://<Cognitoドメイン>.auth.<AWSリージョン>.amazoncognito.com/oauth2/userInfo
Grafanaの起動
DockerコンテナでGrafanaを起動します。grafana/grafanaのlastedを使いますが、2022/11/4時点での最新のGrafanaバージョンがv9.3.1になっています。
以下のコマンドを実行します。grafana.iniのパスのところは上記手順で作成したgrafana.iniファイルのパス
に置き換えてください。
docker run -d -p 3000:3000 -v <grafana.iniのパス>:/etc/grafana/grafana.ini --name grafana-demo grafana/grafana
ログイン
ブラウザからhttp://localhost:3000
にアクセスし、「Sign in with OAuth」をクリックすると、Cognitoの認証ページにリダイレクトされます。
作成済みのtest-userのEメールアドレスと仮パスワードでログインしてみます。
初回ログイン時パスワードの変更とNameの設定を求められます。NameはCognitoでのユーザー作成時に設定したユーザー名とは別で設定可能です。
ログインできました!
Grafana roleのマッピング
Cognitoユーザープールで作成したグループ名に応じて、該当グループに所属するユーザーを特定のGrafana role(Admin、Editor、Viewer)にマッピングすることが可能です。OAuthでログインしたユーザーはデフォルトではViewerになっているので、Adminというグループを作成して、AdminのGrafana roleをマッピングしてみます。
作成済みのCognitoユーザープールを開き、「グループ」タブをクリックし、「グループを作成」をクリックします。
「Admin」という名前でグループを作成します。
上記ユーザーの作成手順で作成したtest-userをグループに追加します。
グループ割り当て情報はid_tokenを介してGrafanaに送信されます。payloadは以下のようになっています。
{
......
"cognito:groups": [
"Admin"
],
......
}
GrafanaはJMESPathを使ってクエリするので、grafana.iniファイルに下記の一行を追加します。
role_attribute_path = ("cognito:groups" | contains([*], 'Admin') && 'Admin' || contains([*], 'Editor') && 'Editor' || 'Viewer')
ユーザーがAdminグループに所属す場合はAdminのroleを付与し、Editorグループに所属する場合はEditorのroleを付与し、それ以外のグループに所属する場合はViewerのroleを付与するという設定になります。
コンテナを再起動します。
docker restart grafana-demo
test-userで再度ログインすると、Adminになっていることがお分かりになるかと思います。
※ユーザーのグループ設定が変更されたら、Grafanaに再ログインすれば反映されます。
Team Sync
Grafana roleのマッピングだけでなく、Grafana teamのマッピングもできます。Grafanaではユーザーをteamに所属させ、team単位でのダッシュボード閲覧や編集などのアクセス制御ができます。
OAuthグループ(Cognitoユーザープールのグループ)をGrafana teamにマッピングすることで、Grafanaでのteam割り当て操作が必要なくなり、より管理しやすくなりますね。roleのマッピングと似たような設定方法で、groups_attribute_path
をgrafana.iniに追加することになります。
ただ、このTeam Syncという機能はGrafana Enterpriseでしか使えない
らしいです。
Grafana Enterpriseを使っていないので、今回はTeam Syncに関する検証はできませんが、今後もし使う機会があったら、また共有させていただければと思います。この機能が気になる方はGrafana公式ドキュメントをご参照ください。