The gcp:secretmanager/regionalSecretIamMember:RegionalSecretIamMember resource, part of the Pulumi GCP provider, grants IAM permissions on regional secrets by adding individual members to roles without replacing existing access. This guide focuses on three capabilities: single-member role grants, time-limited access with IAM Conditions, and role-level member management.
IAM resources for regional secrets come in three variants: RegionalSecretIamMember (non-authoritative, adds one member), RegionalSecretIamBinding (authoritative for a role, sets all members), and RegionalSecretIamPolicy (authoritative for the entire policy). All examples reference existing regional secrets. Combine them with your own secret resources and identity management.
Grant a single user access to a regional secret
Most access grants start by adding a specific user or service account to the secretAccessor role.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const member = new gcp.secretmanager.RegionalSecretIamMember("member", {
project: regional_secret_basic.project,
location: regional_secret_basic.location,
secretId: regional_secret_basic.secretId,
role: "roles/secretmanager.secretAccessor",
member: "user:jane@example.com",
});
import pulumi
import pulumi_gcp as gcp
member = gcp.secretmanager.RegionalSecretIamMember("member",
project=regional_secret_basic["project"],
location=regional_secret_basic["location"],
secret_id=regional_secret_basic["secretId"],
role="roles/secretmanager.secretAccessor",
member="user:jane@example.com")
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/secretmanager"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := secretmanager.NewRegionalSecretIamMember(ctx, "member", &secretmanager.RegionalSecretIamMemberArgs{
Project: pulumi.Any(regional_secret_basic.Project),
Location: pulumi.Any(regional_secret_basic.Location),
SecretId: pulumi.Any(regional_secret_basic.SecretId),
Role: pulumi.String("roles/secretmanager.secretAccessor"),
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.SecretManager.RegionalSecretIamMember("member", new()
{
Project = regional_secret_basic.Project,
Location = regional_secret_basic.Location,
SecretId = regional_secret_basic.SecretId,
Role = "roles/secretmanager.secretAccessor",
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.secretmanager.RegionalSecretIamMember;
import com.pulumi.gcp.secretmanager.RegionalSecretIamMemberArgs;
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 RegionalSecretIamMember("member", RegionalSecretIamMemberArgs.builder()
.project(regional_secret_basic.project())
.location(regional_secret_basic.location())
.secretId(regional_secret_basic.secretId())
.role("roles/secretmanager.secretAccessor")
.member("user:jane@example.com")
.build());
}
}
resources:
member:
type: gcp:secretmanager:RegionalSecretIamMember
properties:
project: ${["regional-secret-basic"].project}
location: ${["regional-secret-basic"].location}
secretId: ${["regional-secret-basic"].secretId}
role: roles/secretmanager.secretAccessor
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. RegionalSecretIamMember is non-authoritative: it adds this member without removing others who already have the role.
Add time-limited access with IAM Conditions
Temporary access grants expire automatically when the condition evaluates to false, eliminating manual cleanup.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const member = new gcp.secretmanager.RegionalSecretIamMember("member", {
project: regional_secret_basic.project,
location: regional_secret_basic.location,
secretId: regional_secret_basic.secretId,
role: "roles/secretmanager.secretAccessor",
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.secretmanager.RegionalSecretIamMember("member",
project=regional_secret_basic["project"],
location=regional_secret_basic["location"],
secret_id=regional_secret_basic["secretId"],
role="roles/secretmanager.secretAccessor",
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/secretmanager"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := secretmanager.NewRegionalSecretIamMember(ctx, "member", &secretmanager.RegionalSecretIamMemberArgs{
Project: pulumi.Any(regional_secret_basic.Project),
Location: pulumi.Any(regional_secret_basic.Location),
SecretId: pulumi.Any(regional_secret_basic.SecretId),
Role: pulumi.String("roles/secretmanager.secretAccessor"),
Member: pulumi.String("user:jane@example.com"),
Condition: &secretmanager.RegionalSecretIamMemberConditionArgs{
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.SecretManager.RegionalSecretIamMember("member", new()
{
Project = regional_secret_basic.Project,
Location = regional_secret_basic.Location,
SecretId = regional_secret_basic.SecretId,
Role = "roles/secretmanager.secretAccessor",
Member = "user:jane@example.com",
Condition = new Gcp.SecretManager.Inputs.RegionalSecretIamMemberConditionArgs
{
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.secretmanager.RegionalSecretIamMember;
import com.pulumi.gcp.secretmanager.RegionalSecretIamMemberArgs;
import com.pulumi.gcp.secretmanager.inputs.RegionalSecretIamMemberConditionArgs;
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 RegionalSecretIamMember("member", RegionalSecretIamMemberArgs.builder()
.project(regional_secret_basic.project())
.location(regional_secret_basic.location())
.secretId(regional_secret_basic.secretId())
.role("roles/secretmanager.secretAccessor")
.member("user:jane@example.com")
.condition(RegionalSecretIamMemberConditionArgs.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:secretmanager:RegionalSecretIamMember
properties:
project: ${["regional-secret-basic"].project}
location: ${["regional-secret-basic"].location}
secretId: ${["regional-secret-basic"].secretId}
role: roles/secretmanager.secretAccessor
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 defines when access is valid. The expression uses Common Expression Language (CEL) to compare request.time against a timestamp. The title and description document the condition’s purpose. When the timestamp passes, GCP automatically denies access without requiring you to remove the binding.
Manage all members for a role with IamBinding
When you need to control the complete member list for a role, RegionalSecretIamBinding replaces all members for that role.
import * as pulumi from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";
const binding = new gcp.secretmanager.RegionalSecretIamBinding("binding", {
project: regional_secret_basic.project,
location: regional_secret_basic.location,
secretId: regional_secret_basic.secretId,
role: "roles/secretmanager.secretAccessor",
members: ["user:jane@example.com"],
});
import pulumi
import pulumi_gcp as gcp
binding = gcp.secretmanager.RegionalSecretIamBinding("binding",
project=regional_secret_basic["project"],
location=regional_secret_basic["location"],
secret_id=regional_secret_basic["secretId"],
role="roles/secretmanager.secretAccessor",
members=["user:jane@example.com"])
package main
import (
"github.com/pulumi/pulumi-gcp/sdk/v9/go/gcp/secretmanager"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := secretmanager.NewRegionalSecretIamBinding(ctx, "binding", &secretmanager.RegionalSecretIamBindingArgs{
Project: pulumi.Any(regional_secret_basic.Project),
Location: pulumi.Any(regional_secret_basic.Location),
SecretId: pulumi.Any(regional_secret_basic.SecretId),
Role: pulumi.String("roles/secretmanager.secretAccessor"),
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.SecretManager.RegionalSecretIamBinding("binding", new()
{
Project = regional_secret_basic.Project,
Location = regional_secret_basic.Location,
SecretId = regional_secret_basic.SecretId,
Role = "roles/secretmanager.secretAccessor",
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.secretmanager.RegionalSecretIamBinding;
import com.pulumi.gcp.secretmanager.RegionalSecretIamBindingArgs;
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 RegionalSecretIamBinding("binding", RegionalSecretIamBindingArgs.builder()
.project(regional_secret_basic.project())
.location(regional_secret_basic.location())
.secretId(regional_secret_basic.secretId())
.role("roles/secretmanager.secretAccessor")
.members("user:jane@example.com")
.build());
}
}
resources:
binding:
type: gcp:secretmanager:RegionalSecretIamBinding
properties:
project: ${["regional-secret-basic"].project}
location: ${["regional-secret-basic"].location}
secretId: ${["regional-secret-basic"].secretId}
role: roles/secretmanager.secretAccessor
members:
- user:jane@example.com
The members property takes a list of identities. RegionalSecretIamBinding is authoritative for this role: it sets exactly these members and removes anyone else who had the role. Other roles on the secret remain unchanged. Use this when you want to declare the complete access list for a role in one place.
Beyond these examples
These snippets focus on specific IAM configuration features: single-member grants, role-level member lists, and time-based access conditions. They’re intentionally minimal rather than full access control policies.
The examples reference pre-existing infrastructure such as regional secrets (referenced as regional_secret_basic). They focus on configuring IAM bindings rather than provisioning the secrets themselves.
To keep things focused, common IAM patterns are omitted, including:
- Full policy replacement (RegionalSecretIamPolicy)
- Multiple conditions per binding
- Custom role definitions
- 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 RegionalSecretIamMember resource reference for all available configuration options.
Let's manage GCP Secret Manager 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
RegionalSecretIamPolicy is authoritative and replaces the entire IAM policy. RegionalSecretIamBinding is authoritative for a specific role, preserving other roles. RegionalSecretIamMember is non-authoritative, adding a single member to a role while preserving other members.RegionalSecretIamPolicy cannot be used with RegionalSecretIamBinding or RegionalSecretIamMember, as they will conflict. RegionalSecretIamBinding and RegionalSecretIamMember can be used together only if they don’t grant privilege to the same role.Identity & Role Configuration
member parameter supports multiple formats: allUsers, allAuthenticatedUsers, user:{email}, serviceAccount:{email}, group:{email}, domain:{domain}, projectOwner:{projectid}, projectEditor:{projectid}, projectViewer:{projectid}, and federated identities like principal://iam.googleapis.com/....[projects|organizations]/{parent-name}/roles/{role-name}. For example, projects/my-project/roles/my-custom-role.member, role, location, secretId, project, and condition are all immutable. Changing them requires recreating the resource.IAM Conditions
condition block with title, description, and expression fields. For example, time-based restrictions use expressions like request.time < timestamp("2020-01-01T00:00:00Z").