Manage GCP Tag Value IAM Members

The gcp:tags/tagValueIamMember:TagValueIamMember resource, part of the Pulumi GCP provider, manages IAM permissions for GCP tag values. This guide focuses on three approaches: non-authoritative member grants, authoritative role bindings, and complete policy replacement.

GCP provides three related resources for tag value IAM management. TagValueIamPolicy replaces the entire policy (authoritative). TagValueIamBinding manages all members for one role (authoritative for that role). TagValueIamMember adds individual members without affecting others (non-authoritative). The examples are intentionally small. Choose the approach that matches your permission management strategy.

Replace the entire IAM policy for a tag value

When you need complete control over permissions, you can set the entire IAM policy at once.

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

const admin = gcp.organizations.getIAMPolicy({
    bindings: [{
        role: "roles/viewer",
        members: ["user:jane@example.com"],
    }],
});
const policy = new gcp.tags.TagValueIamPolicy("policy", {
    tagValue: value.name,
    policyData: admin.then(admin => admin.policyData),
});
import pulumi
import pulumi_gcp as gcp

admin = gcp.organizations.get_iam_policy(bindings=[{
    "role": "roles/viewer",
    "members": ["user:jane@example.com"],
}])
policy = gcp.tags.TagValueIamPolicy("policy",
    tag_value=value["name"],
    policy_data=admin.policy_data)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/organizations"
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/tags"
	"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/viewer",
					Members: []string{
						"user:jane@example.com",
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		_, err = tags.NewTagValueIamPolicy(ctx, "policy", &tags.TagValueIamPolicyArgs{
			TagValue:   pulumi.Any(value.Name),
			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/viewer",
                Members = new[]
                {
                    "user:jane@example.com",
                },
            },
        },
    });

    var policy = new Gcp.Tags.TagValueIamPolicy("policy", new()
    {
        TagValue = @value.Name,
        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.tags.TagValueIamPolicy;
import com.pulumi.gcp.tags.TagValueIamPolicyArgs;
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/viewer")
                .members("user:jane@example.com")
                .build())
            .build());

        var policy = new TagValueIamPolicy("policy", TagValueIamPolicyArgs.builder()
            .tagValue(value.name())
            .policyData(admin.policyData())
            .build());

    }
}
resources:
  policy:
    type: gcp:tags:TagValueIamPolicy
    properties:
      tagValue: ${value.name}
      policyData: ${admin.policyData}
variables:
  admin:
    fn::invoke:
      function: gcp:organizations:getIAMPolicy
      arguments:
        bindings:
          - role: roles/viewer
            members:
              - user:jane@example.com

The TagValueIamPolicy resource replaces any existing policy on the tag value. The getIAMPolicy function constructs the policy document with bindings that map roles to members. The policyData property contains the complete policy. This approach is authoritative: it removes any permissions not explicitly listed.

Grant a role to multiple members at once

When several identities need the same role, you can bind them together in one resource.

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

const binding = new gcp.tags.TagValueIamBinding("binding", {
    tagValue: value.name,
    role: "roles/viewer",
    members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp

binding = gcp.tags.TagValueIamBinding("binding",
    tag_value=value["name"],
    role="roles/viewer",
    members=["user:jane@example.com"])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := tags.NewTagValueIamBinding(ctx, "binding", &tags.TagValueIamBindingArgs{
			TagValue: pulumi.Any(value.Name),
			Role:     pulumi.String("roles/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.Tags.TagValueIamBinding("binding", new()
    {
        TagValue = @value.Name,
        Role = "roles/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.tags.TagValueIamBinding;
import com.pulumi.gcp.tags.TagValueIamBindingArgs;
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 TagValueIamBinding("binding", TagValueIamBindingArgs.builder()
            .tagValue(value.name())
            .role("roles/viewer")
            .members("user:jane@example.com")
            .build());

    }
}
resources:
  binding:
    type: gcp:tags:TagValueIamBinding
    properties:
      tagValue: ${value.name}
      role: roles/viewer
      members:
        - user:jane@example.com

The TagValueIamBinding resource grants one role to a list of members. The members array accepts user emails, service accounts, groups, or special identifiers like allUsers. This resource is authoritative for its specific role but preserves other roles on the tag value. You can use multiple bindings for different roles, but only one binding per role.

Add a single member to a tag value role

For incremental permission changes, you can grant access to one identity at a time.

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

const member = new gcp.tags.TagValueIamMember("member", {
    tagValue: value.name,
    role: "roles/viewer",
    member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp

member = gcp.tags.TagValueIamMember("member",
    tag_value=value["name"],
    role="roles/viewer",
    member="user:jane@example.com")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := tags.NewTagValueIamMember(ctx, "member", &tags.TagValueIamMemberArgs{
			TagValue: pulumi.Any(value.Name),
			Role:     pulumi.String("roles/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.Tags.TagValueIamMember("member", new()
    {
        TagValue = @value.Name,
        Role = "roles/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.tags.TagValueIamMember;
import com.pulumi.gcp.tags.TagValueIamMemberArgs;
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 TagValueIamMember("member", TagValueIamMemberArgs.builder()
            .tagValue(value.name())
            .role("roles/viewer")
            .member("user:jane@example.com")
            .build());

    }
}
resources:
  member:
    type: gcp:tags:TagValueIamMember
    properties:
      tagValue: ${value.name}
      role: roles/viewer
      member: user:jane@example.com

The TagValueIamMember resource adds one member to one role without affecting other members. The member property accepts the same identity formats as bindings: user emails, service accounts, groups, domains, or federated identities. This is the safest approach when you don’t want to manage the complete member list for a role.

Beyond these examples

These snippets focus on specific IAM management approaches: authoritative and non-authoritative IAM management, and single-member and multi-member role grants. They’re intentionally minimal rather than complete access control configurations.

The examples reference pre-existing infrastructure such as tag values created via gcp.tags.TagValue or elsewhere. They focus on permission assignment rather than tag value creation.

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

  • Conditional IAM bindings (condition property)
  • Custom role definitions and formatting
  • Combining Policy, Binding, and Member resources safely
  • Federated identity and workload identity pool configuration

These omissions are intentional: the goal is to illustrate how each IAM resource type works, not provide drop-in access control modules. See the TagValueIamMember resource reference for all available configuration options.

Let's manage GCP Tag Value IAM Members

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 TagValueIamPolicy with TagValueIamBinding or TagValueIamMember?
No, gcp.tags.TagValueIamPolicy cannot be used with gcp.tags.TagValueIamBinding or gcp.tags.TagValueIamMember because they will conflict over the policy configuration.
Can I use TagValueIamBinding and TagValueIamMember together?
Yes, but only if they don’t grant privileges to the same role. Using both for the same role will cause conflicts.
Which IAM resource should I use for managing tag value permissions?
Choose based on your needs: gcp.tags.TagValueIamPolicy for full policy control (replaces entire policy), gcp.tags.TagValueIamBinding for managing all members of a specific role, or gcp.tags.TagValueIamMember for adding individual members without affecting others.
Configuration & Identity Formats
What member identity formats are supported?
Supported formats include allUsers, allAuthenticatedUsers, user:{email}, serviceAccount:{email}, group:{email}, domain:{domain}, projectOwner/Editor/Viewer:{projectid}, and federated identities like principal://iam.googleapis.com/....
What properties can't be changed after creation?
All core properties are immutable: member, role, tagValue, and condition. Changes require resource replacement.
Custom Roles & Advanced Usage
How do I specify custom roles when importing IAM resources?
Use the full custom role name format: [projects/my-project|organizations/my-org]/roles/my-custom-role.

Using a different cloud?

Explore security guides for other cloud providers: