The gcp:apigateway/gatewayIamMember:GatewayIamMember resource, part of the Pulumi GCP provider, grants IAM permissions on API Gateway gateways by adding individual members to roles without affecting other permissions. This guide focuses on three approaches: single-member grants with GatewayIamMember, role-level member management with GatewayIamBinding, and complete policy replacement with GatewayIamPolicy.
These resources reference existing API Gateway gateways and require project and region configuration. The examples are intentionally small. Combine them with your own gateway infrastructure and identity management strategy.
Grant a single user access to a gateway
Most IAM configurations start by granting individual users or service accounts access to specific resources without disrupting existing permissions.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const member = new gcp.apigateway.GatewayIamMember("member", {
project: apiGw.project,
region: apiGw.region,
gateway: apiGw.gatewayId,
role: "roles/apigateway.viewer",
member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp
member = gcp.apigateway.GatewayIamMember("member",
project=api_gw["project"],
region=api_gw["region"],
gateway=api_gw["gatewayId"],
role="roles/apigateway.viewer",
member="user:jane@example.com")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/apigateway"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := apigateway.NewGatewayIamMember(ctx, "member", &apigateway.GatewayIamMemberArgs{
Project: pulumi.Any(apiGw.Project),
Region: pulumi.Any(apiGw.Region),
Gateway: pulumi.Any(apiGw.GatewayId),
Role: pulumi.String("roles/apigateway.viewer"),
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.ApiGateway.GatewayIamMember("member", new()
{
Project = apiGw.Project,
Region = apiGw.Region,
Gateway = apiGw.GatewayId,
Role = "roles/apigateway.viewer",
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.apigateway.GatewayIamMember;
import com.pulumi.gcp.apigateway.GatewayIamMemberArgs;
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 GatewayIamMember("member", GatewayIamMemberArgs.builder()
.project(apiGw.project())
.region(apiGw.region())
.gateway(apiGw.gatewayId())
.role("roles/apigateway.viewer")
.member("user:jane@example.com")
.build());
}
}
resources:
member:
type: gcp:apigateway:GatewayIamMember
properties:
project: ${apiGw.project}
region: ${apiGw.region}
gateway: ${apiGw.gatewayId}
role: roles/apigateway.viewer
member: user:jane@example.com
The member property specifies one identity (user, service account, group, or domain). The role property defines what that member can do. GatewayIamMember is non-authoritative: it adds this one member to this one role, preserving all other members and roles on the gateway.
Grant multiple users the same role
When multiple users need identical permissions, you can manage them together in one resource.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const binding = new gcp.apigateway.GatewayIamBinding("binding", {
project: apiGw.project,
region: apiGw.region,
gateway: apiGw.gatewayId,
role: "roles/apigateway.viewer",
members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp
binding = gcp.apigateway.GatewayIamBinding("binding",
project=api_gw["project"],
region=api_gw["region"],
gateway=api_gw["gatewayId"],
role="roles/apigateway.viewer",
members=["user:jane@example.com"])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/apigateway"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := apigateway.NewGatewayIamBinding(ctx, "binding", &apigateway.GatewayIamBindingArgs{
Project: pulumi.Any(apiGw.Project),
Region: pulumi.Any(apiGw.Region),
Gateway: pulumi.Any(apiGw.GatewayId),
Role: pulumi.String("roles/apigateway.viewer"),
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.ApiGateway.GatewayIamBinding("binding", new()
{
Project = apiGw.Project,
Region = apiGw.Region,
Gateway = apiGw.GatewayId,
Role = "roles/apigateway.viewer",
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.apigateway.GatewayIamBinding;
import com.pulumi.gcp.apigateway.GatewayIamBindingArgs;
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 GatewayIamBinding("binding", GatewayIamBindingArgs.builder()
.project(apiGw.project())
.region(apiGw.region())
.gateway(apiGw.gatewayId())
.role("roles/apigateway.viewer")
.members("user:jane@example.com")
.build());
}
}
resources:
binding:
type: gcp:apigateway:GatewayIamBinding
properties:
project: ${apiGw.project}
region: ${apiGw.region}
gateway: ${apiGw.gatewayId}
role: roles/apigateway.viewer
members:
- user:jane@example.com
The members property lists all identities that should have this role. GatewayIamBinding is authoritative for the specified role: it replaces any existing members for that role while preserving other roles. You can combine GatewayIamBinding with GatewayIamMember as long as they don’t grant the same role.
Replace the entire IAM policy
Some deployments need complete control over all roles and members on a gateway.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const admin = gcp.organizations.getIAMPolicy({
bindings: [{
role: "roles/apigateway.viewer",
members: ["user:jane@example.com"],
}],
});
const policy = new gcp.apigateway.GatewayIamPolicy("policy", {
project: apiGw.project,
region: apiGw.region,
gateway: apiGw.gatewayId,
policyData: admin.then(admin => admin.policyData),
});
import pulumi
import pulumi_gcp as gcp
admin = gcp.organizations.get_iam_policy(bindings=[{
"role": "roles/apigateway.viewer",
"members": ["user:jane@example.com"],
}])
policy = gcp.apigateway.GatewayIamPolicy("policy",
project=api_gw["project"],
region=api_gw["region"],
gateway=api_gw["gatewayId"],
policy_data=admin.policy_data)
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/apigateway"
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/organizations"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
admin, err := organizations.LookupIAMPolicy(ctx, &organizations.LookupIAMPolicyArgs{
Bindings: []organizations.GetIAMPolicyBinding{
{
Role: "roles/apigateway.viewer",
Members: []string{
"user:jane@example.com",
},
},
},
}, nil)
if err != nil {
return err
}
_, err = apigateway.NewGatewayIamPolicy(ctx, "policy", &apigateway.GatewayIamPolicyArgs{
Project: pulumi.Any(apiGw.Project),
Region: pulumi.Any(apiGw.Region),
Gateway: pulumi.Any(apiGw.GatewayId),
PolicyData: pulumi.String(admin.PolicyData),
})
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 admin = Gcp.Organizations.GetIAMPolicy.Invoke(new()
{
Bindings = new[]
{
new Gcp.Organizations.Inputs.GetIAMPolicyBindingInputArgs
{
Role = "roles/apigateway.viewer",
Members = new[]
{
"user:jane@example.com",
},
},
},
});
var policy = new Gcp.ApiGateway.GatewayIamPolicy("policy", new()
{
Project = apiGw.Project,
Region = apiGw.Region,
Gateway = apiGw.GatewayId,
PolicyData = admin.Apply(getIAMPolicyResult => getIAMPolicyResult.PolicyData),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.organizations.OrganizationsFunctions;
import com.pulumi.gcp.organizations.inputs.GetIAMPolicyArgs;
import com.pulumi.gcp.apigateway.GatewayIamPolicy;
import com.pulumi.gcp.apigateway.GatewayIamPolicyArgs;
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) {
final var admin = OrganizationsFunctions.getIAMPolicy(GetIAMPolicyArgs.builder()
.bindings(GetIAMPolicyBindingArgs.builder()
.role("roles/apigateway.viewer")
.members("user:jane@example.com")
.build())
.build());
var policy = new GatewayIamPolicy("policy", GatewayIamPolicyArgs.builder()
.project(apiGw.project())
.region(apiGw.region())
.gateway(apiGw.gatewayId())
.policyData(admin.policyData())
.build());
}
}
resources:
policy:
type: gcp:apigateway:GatewayIamPolicy
properties:
project: ${apiGw.project}
region: ${apiGw.region}
gateway: ${apiGw.gatewayId}
policyData: ${admin.policyData}
variables:
admin:
fn::invoke:
function: gcp:organizations:getIAMPolicy
arguments:
bindings:
- role: roles/apigateway.viewer
members:
- user:jane@example.com
The policyData property comes from getIAMPolicy, which defines all roles and their members in a single policy document. GatewayIamPolicy is fully authoritative: it replaces the entire IAM policy, removing any permissions not explicitly defined. This resource cannot be used with GatewayIamBinding or GatewayIamMember, as they would conflict over policy ownership.
Beyond these examples
These snippets focus on specific IAM management approaches: single-member grants, role-level member lists, and complete policy replacement. They’re intentionally minimal rather than full access control systems.
The examples reference pre-existing infrastructure such as API Gateway gateways (by gatewayId) and GCP project/region configuration. They focus on granting permissions rather than provisioning the underlying gateway resources.
To keep things focused, common IAM patterns are omitted, including:
- Conditional IAM bindings (condition property)
- Custom role definitions
- Federated identity configuration
- Cross-project or organization-level policies
These omissions are intentional: the goal is to illustrate how each IAM resource type is wired, not provide drop-in access control modules. See the GatewayIamMember resource reference for all available configuration options.
Let's manage GCP API Gateway IAM Access
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
GatewayIamPolicy is authoritative and replaces the entire IAM policy. GatewayIamBinding is authoritative for a specific role, preserving other roles. GatewayIamMember is non-authoritative, adding a single member to a role while preserving other members.GatewayIamPolicy cannot be used with GatewayIamBinding or GatewayIamMember because they will conflict over the policy configuration.GatewayIamPolicy to manage the complete policy authoritatively. Use GatewayIamBinding to manage all members for a specific role. Use GatewayIamMember to add individual members without affecting existing ones.IAM Configuration & Identity Formats
allUsers, allAuthenticatedUsers, user:{email}, serviceAccount:{email}, group:{email}, domain:{domain}, projectOwner/Editor/Viewer:{projectid}, and federated identities like principal://iam.googleapis.com/....member to serviceAccount:{emailid}, for example serviceAccount:my-app@appspot.gserviceaccount.com.allAuthenticatedUsers as the member value to grant access to anyone authenticated with a Google account or service account.Custom Roles & Immutability
[projects|organizations]/{parent-name}/roles/{role-name}, for example projects/my-project/roles/my-custom-role.gateway, member, project, region, role) are immutable and cannot be changed after creation.