Create an event handler that receives and processes a Cloud Audit Log event with IAM data
Stay organized with collections
Save and categorize content based on your preferences.
Creates an event handler that receives an incoming Cloud Audit Log event within an HTTP POST request as a CloudEvent.
Code sample
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Hard to understand","hardToUnderstand","thumb-down"],["Incorrect information or sample code","incorrectInformationOrSampleCode","thumb-down"],["Missing the information/samples I need","missingTheInformationSamplesINeed","thumb-down"],["Other","otherDown","thumb-down"]],[],[[["\u003cp\u003eThis content demonstrates how to create an event handler that processes incoming Cloud Audit Log events received as CloudEvents via an HTTP POST request.\u003c/p\u003e\n"],["\u003cp\u003eThe code examples, provided in both Go and Python, illustrate how to transform an HTTP request into a CloudEvent and extract the LogEntryData from it.\u003c/p\u003e\n"],["\u003cp\u003eThe examples show how to identify the user that requested a service account key creation, as well as the key's resource name and the key path that can be used with gcloud to disable or delete it.\u003c/p\u003e\n"],["\u003cp\u003eThe content highlights the use of Application Default Credentials for authentication to Eventarc, along with a link to setup instructions for a local development environment.\u003c/p\u003e\n"]]],[],null,["# Create an event handler that receives and processes a Cloud Audit Log event with IAM data\n\nCreates an event handler that receives an incoming Cloud Audit Log event within an HTTP POST request as a CloudEvent.\n\nCode sample\n-----------\n\n### Go\n\n\nTo authenticate to Eventarc, set up Application Default Credentials.\nFor more information, see\n\n[Set up authentication for a local development environment](/docs/authentication/set-up-adc-local-dev-environment).\n\n\n // Processes CloudEvents containing Cloud Audit Logs for IAM\n package main\n\n import (\n \t\"fmt\"\n \t\"log\"\n \t\"net/http\"\n \t\"os\"\n\n \tcloudevent \"github.com/cloudevents/sdk-go/v2\"\n \t\"github.com/googleapis/google-cloudevents-go/cloud/auditdata\"\n \t\"google.golang.org/protobuf/encoding/protojson\"\n )\n\n func HandleCloudEvent(w http.ResponseWriter, r *http.Request) {\n \t// Transform the HTTP request into a CloudEvent\n \tevent, err := cloudevent.NewEventFromHTTPRequest(r)\n \tif err != nil {\n \t\tw.WriteHeader(http.StatusBadRequest)\n \t\tfmt.Fprintln(w, \"Failed to create CloudEvent from request.\")\n \t\tlog.Fatal(\"cloudevent.NewEventFromHTTPRequest:\", err)\n \t}\n\n \t// Extract the LogEntryData from the CloudEvent\n \tvar logentry auditdata.LogEntryData\n \t// AuditLog objects include a `@type` annotation, which errors when using\n \t// `protojson.Unmarshal`. UnmarshalOptions prevents this error.\n \tumo := &protojson.UnmarshalOptions{DiscardUnknown: true}\n \terr = umo.Unmarshal(event.Data(), &logentry)\n \tif err != nil {\n \t\tw.WriteHeader(http.StatusBadRequest)\n \t\tfmt.Fprintln(w, \"Failed to parse Audit Log\")\n \t\tlog.Fatal(\"protojson.Unmarshal:\", err)\n \t}\n\n \t// Extract relevant fields from the audit log entry.\n \t// Identify the user that requested key creation\n \tactor := logentry.ProtoPayload.AuthenticationInfo.PrincipalEmail\n\n \t// Extract the resource name from the CreateServiceAccountKey request\n \t// For details of this type, see https://cloud.google.com/iam/docs/reference/rpc/google.iam.admin.v1#createserviceaccountkeyrequest\n \tprincipal := logentry.ProtoPayload.GetRequest().AsMap()[\"name\"]\n\n \t// The response is of type google.iam.admin.v1.ServiceAccountKey,\n \t// which is described at https://cloud.google.com/iam/docs/reference/rpc/google.iam.admin.v1#google.iam.admin.v1.ServiceAccountKey\n \t// This key path can be used with gcloud to disable/delete the key:\n \t// e.g. gcloud iam service-accounts keys disable ${keypath}\n \tkeypath := logentry.ProtoPayload.GetResponse().AsMap()[\"name\"]\n\n \ts := fmt.Sprintf(\"New Service Account Key created for %s by %s: %v\", principal, actor, keypath)\n \tlog.Printf(s)\n \tfmt.Fprintln(w, s)\n }\n\n### Python\n\n\nTo authenticate to Eventarc, set up Application Default Credentials.\nFor more information, see\n\n[Set up authentication for a local development environment](/docs/authentication/set-up-adc-local-dev-environment).\n\n @app.route(\"/\", methods=[\"POST\"])\n def index():\n # Transform the HTTP request into a CloudEvent\n event = from_http(request.headers, request.get_data())\n\n # Extract the LogEntryData from the CloudEvent\n # The LogEntryData type is described at https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry\n # re-serialize to json, to convert the json-style 'lowerCamelCase' names to the protobuf-style 'snake_case' equivalents.\n # ignore_unknown_fields is needed to skip the '@type' fields.\n log_entry = LogEntryData.from_json(\n json.dumps(event.get_data()), ignore_unknown_fields=True\n )\n\n # Ensure that this event is for service accout key creation, and succeeded.\n if log_entry.proto_payload.service_name != \"iam.googleapis.com\":\n return (\"Received event was not from IAM.\", 400)\n if log_entry.proto_payload.status.code != 0:\n return (\"Key creation failed, not reporting.\", 204)\n\n # Extract relevant fields from the audit log entry.\n # Identify the user that requested key creation\n user = log_entry.proto_payload.authentication_info.principal_email\n\n # Extract the resource name from the CreateServiceAccountKey request\n # For details of this type, see https://cloud.google.com/iam/docs/reference/rpc/google.iam.admin.v1#createserviceaccountkeyrequest\n service_account = log_entry.proto_payload.request[\"name\"]\n\n # The response is of type google.iam.admin.v1.ServiceAccountKey,\n # which is described at https://cloud.google.com/iam/docs/reference/rpc/google.iam.admin.v1#google.iam.admin.v1.ServiceAccountKey\n # This key path can be used with gcloud to disable/delete the key:\n # e.g. gcloud iam service-accounts keys disable ${keypath}\n keypath = log_entry.proto_payload.response[\"name\"]\n\n print(f\"New Service Account Key created for {service_account} by {user}: {keypath}\")\n return (\n f\"New Service Account Key created for {service_account} by {user}: {keypath}\",\n 200,\n )\n\nWhat's next\n-----------\n\n\nTo search and filter code samples for other Google Cloud products, see the\n[Google Cloud sample browser](/docs/samples?product=eventarc)."]]