The gcp:gemini/repositoryGroupIamMember:RepositoryGroupIamMember resource, part of the Pulumi GCP provider, manages IAM access to Gemini repository groups by granting roles to individual members, multiple members, or replacing the entire policy. This guide focuses on three capabilities: individual member grants, role bindings for multiple users, and authoritative policy replacement.
IAM resources for repository groups come in three variants: IamMember (non-authoritative, adds one member), IamBinding (authoritative for a role, manages all members for that role), and IamPolicy (authoritative for the entire policy). All three reference existing repository groups within code repository indexes. The examples are intentionally small. Combine them with your own repository group infrastructure and access requirements.
Grant a single user access to a repository group
Most access grants start by adding individual users to repository groups without affecting existing members or roles.
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 to grant access, using formats like “user:jane@example.com” for Google accounts or “serviceAccount:…” for service accounts. The role property defines the permission level, here using the predefined repositoryGroupsUser role. The repositoryGroupId and codeRepositoryIndex properties identify which repository group receives the access grant. This resource is non-authoritative: it adds the member without removing other members for the same role.
Grant a role to multiple users at once
When onboarding teams or granting access to groups, binding a role to multiple members simplifies management.
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 members property accepts an array of identities, allowing you to grant the same role to multiple users in one resource. This resource is authoritative for the specified role: it replaces all members for that role on the repository group. Other roles remain unchanged. Use IamBinding when you want to manage all members for a role together, rather than tracking individual IamMember resources.
Replace the entire IAM policy with a custom definition
Organizations with complex requirements sometimes need to define the complete IAM policy from scratch.
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 policyData property accepts a complete IAM policy document, typically retrieved from getIAMPolicy. The bindings array within the policy defines all role-to-members mappings. This resource is fully authoritative: it replaces the entire IAM policy for the repository group. You cannot use IamPolicy alongside IamBinding or IamMember resources on the same repository group, as they will conflict over policy ownership.
Beyond these examples
These snippets focus on specific IAM management features: individual member grants, role bindings for multiple users, and authoritative policy replacement. They’re intentionally minimal rather than full access control configurations.
The examples reference pre-existing infrastructure such as Gemini code repository indexes and repository groups within those indexes. They focus on configuring IAM access rather than provisioning the repository infrastructure itself.
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 FREEFrequently Asked Questions
Resource Selection & Conflicts
You have three options:
- RepositoryGroupIamPolicy - Authoritative. Replaces the entire IAM policy.
- RepositoryGroupIamBinding - Authoritative for a specific role. Preserves other roles in the policy.
- RepositoryGroupIamMember - Non-authoritative. Adds a single member to a role, preserving other members.
RepositoryGroupIamPolicy cannot be used with RepositoryGroupIamBinding or RepositoryGroupIamMember because they will conflict over policy control. Use either Policy (authoritative) or Binding/Member (non-authoritative), never mix them.Configuration & Identity Management
The member property supports:
allUsers- Anyone on the internetallAuthenticatedUsers- Anyone with a Google accountuser:{emailid}- Specific Google account (e.g.,user:alice@gmail.com)serviceAccount:{emailid}- Service account (e.g.,serviceAccount:my-app@appspot.gserviceaccount.com)group:{emailid}- Google group (e.g.,group:admins@example.com)domain:{domain}- G Suite domain (e.g.,domain:example.com)projectOwner:projectid,projectEditor:projectid,projectViewer:projectid- Project-level roles- Federated identities (e.g.,
principal://iam.googleapis.com/locations/global/workforcePools/...)
codeRepositoryIndex, location, member, project, repositoryGroupId, and role. To change any of these, you must recreate the resource.Advanced Topics
[projects|organizations]/{parent-name}/roles/{role-name}. For example, projects/my-project/roles/my-custom-role or organizations/my-org/roles/my-custom-role.Use space-delimited identifiers:
- Member:
pulumi import gcp:gemini/repositoryGroupIamMember:RepositoryGroupIamMember editor "projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{code_repository_index}}/repositoryGroups/{{repository_group_id}} roles/cloudaicompanion.repositoryGroupsUser user:jane@example.com" - Binding:
pulumi import gcp:gemini/repositoryGroupIamMember:RepositoryGroupIamMember editor "projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{code_repository_index}}/repositoryGroups/{{repository_group_id}} roles/cloudaicompanion.repositoryGroupsUser" - Policy:
pulumi import gcp:gemini/repositoryGroupIamMember:RepositoryGroupIamMember editor projects/{{project}}/locations/{{location}}/codeRepositoryIndexes/{{code_repository_index}}/repositoryGroups/{{repository_group_id}}