Configure Google Cloud IAP Web IAM Permissions

The gcp:iap/webIamMember:WebIamMember resource, part of the Pulumi GCP provider, grants IAM roles to individual identities for IAP-protected web resources without affecting other members. This guide focuses on two capabilities: non-authoritative single-member grants and time-based access with IAM Conditions.

This resource manages permissions for IAP-protected web resources (App Engine apps, Compute Engine backends, Cloud Run services) that must already exist with IAP enabled. The examples are intentionally small. Combine them with your own IAP configuration and identity management.

Grant access to a single user

When managing IAP-protected applications, you often need to add individual users without disrupting existing permissions.

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

const member = new gcp.iap.WebIamMember("member", {
    project: projectService.project,
    role: "roles/iap.httpsResourceAccessor",
    member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp

member = gcp.iap.WebIamMember("member",
    project=project_service["project"],
    role="roles/iap.httpsResourceAccessor",
    member="user:jane@example.com")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iap.NewWebIamMember(ctx, "member", &iap.WebIamMemberArgs{
			Project: pulumi.Any(projectService.Project),
			Role:    pulumi.String("roles/iap.httpsResourceAccessor"),
			Member:  pulumi.String("user:jane@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 member = new Gcp.Iap.WebIamMember("member", new()
    {
        Project = projectService.Project,
        Role = "roles/iap.httpsResourceAccessor",
        Member = "user:jane@example.com",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.iap.WebIamMember;
import com.pulumi.gcp.iap.WebIamMemberArgs;
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 member = new WebIamMember("member", WebIamMemberArgs.builder()
            .project(projectService.project())
            .role("roles/iap.httpsResourceAccessor")
            .member("user:jane@example.com")
            .build());

    }
}
resources:
  member:
    type: gcp:iap:WebIamMember
    properties:
      project: ${projectService.project}
      role: roles/iap.httpsResourceAccessor
      member: user:jane@example.com

The member property specifies the identity receiving access, using the format “user:email@example.com”. The role property defines the permission level; roles/iap.httpsResourceAccessor allows HTTPS access to IAP-protected resources. Because WebIamMember is non-authoritative, it adds this user without removing other members who already have the role.

Grant time-limited access with IAM Conditions

Temporary access grants can expire automatically using IAM Conditions, eliminating manual cleanup.

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

const member = new gcp.iap.WebIamMember("member", {
    project: projectService.project,
    role: "roles/iap.httpsResourceAccessor",
    member: "user:jane@example.com",
    condition: {
        title: "expires_after_2019_12_31",
        description: "Expiring at midnight of 2019-12-31",
        expression: "request.time < timestamp(\"2020-01-01T00:00:00Z\")",
    },
});
import pulumi
import pulumi_gcp as gcp

member = gcp.iap.WebIamMember("member",
    project=project_service["project"],
    role="roles/iap.httpsResourceAccessor",
    member="user:jane@example.com",
    condition={
        "title": "expires_after_2019_12_31",
        "description": "Expiring at midnight of 2019-12-31",
        "expression": "request.time < timestamp(\"2020-01-01T00:00:00Z\")",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := iap.NewWebIamMember(ctx, "member", &iap.WebIamMemberArgs{
			Project: pulumi.Any(projectService.Project),
			Role:    pulumi.String("roles/iap.httpsResourceAccessor"),
			Member:  pulumi.String("user:jane@example.com"),
			Condition: &iap.WebIamMemberConditionArgs{
				Title:       pulumi.String("expires_after_2019_12_31"),
				Description: pulumi.String("Expiring at midnight of 2019-12-31"),
				Expression:  pulumi.String("request.time < timestamp(\"2020-01-01T00:00:00Z\")"),
			},
		})
		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 member = new Gcp.Iap.WebIamMember("member", new()
    {
        Project = projectService.Project,
        Role = "roles/iap.httpsResourceAccessor",
        Member = "user:jane@example.com",
        Condition = new Gcp.Iap.Inputs.WebIamMemberConditionArgs
        {
            Title = "expires_after_2019_12_31",
            Description = "Expiring at midnight of 2019-12-31",
            Expression = "request.time < timestamp(\"2020-01-01T00:00:00Z\")",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.iap.WebIamMember;
import com.pulumi.gcp.iap.WebIamMemberArgs;
import com.pulumi.gcp.iap.inputs.WebIamMemberConditionArgs;
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 member = new WebIamMember("member", WebIamMemberArgs.builder()
            .project(projectService.project())
            .role("roles/iap.httpsResourceAccessor")
            .member("user:jane@example.com")
            .condition(WebIamMemberConditionArgs.builder()
                .title("expires_after_2019_12_31")
                .description("Expiring at midnight of 2019-12-31")
                .expression("request.time < timestamp(\"2020-01-01T00:00:00Z\")")
                .build())
            .build());

    }
}
resources:
  member:
    type: gcp:iap:WebIamMember
    properties:
      project: ${projectService.project}
      role: roles/iap.httpsResourceAccessor
      member: user:jane@example.com
      condition:
        title: expires_after_2019_12_31
        description: Expiring at midnight of 2019-12-31
        expression: request.time < timestamp("2020-01-01T00:00:00Z")

The condition block adds time-based restrictions to the grant. The expression property uses CEL (Common Expression Language) to define when access is valid; here, access expires at midnight on 2020-01-01. The title and description properties document the condition’s purpose. IAM evaluates the expression on each request, automatically denying access after the timestamp passes.

Beyond these examples

These snippets focus on specific WebIamMember features: single-member grants and time-based IAM Conditions. They’re intentionally minimal rather than complete access control configurations.

The examples assume pre-existing infrastructure such as IAP-enabled web resources and a GCP project with IAP configured. They focus on granting individual permissions rather than provisioning IAP itself.

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

  • Authoritative policy management (WebIamPolicy)
  • Role-level binding management (WebIamBinding)
  • Service account and group identities
  • Federated identity and workload identity pool principals

These omissions are intentional: the goal is to illustrate how WebIamMember grants are wired, not provide drop-in access control modules. See the IAP WebIamMember resource reference for all available configuration options.

Let's configure Google Cloud IAP Web IAM Permissions

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
Can I use WebIamPolicy together with WebIamBinding or WebIamMember?
No, gcp.iap.WebIamPolicy cannot be used with gcp.iap.WebIamBinding or gcp.iap.WebIamMember because they will conflict over the policy configuration.
Can I use WebIamBinding and WebIamMember together?
Yes, but only if they don’t grant privileges to the same role. Each role must be managed by either gcp.iap.WebIamBinding or gcp.iap.WebIamMember, not both.
What's the difference between WebIamPolicy, WebIamBinding, and WebIamMember?
gcp.iap.WebIamPolicy is authoritative and replaces the entire IAM policy. gcp.iap.WebIamBinding is authoritative for a specific role, managing all members for that role. gcp.iap.WebIamMember is non-authoritative, adding individual members without affecting other members for the role.
IAM Configuration
What member identity formats are supported?
You can use allUsers, allAuthenticatedUsers, user:{email}, serviceAccount:{email}, group:{email}, domain:{domain}, projectOwner:projectid, projectEditor:projectid, projectViewer:projectid, or federated identities like principal://iam.googleapis.com/....
How do I specify custom roles?
Custom roles must use the format [projects|organizations]/{parent-name}/roles/{role-name}. For example, projects/my-project/roles/my-custom-role.
How do I add time-based access conditions?
Use the condition property with title, description, and expression. For example, to expire access at a specific time: expression: "request.time < timestamp(\"2020-01-01T00:00:00Z\")".
Resource Properties & Limitations
What properties can't be changed after creation?
All properties are immutable: member, role, project, and condition. You must recreate the resource to change any of these values.
What are the limitations of IAM Conditions?
IAM Conditions are supported but have known limitations. If you experience issues with conditions, review the Google Cloud documentation on IAM Conditions limitations.

Using a different cloud?

Explore iam guides for other cloud providers: