这些云平台搞的权限控制是真难理解,搞得好复杂。这篇写给刚接触Google Cloud的开发者,介绍一下如何快速理解Google Cloud的IAM的一些概念。
Google Cloud的IAM有服务账号(ServiceAccount)、角色(Role)、权限(Permissions)的概念。
一个ServiceAccount可以理解是一个子账号,ServiceAccount是归属到项目(Project)下面的, 每个项目的ServiceAccount是隔离的。
角色,也是归属到项目下的,角色可以被赋予很多权限(Permissions)。
最后,通过给服务账号分配角色来授权账号相关权限。怎么分配呢?每个服务账号都有一个IAM策略(Policy), 每个IAM策略都可以配置很多Binding,每个Binding用来给账号的IAM策略绑定一个角色。
角色也是可以自定义的,当Google Cloud提供的角色不满足我们对资源粒度的控制的时候,就可以使用自定义角色。
func CreateRoles(ctx context.Context, roleId string, includedPermissions []string) (*iam.Role, error) {
var iamSvc *iam.Service
// ....
return iamSvc.Projects.Roles.Create(fmt.Sprintf("projects/%s", project),
&iam.CreateRoleRequest{
RoleId: roleId,
Role: &iam.Role{
Name: roleId,
IncludedPermissions: includedPermissions,
},
}).Do()
}
如果需要细粒度的控制权限,比如针对资源的实例级别,那么可以通过资源的IAM策略配置。
例如,给一个ServiceAccount赋予一个Cloud Storage的bucket实例的Admin权限。
当我们创建出一个Cloud Storage的bucket实例的时候,这个bucket就有了默认的IAM策略(Policy)。我们只需要给这个bucket的Policy添加一个Binding。
func TestAuthBucketAdminToServiceAccount(t *testing.T) {
serviceAccountEmail := "[email protected]"
var storageSvc *storage.Service
// ....
saMember := fmt.Sprintf("serviceAccount:%s", serviceAccountEmail)
roleId := "roles/storage.admin"
// 获取云产品实例的IAM策略(产品创建就有)
instanceName := "gcf-v2-sources-295403105839-us-central1"
policy, err := storageSvc.Buckets.GetIamPolicy(instanceName).Do()
if err != nil {
t.Errorf(err.Error())
return
}
policy.Version = 3
// 添加条件限制 (不是必须的)
condition := &storage.Expr{
Title: "Nebula Integrations Resource Admin Condition",
Description: "This is a condition automatically added by google-cloud-nebula-integration.",
Expression: ${表达式},
}
// 存在绑定则修改绑定的条件
found := false
for _, binding := range policy.Bindings {
if util.ArrayContains(binding.Members, saMember) {
found = true
binding.Role = roleId
binding.Condition = condition // (不是必须的)
}
}
if !found {
// 添加绑定到IAM策略
newBinding := &storage.PolicyBindings{
Role: roleId,
Members: []string{saMember},
Condition: condition, // (不是必须的)
}
policy.Bindings = append(policy.Bindings, newBinding)
}
// 更新IAM策略
updatePolicy, err := storageSvc.Buckets.SetIamPolicy(instanceName, policy).Do()
fmt.Println("update policy:", updatePolicy, err)
}
我们找到桶实例,查看桶的详情,找到权限。
不出意外我们就能找到上面代码添加的Bindings。
问:此案例中的角色id是从哪里来的?
从“IAM和管理”->“角色”找的。
本篇文章涉及的相关API:
- ServiceAccount:https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts
- 为ServiceAccount创建key:https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys/create
- 创建自定义角色:https://cloud.google.com/iam/docs/reference/rest/v1/projects.roles/create
- 获取存储桶的IAM策略:https://cloud.google.com/storage/docs/json_api/v1/buckets/getIamPolicy
- 给存储桶更新IAM策略:https://cloud.google.com/storage/docs/json_api/v1/buckets/setIamPolicy