์ด ํ์ด์ง์์๋ ์ง์ ID ์ ํด๋ฅผ ์ฌ์ฉํ๋ฉด ์์ฑ๋๋ ๊ฐ์ฌ ๋ก๊ทธ์ ์์๋ฅผ ๋ณด์ฌ์ค๋๋ค. ์ง์ ID ์ ํด๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ ํํฐ ID์์ ์๋น์ค ๊ณ์ ํค๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๋Google Cloud ๋ฆฌ์์ค์ ์ก์ธ์คํ๋๋ก ํ์ฉํ ์ ์์ต๋๋ค.
๊ฐ์ฌ ๋ก๊ทธ ์ฌ์ฉ ์ค์ ๋ฐ ๋ณด๊ธฐ์ ๋ํ ์์ธํ ๋ด์ฉ์ IAM ๊ฐ์ฌ ๋ก๊น ์ ์ฐธ์กฐํ์ธ์.
์ง์ ํ์ ๋ง๋ค๊ณ ๊ด๋ฆฌํ ๋ IAM์ด ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ง์ ํ์ ๊ด๋ฆฌํ ๋ ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์ฌ์ฉ ์ค์ ํ๋ ค๋ฉด ๋ค์ API์ ๋ํ ๋ฐ์ดํฐ ์ก์ธ์ค ํ๋์ ๋ํ ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์ฌ์ฉ ์ค์ ํด์ผ ํฉ๋๋ค.
- Identity and Access Management(IAM) API(๋ก๊ทธ ์ ํ '๊ด๋ฆฌ์ ์ฝ๊ธฐ' ์ฌ์ฉ ์ค์ )
ํ ํฐ ๊ตํ ํ๋ก์ธ์ค ๋๋Google Cloud ์ฝ์(์ ํด) ๋ก๊ทธ์ธ์ ๋ํ ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์ถ๊ฐ๋ก ๊ตฌ์ฑํ๋ ค๋ฉด ๋ค์ API์ ๋ํ ๋ฐ์ดํฐ ์ก์ธ์ค ํ๋์ ๋ํ ๊ฐ์ฌ ๋ก๊ทธ๋ ์ฌ์ฉ ์ค์ ํด์ผ ํฉ๋๋ค.
- Security Token Service API(๋ก๊ทธ ์ ํ '๊ด๋ฆฌ์ ์ฝ๊ธฐ' ์ฌ์ฉ ์ค์ )
์ง์ ํ ๋ง๋ค๊ธฐ ๋ก๊ทธ
๋ค์ ์์์์๋ ์ง์ ํ์ ๋ง๋๋ ๋ก๊ทธ ํญ๋ชฉ์ ๋ณด์ฌ์ค๋๋ค. ์ด ์์์์ ์ฌ์ฉ์ sam@example.com
์ ID๊ฐ 123456789012
์ธ ์กฐ์ง์ ID๊ฐ my-pool
์ธ ์ง์ ํ์ ๋ง๋ค์์ต๋๋ค.
{ "logName": "organizations/123456789012/logs/cloudaudit.googleapis.com%2Factivity", "protoPayload": { "@type": "type.googleapis.com/google.cloud.audit.AuditLog", "authenticationInfo": { "principalEmail": "sam@example.com", }, "methodName": "google.iam.admin.v1.WorkforcePools.CreateWorkforcePool", "resourceName": "locations/global/workforcePools/my-pool", "serviceName": "iam.googleapis.com", "request": { "@type": "type.googleapis.com/google.iam.admin.v1.CreateWorkforcePoolRequest", "workforcePool": { "parent": "organizations/123456789012" }, "workforcePoolId": "my-pool" } }, "resource": { "type": "audited_resource" } }
IdP ํ ํฐ์ ์ ํด ํ ํฐ์ผ๋ก ๊ตํํ๊ธฐ ์ํ ๋ก๊ทธ
์ง์ ID ํ๊ณผ ์ง์ ID ํ ๊ณต๊ธ์ ์ฒด๋ฅผ ์ค์ ํ ํ ID ๊ณต๊ธ์ ์ฒด(IdP)์ ํ ํฐ์ ๋ง๋ค์ด ์ ํด ํ ํฐ์ผ๋ก ๊ตํํ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ ์ก์ธ์ค ํ๋์ Cloud ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์ฌ์ฉ ์ค์ ํ๋ฉด IAM์ ์ฃผ ๊ตฌ์ฑ์์ด ํ ํฐ์ ๊ตํํ ๋๋ง๋ค ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ์ ์์ฑํฉ๋๋ค. ๋ก๊ทธ ํญ๋ชฉ์๋ ๋ค์ ํ๋๊ฐ ํฌํจ๋ฉ๋๋ค.
protoPayload.authenticationInfo.principalSubject
: IdP ํ ํฐ ์ ๋ชฉ์ ๋๋ค.- OIDC IdP์ ๊ฒฝ์ฐ ์ด ํ๋์๋ OIDC ํ ํฐ์
sub
๋๋ ์ ๋ชฉ, ํด๋ ์ ๊ฐ์ด ํฌํจ๋ฉ๋๋ค. - SAML IdP์ ๊ฒฝ์ฐ ์ด ํ๋์ SAML ์ด์ค์
์ ์๋
Subject
์์ฑ์NameID
ํ์ ์์ฑ ๊ฐ์ด ํฌํจ๋ฉ๋๋ค.
- OIDC IdP์ ๊ฒฝ์ฐ ์ด ํ๋์๋ OIDC ํ ํฐ์
protoPayload.metadata.mapped_principal
: ํ ํฐ์ ์ ๋ชฉ์ผ๋ก IAM ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์ฃผ ๊ตฌ์ฑ์์ ์๋ณํฉ๋๋ค.principal://iam.googleapis.com/locations/global/workforcePools/POOL_ID/subject/IDENTIFIER
protoPayload.resourceName
: ํ ํฐ์ด ์ฐ๊ฒฐ๋ ์ง์ ํ ์ ๊ณต์ ์ฒด์ ๋๋ค.
๋ค์ ์์์์๋ ํ ํฐ ๊ตํ ์์ฒญ์ ๋ํ ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ์ ๋ณด์ฌ์ค๋๋ค. ์ด ์์์์๋ OIDC ํ ํฐ์ด ์ ํด ํ ํฐ์ผ๋ก ๊ตํ๋ฉ๋๋ค.
{ "logName": "organizations/123456789012/logs/cloudaudit.googleapis.com%2Fdata_access", "protoPayload": { "@type": "type.googleapis.com/google.cloud.audit.AuditLog", "authenticationInfo": { "principalSubject": "b6112abb-5791-4507-adb5-7e8cc306eb2e" }, "metadata": { "mapped_principal": "principal://iam.googleapis.com/locations/global/workforcePools/oidc-pool/subject/a1234bcd-5678-9012-efa3-4b5cd678ef9a" }, "methodName": "google.identity.sts.v1.SecurityTokenService.ExchangeToken", "resourceName": "locations/global/workforcePools/oidc-pool/providers/oidc-provider", "serviceName": "sts.googleapis.com", "request": { "@type": "type.googleapis.com/google.identity.sts.v1.ExchangeTokenRequest", "audience": "//iam.googleapis.com/locations/global/workforcePools/oidc-pool/providers/oidc-provider", "grantType": "urn:ietf:params:oauth:grant-type:token-exchange", "requestedTokenType": "urn:ietf:params:oauth:token-type:access_token", "subjectTokenType": "urn:ietf:params:oauth:token-type:id_token" } }, "resource": { "type": "audited_resource" } }
์๋ช ๋ฐ ์ํธํ๋ SAML ์ด์ค์ ๋ก๊ทธ
์ด ์น์ ์์๋ ๋ณด์ ํ ํฐ ์๋น์ค์์ ์๋ช ๋ SAML ์ด์ค์ ์ ํ์ธํ๊ฑฐ๋ IdP์์ ์ ์ก๋ ์ํธํ๋ ์ด์ค์ ์ ๋ณตํธํํ๋ฉด ์์ฑ๋๋ Cloud ๊ฐ์ฌ ๋ก๊ทธ์ ๋ก๊ทธ ํญ๋ชฉ์ ์ค๋ช ํฉ๋๋ค.
์ง์ ID ์ ํด์ ๊ฒฝ์ฐ ๊ด๋ จ ๋ก๊ทธ ํญ๋ชฉ์ ๋ค์๊ณผ ์ ์ฌํฉ๋๋ค.
"keyInfo": [ { "use": "verify" "fingerprint": "3C:B2:47:F8:A5:9A:8A:52:BD:1C:BC:96:B5:45:C1:8D:A7:F1:73:2D" }, { "use": "decrypt" "resourceName": "//iam.googleapis.com/locations/global/workforcePools/WORKFORCE_POOL_NAME/providers/PROVIDER_NAME/keys/KEY_NAME" } ]
์ด ์ถ๋ ฅ์๋ ๋ค์ ๊ฐ์ด ํฌํจ๋ฉ๋๋ค.
fingerprint
: SAML ์ฌ์ฉ์ ์ธ์ฆ ์ ๋ณด์ ์๋ช ์ ํ์ธํ๋ ๋ฐ ์ฌ์ฉ๋ X.509 ์ธ์ฆ์ SHA-256 ํด์์ 16์ง์ ํํ์ ๋๋ค. X.509 ์ธ์ฆ์๋ ์ง์ ID ํ ๊ณต๊ธ์ ์ฒด์ ์ฐ๊ฒฐ๋ SAML XML ๋ฉํ๋ฐ์ดํฐ์์ ์ถ์ถ๋ฉ๋๋ค.resourceName
: ์ํธํ๋ SAML ์ด์ค์ ์ ๋ณตํธํํ๋ ๋ฐ ์ฌ์ฉ๋ ์ธ๋ ฅ ID ํ ๊ณต๊ธ์ ์ฒด ํค์ ๋ฆฌ์์ค ์ด๋ฆ์ ๋๋ค. ์ด ํ๋๋ ID ์ ํด์์ IdP๋ก๋ถํฐ ์ํธํ๋ SAML ์๋ต์ ์์ ํ๋ ๊ฒฝ์ฐ์๋ง ํ์๋ฉ๋๋ค.
์ ํด ํ ํฐ์ผ๋ก Google Cloud API๋ฅผ ํธ์ถํ๊ธฐ ์ํ ๋ก๊ทธ
IdP ํ ํฐ์ ์ ํด ํ ํฐ์ผ๋ก ๊ตํํ ํ ์ ํด ํ ํฐ์ ์ฌ์ฉํ์ฌ Google Cloud API๋ฅผ ํธ์ถํ ์ ์์ต๋๋ค. ํธ์ถํ๋ ๋ฉ์๋ ์ค ์ผ๋ถ๋ ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
๋ค์ ์์์์๋ ์ ํด ํ ํฐ์ ์ฌ์ฉํด์ ํ๋ก์ ํธ์ Cloud Storage ๋ฒํท์ ๋์ดํ๋ ์์ฒญ์ ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ์ ๋ณด์ฌ์ค๋๋ค.
{ "logName": "projects/my-project/logs/cloudaudit.googleapis.com%2Fdata_access", "protoPayload": { "@type": "type.googleapis.com/google.cloud.audit.AuditLog", "authenticationInfo": { "principalSubject": "principal://iam.googleapis.com/locations/global/workforcePools/oidc-pool/subject/kalani@altostrat.com" }, "methodName": "storage.buckets.list", "serviceName": "storage.googleapis.com", }, "resource": { "type": "gcs_bucket" } }
Google Cloud ์ฝ์(์ ํด) ๋ก๊ทธ์ธ ๋ก๊ทธ
์ง์ ID ํ๊ณผ ํด๋น IdP๋ฅผ ์ค์ ํ ํ ์ฌ์ฉ์๊ฐ ์ฝ์(์ ํด)์ ์ฌ์ฉํ์ฌ Google Cloud ์ ๋ก๊ทธ์ธํ ์ ์์ต๋๋ค.
์ฑ๊ณต์ ์ธ ๋ก๊ทธ์ธ ๋ก๊ทธ
์ด ์น์
์์๋ ์ฑ๊ณตํ ๋ก๊ทธ์ธ์ ๊ฒฐ๊ณผ๋ก ๊ธฐ๋ก๋ ์์ Cloud ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ ์์๋ฅผ ๋ณด์ฌ์ค๋๋ค. ์ด ์์์์๋ ์ฌ์ฉ์ user@example.com
์ด locations/global/workforcePools/my-pool/providers/my-provider
๊ณต๊ธ์
์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธํฉ๋๋ค. ์ด ๊ฒฝ์ฐ ๋ค์ Cloud ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ์ด ์์ฑ๋ฉ๋๋ค.
{
"logName": "organizations/my-organization-id/logs/cloudaudit.googleapis.com%2Fdata_access",
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo": {
"principalSubject": "user@example.com",
},
"serviceName": "sts.googleapis.com",
"methodName": "google.identity.sts.SecurityTokenService.WebSignIn",
"resourceName": "locations/global/workforcePools/my-pool/providers/my-provider",
"request": {
"@type": "type.googleapis.com/google.identity.sts.SecurityTokenService.WebSignInRequest",
"provider": "//iam.googleapis.com/locations/global/workforcePools/my-pool/providers/my-provider",
"continueUrl": "https://console.cloud.google",
"host": "http://auth.cloud.google",
},
"metadata": {
"mappedPrincipal": "principal://iam.googleapis.com/locations/global/workforcePools/my-pool/subject/user@example.com",
}
},
"resource": {
"type": "audited_resource",
"labels": {
"service": "sts.googleapis.com",
"method": "google.identity.sts.SecurityTokenService.WebSignIn",
}
},
}
SAML ๊ณต๊ธ์ ์ฒด์ Cloud ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ์ ๋ฉํ๋ฐ์ดํฐ ํ๋์ ์๋ช ํค ์ ๋ณด๋ฅผ ์ถ๊ฐ๋ก ํฌํจํ ์ ์์ต๋๋ค.
{
"metadata": {
"mappedPrincipal": "principal://iam.googleapis.com/locations/global/workforcePools/my-pool/subject/user@example.com",
"keyInfo": [
{
"use": "verify",
"fingerprint": "AE:CK:LM:EF:LK:OG:EH:IJ:KN:AL:OM:AD:NO",
}
],
}
}
์คํจํ ๋ก๊ทธ์ธ ๋ก๊ทธ
์ด ์น์
์์๋ ์คํจํ ๋ก๊ทธ์ธ์ ๊ฒฐ๊ณผ๋ก ๊ธฐ๋ก๋ Cloud ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ ์์๋ฅผ ๋ณด์ฌ์ค๋๋ค. ์ด ์์์์๋ ์ฌ์ฉ์ user@example.com
์ด locations/global/workforcePools/my-pool/providers/my-provider
๊ณต๊ธ์
์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธ์ ์๋ํ์ง๋ง ํน์ฑ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋์ง ์์ ์ก์ธ์ค๊ฐ ๊ฑฐ๋ถ๋ฉ๋๋ค. ์ด ๊ฒฝ์ฐ ๋ค์ Cloud ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ์ด ์์ฑ๋ฉ๋๋ค.
{
"logName": "organizations/my-organization-id/logs/cloudaudit.googleapis.com%2Fdata_access",
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo": {
"principalSubject": "user@example.com",
},
"status": {
"code": 3,
"message": "The given credential is rejected by the attribute condition.",
},
"serviceName": "sts.googleapis.com",
"methodName": "google.identity.sts.SecurityTokenService.WebSignIn",
"resourceName": "locations/global/workforcePools/my-pool/subject/user@example.com",
"request": {
"@type": "type.googleapis.com/google.identity.sts.SecurityTokenService.WebSignInRequest",
"provider": "//iam.googleapis.com/locations/global/workforcePools/my-pool/providers/my-provider",
"host": "http://auth.cloud.google",
},
"metadata": {
"mappedPrincipal": "principal://iam.googleapis.com/locations/global/workforcePools/my-pool/subject/user@example.com",
}
},
"resource": {
"type": "audited_resource",
"labels": {
"service": "sts.googleapis.com",
"method": "google.identity.sts.SecurityTokenService.WebSignIn",
}
},
}
๋ก๊ทธ์์ ๋ก๊ทธ
์ด ์น์
์์๋ ๋ก๊ทธ์์ ์ด๋ฒคํธ์ ๊ฒฐ๊ณผ๋ก ๊ธฐ๋ก๋๋ Cloud ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ ์์๋ฅผ ๋ณด์ฌ์ค๋๋ค. ์ด ์์์์๋ locations/global/workforcePools/my-pool/providers/my-provider
๊ณต๊ธ์
์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธํ ์ฌ์ฉ์ user@example.com
์ด ๋ก๊ทธ์์์ ์์ํฉ๋๋ค. ์ด ๊ฒฝ์ฐ ๋ค์ Cloud ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ์ด ์์ฑ๋ฉ๋๋ค.
{
"logName": "organizations/my-organization-id/logs/cloudaudit.googleapis.com%2Fdata_access",
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo": {
"principalSubject": "user@example.com",
},
"serviceName": "sts.googleapis.com",
"methodName": "google.identity.sts.SecurityTokenService.WebSignOut",
"resourceName": "locations/global/workforcePools/my-pool/providers/my-provider",
"request": {
"@type": "type.googleapis.com/google.identity.sts.SecurityTokenService.WebSignOutRequest",
"provider": "//iam.googleapis.com/locations/global/workforcePools/my-pool/providers/my-provider",
"host": "http://auth.cloud.google"
},
"metadata": {
"mappedPrincipal": "principal://iam.googleapis.com/locations/global/workforcePools/my-pool/subject/user@example.com",
}
},
"resource": {
"type": "audited_resource",
"labels": {
"service": "sts.googleapis.com",
"method": "google.identity.sts.SecurityTokenService.WebSignOut"
}
},
}
OAuth ํ๋ฆ์ ์ฌ์ฉํ๋ ๋ก๊ทธ์ธ ๋ก๊ทธ
์ง์ ID ํ ๋ฐ ์ง์ ID ํ ์ ๊ณต์ ์ฒด๋ฅผ ์ค์ ํ ํ OAuth ํ๋ฆ์ ์ฌ์ฉํ์ฌ Google Cloud ๋ฆฌ์์ค์ ์ก์ธ์คํ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ ์ก์ธ์ค ๊ฐ์ฌ ๋ก๊ทธ ํ๋์ Cloud ๊ฐ์ฌ ๋ก๊ทธ๋ฅผ ์ฌ์ฉ ์ค์ ํ ํ IAM์ ์ฃผ ๊ตฌ์ฑ์์ด OAuth ํ๋ฆ์ ์ฌ์ฉํ์ฌ ๋ก๊ทธ์ธํ ๋๋ง๋ค ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ์ ์์ฑํฉ๋๋ค. ๋ก๊ทธ ํญ๋ชฉ์๋ ๋ค์ ํ๋๊ฐ ํฌํจ๋ฉ๋๋ค.
protoPayload.authenticationInfo.principalSubject
: IdP ํ ํฐ ์ ๋ชฉ์ ๋๋ค.- OIDC IdP์ ๊ฒฝ์ฐ ์ด ํ๋์๋ OIDC ํ ํฐ์
sub
๋๋ ์ ๋ชฉ, ํด๋ ์ ๊ฐ์ด ํฌํจ๋ฉ๋๋ค. - SAML IdP์ ๊ฒฝ์ฐ ์ด ํ๋์ SAML ์ด์ค์
์ ์๋
Subject
์์ฑ์NameID
ํ์ ์์ฑ ๊ฐ์ด ํฌํจ๋ฉ๋๋ค.
- OIDC IdP์ ๊ฒฝ์ฐ ์ด ํ๋์๋ OIDC ํ ํฐ์
protoPayload.metadata.mapped_principal
: ํ ํฐ์ ์ ๋ชฉ์ผ๋ก IAM ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์ฃผ ๊ตฌ์ฑ์์ ์๋ณํฉ๋๋ค.principal://iam.googleapis.com/locations/global/workforcePools/POOL_ID/subject/IDENTIFIER
protoPayload.resourceName
: ํ ํฐ์ด ์ฐ๊ฒฐ๋ ์ง์ ํ ์ ๊ณต์ ์ฒด์ ๋๋ค.
๋ค์ ์์์์๋ ํ ํฐ ๊ตํ ์์ฒญ์ ๋ํ ๊ฐ์ฌ ๋ก๊ทธ ํญ๋ชฉ์ ๋ณด์ฌ์ค๋๋ค. ์ด ์์์์ ์ฃผ ๊ตฌ์ฑ์์ OIDC ์ ๊ณต์ ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ์ ํด๋ฉ๋๋ค.
{ "logName": "organizations/123456789012/logs/cloudaudit.googleapis.com%2Fdata_access", "protoPayload": { "@type": "type.googleapis.com/google.cloud.audit.AuditLog", "authenticationInfo": { "principalSubject": "b6112abb-5791-4507-adb5-7e8cc306eb2e" }, "metadata": { "mapped_principal": "principal://iam.googleapis.com/locations/global/workforcePools/POOL_ID/subject/IDENTIFIER" }, "methodName": "google.identity.sts.v1.SecurityTokenService.ExchangeOauthToken", "resourceName": "locations/global/workforcePools/POOL_ID/providers/WORKFORCE_PROVIDER_ID", "serviceName": "sts.googleapis.com", "request": { "@type": "type.googleapis.com/google.identity.sts.v1.ExchangeOauthTokenRequest", "grantType": "authorization_code", } }, "resource": { "type": "audited_resource" } }
๋ค์ ๋จ๊ณ
- IAM์ ๊ฐ์ฌ ๋ก๊ทธ ๊ตฌ์ฑ ๋ฐ ๋ณด๊ธฐ
- Cloud ๊ฐ์ฌ ๋ก๊ทธ์ ๋ํด ์์ธํ ์์๋ณด๊ธฐ
- ์ง์ ID ํ์ ์ฌ์ฉํ์ฌ ์ง์ ID ์ ํด ์ค์