Manage GCP Pub/Sub Subscription IAM Access

The gcp:pubsub/subscriptionIAMMember:SubscriptionIAMMember resource, part of the Pulumi GCP provider, grants IAM roles to identities on Pub/Sub subscriptions without replacing existing role assignments. This guide focuses on two capabilities: single-member role grants and multi-member role management.

This resource is non-authoritative: it adds members to roles without removing existing assignments. It references existing Pub/Sub subscriptions and can work alongside SubscriptionIAMBinding for non-conflicting roles. The examples are intentionally small. Combine them with your own subscription references and identity management.

Grant a role to a single member

Most IAM configurations start by granting a specific role to one identity, preserving existing assignments for other members.

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

const editor = new gcp.pubsub.SubscriptionIAMMember("editor", {
    subscription: "your-subscription-name",
    role: "roles/editor",
    member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp

editor = gcp.pubsub.SubscriptionIAMMember("editor",
    subscription="your-subscription-name",
    role="roles/editor",
    member="user:jane@example.com")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := pubsub.NewSubscriptionIAMMember(ctx, "editor", &pubsub.SubscriptionIAMMemberArgs{
			Subscription: pulumi.String("your-subscription-name"),
			Role:         pulumi.String("roles/editor"),
			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 editor = new Gcp.PubSub.SubscriptionIAMMember("editor", new()
    {
        Subscription = "your-subscription-name",
        Role = "roles/editor",
        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.pubsub.SubscriptionIAMMember;
import com.pulumi.gcp.pubsub.SubscriptionIAMMemberArgs;
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 editor = new SubscriptionIAMMember("editor", SubscriptionIAMMemberArgs.builder()
            .subscription("your-subscription-name")
            .role("roles/editor")
            .member("user:jane@example.com")
            .build());

    }
}
resources:
  editor:
    type: gcp:pubsub:SubscriptionIAMMember
    properties:
      subscription: your-subscription-name
      role: roles/editor
      member: user:jane@example.com

The member property specifies the identity receiving access, using formats like user:jane@example.com or serviceAccount:app@project.iam.gserviceaccount.com. The role property defines the permission level. This resource adds the member without affecting other identities already assigned to the role.

Grant a role to multiple members at once

When multiple identities need the same role, SubscriptionIAMBinding manages the complete member list for that role.

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

const editor = new gcp.pubsub.SubscriptionIAMBinding("editor", {
    subscription: "your-subscription-name",
    role: "roles/editor",
    members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp

editor = gcp.pubsub.SubscriptionIAMBinding("editor",
    subscription="your-subscription-name",
    role="roles/editor",
    members=["user:jane@example.com"])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := pubsub.NewSubscriptionIAMBinding(ctx, "editor", &pubsub.SubscriptionIAMBindingArgs{
			Subscription: pulumi.String("your-subscription-name"),
			Role:         pulumi.String("roles/editor"),
			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 editor = new Gcp.PubSub.SubscriptionIAMBinding("editor", new()
    {
        Subscription = "your-subscription-name",
        Role = "roles/editor",
        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.pubsub.SubscriptionIAMBinding;
import com.pulumi.gcp.pubsub.SubscriptionIAMBindingArgs;
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 editor = new SubscriptionIAMBinding("editor", SubscriptionIAMBindingArgs.builder()
            .subscription("your-subscription-name")
            .role("roles/editor")
            .members("user:jane@example.com")
            .build());

    }
}
resources:
  editor:
    type: gcp:pubsub:SubscriptionIAMBinding
    properties:
      subscription: your-subscription-name
      role: roles/editor
      members:
        - user:jane@example.com

The members property lists all identities that should have the role. This replaces any existing members for this specific role but preserves other roles on the subscription. Use SubscriptionIAMBinding when you want to control the full member list; use SubscriptionIAMMember when you want to add members incrementally.

Beyond these examples

These snippets focus on specific IAM binding features: single-member and multi-member role grants. They’re intentionally minimal rather than full access control configurations.

The examples reference pre-existing infrastructure such as Pub/Sub subscriptions. They focus on granting access rather than provisioning the subscriptions themselves.

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

  • Conditional IAM bindings (condition property)
  • Full policy replacement (SubscriptionIAMPolicy)
  • Custom role formatting ([projects|organizations]/{parent}/roles/{name})

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

Let's manage GCP Pub/Sub Subscription IAM Access

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
What's the difference between SubscriptionIAMPolicy, SubscriptionIAMBinding, and SubscriptionIAMMember?
SubscriptionIAMPolicy is authoritative and replaces the entire IAM policy. SubscriptionIAMBinding is authoritative for a given role, updating members for that role while preserving other roles. SubscriptionIAMMember is non-authoritative, adding a single member to a role while preserving other members.
Can I use SubscriptionIAMPolicy with SubscriptionIAMBinding or SubscriptionIAMMember?
No, SubscriptionIAMPolicy cannot be used with SubscriptionIAMBinding or SubscriptionIAMMember because they will conflict over the policy.
Can I use SubscriptionIAMBinding and SubscriptionIAMMember together?
Yes, but only if they don’t grant privileges to the same role. If they target the same role, they will conflict.
Which IAM resource should I use for my subscription?
Use SubscriptionIAMPolicy for full control over the entire policy. Use SubscriptionIAMBinding to manage all members for a specific role. Use SubscriptionIAMMember to add individual members without affecting others.
Configuration & Identity Formats
What identity formats can I use for the member parameter?
You can use allUsers, allAuthenticatedUsers, user:{email}, serviceAccount:{email}, group:{email}, or domain:{domain} (e.g., user:jane@example.com or serviceAccount:my-app@appspot.gserviceaccount.com).
How do I specify a custom role?
Custom roles must use the format [projects|organizations]/{parent-name}/roles/{role-name} (e.g., projects/my-project/roles/my-custom-role).

Using a different cloud?

Explore security guides for other cloud providers: