基本的に以下のドキュメントの内容なのですが、正にOPがインターネット上で稼働してなくてもできるよ。必要なのはOpenID Provider Configuration Informationとjwks_uriをインターネット上で公開することだけだよ。ということです。
まったくインターネットを使わないということであれば無理そうです。
手順
-
パブリックドメインを取得する。
-
プライベートホストゾーンをパブリックドメイン(パブリックホストゾーン)と同名で作成する
-
OIDCサーバーをプライベートなネットワークに上記のドメインを使用して構築する
3.1. ホストを auth.example.com, issuer が auth.example.com/realms/main とします。
3.2. 同名のパブリックドメインを取得しているので、証明書はACMで取得するのが簡単です。 -
インターネット上でOpenID Provider Configuration Information、および jwks_uriで示されるドキュメントをOIDCサーバーと同じURLで公開します。(S3 + CloudFront + ACM が簡単ですが、どんな方法でも構いません)
以下はKeycloakで構築した時のURLの例です。(レルムはmainとしています)
これらをcurlなどで取得して公開します。鍵のローテーション時に自動でアップできるとよいですが、ローテーションの時間を決めることができれば、それに合わせて定期的にアップするのでもよいと思います。閉域VPC内からだとS3へVPCエンドポイントでアクセスしたり、SNSで他アカウントと連携したりして公開しましょう。 -
IAM にOIDCプロバイダーを登録する
- IDプロバイダーは https://auth.example.com/realms/main で登録します。
- 内部的にはAWSが
.well-known/openid-configuration
とjwks_uri
にアクセスします
コンソールでの追加を想定しています。それ以外の場合はSSL証明書のthumbprintの登録が必要です。
-
IAM に登録したOIDCプロバイダを信頼するロールを登録する
以下のような信頼関係ポリシーを持ったロールを作成します{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Federated": "arn:aws:iam::<ACCOUNT-ID>:oidc-provider/auth.example.com/realms/main" }, "Action": "sts:AssumeRoleWithWebIdentity", "Condition": { "StringEquals": { "auth.example.com/realms/main:aud": "example" } } } ] }
上記設定ではclient_idはexampleとしています。
これで認証時に受け取ったid_tokenを使用してAssumeRoleWithWebIdentityすればAssumeRoleした一時クレデンシャルを取得できます。閉域VPC内からということであれば、stsサービスのVPCエンドポイントが必要になります。
aws sts assume-role-with-web-identity \
--role-arn "$role_arn" \
--role-session-name "$session" \
--web-identity-token "$id_token"
まとめ
要するに以下の条件を満たしていればよいということですね。
- issuerはhttpsでなければならない
- OpenID Provider Configuration Informationにインターネット経由でアクセスできなければならない
- jwks_uriはhttpsでなければならず、やはりインターネット経由でアクセスできなければならない
注意事項
その他の注意事項としては以下のようなことに気を付けましょう。
トークンの署名はRS256のみです。Keycloakの既定はRS256ですが、気を付けないといけませんね。
The OAuth 2.0 access token or OpenID Connect ID token that is provided by the identity provider. Your application must get this token by authenticating the user who is using your application with a web identity provider before the application makes an AssumeRoleWithWebIdentity call. Only tokens with RSA algorithms (RS256) are supported.
.well-known/openid-configuration
, jwks_uri
ともに content-typeは application/json
です。
Keycloakから OIDC Provider Infomationを取得するときはバックチャネルでのアクセスはやめておくのが無難です。httpで返ってきたり、ホスト名がlocalhostになっていたりします。