The gcp:iap/webTypeComputeIamMember:WebTypeComputeIamMember resource, part of the Pulumi GCP provider, grants IAM roles to individual identities for Identity-Aware Proxy compute resources without affecting other members. This guide focuses on three capabilities: incremental member grants, time-limited access with IAM Conditions, and authoritative role management.
IAP access control operates at the project level for compute resources. The examples assume IAP is enabled and reference a project that must exist. They’re intentionally small. Combine them with your own IAP configuration and identity management.
Grant access to a single user incrementally
When adding individual users to IAP access, the Member resource preserves existing permissions while adding new identities.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const member = new gcp.iap.WebTypeComputeIamMember("member", {
project: projectService.project,
role: "roles/iap.httpsResourceAccessor",
member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp
member = gcp.iap.WebTypeComputeIamMember("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.NewWebTypeComputeIamMember(ctx, "member", &iap.WebTypeComputeIamMemberArgs{
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.WebTypeComputeIamMember("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.WebTypeComputeIamMember;
import com.pulumi.gcp.iap.WebTypeComputeIamMemberArgs;
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 WebTypeComputeIamMember("member", WebTypeComputeIamMemberArgs.builder()
.project(projectService.project())
.role("roles/iap.httpsResourceAccessor")
.member("user:jane@example.com")
.build());
}
}
resources:
member:
type: gcp:iap:WebTypeComputeIamMember
properties:
project: ${projectService.project}
role: roles/iap.httpsResourceAccessor
member: user:jane@example.com
The member property specifies the identity to grant access, using formats like “user:email@example.com” for Google accounts or “serviceAccount:email@project.iam.gserviceaccount.com” for service accounts. The role property defines what the identity can do; “roles/iap.httpsResourceAccessor” allows HTTPS access to IAP-protected resources. This resource is non-authoritative: other members with the same role remain unchanged.
Add time-limited access with IAM Conditions
IAM Conditions automatically revoke access when expressions evaluate to false, eliminating manual cleanup for temporary grants.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const member = new gcp.iap.WebTypeComputeIamMember("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.WebTypeComputeIamMember("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.NewWebTypeComputeIamMember(ctx, "member", &iap.WebTypeComputeIamMemberArgs{
Project: pulumi.Any(projectService.Project),
Role: pulumi.String("roles/iap.httpsResourceAccessor"),
Member: pulumi.String("user:jane@example.com"),
Condition: &iap.WebTypeComputeIamMemberConditionArgs{
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.WebTypeComputeIamMember("member", new()
{
Project = projectService.Project,
Role = "roles/iap.httpsResourceAccessor",
Member = "user:jane@example.com",
Condition = new Gcp.Iap.Inputs.WebTypeComputeIamMemberConditionArgs
{
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.WebTypeComputeIamMember;
import com.pulumi.gcp.iap.WebTypeComputeIamMemberArgs;
import com.pulumi.gcp.iap.inputs.WebTypeComputeIamMemberConditionArgs;
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 WebTypeComputeIamMember("member", WebTypeComputeIamMemberArgs.builder()
.project(projectService.project())
.role("roles/iap.httpsResourceAccessor")
.member("user:jane@example.com")
.condition(WebTypeComputeIamMemberConditionArgs.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:WebTypeComputeIamMember
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 temporal constraints to the member 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 conditions on every request, so access stops immediately when the timestamp passes.
Manage all members for a role authoritatively
When you need to define the complete member list for a role, Binding resources replace existing grants with your declared list.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const binding = new gcp.iap.WebTypeComputeIamBinding("binding", {
project: projectService.project,
role: "roles/iap.httpsResourceAccessor",
members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp
binding = gcp.iap.WebTypeComputeIamBinding("binding",
project=project_service["project"],
role="roles/iap.httpsResourceAccessor",
members=["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.NewWebTypeComputeIamBinding(ctx, "binding", &iap.WebTypeComputeIamBindingArgs{
Project: pulumi.Any(projectService.Project),
Role: pulumi.String("roles/iap.httpsResourceAccessor"),
Members: pulumi.StringArray{
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 binding = new Gcp.Iap.WebTypeComputeIamBinding("binding", new()
{
Project = projectService.Project,
Role = "roles/iap.httpsResourceAccessor",
Members = new[]
{
"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.WebTypeComputeIamBinding;
import com.pulumi.gcp.iap.WebTypeComputeIamBindingArgs;
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 binding = new WebTypeComputeIamBinding("binding", WebTypeComputeIamBindingArgs.builder()
.project(projectService.project())
.role("roles/iap.httpsResourceAccessor")
.members("user:jane@example.com")
.build());
}
}
resources:
binding:
type: gcp:iap:WebTypeComputeIamBinding
properties:
project: ${projectService.project}
role: roles/iap.httpsResourceAccessor
members:
- user:jane@example.com
The members property takes an array of identities, replacing any existing members for this role. Unlike Member resources, Binding is authoritative for the specified role: identities not in the list lose access. Use Binding when you want to declare “these are the only identities with this role,” not “add this identity to the existing list.”
Beyond these examples
These snippets focus on specific IAM grant features: incremental member grants, authoritative role management, and time-based access with IAM Conditions. They’re intentionally minimal rather than full access control configurations.
The examples assume pre-existing infrastructure such as a GCP project with IAP enabled on compute resources and Identity-Aware Proxy configuration. They focus on granting access rather than provisioning IAP itself.
To keep things focused, common IAM patterns are omitted, including:
- Full policy replacement (WebTypeComputeIamPolicy)
- Multiple role grants in a single resource
- Complex condition expressions (location, resource attributes)
- Service account and group identity formats
These omissions are intentional: the goal is to illustrate how each IAM grant mechanism is wired, not provide drop-in access control modules. See the IAP WebTypeComputeIamMember resource reference for all available configuration options.
Let's manage GCP Identity-Aware Proxy IAM Permissions
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Resource Selection & Conflicts
gcp.iap.WebTypeComputeIamPolicy (authoritative, replaces entire policy), gcp.iap.WebTypeComputeIamBinding (authoritative per role, preserves other roles), or gcp.iap.WebTypeComputeIamMember (non-authoritative, preserves other members for the role).gcp.iap.WebTypeComputeIamPolicy cannot be used with gcp.iap.WebTypeComputeIamBinding or gcp.iap.WebTypeComputeIamMember because they will conflict over policy management.Configuration & Identity Formats
allUsers, allAuthenticatedUsers, user:{email}, serviceAccount:{email}, group:{email}, domain:{domain}, projectOwner:{projectid}, projectEditor:{projectid}, projectViewer:{projectid}, and federated identities like principal://iam.googleapis.com/....member, role, project, and condition. Changes require recreating the resource.IAM Conditions
condition property with title, description, and expression. For example, set expression to request.time < timestamp("2020-01-01T00:00:00Z") to expire access at a specific time.Advanced Topics
[projects|organizations]/{parent-name}/roles/{role-name}, for example projects/my-project/roles/my-custom-role.