The gcp:compute/backendServiceIamMember:BackendServiceIamMember resource, part of the Pulumi GCP provider, grants IAM roles to individual members on backend services without affecting other members who already have access. This resource is non-authoritative, meaning it adds one member to a role while preserving existing role assignments. This guide focuses on two capabilities: single-member role grants and time-based access conditions.
This resource is one of three IAM resources for backend services. BackendServiceIamPolicy replaces the entire policy (authoritative), BackendServiceIamBinding manages all members for a role (authoritative for that role), and BackendServiceIamMember adds individual members (non-authoritative). The examples reference existing backend services and projects. Combine them with your own backend service infrastructure.
Grant a role to a single member
When you need to give one user or service account access without changing who else has that role, use BackendServiceIamMember.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const member = new gcp.compute.BackendServiceIamMember("member", {
project: _default.project,
name: _default.name,
role: "roles/compute.admin",
member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp
member = gcp.compute.BackendServiceIamMember("member",
project=default["project"],
name=default["name"],
role="roles/compute.admin",
member="user:jane@example.com")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := compute.NewBackendServiceIamMember(ctx, "member", &compute.BackendServiceIamMemberArgs{
Project: pulumi.Any(_default.Project),
Name: pulumi.Any(_default.Name),
Role: pulumi.String("roles/compute.admin"),
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.Compute.BackendServiceIamMember("member", new()
{
Project = @default.Project,
Name = @default.Name,
Role = "roles/compute.admin",
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.compute.BackendServiceIamMember;
import com.pulumi.gcp.compute.BackendServiceIamMemberArgs;
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 BackendServiceIamMember("member", BackendServiceIamMemberArgs.builder()
.project(default_.project())
.name(default_.name())
.role("roles/compute.admin")
.member("user:jane@example.com")
.build());
}
}
resources:
member:
type: gcp:compute:BackendServiceIamMember
properties:
project: ${default.project}
name: ${default.name}
role: roles/compute.admin
member: user:jane@example.com
The member property identifies who receives access using formats like “user:jane@example.com” or “serviceAccount:app@project.iam.gserviceaccount.com”. The role property specifies the permission level (e.g., “roles/compute.admin”). The name property references the backend service, and project identifies the GCP project. This resource adds the member to the role without removing other members who already have it.
Grant time-limited access with IAM Conditions
For contractors, auditors, or temporary projects, IAM Conditions let you attach expiration dates to role grants.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const member = new gcp.compute.BackendServiceIamMember("member", {
project: _default.project,
name: _default.name,
role: "roles/compute.admin",
member: "user:jane@example.com",
condition: {
title: "expires_after_2019_12_31",
description: "Expiring at midnight of 2019-12-31",
expression: "request.time < timestamp(\"2020-01-01T00:00:00Z\")",
},
});
import pulumi
import pulumi_gcp as gcp
member = gcp.compute.BackendServiceIamMember("member",
project=default["project"],
name=default["name"],
role="roles/compute.admin",
member="user:jane@example.com",
condition={
"title": "expires_after_2019_12_31",
"description": "Expiring at midnight of 2019-12-31",
"expression": "request.time < timestamp(\"2020-01-01T00:00:00Z\")",
})
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/compute"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := compute.NewBackendServiceIamMember(ctx, "member", &compute.BackendServiceIamMemberArgs{
Project: pulumi.Any(_default.Project),
Name: pulumi.Any(_default.Name),
Role: pulumi.String("roles/compute.admin"),
Member: pulumi.String("user:jane@example.com"),
Condition: &compute.BackendServiceIamMemberConditionArgs{
Title: pulumi.String("expires_after_2019_12_31"),
Description: pulumi.String("Expiring at midnight of 2019-12-31"),
Expression: pulumi.String("request.time < timestamp(\"2020-01-01T00:00:00Z\")"),
},
})
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.Compute.BackendServiceIamMember("member", new()
{
Project = @default.Project,
Name = @default.Name,
Role = "roles/compute.admin",
Member = "user:jane@example.com",
Condition = new Gcp.Compute.Inputs.BackendServiceIamMemberConditionArgs
{
Title = "expires_after_2019_12_31",
Description = "Expiring at midnight of 2019-12-31",
Expression = "request.time < timestamp(\"2020-01-01T00:00:00Z\")",
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.gcp.compute.BackendServiceIamMember;
import com.pulumi.gcp.compute.BackendServiceIamMemberArgs;
import com.pulumi.gcp.compute.inputs.BackendServiceIamMemberConditionArgs;
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 BackendServiceIamMember("member", BackendServiceIamMemberArgs.builder()
.project(default_.project())
.name(default_.name())
.role("roles/compute.admin")
.member("user:jane@example.com")
.condition(BackendServiceIamMemberConditionArgs.builder()
.title("expires_after_2019_12_31")
.description("Expiring at midnight of 2019-12-31")
.expression("request.time < timestamp(\"2020-01-01T00:00:00Z\")")
.build())
.build());
}
}
resources:
member:
type: gcp:compute:BackendServiceIamMember
properties:
project: ${default.project}
name: ${default.name}
role: roles/compute.admin
member: user:jane@example.com
condition:
title: expires_after_2019_12_31
description: Expiring at midnight of 2019-12-31
expression: request.time < timestamp("2020-01-01T00:00:00Z")
The condition block adds constraints to the role grant. The expression property uses CEL (Common Expression Language) to define when access is valid; here, it expires at midnight on 2020-01-01. The title property names the condition for identification, and description explains its purpose. IAM evaluates the condition on every request; once the timestamp passes, the member loses access automatically.
Beyond these examples
These snippets focus on specific member-level features: single-member role grants and time-based access conditions. They’re intentionally minimal rather than full IAM configurations.
The examples reference pre-existing infrastructure such as backend services and GCP projects. They focus on granting access to individual members rather than managing complete IAM policies.
To keep things focused, common IAM patterns are omitted, including:
- Multi-member role bindings (use BackendServiceIamBinding)
- Full policy replacement (use BackendServiceIamPolicy)
- Complex condition expressions (location, resource attributes)
- Custom role definitions
These omissions are intentional: the goal is to illustrate how member-level access grants are wired, not provide drop-in IAM modules. See the BackendServiceIamMember resource reference for all available configuration options.
Let's manage GCP Backend Service IAM Permissions
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
BackendServiceIamPolicy is fully authoritative and replaces the entire IAM policy. BackendServiceIamBinding is authoritative for a specific role, managing all members for that role while preserving other roles. BackendServiceIamMember is non-authoritative, adding individual members without affecting other members or roles.BackendServiceIamPolicy cannot be used with BackendServiceIamBinding or BackendServiceIamMember as they will conflict. However, BackendServiceIamBinding and BackendServiceIamMember can be used together if they manage different roles.BackendServiceIamMember when you want to add individual members non-authoritatively without affecting other members for the same role. Use BackendServiceIamBinding when you want to manage all members for a specific role authoritatively.IAM Configuration
allUsers, allAuthenticatedUsers, user:{email}, serviceAccount:{email}, group:{email}, domain:{domain}, projectOwner:{projectid}, projectEditor:{projectid}, projectViewer:{projectid}, and federated identities using principal:// URIs.[projects|organizations]/{parent-name}/roles/{role-name}. For example, projects/my-project/roles/my-custom-role.condition property with title, description, and expression fields. For example, set expression to request.time < timestamp("2020-01-01T00:00:00Z") for time-based expiration.Resource Properties & Constraints
member, role, name, project, and condition. Any changes require recreating the resource.