はじめに
Auth0活用記事第2弾。
第一弾では、AWSのマネージメントコンソールログインをSAML認証で行えるようにした。
今回は、Amazon Managed GrafanaへのログインをAuth0をIdPに設定して行えるようにする。
Amazon Managed Grafanaは、Grafanaをフルマネージド化した魅力的なサービスだが、GrafanaへのログインがAmazonのマネージメントコンソールログインとは分けられており、かつSAML認証が必要である。
AWSに閉じて利用しようとすると、Organizationsを前提としたIAM Identity Centerを設定しなければならず、お手軽には使いにくい。
おためしで使ったり、小さいチームで利用するユースケースとしては、Auth0等のIDaaSの機能を利用するのが良いだろう。
今回は、このAmazon Managed GrafanaとAuth0の連携部分についてTerraformで自動構築をしていく。
なお、Terraformを扱うにあたってのプロバイダの設定とAuth0テナントのユーザは前回の設定をそのまま流用するため、Amazon Managed Grafanaのみ使いたい方については、前回記事の「Auth0のTerraformプロバイダの設定」の章を参照していただきたい。
Amazon Managed Grafanaの設定
まずは、Amazon Managed Grafanaのワークスペースを設定する。
authentication_providers
には、IAM Identity Centerを使う場合はAWS_SSO
を設定するが、今回は外部のSAML IdPを利用するため、SAML
を設定する。
本記事では、ログインするところまでを目的としているので、IAMロールのみ作ってIAMポリシーのアタッチを行っていないが、実際の運用ではポリシーの設定まで行う。
resource "aws_grafana_workspace" "example" {
name = local.amg_workpace_name
account_access_type = "CURRENT_ACCOUNT"
authentication_providers = ["SAML"]
permission_type = "CUSTOMER_MANAGED"
role_arn = aws_iam_role.amg.arn
}
resource "aws_iam_role" "amg" {
name = local.iam_amg_role_name
assume_role_policy = data.aws_iam_policy_document.amg_assume.json
}
data "aws_iam_policy_document" "amg_assume" {
statement {
effect = "Allow"
actions = [
"sts:AssumeRole",
]
principals {
type = "Service"
identifiers = [
"grafana.amazonaws.com",
]
}
}
}
Auth0のクライアントアプリケーションの設定
Auth0のクライアントアプリケーションは以下のように設定する。
callbacks
と、addons.samlp.audience
およびaddons.samlp.destination
には、Amazon Managed Grafanaワークスペースの構築時に払い出されるエンドポイントを設定する。
resource "auth0_client" "amazon_managed_grafana" {
name = "AWS Managed Grafana"
description = "AWS Managed Grafana Login"
app_type = "regular_web"
custom_login_page_on = true
is_first_party = true
is_token_endpoint_ip_header_trusted = false
oidc_conformant = true
require_proof_of_possession = false
callbacks = ["https://${aws_grafana_workspace.example.endpoint}/saml/acs"]
grant_types = [
"authorization_code",
"implicit",
"refresh_token",
"client_credentials",
]
jwt_configuration {
alg = "RS256"
lifetime_in_seconds = 36000
secret_encoded = false
}
refresh_token {
leeway = 0
token_lifetime = 31557600
rotation_type = "non-rotating"
expiration_type = "non-expiring"
}
addons {
samlp {
audience = "https://${aws_grafana_workspace.example.endpoint}/saml/metadata"
destination = "https://${aws_grafana_workspace.example.endpoint}/saml/acs"
mappings = {
email = "email"
nickname = "nickname"
}
create_upn_claim = false
passthrough_claims_with_no_mapping = false
map_unknown_claims_as_is = false
}
}
}
再び、Amazon Managed Grafanaの設定(SAML設定)
Auth0のクライアントアプリケーションの登録が完了したら、再びAWSの設定に戻る。
Amazon Managed Grafanaとワークスペースの連携は、aws_grafana_workspace_saml_configuration
のリソースで設定を行う。
idp_metadata_url
は、Auth0クライアントアプリケーションのメタデータURLを設定する。前回のIDプロバイダーの記事では、SAMLメタデータのBodyが直接必要であったため、http
データソースを利用したが、今回はエンドポイントのURLだけあれば良いので楽だ。
*_assertion
は、SAML認証のアサーションのどの項目をGrafanaの設定値にマッピングするかの設定だ。
resource "aws_grafana_workspace_saml_configuration" "example" {
workspace_id = aws_grafana_workspace.example.id
editor_role_values = ["editor"]
idp_metadata_url = "https://${var.auth0_domain}/samlp/metadata/${auth0_client.amazon_managed_grafana.id}"
admin_role_values = [auth0_user.user.email]
login_assertion = "email"
name_assertion = "nickname"
email_assertion = "email"
role_assertion = "email"
}
これで、設定は完了だ。少ない手順で実行できて嬉しい。
いざ、動かす!
terraform apply
したら、Amazon Managed Grafanaのログイン画面にアクセスしよう。
ログインのエンドポイントは、マネージメントコンソールの以下のURLで良い。
アクセスすると、以下のようにSAMLログイン用のボタンが表示される。
ボタンを押すと、前回同様のAuth0のログイン画面に遷移する。
ここで、前回作成したユーザで認証を行うと、無事、Amazon Managed Grafanaのコンソール画面にアクセスできた!
なお、Auth0のテナントを前回と同じにしておくことで、ログイン状態が共有される。
Amazon Managed Grafana用のログインを行っている状態で、AWSのマネージメントコンソールのログインエンドポイントのURLにアクセスすると、認証なしでマネージメントコンソールにもアクセスができる。
同じテナントにすることで、アプリケーションによらずSSOができるようになるということだ。便利!
ただし、ログイン状態が共有されるということはログアウトも同期される。
単純にAmazon Managed Grafanaからログアウトしただけでは、Auth0のログインセッションは残るため、再度Amazon Managed Grafanaにアクセスすると認証なしでログインができてしまう。
一方で、ログアウト用のエンドポイントを叩いてしまうと、マネージメントコンソールのログアウトもしてしまう。
この問題は非常に難しいようで、Auth0も枠外にリンクしたようなブログ記事を投稿している。
エンドユーザに関連するサービスを提供する場合、ログイン管理における要件を整理する必要があることを留意していただきたい。