[09] 為什麼 EKS 可以整合 IAM roles for service accounts(IRSA)(二)
上一篇,我們根據 token 內容得知 OIDC provider URL 設定為 EKS OICD provider,然而為什麼 IAM OIDC 與 EKS 關係為何?其 token 又是怎麼被掛載注入於 Pod 呢?
- 2014 年,IAM 服務支援 OpenID Connect (OIDC) 的聯合身分。此功能可讓您向支援的身分提供者驗證 AWS API 呼叫,並接收有效的 OIDC JSON Web Token (JWT)。因此可以將 token 提供 AWS STS
AssumeRoleWithWebIdentity
2 API ,並取得 IAM temporary security credentials,並藉由此 credentials 與 AWS 服務互動。 - Kubernetes 預設使用 Service Account 作為內部身份系統。Pods 可以使用由 Kubernetes API server 驗證自動掛載的 Token 訪問 API server。在 Kubernetes 1.12 版本支援了
ProjectedServiceAccountToken
功能。此功能是 OIDC JSON Web Token,同時包含服務帳戶身分,並支援可設定的對象。
故本文接續討論:
- OIDC 流程
- 此 token 是如何被產生的
- AssumeRoleWithWebIdentity API
OIDC 流程
首先,OpenID Providers 必須提供提供一個 JSON 格式文件設定檔於路徑 /.well-known/openid-configuration
給 issuer。因此我們可以透過 curl
命令檢視 EKS OIDC endpoint 所提供設定,其詳細欄位定義查看官方 OIDC 文件欄位定義 3:
$ curl -s https://oidc.eks.eu-west-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/.well-known/openid-configuration | jq .
{
"issuer": "https://oidc.eks.eu-west-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"jwks_uri": "https://oidc.eks.eu-west-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/keys",
"authorization_endpoint": "urn:kubernetes:programmatic_authorization",
"response_types_supported": [
"id_token"
],
"subject_types_supported": [
"public"
],
"claims_supported": [
"sub",
"iss"
],
"id_token_signing_alg_values_supported": [
"RS256"
]
}
其中我們關注於 jwks_uri
:提供 JSON Web Key (JWK) set 的 openid-configuration 中指定的 endpoint,換言之,主要目的用於簽署來自 issuer 的 token。
$ curl -s https://oidc.eks.eu-west-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/keys | jq .
{
"keys": [
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"kid": "001bbf00f107017bc195419a1f47c4d3debad7d8",
"alg": "RS256",
"n": "qxowTumR7IVAaxNmMluNDliaZO-rRGnREr0s7oIFZf2iJzO31UW7W8a3MGOauHxrjMxhop0yO4ScKfP29OsCOAoG--_0mbVUnNYaa4aFbB5QqFhynXYGuITTi4AuRs4nMxdlViMA_AloC57q_dKGnfW2azdKpr8hFWv6y_NX_oauiJ1LVQdhpHXi5WJkev8yxsUH5L3Nzs3016j3t8VEQ6CjUt71BBcpeSLAOiEPM99EnNdF9oUmHttnpg09laK7dEuR0LkwVJd_MuNkAh8qn9GWl-sJOGqkvwCGu7i_p92BvvB3Uf0WdQRqadWBuWcdCR69Khp0DdHhhEv2blAzuw"
},
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"kid": "1e1d3732da4f678d29629aa8904535c354a50cc9",
"alg": "RS256",
"n": "s9nXfKxBjAY3akEnV5Enr76ZLkXCoeWjm0Ydr5bhubEAhWGszrPaLFVGskiddlYnGa_GGRDFFs-Lr_Gvb_Mxcvk0BfuylhAdfW6_slq6mmEJqw_HIekYnWmd2B6JIyGgmOFtebWEyKWgQd_U_WxPRxUqTh-wnEDP8Lb7V5F15lhGYtZzxKQMLxIDfbZVJmjQ2iruIUAMMXTgGMOSIq6dg4f4YE2-VnTr3_e35NHY83A0fr4_LnyMq7LX9LC5mBWH5yU4GFUvBo39eOMopZSBnEoytzNbHVNwUr7HFSRpKtXsUQCo5VqSRF-wq8cxT7FGpeETBoBGO5gdbvGjpCZJ-Q"
}
]
}
AWS STS 藉由在 jwks_uri
定義的 endpoint https://oidc.eks.eu-west-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/keys
檢查此 token 已經由信任來源(Identity Provider defined in IAM,如 EKS)簽署並驗證其 signature。以下整理 OIDC 流程:
- client 提供了一個由信任 provider 簽署 JWT token 至 AWS STS endpoint 進行身份驗證(authenticate)。
- AWS STS endpoint 接收此 JWT 並確認 AWS STS endpoint 接收 JWT 並確定其是否具有由 JWT header 中的
kid
(key ID)attribute 的 public key。 如果它不識別 key,則會有以下流程:- 透過
/.well-known/openid-configuration
路徑取得 OIDC 設定檔。 - 並基於上述 URL 路徑中的
jwks_uri
欄位取得 provider 的 published public keys (the JWKS)。
- 透過
- 一旦 AWS STS endpoint 取得 provider 的 public key,將會驗證(validates)token 簽名、到期時間(expiration)、audience claims
- 驗證完畢後,API 則可以確保 token 有效性。