0
# IAM and Security
1
2
Identity and Access Management operations for controlling access to secrets. These operations integrate with Google Cloud IAM to provide fine-grained access control, allowing you to set policies, retrieve current policies, and test permissions on secret resources.
3
4
## Capabilities
5
6
### Setting IAM Policies
7
8
Sets the IAM policy for a secret, defining who can access the secret and what actions they can perform. Replaces the existing policy entirely.
9
10
```python { .api }
11
def set_iam_policy(self, request: SetIamPolicyRequest = None, **kwargs) -> Policy:
12
"""
13
Sets the access control policy on the specified secret.
14
15
Args:
16
request (SetIamPolicyRequest): The request object containing resource and policy.
17
resource (str): Required. The resource for which the policy is being specified.
18
Format: projects/*/secrets/*.
19
policy (Policy): Required. The policy to apply to the resource.
20
21
Returns:
22
Policy: The updated IAM policy.
23
24
Raises:
25
google.api_core.exceptions.NotFound: If the secret does not exist.
26
google.api_core.exceptions.InvalidArgument: If policy is malformed.
27
google.api_core.exceptions.PermissionDenied: If insufficient permissions.
28
"""
29
```
30
31
**Usage Example:**
32
33
```python
34
from google.iam.v1 import iam_policy_pb2
35
from google.iam.v1 import policy_pb2
36
37
# Create a policy granting secret accessor role
38
policy = policy_pb2.Policy()
39
40
# Add binding for service account
41
binding = policy_pb2.Binding()
42
binding.role = "roles/secretmanager.secretAccessor"
43
binding.members.append("serviceAccount:app@my-project.iam.gserviceaccount.com")
44
policy.bindings.append(binding)
45
46
# Add binding for user
47
user_binding = policy_pb2.Binding()
48
user_binding.role = "roles/secretmanager.viewer"
49
user_binding.members.append("user:developer@company.com")
50
policy.bindings.append(user_binding)
51
52
# Set the policy
53
request = iam_policy_pb2.SetIamPolicyRequest()
54
request.resource = "projects/my-project/secrets/api-key"
55
request.policy = policy
56
57
updated_policy = client.set_iam_policy(request=request)
58
print(f"Policy updated with {len(updated_policy.bindings)} bindings")
59
```
60
61
### Getting IAM Policies
62
63
Retrieves the current IAM policy for a secret, showing all current access permissions and role bindings.
64
65
```python { .api }
66
def get_iam_policy(self, request: GetIamPolicyRequest = None, **kwargs) -> Policy:
67
"""
68
Gets the access control policy for a secret.
69
70
Args:
71
request (GetIamPolicyRequest): The request object.
72
resource (str): Required. The resource for which the policy is being requested.
73
Format: projects/*/secrets/*.
74
options (GetPolicyOptions): Optional. Options for getting the policy.
75
76
Returns:
77
Policy: The current IAM policy for the resource.
78
79
Raises:
80
google.api_core.exceptions.NotFound: If the secret does not exist.
81
google.api_core.exceptions.PermissionDenied: If insufficient permissions.
82
"""
83
```
84
85
**Usage Example:**
86
87
```python
88
from google.iam.v1 import iam_policy_pb2
89
90
# Get current policy
91
request = iam_policy_pb2.GetIamPolicyRequest()
92
request.resource = "projects/my-project/secrets/api-key"
93
94
policy = client.get_iam_policy(request=request)
95
print(f"Current policy has {len(policy.bindings)} bindings")
96
97
for binding in policy.bindings:
98
print(f"Role: {binding.role}")
99
for member in binding.members:
100
print(f" Member: {member}")
101
if binding.condition:
102
print(f" Condition: {binding.condition.expression}")
103
```
104
105
### Testing IAM Permissions
106
107
Tests whether the caller has specified permissions on a secret. Useful for checking access before attempting operations.
108
109
```python { .api }
110
def test_iam_permissions(self, request: TestIamPermissionsRequest = None, **kwargs) -> TestIamPermissionsResponse:
111
"""
112
Returns permissions that a caller has on the specified secret.
113
114
Args:
115
request (TestIamPermissionsRequest): The request object.
116
resource (str): Required. The resource for which the policy detail is being requested.
117
Format: projects/*/secrets/*.
118
permissions (Sequence[str]): Required. The set of permissions to check for the resource.
119
120
Returns:
121
TestIamPermissionsResponse: Response containing permissions the caller has.
122
123
Raises:
124
google.api_core.exceptions.NotFound: If the secret does not exist.
125
google.api_core.exceptions.InvalidArgument: If permissions list is invalid.
126
google.api_core.exceptions.PermissionDenied: If insufficient permissions to test.
127
"""
128
```
129
130
**Usage Example:**
131
132
```python
133
from google.iam.v1 import iam_policy_pb2
134
135
# Test multiple permissions
136
request = iam_policy_pb2.TestIamPermissionsRequest()
137
request.resource = "projects/my-project/secrets/api-key"
138
request.permissions.extend([
139
"secretmanager.secrets.get",
140
"secretmanager.versions.access",
141
"secretmanager.secrets.update",
142
"secretmanager.secrets.delete"
143
])
144
145
response = client.test_iam_permissions(request=request)
146
print("Granted permissions:")
147
for permission in response.permissions:
148
print(f" {permission}")
149
150
# Check specific permission
151
has_access = "secretmanager.versions.access" in response.permissions
152
print(f"Can access secret data: {has_access}")
153
```
154
155
## Common IAM Roles
156
157
The following predefined roles are commonly used with Secret Manager:
158
159
### Predefined Roles
160
161
```python
162
# Common Secret Manager roles
163
ROLES = {
164
"roles/secretmanager.admin": "Full access to secrets and versions",
165
"roles/secretmanager.secretAccessor": "Access to secret data",
166
"roles/secretmanager.viewer": "Read secret and version metadata",
167
"roles/secretmanager.secretVersionAdder": "Add new secret versions",
168
"roles/secretmanager.secretVersionManager": "Manage secret version lifecycle"
169
}
170
```
171
172
### Permissions
173
174
```python
175
# Common permissions for testing
176
PERMISSIONS = [
177
"secretmanager.secrets.create", # Create secrets
178
"secretmanager.secrets.delete", # Delete secrets
179
"secretmanager.secrets.get", # Get secret metadata
180
"secretmanager.secrets.list", # List secrets
181
"secretmanager.secrets.update", # Update secret metadata
182
"secretmanager.versions.access", # Access secret data
183
"secretmanager.versions.add", # Add secret versions
184
"secretmanager.versions.destroy", # Destroy versions
185
"secretmanager.versions.disable", # Disable versions
186
"secretmanager.versions.enable", # Enable versions
187
"secretmanager.versions.get", # Get version metadata
188
"secretmanager.versions.list" # List versions
189
]
190
```
191
192
## Advanced IAM Features
193
194
### Conditional Access
195
196
Use IAM conditions to create more granular access controls:
197
198
```python
199
from google.type import expr_pb2
200
201
# Create conditional binding
202
binding = policy_pb2.Binding()
203
binding.role = "roles/secretmanager.secretAccessor"
204
binding.members.append("serviceAccount:app@my-project.iam.gserviceaccount.com")
205
206
# Add condition - only allow access during business hours
207
condition = expr_pb2.Expr()
208
condition.title = "Business hours only"
209
condition.description = "Allow access only during business hours (9 AM to 5 PM UTC)"
210
condition.expression = 'request.time.getHours() >= 9 && request.time.getHours() < 17'
211
binding.condition.CopyFrom(condition)
212
213
policy.bindings.append(binding)
214
```
215
216
### Policy Management Utilities
217
218
```python
219
def add_member_to_policy(policy, role, member):
220
"""Add a member to a specific role in the policy."""
221
for binding in policy.bindings:
222
if binding.role == role:
223
if member not in binding.members:
224
binding.members.append(member)
225
return
226
227
# Create new binding if role doesn't exist
228
new_binding = policy_pb2.Binding()
229
new_binding.role = role
230
new_binding.members.append(member)
231
policy.bindings.append(new_binding)
232
233
def remove_member_from_policy(policy, role, member):
234
"""Remove a member from a specific role in the policy."""
235
for binding in policy.bindings:
236
if binding.role == role and member in binding.members:
237
binding.members.remove(member)
238
break
239
240
# Usage example
241
policy = client.get_iam_policy(request=get_request)
242
add_member_to_policy(policy, "roles/secretmanager.secretAccessor",
243
"user:newuser@company.com")
244
245
# Update the policy
246
set_request = iam_policy_pb2.SetIamPolicyRequest()
247
set_request.resource = "projects/my-project/secrets/api-key"
248
set_request.policy = policy
249
client.set_iam_policy(request=set_request)
250
```
251
252
## Security Best Practices
253
254
### Principle of Least Privilege
255
256
```python
257
# Grant minimal necessary permissions
258
def setup_app_access(secret_resource, service_account):
259
"""Set up minimal access for an application service account."""
260
policy = client.get_iam_policy(resource=secret_resource)
261
262
# Only grant secretAccessor, not admin
263
add_member_to_policy(policy,
264
"roles/secretmanager.secretAccessor",
265
f"serviceAccount:{service_account}")
266
267
client.set_iam_policy(resource=secret_resource, policy=policy)
268
```
269
270
### Audit and Monitoring
271
272
```python
273
def audit_secret_access(secret_resource):
274
"""Audit who has access to a secret."""
275
policy = client.get_iam_policy(resource=secret_resource)
276
277
access_report = {
278
"secret": secret_resource,
279
"bindings": []
280
}
281
282
for binding in policy.bindings:
283
binding_info = {
284
"role": binding.role,
285
"members": list(binding.members),
286
"has_condition": bool(binding.condition)
287
}
288
if binding.condition:
289
binding_info["condition"] = binding.condition.expression
290
291
access_report["bindings"].append(binding_info)
292
293
return access_report
294
```
295
296
## Request Types
297
298
### SetIamPolicyRequest
299
300
```python { .api }
301
class SetIamPolicyRequest:
302
"""
303
Request message for SetIamPolicy method.
304
305
Attributes:
306
resource (str): Required. The resource for which the policy is being specified.
307
policy (Policy): Required. The policy to apply.
308
update_mask (FieldMask): Optional. Fields to update.
309
"""
310
resource: str
311
policy: Policy
312
update_mask: field_mask_pb2.FieldMask
313
```
314
315
### GetIamPolicyRequest
316
317
```python { .api }
318
class GetIamPolicyRequest:
319
"""
320
Request message for GetIamPolicy method.
321
322
Attributes:
323
resource (str): Required. The resource for which the policy is being requested.
324
options (GetPolicyOptions): Optional. Options for getting the policy.
325
"""
326
resource: str
327
options: GetPolicyOptions
328
```
329
330
### TestIamPermissionsRequest
331
332
```python { .api }
333
class TestIamPermissionsRequest:
334
"""
335
Request message for TestIamPermissions method.
336
337
Attributes:
338
resource (str): Required. The resource for which the policy detail is being requested.
339
permissions (Sequence[str]): Required. The set of permissions to check.
340
"""
341
resource: str
342
permissions: Sequence[str]
343
```
344
345
### TestIamPermissionsResponse
346
347
```python { .api }
348
class TestIamPermissionsResponse:
349
"""
350
Response message for TestIamPermissions method.
351
352
Attributes:
353
permissions (Sequence[str]): The permissions that the caller has on the resource.
354
"""
355
permissions: Sequence[str]
356
```