Manage GCP Gemini Repository Group IAM Access

The gcp:gemini/repositoryGroupIamMember:RepositoryGroupIamMember resource, part of the Pulumi GCP provider, manages IAM permissions for Gemini repository groups by granting roles to individual members, lists of members, or replacing entire policies. This guide focuses on three capabilities: single-member role grants, multi-member role bindings, and authoritative policy replacement.

These resources reference existing repository groups within code repository indexes. The RepositoryGroupIamPolicy resource cannot be used alongside IamBinding or IamMember resources on the same repository group, as they will conflict over policy state. The examples are intentionally small. Combine them with your own repository group infrastructure and member identities.

Grant a single user access to a repository group

When you need to add one user to a repository group without affecting other members’ permissions, use the non-authoritative IamMember resource.

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

const member = new gcp.gemini.RepositoryGroupIamMember("member", {
    project: example.project,
    location: example.location,
    codeRepositoryIndex: example.codeRepositoryIndex,
    repositoryGroupId: example.repositoryGroupId,
    role: "roles/cloudaicompanion.repositoryGroupsUser",
    member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp

member = gcp.gemini.RepositoryGroupIamMember("member",
    project=example["project"],
    location=example["location"],
    code_repository_index=example["codeRepositoryIndex"],
    repository_group_id=example["repositoryGroupId"],
    role="roles/cloudaicompanion.repositoryGroupsUser",
    member="user:jane@example.com")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := gemini.NewRepositoryGroupIamMember(ctx, "member", &gemini.RepositoryGroupIamMemberArgs{
			Project:             pulumi.Any(example.Project),
			Location:            pulumi.Any(example.Location),
			CodeRepositoryIndex: pulumi.Any(example.CodeRepositoryIndex),
			RepositoryGroupId:   pulumi.Any(example.RepositoryGroupId),
			Role:                pulumi.String("roles/cloudaicompanion.repositoryGroupsUser"),
			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.Gemini.RepositoryGroupIamMember("member", new()
    {
        Project = example.Project,
        Location = example.Location,
        CodeRepositoryIndex = example.CodeRepositoryIndex,
        RepositoryGroupId = example.RepositoryGroupId,
        Role = "roles/cloudaicompanion.repositoryGroupsUser",
        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.gemini.RepositoryGroupIamMember;
import com.pulumi.gcp.gemini.RepositoryGroupIamMemberArgs;
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 RepositoryGroupIamMember("member", RepositoryGroupIamMemberArgs.builder()
            .project(example.project())
            .location(example.location())
            .codeRepositoryIndex(example.codeRepositoryIndex())
            .repositoryGroupId(example.repositoryGroupId())
            .role("roles/cloudaicompanion.repositoryGroupsUser")
            .member("user:jane@example.com")
            .build());

    }
}
resources:
  member:
    type: gcp:gemini:RepositoryGroupIamMember
    properties:
      project: ${example.project}
      location: ${example.location}
      codeRepositoryIndex: ${example.codeRepositoryIndex}
      repositoryGroupId: ${example.repositoryGroupId}
      role: roles/cloudaicompanion.repositoryGroupsUser
      member: user:jane@example.com

The member property specifies the identity receiving access, using formats like “user:jane@example.com” for Google accounts or “serviceAccount:…” for service accounts. The role property defines the permission level. The repositoryGroupId and codeRepositoryIndex properties identify which repository group receives the binding. This resource preserves existing members for the same role.

Grant multiple users the same role

When multiple team members need identical permissions, binding a role to a list ensures consistent access control.

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

const binding = new gcp.gemini.RepositoryGroupIamBinding("binding", {
    project: example.project,
    location: example.location,
    codeRepositoryIndex: example.codeRepositoryIndex,
    repositoryGroupId: example.repositoryGroupId,
    role: "roles/cloudaicompanion.repositoryGroupsUser",
    members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp

binding = gcp.gemini.RepositoryGroupIamBinding("binding",
    project=example["project"],
    location=example["location"],
    code_repository_index=example["codeRepositoryIndex"],
    repository_group_id=example["repositoryGroupId"],
    role="roles/cloudaicompanion.repositoryGroupsUser",
    members=["user:jane@example.com"])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := gemini.NewRepositoryGroupIamBinding(ctx, "binding", &gemini.RepositoryGroupIamBindingArgs{
			Project:             pulumi.Any(example.Project),
			Location:            pulumi.Any(example.Location),
			CodeRepositoryIndex: pulumi.Any(example.CodeRepositoryIndex),
			RepositoryGroupId:   pulumi.Any(example.RepositoryGroupId),
			Role:                pulumi.String("roles/cloudaicompanion.repositoryGroupsUser"),
			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.Gemini.RepositoryGroupIamBinding("binding", new()
    {
        Project = example.Project,
        Location = example.Location,
        CodeRepositoryIndex = example.CodeRepositoryIndex,
        RepositoryGroupId = example.RepositoryGroupId,
        Role = "roles/cloudaicompanion.repositoryGroupsUser",
        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.gemini.RepositoryGroupIamBinding;
import com.pulumi.gcp.gemini.RepositoryGroupIamBindingArgs;
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 RepositoryGroupIamBinding("binding", RepositoryGroupIamBindingArgs.builder()
            .project(example.project())
            .location(example.location())
            .codeRepositoryIndex(example.codeRepositoryIndex())
            .repositoryGroupId(example.repositoryGroupId())
            .role("roles/cloudaicompanion.repositoryGroupsUser")
            .members("user:jane@example.com")
            .build());

    }
}
resources:
  binding:
    type: gcp:gemini:RepositoryGroupIamBinding
    properties:
      project: ${example.project}
      location: ${example.location}
      codeRepositoryIndex: ${example.codeRepositoryIndex}
      repositoryGroupId: ${example.repositoryGroupId}
      role: roles/cloudaicompanion.repositoryGroupsUser
      members:
        - user:jane@example.com

The RepositoryGroupIamBinding resource grants a role to multiple members at once through the members array. Unlike IamMember, this resource is authoritative for the specified role: it replaces any existing members for that role while preserving other roles on the repository group. You can use IamBinding and IamMember together only if they manage different roles.

Replace all repository group permissions with a policy

Organizations with centralized IAM management often define complete policies that replace any existing permissions.

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

const admin = gcp.organizations.getIAMPolicy({
    bindings: [{
        role: "roles/cloudaicompanion.repositoryGroupsUser",
        members: ["user:jane@example.com"],
    }],
});
const policy = new gcp.gemini.RepositoryGroupIamPolicy("policy", {
    project: example.project,
    location: example.location,
    codeRepositoryIndex: example.codeRepositoryIndex,
    repositoryGroupId: example.repositoryGroupId,
    policyData: admin.then(admin => admin.policyData),
});
import pulumi
import pulumi_gcp as gcp

admin = gcp.organizations.get_iam_policy(bindings=[{
    "role": "roles/cloudaicompanion.repositoryGroupsUser",
    "members": ["user:jane@example.com"],
}])
policy = gcp.gemini.RepositoryGroupIamPolicy("policy",
    project=example["project"],
    location=example["location"],
    code_repository_index=example["codeRepositoryIndex"],
    repository_group_id=example["repositoryGroupId"],
    policy_data=admin.policy_data)
package main

import (
	"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/gemini"
	"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/cloudaicompanion.repositoryGroupsUser",
					Members: []string{
						"user:jane@example.com",
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		_, err = gemini.NewRepositoryGroupIamPolicy(ctx, "policy", &gemini.RepositoryGroupIamPolicyArgs{
			Project:             pulumi.Any(example.Project),
			Location:            pulumi.Any(example.Location),
			CodeRepositoryIndex: pulumi.Any(example.CodeRepositoryIndex),
			RepositoryGroupId:   pulumi.Any(example.RepositoryGroupId),
			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/cloudaicompanion.repositoryGroupsUser",
                Members = new[]
                {
                    "user:jane@example.com",
                },
            },
        },
    });

    var policy = new Gcp.Gemini.RepositoryGroupIamPolicy("policy", new()
    {
        Project = example.Project,
        Location = example.Location,
        CodeRepositoryIndex = example.CodeRepositoryIndex,
        RepositoryGroupId = example.RepositoryGroupId,
        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.gemini.RepositoryGroupIamPolicy;
import com.pulumi.gcp.gemini.RepositoryGroupIamPolicyArgs;
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/cloudaicompanion.repositoryGroupsUser")
                .members("user:jane@example.com")
                .build())
            .build());

        var policy = new RepositoryGroupIamPolicy("policy", RepositoryGroupIamPolicyArgs.builder()
            .project(example.project())
            .location(example.location())
            .codeRepositoryIndex(example.codeRepositoryIndex())
            .repositoryGroupId(example.repositoryGroupId())
            .policyData(admin.policyData())
            .build());

    }
}
resources:
  policy:
    type: gcp:gemini:RepositoryGroupIamPolicy
    properties:
      project: ${example.project}
      location: ${example.location}
      codeRepositoryIndex: ${example.codeRepositoryIndex}
      repositoryGroupId: ${example.repositoryGroupId}
      policyData: ${admin.policyData}
variables:
  admin:
    fn::invoke:
      function: gcp:organizations:getIAMPolicy
      arguments:
        bindings:
          - role: roles/cloudaicompanion.repositoryGroupsUser
            members:
              - user:jane@example.com

The RepositoryGroupIamPolicy resource sets the entire IAM policy for a repository group using policyData from getIAMPolicy. This approach is fully authoritative: it replaces all existing permissions. The bindings array in getIAMPolicy defines roles and their members. This resource cannot coexist with IamBinding or IamMember resources on the same repository group.

Beyond these examples

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

The examples reference pre-existing infrastructure such as repository groups within code repository indexes, and GCP projects and locations. They focus on IAM binding configuration rather than provisioning the underlying Gemini resources.

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

  • Conditional IAM bindings (condition property)
  • Custom role definitions
  • Service account and group member types
  • Federated identity principals

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 RepositoryGroupIamMember resource reference for all available configuration options.

Let's manage GCP Gemini Repository Group 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
Can I use RepositoryGroupIamPolicy with RepositoryGroupIamBinding or RepositoryGroupIamMember?
No, RepositoryGroupIamPolicy cannot be used together with RepositoryGroupIamBinding or RepositoryGroupIamMember as they will conflict over policy control. Use either RepositoryGroupIamPolicy alone for full policy management, or use RepositoryGroupIamBinding and RepositoryGroupIamMember together.
Can I use RepositoryGroupIamBinding and RepositoryGroupIamMember together?
Yes, but only if they don’t grant privileges to the same role. If both resources manage the same role, they’ll conflict. Use them for different roles or choose one resource type per role.
Which IAM resource should I use to manage repository group permissions?

Choose based on your needs:

  • RepositoryGroupIamPolicy: Authoritative control of the entire IAM policy (replaces existing policy)
  • RepositoryGroupIamBinding: Authoritative control of all members for a specific role (preserves other roles)
  • RepositoryGroupIamMember: Non-authoritative addition of individual members (preserves other members and roles)
Configuration & Identity Management
What member identity formats are supported?

The member property supports multiple identity formats:

  • allUsers or allAuthenticatedUsers for public/authenticated access
  • user:{email}, serviceAccount:{email}, or group:{email} for specific identities
  • domain:{domain} for G Suite domains
  • projectOwner:projectid, projectEditor:projectid, or projectViewer:projectid for project roles
  • Federated identities using principal identifiers (e.g., principal://iam.googleapis.com/...)
How do I use custom IAM roles?
Custom roles must follow the format [projects|organizations]/{parent-name}/roles/{role-name}. For example, projects/my-project/roles/customRole or organizations/my-org/roles/customRole.
Can I change the role or member after creating the resource?
No, all properties (codeRepositoryIndex, location, member, project, repositoryGroupId, and role) are immutable and cannot be changed after creation. You must destroy and recreate the resource to make changes.
Resource Management
How do I import existing IAM resources?

Use space-delimited identifiers in the import command:

  • Member: resource_id role member_identity (e.g., projects/.../repositoryGroups/my-group roles/cloudaicompanion.repositoryGroupsUser user:jane@example.com)
  • Binding: resource_id role (e.g., projects/.../repositoryGroups/my-group roles/cloudaicompanion.repositoryGroupsUser)
  • Policy: resource_id only (e.g., projects/.../repositoryGroups/my-group)

The resource ID supports multiple formats from full path to just the repository_group_id.

Using a different cloud?

Explore security guides for other cloud providers: