创建事件处理程序,以使用 IAM 数据接收和处理 Cloud Audit Logs 事件

创建一个事件处理程序,以接收 HTTP POST 请求中传入的 Cloud Audit Log 事件作为 CloudEvent。

代码示例

Go

如需向 Eventarc 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证


// Processes CloudEvents containing Cloud Audit Logs for IAM
package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	cloudevent "github.com/cloudevents/sdk-go/v2"
	"github.com/googleapis/google-cloudevents-go/cloud/auditdata"
	"google.golang.org/protobuf/encoding/protojson"
)

func HandleCloudEvent(w http.ResponseWriter, r *http.Request) {
	// Transform the HTTP request into a CloudEvent
	event, err := cloudevent.NewEventFromHTTPRequest(r)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintln(w, "Failed to create CloudEvent from request.")
		log.Fatal("cloudevent.NewEventFromHTTPRequest:", err)
	}

	// Extract the LogEntryData from the CloudEvent
	var logentry auditdata.LogEntryData
	// AuditLog objects include a `@type` annotation, which errors when using
	// `protojson.Unmarshal`. UnmarshalOptions prevents this error.
	umo := &protojson.UnmarshalOptions{DiscardUnknown: true}
	err = umo.Unmarshal(event.Data(), &logentry)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintln(w, "Failed to parse Audit Log")
		log.Fatal("protojson.Unmarshal:", err)
	}

	// Extract relevant fields from the audit log entry.
	// Identify the user that requested key creation
	actor := logentry.ProtoPayload.AuthenticationInfo.PrincipalEmail

	// Extract the resource name from the CreateServiceAccountKey request
	// For details of this type, see https://cloud.google.com/iam/docs/reference/rpc/google.iam.admin.v1#createserviceaccountkeyrequest
	principal := logentry.ProtoPayload.GetRequest().AsMap()["name"]

	// The response is of type google.iam.admin.v1.ServiceAccountKey,
	// which is described at https://cloud.google.com/iam/docs/reference/rpc/google.iam.admin.v1#google.iam.admin.v1.ServiceAccountKey
	// This key path can be used with gcloud to disable/delete the key:
	// e.g. gcloud iam service-accounts keys disable ${keypath}
	keypath := logentry.ProtoPayload.GetResponse().AsMap()["name"]

	s := fmt.Sprintf("New Service Account Key created for %s by %s: %v", principal, actor, keypath)
	log.Printf(s)
	fmt.Fprintln(w, s)
}

Python

如需向 Eventarc 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

@app.route("/", methods=["POST"])
def index():
    # Transform the HTTP request into a CloudEvent
    event = from_http(request.headers, request.get_data())

    # Extract the LogEntryData from the CloudEvent
    # The LogEntryData type is described at https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry
    # re-serialize to json, to convert the json-style 'lowerCamelCase' names to the protobuf-style 'snake_case' equivalents.
    # ignore_unknown_fields is needed to skip the '@type' fields.
    log_entry = LogEntryData.from_json(
        json.dumps(event.get_data()), ignore_unknown_fields=True
    )

    # Ensure that this event is for service accout key creation, and succeeded.
    if log_entry.proto_payload.service_name != "iam.googleapis.com":
        return ("Received event was not from IAM.", 400)
    if log_entry.proto_payload.status.code != 0:
        return ("Key creation failed, not reporting.", 204)

    # Extract relevant fields from the audit log entry.
    # Identify the user that requested key creation
    user = log_entry.proto_payload.authentication_info.principal_email

    # Extract the resource name from the CreateServiceAccountKey request
    # For details of this type, see https://cloud.google.com/iam/docs/reference/rpc/google.iam.admin.v1#createserviceaccountkeyrequest
    service_account = log_entry.proto_payload.request["name"]

    # The response is of type google.iam.admin.v1.ServiceAccountKey,
    # which is described at https://cloud.google.com/iam/docs/reference/rpc/google.iam.admin.v1#google.iam.admin.v1.ServiceAccountKey
    # This key path can be used with gcloud to disable/delete the key:
    # e.g. gcloud iam service-accounts keys disable ${keypath}
    keypath = log_entry.proto_payload.response["name"]

    print(f"New Service Account Key created for {service_account} by {user}: {keypath}")
    return (
        f"New Service Account Key created for {service_account} by {user}: {keypath}",
        200,
    )

后续步骤

如需搜索和过滤其他 Google Cloud 产品的代码示例,请参阅 Google Cloud 示例浏览器