恢复 IAM 允许政策的先前版本

本页介绍了在意外更改或意外删除 IAM 允许政策后,如何恢复该政策的先前版本。

如需恢复之前的 IAM 政策,请找到更改或删除之前的最后一次成功 setIamPolicy,并使用它来恢复政策。

所需的角色

如需获得恢复之前的允许政策所需的权限,请让管理员向您授予项目、文件夹或组织的以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

使用 setIamPolicy 恢复允许政策时,组织级和文件夹级允许政策需要组织管理员角色,项目级允许政策需要所有者角色。

您也可以使用自定义角色或其他预定义角色来获取这些权限。

恢复具有上次成功 setIamPolicy 实例的允许政策

如需将允许政策恢复到之前的版本,您可以查看审核日志,找到更改或删除操作之前最后一次成功执行 setIamPolicy 的实例,然后使用该实例中的信息来恢复政策。此过程包括以下步骤:

  1. 确定允许政策的最后一个成功 setIamPolicy 实例,并检索 insertId
  2. 使用 setIamPolicy 请求中的 insertId 以 YAML 或 JSON 格式导出允许政策。
  3. 修改输出文件,使其与之前的有效允许政策相匹配,并替换当前的允许政策。

确定 setIamPolicy 的上次成功实例并检索 insertId

如需确定上次成功运行 setIamPolicy 的实例并检索 isertId,请使用 Google Cloud 控制台或 gcloud CLI 查看审核日志。

控制台

  1. 在 Google Cloud 控制台中,前往 Logs Explorer 页面。

    转到日志浏览器

  2. 在查询编辑器中,输入以下任一查询。这些查询会在您的审核日志中搜索 protoPayloadmethodName 字段中包含 SetIamPolicy 的条目:

    • 如需获取对资源所做的所有允许政策更改的日志,请使用以下查询:

      logName="RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Factivity"
      protoPayload.methodName:SetIamPolicy
      
    • 如需获取涉及特定用户或服务账号的允许政策更改日志,请使用以下查询:

      logName="RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Factivity"
      protoPayload.methodName:SetIamPolicy
      protoPayload.serviceData.policyDelta.bindingDeltas.member:"EMAIL_ADDRESS"
      

      替换以下内容:

      • RESOURCE_TYPE:要为其列出审核日志的资源类型。有效值为 projectsfoldersorganizations
      • RESOURCE_ID:您的 Google Cloud 项目、文件夹或组织 ID。项目 ID 为字母数字,例如 my-project。文件夹和组织 ID 是数字,例如 123456789012
      • EMAIL_ADDRESS:用户或服务账号的电子邮件地址,例如 example-service-account@example-project.
  3. 如需运行查询,请点击运行查询

  4. 使用时间轴选择器为查询指定适当的时间范围。或者,您也可以直接向查询编辑器添加时间戳表达式。如需了解详情,请参阅按时间范围查看日志

  5. 从更改或删除之前的最后一个成功实例中复制 setIamPolicyinsertId

gcloud

gcloud logging read 命令用于读取日志条目。

在使用下面的命令数据之前,请先进行以下替换:

  • RESOURCE_TYPE:要为其列出审核日志的资源类型。使用值 projectsfoldersorganizations
  • RESOURCE_ID:您的 Google Cloud项目、组织或文件夹 ID。项目 ID 是字母数字字符串,例如 my-project。文件夹和组织 ID 是数字,例如 123456789012
  • TIME_PERIOD:要为其列出审核日志的时间段。返回的条目不会早于此值。如果未指定,则默认值为 1d。如需了解时间格式,请参阅 gcloud topic datetimes
  • RESOURCE_TYPE_SINGULAR:要为其列出审核日志的资源类型。使用值 projectfolderorganization

执行以下命令:

Linux、macOS 或 Cloud Shell

gcloud logging read \
    'logName:RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Factivity
    AND protoPayload.methodName=SetIamPolicy' \
    --freshness=TIME_PERIOD \
    --RESOURCE_TYPE_SINGULAR=RESOURCE_ID

Windows (PowerShell)

gcloud logging read `
    'logName:RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Factivity
    AND protoPayload.methodName=SetIamPolicy' `
    --freshness=TIME_PERIOD `
    --RESOURCE_TYPE_SINGULAR=RESOURCE_ID

Windows (cmd.exe)

gcloud logging read ^
    'logName:RESOURCE_TYPE/RESOURCE_ID/logs/cloudaudit.googleapis.com%2Factivity
    AND protoPayload.methodName=SetIamPolicy' ^
    --freshness=TIME_PERIOD ^
    --RESOURCE_TYPE_SINGULAR=RESOURCE_ID

从更改或删除之前的最后一个成功运行的 setIamPolicy 实例中复制 insertId

使用 insertId 导出允许政策

使用从上次成功运行 setIamPolicy 时检索到的 insertId,在 gcloud CLI 中运行以下命令,以导出 JSON 或 YAML 格式的许可政策。您可以导出组织和项目的允许政策。

组织级层

gcloud logging read 命令用于读取日志条目。

在使用下面的命令数据之前,请先进行以下替换:

  • ORGANIZATION_ID:您要查看和导出相应允许政策的组织。
  • INSERT_IDsetIamPolicy 请求的 insertId
  • FORMAT:响应的格式。请使用 jsonyaml
  • TIME_PERIOD:要为其列出审核日志的时间段。返回的条目不会早于此值。如果未指定,则默认值为 1d。如需了解时间格式,请参阅 gcloud topic datetimes
  • OUTPUT_FILE:输出的文件名和扩展名。例如,previous_policy.jsonprevious_policy.yaml

执行以下命令:

Linux、macOS 或 Cloud Shell

gcloud logging read organizations/ORGANIZATION_ID/logs/cloudaudit.googleapis.com
insertId="INSERT_ID"'
--organization=ORGANIZATION_ID
--format="FORMAT(protoPayload.request.policy)"
--freshness=TIME_PERIOD > OUTPUT_FILE

Windows (PowerShell)

gcloud logging read organizations/ORGANIZATION_ID/logs/cloudaudit.googleapis.com
insertId="INSERT_ID"'
--organization=ORGANIZATION_ID
--format="FORMAT(protoPayload.request.policy)"
--freshness=TIME_PERIOD > OUTPUT_FILE

Windows (cmd.exe)

gcloud logging read organizations/ORGANIZATION_ID/logs/cloudaudit.googleapis.com
insertId="INSERT_ID"'
--organization=ORGANIZATION_ID
--format="FORMAT(protoPayload.request.policy)"
--freshness=TIME_PERIOD > OUTPUT_FILE

项目级

gcloud logging read 命令用于读取日志条目。

在使用下面的命令数据之前,请先进行以下替换:

  • INSERT_IDsetIamPolicy 请求的 insertId
  • TIME_PERIOD:要为其列出审核日志的时间段。返回的条目不会早于此值。如果未指定,则默认值为 1d。如需了解时间格式,请参阅 gcloud topic datetimes
  • FORMAT:响应的格式。请使用 jsonyaml
  • OUTPUT_FILE:要保存输出的文件名,例如 previous_policy.jsonprevious_policy.yaml

执行以下命令:

Linux、macOS 或 Cloud Shell

gcloud logging read \
'protoPayload.methodName="SetIamPolicy" AND insertId="INSERT_ID"' \
--freshness=TIME_PERIOD \
--format="FORMAT(protoPayload.request.policy)" > OUTPUT_FILE

Windows (PowerShell)

gcloud logging read `
'protoPayload.methodName="SetIamPolicy" AND insertId="INSERT_ID"' `
--freshness=TIME_PERIOD `
--format="FORMAT(protoPayload.request.policy)" > OUTPUT_FILE

Windows (cmd.exe)

gcloud logging read ^
'protoPayload.methodName="SetIamPolicy" AND insertId="INSERT_ID"' ^
--freshness=TIME_PERIOD ^
--format="FORMAT(protoPayload.request.policy)" > OUTPUT_FILE

修改输出文件并替换当前允许政策

按以下方式修改输出文件,并替换当前的允许政策。

  1. 以编程方式或使用文本编辑器修改输出文件,方法是删除以下行:

     ---
     protoPayload:
        request:
          policy:
    

    生成的文件以 auditConfigs: 开头。

  2. 获取当前允许政策。

    gcloud

    gcloud get-iam-policy 命令可获取项目、文件夹或组织的允许政策。

    在使用下面的命令数据之前,请先进行以下替换:

    • RESOURCE_TYPE:要获取允许政策的资源类型。有效值为 projectsresource-manager foldersorganizations

    • RESOURCE_ID:您的 Google Cloud 项目、文件夹或组织 ID。项目 ID 为字母数字,例如 my-project。文件夹和组织 ID 是数字,例如 123456789012

    • FORMAT:允许政策所需的格式。请使用 jsonyaml

    • PATH:指向允许政策的新输出文件的路径。

    执行以下命令:

    Linux、macOS 或 Cloud Shell

    gcloud RESOURCE_TYPE get-iam-policy RESOURCE_ID --format=FORMAT > PATH

    Windows (PowerShell)

    gcloud RESOURCE_TYPE get-iam-policy RESOURCE_ID --format=FORMAT > PATH

    Windows (cmd.exe)

    gcloud RESOURCE_TYPE get-iam-policy RESOURCE_ID --format=FORMAT > PATH

    例如,以下命令会获取项目 my-project 的允许政策,并以 JSON 格式将其保存到主目录中:

    gcloud projects get-iam-policy my-project --format json > ~/policy.json

    C#

    如需向 Resource Manager 进行身份验证,请设置应用默认凭证。如需了解更多信息,请参阅准备工作

    如需了解如何安装和使用 Resource Manager 客户端库,请参阅 Resource Manager 客户端库

    以下示例展示了如何获取项目的允许政策。如需了解如何获取文件夹或组织的允许政策,请查看适合您的编程语言的 Resource Manager 客户端库文档

    
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.CloudResourceManager.v1;
    using Google.Apis.CloudResourceManager.v1.Data;
    
    public partial class AccessManager
    {
        public static Policy GetPolicy(string projectId)
        {
            var credential = GoogleCredential.GetApplicationDefault()
                .CreateScoped(CloudResourceManagerService.Scope.CloudPlatform);
            var service = new CloudResourceManagerService(
                new CloudResourceManagerService.Initializer
                {
                    HttpClientInitializer = credential
                });
    
            var policy = service.Projects.GetIamPolicy(new GetIamPolicyRequest(),
                projectId).Execute();
            return policy;
        }
    }
    

    Java

    如需向 Resource Manager 进行身份验证,请设置应用默认凭证。如需了解更多信息,请参阅准备工作

    如需了解如何安装和使用 Resource Manager 客户端库,请参阅 Resource Manager 客户端库

    以下示例展示了如何获取项目的允许政策。如需了解如何获取文件夹或组织的允许政策,请查看适合您的编程语言的 Resource Manager 客户端库文档

    import com.google.cloud.resourcemanager.v3.ProjectsClient;
    import com.google.iam.admin.v1.ProjectName;
    import com.google.iam.v1.GetIamPolicyRequest;
    import com.google.iam.v1.Policy;
    import java.io.IOException;
    
    public class GetProjectPolicy {
      public static void main(String[] args) throws IOException {
        // TODO(developer): Replace the variables before running the sample.
        // TODO: Replace with your project ID.
        String projectId = "your-project-id";
    
        getProjectPolicy(projectId);
      }
    
      // Gets a project's policy.
      public static Policy getProjectPolicy(String projectId) throws IOException {
        // Initialize client that will be used to send requests.
        // This client only needs to be created once, and can be reused for multiple requests.
        try (ProjectsClient projectsClient = ProjectsClient.create()) {
          GetIamPolicyRequest request = GetIamPolicyRequest.newBuilder()
                  .setResource(ProjectName.of(projectId).toString())
                  .build();
          return projectsClient.getIamPolicy(request);
        }
      }
    }

    Python

    如需向 Resource Manager 进行身份验证,请设置应用默认凭证。如需了解更多信息,请参阅准备工作

    如需了解如何安装和使用 Resource Manager 客户端库,请参阅 Resource Manager 客户端库

    以下示例展示了如何获取项目的允许政策。如需了解如何获取文件夹或组织的允许政策,请查看适合您的编程语言的 Resource Manager 客户端库文档

    from google.cloud import resourcemanager_v3
    from google.iam.v1 import iam_policy_pb2, policy_pb2
    
    
    def get_project_policy(project_id: str) -> policy_pb2.Policy:
        """Get policy for project.
    
        project_id: ID or number of the Google Cloud project you want to use.
        """
    
        client = resourcemanager_v3.ProjectsClient()
        request = iam_policy_pb2.GetIamPolicyRequest()
        request.resource = f"projects/{project_id}"
    
        policy = client.get_iam_policy(request)
        print(f"Policy retrieved: {policy}")
    
        return policy

    REST

    Resource Manager API 的 get-iam-policy 方法可获取项目、文件夹或组织的允许政策。

    在使用任何请求数据之前,请先进行以下替换:

    • API_VERSION:要使用的 API 版本。对于项目和组织,请使用 v1。对于文件夹,请使用 v2
    • RESOURCE_TYPE:您要管理其政策的资源类型。使用值 projectsfoldersorganizations
    • RESOURCE_ID:您的 Google Cloud项目、组织或文件夹 ID。项目 ID 是字母数字字符串,例如 my-project。文件夹和组织 ID 是数字,例如 123456789012
    • POLICY_VERSION:要返回的政策版本。请求应指定最新的政策版本,即政策版本 3。如需了解详情,请参阅在获取政策时指定政策版本

    HTTP 方法和网址:

    POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:getIamPolicy

    请求 JSON 正文:

    {
      "options": {
        "requestedPolicyVersion": POLICY_VERSION
      }
    }
    

    如需发送您的请求,请展开以下选项之一:

    响应包含资源的允许政策。例如:

    {
      "version": 1,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "role": "roles/owner",
          "members": [
            ""
          ]
        }
      ]
    }
    

    将响应保存在相应类型(jsonyaml)的文件中。

  3. 从当前允许政策中复制 etag 值。

  4. 将输出文件中的 etag 值替换为您从当前允许政策中复制的 etag 值。输出文件中的 etag 必须与当前的 etag 一致,才能发起新的 setIamPolicy 请求。确保输出文件中 etag 的间距未发生变化。

  5. 查看该文件,确保其与之前的有效允许政策一致。您可以考虑创建一个新项目并应用该政策,以确保其按预期运行。

  6. 设置允许政策,以使用您创建的输出文件中的政策替换当前的允许政策。

    gcloud

    gcloud set-iam-policy 命令会将请求中的政策设置为项目、文件夹或组织的新允许政策。

    在使用下面的命令数据之前,请先进行以下替换:

    • RESOURCE_TYPE:您要设置允许政策的资源的类型。有效值为 projectsresource-manager foldersorganizations

    • RESOURCE_ID:您的 Google Cloud 项目、文件夹或组织 ID。项目 ID 为字母数字,例如 my-project。文件夹和组织 ID 是数字,例如 123456789012

    • PATH:包含新允许政策的文件的路径。

    执行以下命令:

    Linux、macOS 或 Cloud Shell

    gcloud RESOURCE_TYPE set-iam-policy RESOURCE_ID PATH

    Windows (PowerShell)

    gcloud RESOURCE_TYPE set-iam-policy RESOURCE_ID PATH

    Windows (cmd.exe)

    gcloud RESOURCE_TYPE set-iam-policy RESOURCE_ID PATH

    响应包含更新后的允许政策。

    例如,以下命令将存储在 policy.json 中的允许政策设置为项目 my-project 的允许政策:

    gcloud projects set-iam-policy my-project ~/policy.json

    C#

    
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.CloudResourceManager.v1;
    using Google.Apis.CloudResourceManager.v1.Data;
    
    public partial class AccessManager
    {
        public static Policy SetPolicy(string projectId, Policy policy)
        {
            var credential = GoogleCredential.GetApplicationDefault()
                .CreateScoped(CloudResourceManagerService.Scope.CloudPlatform);
            var service = new CloudResourceManagerService(
                new CloudResourceManagerService.Initializer
                {
                    HttpClientInitializer = credential
                });
    
            return service.Projects.SetIamPolicy(new SetIamPolicyRequest
            {
                Policy = policy
            }, projectId).Execute();
        }
    }
    

    Java

    如需向 Resource Manager 进行身份验证,请设置应用默认凭证。如需了解更多信息,请参阅准备工作

    如需了解如何安装和使用 Resource Manager 客户端库,请参阅 Resource Manager 客户端库

    以下示例展示了如何设置项目的允许政策。如需了解如何设置文件夹或组织的允许政策,请查看适合您的编程语言的 Resource Manager 客户端库文档

    import com.google.cloud.resourcemanager.v3.ProjectsClient;
    import com.google.iam.admin.v1.ProjectName;
    import com.google.iam.v1.Policy;
    import com.google.iam.v1.SetIamPolicyRequest;
    import com.google.protobuf.FieldMask;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    
    public class SetProjectPolicy {
      public static void main(String[] args) throws IOException {
        // TODO(developer): Replace the variables before running the sample.
        // TODO: Replace with your project ID.
        String projectId = "your-project-id";
        // TODO: Replace with your policy, GetPolicy.getPolicy(projectId, serviceAccount).
        Policy policy = Policy.newBuilder().build();
    
        setProjectPolicy(policy, projectId);
      }
    
      // Sets a project's policy.
      public static Policy setProjectPolicy(Policy policy, String projectId)
              throws IOException {
    
        // Initialize client that will be used to send requests.
        // This client only needs to be created once, and can be reused for multiple requests.
        try (ProjectsClient projectsClient = ProjectsClient.create()) {
          List<String> paths = Arrays.asList("bindings", "etag");
          SetIamPolicyRequest request = SetIamPolicyRequest.newBuilder()
                  .setResource(ProjectName.of(projectId).toString())
                  .setPolicy(policy)
                  // A FieldMask specifying which fields of the policy to modify. Only
                  // the fields in the mask will be modified. If no mask is provided, the
                  // following default mask is used:
                  // `paths: "bindings, etag"`
                  .setUpdateMask(FieldMask.newBuilder().addAllPaths(paths).build())
                  .build();
    
          return projectsClient.setIamPolicy(request);
        }
      }
    }

    Python

    如需向 Resource Manager 进行身份验证,请设置应用默认凭证。如需了解更多信息,请参阅准备工作

    如需了解如何安装和使用 Resource Manager 客户端库,请参阅 Resource Manager 客户端库

    以下示例展示了如何设置项目的允许政策。如需了解如何设置文件夹或组织的允许政策,请查看适合您的编程语言的 Resource Manager 客户端库文档

    from google.cloud import resourcemanager_v3
    from google.iam.v1 import iam_policy_pb2, policy_pb2
    
    
    def set_project_policy(
        project_id: str, policy: policy_pb2.Policy, merge: bool = True
    ) -> policy_pb2.Policy:
        """
        Set policy for project. Pay attention that previous state will be completely rewritten.
        If you want to update only part of the policy follow the approach read->modify->write.
        For more details about policies check out https://cloud.google.com/iam/docs/policies
    
        project_id: ID or number of the Google Cloud project you want to use.
        policy: Policy which has to be set.
        merge: The strategy to be used forming the request. CopyFrom is clearing both mutable and immutable fields,
        when MergeFrom is replacing only immutable fields and extending mutable.
        https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message.CopyFrom
        """
        client = resourcemanager_v3.ProjectsClient()
    
        request = iam_policy_pb2.GetIamPolicyRequest()
        request.resource = f"projects/{project_id}"
        current_policy = client.get_iam_policy(request)
    
        # Etag should as fresh as possible to lower chance of collisions
        policy.ClearField("etag")
        if merge:
            current_policy.MergeFrom(policy)
        else:
            current_policy.CopyFrom(policy)
    
        request = iam_policy_pb2.SetIamPolicyRequest()
        request.resource = f"projects/{project_id}"
    
        # request.etag field also will be merged which means you are secured from collision,
        # but it means that request may fail and you need to leverage exponential retries approach
        # to be sure policy has been updated.
        request.policy.CopyFrom(current_policy)
    
        policy = client.set_iam_policy(request)
        return policy
    
    

    REST

    Resource Manager API 的 set-iam-policy 方法会将请求中的政策设置为项目、文件夹或组织的新允许政策。

    在使用任何请求数据之前,请先进行以下替换:

    • API_VERSION:要使用的 API 版本。对于项目和组织,请使用 v1。对于文件夹,请使用 v2
    • RESOURCE_TYPE:您要管理其政策的资源类型。使用值 projectsfoldersorganizations
    • RESOURCE_ID:您的 Google Cloud项目、组织或文件夹 ID。项目 ID 是字母数字字符串,例如 my-project。文件夹和组织 ID 是数字,例如 123456789012
    • POLICY:您要设置的政策的 JSON 格式。如需详细了解政策的格式,请参阅政策参考

    HTTP 方法和网址:

    POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:setIamPolicy

    请求 JSON 正文:

    {
      "policy": POLICY
    }
    

    如需发送您的请求,请展开以下选项之一:

    响应包含更新后的允许政策。