For an alternative way to control access
to individual objects in your buckets, seeAccess Control Lists.
For more information about controlling access to Cloud Storage
resources, readOverview of Access Control.
Required roles
To get the permissions that you need to set and manage IAM
policies for a bucket, ask your administrator to grant you the Storage Admin
(roles/storage.admin) IAM role for the bucket.
This role contains the following permissions, which are required to set
and manage IAM policies for buckets:
storage.buckets.get
storage.buckets.getIamPolicy
storage.buckets.setIamPolicy
storage.buckets.update
storage.buckets.list
This permission is only required if you plan on using the
Google Cloud console to perform the tasks on this page.
You can also get these permissions withcustom roles.
Add a principal to a bucket-level policy
For a list of roles associated with Cloud Storage, seeIAM Roles. For information on entities to which you grant
IAM roles, seePrincipal identifiers.
Console
In the Google Cloud console, go to the Cloud StorageBucketspage.
In the list of buckets, click the name of the bucket for which you want
to grant a principal a role.
Select thePermissionstab near the top of the page.
Click theadd_boxGrant accessbutton.
TheAdd principalsdialog appears.
In theNew principalsfield, enter one or more identities
that need access to your bucket.
Select a role (or roles) from theSelect a roledrop-down menu.
The roles you select appear in the pane with a short description of
the permissions they grant.
ClickSave.
To learn how to get detailed error information about failed Cloud Storage
operations in the Google Cloud console, seeTroubleshooting.
BUCKET_NAMEis the name of the bucket you are
granting the principal access to. For example,my-bucket.
PRINCIPAL_IDENTIFIERidentifies who you are
granting bucket access to. For example,user:jane@gmail.com. For a
list of principal identifier formats, seePrincipal identifiers.
IAM_ROLEis theIAM roleyou are granting to the principal. For example,roles/storage.objectViewer.
using Google.Apis.Storage.v1.Data;
using Google.Cloud.Storage.V1;
using System;
using System.Collections.Generic;
public class AddBucketIamMemberSample
{
public Policy AddBucketIamMember(
string bucketName = "your-unique-bucket-name",
string role = "roles/storage.objectViewer",
string member = "serviceAccount:dev@iam.gserviceaccount.com")
{
var storage = StorageClient.Create();
var policy = storage.GetBucketIamPolicy(bucketName, new GetBucketIamPolicyOptions
{
RequestedPolicyVersion = 3
});
// Set the policy schema version. For more information, please refer to https://cloud.google.com/iam/docs/policies#versions.
policy.Version = 3;
Policy.BindingsData bindingToAdd = new Policy.BindingsData
{
Role = role,
Members = new List<string> { member }
};
policy.Bindings.Add(bindingToAdd);
var bucketIamPolicy = storage.SetBucketIamPolicy(bucketName, policy);
Console.WriteLine($"Added {member} with role {role} " + $"to {bucketName}");
return bucketIamPolicy;
}
}
import (
"context"
"fmt"
"io"
"time"
"cloud.google.com/go/iam"
"cloud.google.com/go/storage"
)
// addBucketIAMMember adds the bucket IAM member to permission role.
func addBucketIAMMember(w io.Writer, bucketName string) error {
// bucketName := "bucket-name"
ctx := context.Background()
client, err := storage.NewClient(ctx)
if err != nil {
return fmt.Errorf("storage.NewClient: %w", err)
}
defer client.Close()
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
bucket := client.Bucket(bucketName)
policy, err := bucket.IAM().Policy(ctx)
if err != nil {
return fmt.Errorf("Bucket(%q).IAM().Policy: %w", bucketName, err)
}
// Other valid prefixes are "serviceAccount:", "user:"
// See the documentation for more values.
// https://cloud.google.com/storage/docs/access-control/iam
identity := "group:cloud-logs@google.com"
var role iam.RoleName = "roles/storage.objectViewer"
policy.Add(identity, role)
if err := bucket.IAM().SetPolicy(ctx, policy); err != nil {
return fmt.Errorf("Bucket(%q).IAM().SetPolicy: %w", bucketName, err)
}
// NOTE: It may be necessary to retry this operation if IAM policies are
// being modified concurrently. SetPolicy will return an error if the policy
// was modified since it was retrieved.
fmt.Fprintf(w, "Added %v with role %v to %v\n", identity, role, bucketName)
return nil
}
import com.google.cloud.Binding;
import com.google.cloud.Policy;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class AddBucketIamMember {
/** Example of adding a member to the Bucket-level IAM */
public static void addBucketIamMember(String projectId, String bucketName) {
// The ID of your GCP project
// String projectId = "your-project-id";
// The ID of your GCS bucket
// String bucketName = "your-unique-bucket-name";
// For more information please read:
// https://cloud.google.com/storage/docs/access-control/iam
Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
Policy originalPolicy =
storage.getIamPolicy(bucketName, Storage.BucketSourceOption.requestedPolicyVersion(3));
String role = "roles/storage.objectViewer";
String member = "group:example@google.com";
// getBindingsList() returns an ImmutableList and copying over to an ArrayList so it's mutable.
List<Binding> bindings = new ArrayList(originalPolicy.getBindingsList());
// Create a new binding using role and member
Binding.Builder newMemberBindingBuilder = Binding.newBuilder();
newMemberBindingBuilder.setRole(role).setMembers(Arrays.asList(member));
bindings.add(newMemberBindingBuilder.build());
// Update policy to add member
Policy.Builder updatedPolicyBuilder = originalPolicy.toBuilder();
updatedPolicyBuilder.setBindings(bindings).setVersion(3);
Policy updatedPolicy = storage.setIamPolicy(bucketName, updatedPolicyBuilder.build());
System.out.printf("Added %s with role %s to %s\n", member, role, bucketName);
}
}
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';
// The role to grant
// const roleName = 'roles/storage.objectViewer';
// The members to grant the new role to
// const members = [
// 'user:jdoe@example.com',
// 'group:admins@example.com',
// ];
// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');
// Creates a client
const storage = new Storage();
async function addBucketIamMember() {
// Get a reference to a Google Cloud Storage bucket
const bucket = storage.bucket(bucketName);
// For more information please read:
// https://cloud.google.com/storage/docs/access-control/iam
const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
// Adds the new roles to the bucket's IAM policy
policy.bindings.push({
role: roleName,
members: members,
});
// Updates the bucket's IAM policy
await bucket.iam.setPolicy(policy);
console.log(
`Added the following member(s) with role ${roleName} to ${bucketName}:`
);
members.forEach(member => {
console.log(` ${member}`);
});
}
addBucketIamMember().catch(console.error);
use Google\Cloud\Storage\StorageClient;
/**
* Adds a new member / role IAM pair to a given Cloud Storage bucket.
*
* @param string $bucketName The name of your Cloud Storage bucket.
* (e.g. 'my-bucket')
* @param string $role The role to which the given member should be added.
* (e.g. 'roles/storage.objectViewer')
* @param string[] $members The member(s) to be added to the role.
* (e.g. ['group:example@google.com'])
*/
function add_bucket_iam_member(string $bucketName, string $role, array $members): void
{
$storage = new StorageClient();
$bucket = $storage->bucket($bucketName);
$policy = $bucket->iam()->policy(['requestedPolicyVersion' => 3]);
$policy['version'] = 3;
$policy['bindings'][] = [
'role' => $role,
'members' => $members
];
$bucket->iam()->setPolicy($policy);
printf('Added the following member(s) to role %s for bucket %s' . PHP_EOL, $role, $bucketName);
foreach ($members as $member) {
printf(' %s' . PHP_EOL, $member);
}
}
from google.cloud import storage
def add_bucket_iam_member(bucket_name, role, member):
"""Add a new member to an IAM Policy"""
# bucket_name = "your-bucket-name"
# role = "IAM role, e.g., roles/storage.objectViewer"
# member = "IAM identity, e.g., user: name@example.com"
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
policy = bucket.get_iam_policy(requested_policy_version=3)
policy.bindings.append({"role": role, "members": {member}})
bucket.set_iam_policy(policy)
print(f"Added {member} with role {role} to {bucket_name}.")
def add_bucket_iam_member bucket_name:
# The ID of your GCS bucket
# bucket_name = "your-unique-bucket-name"
require "google/cloud/storage"
storage = Google::Cloud::Storage.new
bucket = storage.bucket bucket_name
role = "roles/storage.objectViewer"
member = "group:example@google.com"
bucket.policy requested_policy_version: 3 do |policy|
policy.bindings.insert role: role, members: [member]
end
puts "Added #{member} with role #{role} to #{bucket_name}"
end
IAM_ROLEis theIAM roleyou are granting. For example,roles/storage.objectViewer.
PRINCIPAL_IDENTIFIERidentifies who you are
granting bucket access to. For example,user:jane@gmail.com. For a
list of principal identifier formats, seePrincipal identifiers.
using Google.Apis.Storage.v1.Data;
using Google.Cloud.Storage.V1;
using System;
public class ViewBucketIamMembersSample
{
public Policy ViewBucketIamMembers(string bucketName = "your-unique-bucket-name")
{
var storage = StorageClient.Create();
var policy = storage.GetBucketIamPolicy(bucketName, new GetBucketIamPolicyOptions
{
RequestedPolicyVersion = 3
});
foreach (var binding in policy.Bindings)
{
Console.WriteLine($"Role: {binding.Role}");
Console.WriteLine("Members:");
foreach (var member in binding.Members)
{
Console.WriteLine($"{member}");
}
}
return policy;
}
}
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';
// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');
// Creates a client
const storage = new Storage();
async function viewBucketIamMembers() {
// For more information please read:
// https://cloud.google.com/storage/docs/access-control/iam
const results = await storage
.bucket(bucketName)
.iam.getPolicy({requestedPolicyVersion: 3});
const bindings = results[0].bindings;
console.log(`Bindings for bucket ${bucketName}:`);
for (const binding of bindings) {
console.log(` Role: ${binding.role}`);
console.log(' Members:');
const members = binding.members;
for (const member of members) {
console.log(` ${member}`);
}
const condition = binding.condition;
if (condition) {
console.log(' Condition:');
console.log(` Title: ${condition.title}`);
console.log(` Description: ${condition.description}`);
console.log(` Expression: ${condition.expression}`);
}
}
}
viewBucketIamMembers().catch(console.error);
BUCKET_NAMEis the name of the bucket you are
revoking access to. For example,my-bucket.
PRINCIPAL_IDENTIFIERidentifies who you are
revoking access from. For example,user:jane@gmail.com. For a list
of principal identifier formats, seePrincipal identifiers.
IAM_ROLEis theIAM roleyou are revoking. For example,roles/storage.objectViewer.
using Google.Cloud.Storage.V1;
using System;
using System.Linq;
public class RemoveBucketIamMemberSample
{
public void RemoveBucketIamMember(
string bucketName = "your-unique-bucket-name",
string role = "roles/storage.objectViewer",
string member = "serviceAccount:dev@iam.gserviceaccount.com")
{
var storage = StorageClient.Create();
var policy = storage.GetBucketIamPolicy(bucketName, new GetBucketIamPolicyOptions
{
RequestedPolicyVersion = 3
});
// Set the policy schema version. For more information, please refer to https://cloud.google.com/iam/docs/policies#versions.
policy.Version = 3;
foreach (var binding in policy.Bindings.Where(c => c.Role == role).ToList())
{
// Remove the role/member combo from the IAM policy.
binding.Members = binding.Members.Where(m => m != member).ToList();
// Remove role if it contains no members.
if (binding.Members.Count == 0)
{
policy.Bindings.Remove(binding);
}
}
// Set the modified IAM policy to be the current IAM policy.
storage.SetBucketIamPolicy(bucketName, policy);
Console.WriteLine($"Removed {member} with role {role} from {bucketName}");
}
}
import (
"context"
"fmt"
"io"
"time"
"cloud.google.com/go/iam"
"cloud.google.com/go/storage"
)
// removeBucketIAMMember removes the bucket IAM member.
func removeBucketIAMMember(w io.Writer, bucketName string) error {
// bucketName := "bucket-name"
ctx := context.Background()
client, err := storage.NewClient(ctx)
if err != nil {
return fmt.Errorf("storage.NewClient: %w", err)
}
defer client.Close()
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
bucket := client.Bucket(bucketName)
policy, err := bucket.IAM().Policy(ctx)
if err != nil {
return fmt.Errorf("Bucket(%q).IAM().Policy: %w", bucketName, err)
}
// Other valid prefixes are "serviceAccount:", "user:"
// See the documentation for more values.
// https://cloud.google.com/storage/docs/access-control/iam
// member string, role iam.RoleName
identity := "group:cloud-logs@google.com"
var role iam.RoleName = "roles/storage.objectViewer"
policy.Remove(identity, role)
if err := bucket.IAM().SetPolicy(ctx, policy); err != nil {
return fmt.Errorf("Bucket(%q).IAM().SetPolicy: %w", bucketName, err)
}
// NOTE: It may be necessary to retry this operation if IAM policies are
// being modified concurrently. SetPolicy will return an error if the policy
// was modified since it was retrieved.
fmt.Fprintf(w, "Removed %v with role %v from %v\n", identity, role, bucketName)
return nil
}
import com.google.cloud.Binding;
import com.google.cloud.Policy;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.util.ArrayList;
import java.util.List;
public class RemoveBucketIamMember {
public static void removeBucketIamMember(String projectId, String bucketName) {
// The ID of your GCP project
// String projectId = "your-project-id";
// The ID of your GCS bucket
// String bucketName = "your-unique-bucket-name";
// For more information please read:
// https://cloud.google.com/storage/docs/access-control/iam
Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
Policy originalPolicy =
storage.getIamPolicy(bucketName, Storage.BucketSourceOption.requestedPolicyVersion(3));
String role = "roles/storage.objectViewer";
String member = "group:example@google.com";
// getBindingsList() returns an ImmutableList and copying over to an ArrayList so it's mutable.
List<Binding> bindings = new ArrayList(originalPolicy.getBindingsList());
// Remove role-member binding without a condition.
for (int index = 0; index < bindings.size(); index++) {
Binding binding = bindings.get(index);
boolean foundRole = binding.getRole().equals(role);
boolean foundMember = binding.getMembers().contains(member);
boolean bindingIsNotConditional = binding.getCondition() == null;
if (foundRole && foundMember && bindingIsNotConditional) {
bindings.set(index, binding.toBuilder().removeMembers(member).build());
break;
}
}
// Update policy to remove member
Policy.Builder updatedPolicyBuilder = originalPolicy.toBuilder();
updatedPolicyBuilder.setBindings(bindings).setVersion(3);
Policy updatedPolicy = storage.setIamPolicy(bucketName, updatedPolicyBuilder.build());
System.out.printf("Removed %s with role %s from %s\n", member, role, bucketName);
}
}
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';
// The role to revoke
// const roleName = 'roles/storage.objectViewer';
// The members to revoke the roles from
// const members = [
// 'user:jdoe@example.com',
// 'group:admins@example.com',
// ];
// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');
// Creates a client
const storage = new Storage();
async function removeBucketIamMember() {
// Get a reference to a Google Cloud Storage bucket
const bucket = storage.bucket(bucketName);
// For more information please read:
// https://cloud.google.com/storage/docs/access-control/iam
const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
// Finds and updates the appropriate role-member group, without a condition.
const index = policy.bindings.findIndex(
binding => binding.role === roleName && !binding.condition
);
const role = policy.bindings[index];
if (role) {
role.members = role.members.filter(
member => members.indexOf(member) === -1
);
// Updates the policy object with the new (or empty) role-member group
if (role.members.length === 0) {
policy.bindings.splice(index, 1);
} else {
policy.bindings.index = role;
}
// Updates the bucket's IAM policy
await bucket.iam.setPolicy(policy);
} else {
// No matching role-member group(s) were found
throw new Error('No matching role-member group(s) found.');
}
console.log(
`Removed the following member(s) with role ${roleName} from ${bucketName}:`
);
members.forEach(member => {
console.log(` ${member}`);
});
}
removeBucketIamMember().catch(console.error);
use Google\Cloud\Storage\StorageClient;
/**
* Removes a member / role IAM pair from a given Cloud Storage bucket.
*
* @param string $bucketName The name of your Cloud Storage bucket.
* (e.g. 'my-bucket')
* @param string $role The role from which the specified member should be removed.
* (e.g. 'roles/storage.objectViewer')
* @param string $member The member to be removed from the specified role.
* (e.g. 'group:example@google.com')
*/
function remove_bucket_iam_member(string $bucketName, string $role, string $member): void
{
$storage = new StorageClient();
$bucket = $storage->bucket($bucketName);
$iam = $bucket->iam();
$policy = $iam->policy(['requestedPolicyVersion' => 3]);
$policy['version'] = 3;
foreach ($policy['bindings'] as $i => $binding) {
// This example only removes member from bindings without a condition.
if ($binding['role'] == $role && !isset($binding['condition'])) {
$key = array_search($member, $binding['members']);
if ($key !== false) {
unset($binding['members'][$key]);
// If the last member is removed from the binding, clean up the
// binding.
if (count($binding['members']) == 0) {
unset($policy['bindings'][$i]);
// Ensure array keys are sequential, otherwise JSON encodes
// the array as an object, which fails when calling the API.
$policy['bindings'] = array_values($policy['bindings']);
} else {
// Ensure array keys are sequential, otherwise JSON encodes
// the array as an object, which fails when calling the API.
$binding['members'] = array_values($binding['members']);
$policy['bindings'][$i] = $binding;
}
$iam->setPolicy($policy);
printf('User %s removed from role %s for bucket %s' . PHP_EOL, $member, $role, $bucketName);
return;
}
}
}
throw new \RuntimeException('No matching role-member group(s) found.');
}
from google.cloud import storage
def remove_bucket_iam_member(bucket_name, role, member):
"""Remove member from bucket IAM Policy"""
# bucket_name = "your-bucket-name"
# role = "IAM role, e.g. roles/storage.objectViewer"
# member = "IAM identity, e.g. user: name@example.com"
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
policy = bucket.get_iam_policy(requested_policy_version=3)
for binding in policy.bindings:
print(binding)
if binding["role"] == role and binding.get("condition") is None:
binding["members"].discard(member)
bucket.set_iam_policy(policy)
print(f"Removed {member} with role {role} from {bucket_name}.")
def remove_bucket_iam_member bucket_name:
# The ID of your GCS bucket
# bucket_name = "your-unique-bucket-name"
# For more information please read: https://cloud.google.com/storage/docs/access-control/iam
require "google/cloud/storage"
storage = Google::Cloud::Storage.new
bucket = storage.bucket bucket_name
role = "roles/storage.objectViewer"
member = "group:example@google.com"
bucket.policy requested_policy_version: 3 do |policy|
policy.bindings.each do |binding|
if binding.role == role && binding.condition.nil?
binding.members.delete member
end
end
end
puts "Removed #{member} with role #{role} from #{bucket_name}"
end
JSON_FILE_NAMEis the path for the file
that you created in Step 3.
BUCKET_NAMEis the name of the bucket from
which you want to remove access. For example,my-bucket.
Use IAM Conditions on buckets
The following sections show you how to add and removeIAM Conditionson your buckets. To view the
IAM Conditions for your bucket, seeViewing the IAM policy for a bucket. For more information
about using IAM Conditions with Cloud Storage, seeConditions.
In the list of buckets, click the name of the bucket that you want to add
a new condition for.
In theBucket detailspage, click thePermissionstab.
The IAM policy that applies to the bucket appears in
thePermissionssection.
Click+ Grant access.
ForNew principals, fill out the principals to which you want to grant
access to your bucket.
For each role to which you want to apply a condition:
Select aRoleto grant the principals.
ClickAdd conditionto open theEdit conditionform.
Fill out theTitleof the condition. TheDescriptionfield is
optional.
Use theCondition Builderto build your condition visually, or use theCondition Editortab to enter theCEL expression.
ClickSaveto return to theAdd principalform. To add
multiple roles, clickAdd another role.
ClickSave.
To learn how to get detailed error information about failed Cloud Storage
operations in the Google Cloud console, seeTroubleshooting.
Command line
Create a JSON or YAML file that defines the condition, including thetitleof the condition, theattribute-basedlogicexpressionfor the condition, and, optionally, adescriptionfor
the condition.
BUCKET_NAMEis the name of the bucket you are
granting the principal access to. For example,my-bucket.
PRINCIPAL_IDENTIFIERidentifies who the
condition applies to. For example,user:jane@gmail.com. For a
list of principal identifier formats, seePrincipal identifiers.
IAM_ROLEis theIAM roleyou are granting to the principal. For example,roles/storage.objectViewer.
CONDITION_FILEis the file you created in the
previous step.
Alternatively, you can include the condition directly in the command
with the--conditionflag instead of the--condition-from-fileflag.
using Google.Apis.Storage.v1.Data;
using Google.Cloud.Storage.V1;
using System;
using System.Collections.Generic;
public class AddBucketConditionalIamBindingSample
{
/// <summary>
/// Adds a conditional Iam policy to a bucket.
/// </summary>
/// <param name="bucketName">The name of the bucket.</param>
/// <param name="role">The role that members may assume.</param>
/// <param name="member">The identifier of the member who may assume the provided role.</param>
/// <param name="title">Title for the expression.</param>
/// <param name="description">Description of the expression.</param>
/// <param name="expression">Describes the conditions that need to be met for the policy to be applied.
/// It's represented as a string using Common Expression Language syntax.</param>
public Policy AddBucketConditionalIamBinding(
string bucketName = "your-unique-bucket-name",
string role = "roles/storage.objectViewer",
string member = "serviceAccount:dev@iam.gserviceaccount.com",
string title = "title",
string description = "description",
string expression = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")")
{
var storage = StorageClient.Create();
var policy = storage.GetBucketIamPolicy(bucketName, new GetBucketIamPolicyOptions
{
RequestedPolicyVersion = 3
});
// Set the policy schema version. For more information, please refer to https://cloud.google.com/iam/docs/policies#versions.
policy.Version = 3;
Policy.BindingsData bindingToAdd = new Policy.BindingsData
{
Role = role,
Members = new List<string> { member },
Condition = new Expr
{
Title = title,
Description = description,
Expression = expression
}
};
policy.Bindings.Add(bindingToAdd);
var bucketIamPolicy = storage.SetBucketIamPolicy(bucketName, policy);
Console.WriteLine($"Added {member} with role {role} " + $"to {bucketName}");
return bucketIamPolicy;
}
}
import com.google.cloud.Binding;
import com.google.cloud.Condition;
import com.google.cloud.Policy;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class AddBucketIamConditionalBinding {
/** Example of adding a conditional binding to the Bucket-level IAM */
public static void addBucketIamConditionalBinding(String projectId, String bucketName) {
// The ID of your GCP project
// String projectId = "your-project-id";
// The ID of your GCS bucket
// String bucketName = "your-unique-bucket-name";
// For more information please read:
// https://cloud.google.com/storage/docs/access-control/iam
Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
Policy originalPolicy =
storage.getIamPolicy(bucketName, Storage.BucketSourceOption.requestedPolicyVersion(3));
String role = "roles/storage.objectViewer";
String member = "group:example@google.com";
// Create a condition
String conditionTitle = "Title";
String conditionDescription = "Description";
String conditionExpression =
"resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")";
Condition.Builder conditionBuilder = Condition.newBuilder();
conditionBuilder.setTitle(conditionTitle);
conditionBuilder.setDescription(conditionDescription);
conditionBuilder.setExpression(conditionExpression);
// getBindingsList() returns an ImmutableList, we copy over to an ArrayList so it's mutable
List<Binding> bindings = new ArrayList(originalPolicy.getBindingsList());
// Add condition to a binding
Binding.Builder newBindingBuilder =
Binding.newBuilder()
.setRole(role)
.setMembers(Arrays.asList(member))
.setCondition(conditionBuilder.build());
bindings.add(newBindingBuilder.build());
// Update policy with new conditional binding
Policy.Builder updatedPolicyBuilder = originalPolicy.toBuilder();
updatedPolicyBuilder.setBindings(bindings).setVersion(3);
storage.setIamPolicy(bucketName, updatedPolicyBuilder.build());
System.out.printf(
"Added %s with role %s to %s with condition %s %s %s\n",
member, role, bucketName, conditionTitle, conditionDescription, conditionExpression);
}
}
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';
// The role to grant
// const roleName = 'roles/storage.objectViewer';
// The members to grant the new role to
// const members = [
// 'user:jdoe@example.com',
// 'group:admins@example.com',
// ];
// Create a condition
// const title = 'Title';
// const description = 'Description';
// const expression = 'resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")';
// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');
// Creates a client
const storage = new Storage();
async function addBucketConditionalBinding() {
// Get a reference to a Google Cloud Storage bucket
const bucket = storage.bucket(bucketName);
// Gets and updates the bucket's IAM policy
const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
// Set the policy's version to 3 to use condition in bindings.
policy.version = 3;
// Adds the new roles to the bucket's IAM policy
policy.bindings.push({
role: roleName,
members: members,
condition: {
title: title,
description: description,
expression: expression,
},
});
// Updates the bucket's IAM policy
await bucket.iam.setPolicy(policy);
console.log(
`Added the following member(s) with role ${roleName} to ${bucketName}:`
);
members.forEach(member => {
console.log(` ${member}`);
});
console.log('with condition:');
console.log(` Title: ${title}`);
console.log(` Description: ${description}`);
console.log(` Expression: ${expression}`);
}
addBucketConditionalBinding().catch(console.error);
use Google\Cloud\Storage\StorageClient;
/**
* Adds a conditional IAM binding to a bucket's IAM policy.
*
* @param string $bucketName The name of your Cloud Storage bucket.
* (e.g. 'my-bucket')
* @param string $role The role that will be given to members in this binding.
* (e.g. 'roles/storage.objectViewer')
* @param string[] $members The member(s) associated with this binding.
* (e.g. ['group:example@google.com'])
* @param string $title The title of the condition. (e.g. 'Title')
* @param string $description The description of the condition.
* (e.g. 'Condition Description')
* @param string $expression The condition specified in CEL expression language.
* (e.g. 'resource.name.startsWith("projects/_/buckets/bucket-name/objects/prefix-a-")')
*
* To see how to express a condition in CEL, visit:
* @see https://cloud.google.com/storage/docs/access-control/iam#conditions.
*/
function add_bucket_conditional_iam_binding(string $bucketName, string $role, array $members, string $title, string $description, string $expression): void
{
$storage = new StorageClient();
$bucket = $storage->bucket($bucketName);
$policy = $bucket->iam()->policy(['requestedPolicyVersion' => 3]);
$policy['version'] = 3;
$policy['bindings'][] = [
'role' => $role,
'members' => $members,
'condition' => [
'title' => $title,
'description' => $description,
'expression' => $expression,
],
];
$bucket->iam()->setPolicy($policy);
printf('Added the following member(s) with role %s to %s:' . PHP_EOL, $role, $bucketName);
foreach ($members as $member) {
printf(' %s' . PHP_EOL, $member);
}
printf('with condition:' . PHP_EOL);
printf(' Title: %s' . PHP_EOL, $title);
printf(' Description: %s' . PHP_EOL, $description);
printf(' Expression: %s' . PHP_EOL, $expression);
}
from google.cloud import storage
def add_bucket_conditional_iam_binding(
bucket_name, role, title, description, expression, members
):
"""Add a conditional IAM binding to a bucket's IAM policy."""
# bucket_name = "your-bucket-name"
# role = "IAM role, e.g. roles/storage.objectViewer"
# members = {"IAM identity, e.g. user: name@example.com}"
# title = "Condition title."
# description = "Condition description."
# expression = "Condition expression."
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
policy = bucket.get_iam_policy(requested_policy_version=3)
# Set the policy's version to 3 to use condition in bindings.
policy.version = 3
policy.bindings.append(
{
"role": role,
"members": members,
"condition": {
"title": title,
"description": description,
"expression": expression,
},
}
)
bucket.set_iam_policy(policy)
print(f"Added the following member(s) with role {role} to {bucket_name}:")
for member in members:
print(f" {member}")
print("with condition:")
print(f" Title: {title}")
print(f" Description: {description}")
print(f" Expression: {expression}")
VERSIONis theIAM policy version, which is required to be 3
for buckets with IAM Conditions.
IAM_ROLEis the role to which the condition
applies. For example,roles/storage.objectViewer.
PRINCIPAL_IDENTIFIERidentifies who the
condition applies to. For example,user:jane@gmail.com. For a list
of principal identifier formats, seePrincipal identifiers.
TITLEis the title of the condition. For
example,expires in 2019.
DESCRIPTIONis an optional description of
the condition. For example,Permission revoked on New Year's.
using Google.Apis.Storage.v1.Data;
using Google.Cloud.Storage.V1;
using System;
using System.Linq;
public class RemoveBucketConditionalIamBindingSample
{
public Policy RemoveBucketConditionalIamBinding(
string bucketName = "your-unique-bucket-name",
string role = "roles/storage.objectViewer",
string title = "title",
string description = "description",
string expression = "resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")")
{
var storage = StorageClient.Create();
var policy = storage.GetBucketIamPolicy(bucketName, new GetBucketIamPolicyOptions
{
RequestedPolicyVersion = 3
});
// Set the policy schema version. For more information, please refer to https://cloud.google.com/iam/docs/policies#versions.
policy.Version = 3;
var bindingsToRemove = policy.Bindings.Where(binding => binding.Role == role
&& binding.Condition != null
&& binding.Condition.Title == title
&& binding.Condition.Description == description
&& binding.Condition.Expression == expression).ToList();
if (bindingsToRemove.Count() > 0)
{
foreach (var binding in bindingsToRemove)
{
policy.Bindings.Remove(binding);
}
// Set the modified IAM policy to be the current IAM policy.
policy = storage.SetBucketIamPolicy(bucketName, policy);
Console.WriteLine("Conditional Binding was removed.");
}
else
{
Console.WriteLine("No matching conditional binding found.");
}
return policy;
}
}
import (
"context"
"fmt"
"io"
"time"
"cloud.google.com/go/storage"
)
// removeBucketConditionalIAMBinding removes bucket conditional IAM binding.
func removeBucketConditionalIAMBinding(w io.Writer, bucketName, role, title, description, expression string) error {
// bucketName := "bucket-name"
// role := "bucket-level IAM role"
// title := "condition title"
// description := "condition description"
// expression := "condition expression"
ctx := context.Background()
client, err := storage.NewClient(ctx)
if err != nil {
return fmt.Errorf("storage.NewClient: %w", err)
}
defer client.Close()
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
bucket := client.Bucket(bucketName)
policy, err := bucket.IAM().V3().Policy(ctx)
if err != nil {
return fmt.Errorf("Bucket(%q).IAM().V3().Policy: %w", bucketName, err)
}
// Find the index of the binding matching inputs.
i := -1
for j, binding := range policy.Bindings {
if binding.Role == role && binding.Condition != nil {
condition := binding.Condition
if condition.Title == title &&
condition.Description == description &&
condition.Expression == expression {
i = j
}
}
}
if i == -1 {
return fmt.Errorf("no matching binding group found")
}
// Get a slice of the bindings, removing the binding at index i.
policy.Bindings = append(policy.Bindings[:i], policy.Bindings[i+1:]...)
if err := bucket.IAM().V3().SetPolicy(ctx, policy); err != nil {
return fmt.Errorf("Bucket(%q).IAM().V3().SetPolicy: %w", bucketName, err)
}
// NOTE: It may be necessary to retry this operation if IAM policies are
// being modified concurrently. SetPolicy will return an error if the policy
// was modified since it was retrieved.
fmt.Fprintln(w, "Conditional binding was removed")
return nil
}
import com.google.cloud.Binding;
import com.google.cloud.Condition;
import com.google.cloud.Policy;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class RemoveBucketIamConditionalBinding {
/** Example of removing a conditional binding to the Bucket-level IAM */
public static void removeBucketIamConditionalBinding(String projectId, String bucketName) {
// The ID of your GCP project
// String projectId = "your-project-id";
// The ID of your GCS bucket
// String bucketName = "your-unique-bucket-name";
// For more information please read:
// https://cloud.google.com/storage/docs/access-control/iam
Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
Policy originalPolicy =
storage.getIamPolicy(bucketName, Storage.BucketSourceOption.requestedPolicyVersion(3));
String role = "roles/storage.objectViewer";
// getBindingsList() returns an ImmutableList and copying over to an ArrayList so it's mutable.
List<Binding> bindings = new ArrayList(originalPolicy.getBindingsList());
// Create a condition to compare against
Condition.Builder conditionBuilder = Condition.newBuilder();
conditionBuilder.setTitle("Title");
conditionBuilder.setDescription("Description");
conditionBuilder.setExpression(
"resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")");
Iterator iterator = bindings.iterator();
while (iterator.hasNext()) {
Binding binding = (Binding) iterator.next();
boolean foundRole = binding.getRole().equals(role);
boolean conditionsEqual = conditionBuilder.build().equals(binding.getCondition());
// Remove condition when the role and condition are equal
if (foundRole && conditionsEqual) {
iterator.remove();
break;
}
}
// Update policy to remove conditional binding
Policy.Builder updatedPolicyBuilder = originalPolicy.toBuilder();
updatedPolicyBuilder.setBindings(bindings).setVersion(3);
Policy updatedPolicy = storage.setIamPolicy(bucketName, updatedPolicyBuilder.build());
System.out.println("Conditional Binding was removed.");
}
}
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';
// The role to grant
// const roleName = 'roles/storage.objectViewer';
// The members to grant the new role to
// const members = [
// 'user:jdoe@example.com',
// 'group:admins@example.com',
// ];
// Create a condition
// const title = 'Title';
// const description = 'Description';
// const expression = 'resource.name.startsWith(\"projects/_/buckets/bucket-name/objects/prefix-a-\")';
// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');
// Creates a client
const storage = new Storage();
async function removeBucketConditionalBinding() {
// Get a reference to a Google Cloud Storage bucket
const bucket = storage.bucket(bucketName);
// Gets and updates the bucket's IAM policy
const [policy] = await bucket.iam.getPolicy({requestedPolicyVersion: 3});
// Set the policy's version to 3 to use condition in bindings.
policy.version = 3;
// Finds and removes the appropriate role-member group with specific condition.
const index = policy.bindings.findIndex(
binding =>
binding.role === roleName &&
binding.condition &&
binding.condition.title === title &&
binding.condition.description === description &&
binding.condition.expression === expression
);
const binding = policy.bindings[index];
if (binding) {
policy.bindings.splice(index, 1);
// Updates the bucket's IAM policy
await bucket.iam.setPolicy(policy);
console.log('Conditional Binding was removed.');
} else {
// No matching role-member group with specific condition were found
throw new Error('No matching binding group found.');
}
}
removeBucketConditionalBinding().catch(console.error);
use Google\Cloud\Storage\StorageClient;
/**
* Removes a conditional IAM binding from a bucket's IAM policy.
*
* To see how to express a condition in CEL, visit:
* @see https://cloud.google.com/storage/docs/access-control/iam#conditions.
*
* @param string $bucketName The name of your Cloud Storage bucket.
* (e.g. 'my-bucket')
* @param string $role the role that will be given to members in this binding.
* (e.g. 'roles/storage.objectViewer')
* @param string $title The title of the condition. (e.g. 'Title')
* @param string $description The description of the condition.
* (e.g. 'Condition Description')
* @param string $expression Te condition specified in CEL expression language.
* (e.g. 'resource.name.startsWith("projects/_/buckets/bucket-name/objects/prefix-a-")')
*/
function remove_bucket_conditional_iam_binding(string $bucketName, string $role, string $title, string $description, string $expression): void
{
$storage = new StorageClient();
$bucket = $storage->bucket($bucketName);
$policy = $bucket->iam()->policy(['requestedPolicyVersion' => 3]);
$policy['version'] = 3;
$key_of_conditional_binding = null;
foreach ($policy['bindings'] as $key => $binding) {
if ($binding['role'] == $role && isset($binding['condition'])) {
$condition = $binding['condition'];
if ($condition['title'] == $title
&& $condition['description'] == $description
&& $condition['expression'] == $expression) {
$key_of_conditional_binding = $key;
break;
}
}
}
if ($key_of_conditional_binding != null) {
unset($policy['bindings'][$key_of_conditional_binding]);
// Ensure array keys are sequential, otherwise JSON encodes
// the array as an object, which fails when calling the API.
$policy['bindings'] = array_values($policy['bindings']);
$bucket->iam()->setPolicy($policy);
print('Conditional Binding was removed.' . PHP_EOL);
} else {
print('No matching conditional binding found.' . PHP_EOL);
}
}
from google.cloud import storage
def remove_bucket_conditional_iam_binding(
bucket_name, role, title, description, expression
):
"""Remove a conditional IAM binding from a bucket's IAM policy."""
# bucket_name = "your-bucket-name"
# role = "IAM role, e.g. roles/storage.objectViewer"
# title = "Condition title."
# description = "Condition description."
# expression = "Condition expression."
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
policy = bucket.get_iam_policy(requested_policy_version=3)
# Set the policy's version to 3 to use condition in bindings.
policy.version = 3
condition = {
"title": title,
"description": description,
"expression": expression,
}
policy.bindings = [
binding
for binding in policy.bindings
if not (binding["role"] == role and binding.get("condition") == condition)
]
bucket.set_iam_policy(policy)
print("Conditional Binding was removed.")
WhereBUCKET_NAMEis the name of the bucket
whose IAM policy you want to modify. For example,my-bucket.
Best practices
You should set the minimum role needed to give the principal
the required access. For example, if a team member only needs to read
objects stored in a bucket, grant them the Storage Object Viewer
(roles/storage.objectViewer) role instead of the Storage Object Admin
(roles/storage.objectAdmin) role. Similarly, if the team member needs full
control of objects in the bucket but not the bucket itself, grant them the
Storage Object Admin (roles/storage.objectAdmin) role instead of the
Storage Admin (roles/storage.admin) role.