Configure GCP Project IAM Audit Logging

The gcp:projects/iAMAuditConfig:IAMAuditConfig resource, part of the Pulumi GCP provider, configures audit logging for GCP services at the project level. It controls which operations are logged and which members are exempted. This guide focuses on three capabilities: enabling audit logs across all services, configuring log types, and exempting specific members.

This resource is authoritative for a given service. It cannot be used alongside gcp.projects.IAMPolicy (they will conflict), but it can coexist with IAMBinding and IAMMember. The examples are intentionally small. Combine them with your own project configuration and log sink setup.

Enable audit logging for all services

Compliance teams need visibility into administrative actions and data access across GCP services to track who did what and when.

import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

const project = new gcp.projects.IAMAuditConfig("project", {
    project: "your-project-id",
    service: "allServices",
    auditLogConfigs: [
        {
            logType: "ADMIN_READ",
        },
        {
            logType: "DATA_READ",
            exemptedMembers: ["user:joebloggs@example.com"],
        },
    ],
});
import pulumi
import pulumi_gcp as gcp

project = gcp.projects.IAMAuditConfig("project",
    project="your-project-id",
    service="allServices",
    audit_log_configs=[
        {
            "log_type": "ADMIN_READ",
        },
        {
            "log_type": "DATA_READ",
            "exempted_members": ["user:joebloggs@example.com"],
        },
    ])
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/projects"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := projects.NewIAMAuditConfig(ctx, "project", &projects.IAMAuditConfigArgs{
			Project: pulumi.String("your-project-id"),
			Service: pulumi.String("allServices"),
			AuditLogConfigs: projects.IAMAuditConfigAuditLogConfigArray{
				&projects.IAMAuditConfigAuditLogConfigArgs{
					LogType: pulumi.String("ADMIN_READ"),
				},
				&projects.IAMAuditConfigAuditLogConfigArgs{
					LogType: pulumi.String("DATA_READ"),
					ExemptedMembers: pulumi.StringArray{
						pulumi.String("user:joebloggs@example.com"),
					},
				},
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Gcp = Pulumi.Gcp;

return await Deployment.RunAsync(() => 
{
    var project = new Gcp.Projects.IAMAuditConfig("project", new()
    {
        Project = "your-project-id",
        Service = "allServices",
        AuditLogConfigs = new[]
        {
            new Gcp.Projects.Inputs.IAMAuditConfigAuditLogConfigArgs
            {
                LogType = "ADMIN_READ",
            },
            new Gcp.Projects.Inputs.IAMAuditConfigAuditLogConfigArgs
            {
                LogType = "DATA_READ",
                ExemptedMembers = new[]
                {
                    "user:joebloggs@example.com",
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.projects.IAMAuditConfig;
import com.pulumi.gcp.projects.IAMAuditConfigArgs;
import com.pulumi.gcp.projects.inputs.IAMAuditConfigAuditLogConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var project = new IAMAuditConfig("project", IAMAuditConfigArgs.builder()
            .project("your-project-id")
            .service("allServices")
            .auditLogConfigs(            
                IAMAuditConfigAuditLogConfigArgs.builder()
                    .logType("ADMIN_READ")
                    .build(),
                IAMAuditConfigAuditLogConfigArgs.builder()
                    .logType("DATA_READ")
                    .exemptedMembers("user:joebloggs@example.com")
                    .build())
            .build());

    }
}
resources:
  project:
    type: gcp:projects:IAMAuditConfig
    properties:
      project: your-project-id
      service: allServices
      auditLogConfigs:
        - logType: ADMIN_READ
        - logType: DATA_READ
          exemptedMembers:
            - user:joebloggs@example.com

The service property set to “allServices” enables logging across all GCP APIs. The auditLogConfigs array defines which operation types to log. ADMIN_READ captures administrative read operations (like listing resources), while DATA_READ captures data access operations (like reading object contents). Each log type generates entries in Cloud Logging that can be exported to BigQuery, Cloud Storage, or Pub/Sub for analysis.

The exemptedMembers property excludes specific users or service accounts from DATA_READ logging. This reduces log volume for automated systems or excludes service accounts that perform high-frequency reads. Exemptions only apply to the specific log type where they’re defined; ADMIN_READ logs still capture all members.

Beyond these examples

These snippets focus on specific audit config features: audit log configuration for services, log type selection, and member exemptions. They’re intentionally minimal rather than full compliance solutions.

The examples reference pre-existing infrastructure such as a GCP project with appropriate IAM permissions. They focus on configuring audit logging rather than provisioning the surrounding infrastructure.

To keep things focused, common audit patterns are omitted, including:

  • Service-specific audit configs (vs allServices)
  • ADMIN_WRITE and DATA_WRITE log types
  • Multiple audit configs for different services
  • Integration with Cloud Logging and log sinks

These omissions are intentional: the goal is to illustrate how audit logging is wired, not provide drop-in compliance modules. See the IAMAuditConfig resource reference for all available configuration options.

Let's configure GCP Project IAM Audit Logging

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Resource Selection & Conflicts
Which IAM resource should I use for my use case?
Choose based on your needs: gcp.projects.IAMPolicy (authoritative, replaces entire policy), gcp.projects.IAMBinding (authoritative for a specific role), gcp.projects.IAMMember (non-authoritative, adds single member to a role), or gcp.projects.IAMAuditConfig (authoritative for audit logging per service).
Can I use IAMPolicy with other IAM resources?
No, gcp.projects.IAMPolicy cannot be used with gcp.projects.IAMBinding, gcp.projects.IAMMember, or gcp.projects.IAMAuditConfig because they will conflict over policy state.
Can I use IAMBinding and IAMMember together?
Yes, but only if they don’t grant privileges to the same role. Using both for the same role causes conflicts.
IAMPolicy Lockout Risks
Can I accidentally lock myself out using IAMPolicy?
Yes, deleting gcp.projects.IAMPolicy removes access from anyone without organization-level access. Don’t use it with your provider project, and only use it with fully managed projects.
Should I import my policy before applying IAMPolicy changes?
Yes, it’s recommended to import the existing policy before applying changes to avoid accidentally removing access.
Audit Logging Configuration
How does 'allServices' work with specific service audit configs?
When multiple gcp.projects.IAMAuditConfig resources cover both allServices and a specific service, the union is used: log_types from both are enabled, and exempted_members from both are exempted.
What log types can I configure for audit logging?
Configure auditLogConfigs with log types like ADMIN_READ and DATA_READ, optionally specifying exemptedMembers for each type.
IAM Conditions & Constraints
Can I use IAM Conditions with Basic Roles like Owner?
No, IAM Conditions cannot be used with Basic Roles such as Owner. Use predefined or custom roles instead.

Using a different cloud?

Explore security guides for other cloud providers: