Skip to content

Commit 8ab4153

Browse files
sethvargokurtisvg
andauthored
Add Secret Manager IAM samples (GoogleCloudPlatform#2749)
* Add Secret Manager IAM samples * Use an envvar for the iam user * Add env var to secrets. Co-authored-by: Kurtis Van Gent <[email protected]>
1 parent ee73ade commit 8ab4153

File tree

6 files changed

+213
-1
lines changed

6 files changed

+213
-1
lines changed

secretmanager/api-client/README.rst

+58
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,64 @@ To run this sample:
280280
281281
282282
283+
IAM Grant Access
284+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
285+
286+
.. image:: https://gstatic.com/cloudssh/images/open-btn.png
287+
:target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=secretmanager/api-client/iam_grant_access.py,secretmanager/api-client/README.rst
288+
289+
290+
291+
292+
To run this sample:
293+
294+
.. code-block:: bash
295+
296+
$ python iam_grant_access.py
297+
298+
usage: iam_grant_access.py [-h] project_id secret_id member
299+
300+
command line application and sample code for granting access to a secret.
301+
302+
positional arguments:
303+
project_id id of the GCP project
304+
secret_id id of the secret to get
305+
member member to grant access
306+
307+
optional arguments:
308+
-h, --help show this help message and exit
309+
310+
311+
312+
IAM Revoke Access
313+
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
314+
315+
.. image:: https://gstatic.com/cloudssh/images/open-btn.png
316+
:target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=secretmanager/api-client/iam_revoke_access.py,secretmanager/api-client/README.rst
317+
318+
319+
320+
321+
To run this sample:
322+
323+
.. code-block:: bash
324+
325+
$ python iam_revoke_access.py
326+
327+
usage: iam_revoke_access.py [-h] project_id secret_id member
328+
329+
command line application and sample code for revoking access to a secret.
330+
331+
positional arguments:
332+
project_id id of the GCP project
333+
secret_id id of the secret to get
334+
member member to revoke access
335+
336+
optional arguments:
337+
-h, --help show this help message and exit
338+
339+
340+
283341
Get Secret
284342
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
285343

secretmanager/api-client/README.rst.in

+6
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ samples:
3636
- name: Get Secret Version
3737
file: get_secret_version.py
3838
show_help: True
39+
- name: IAM Grant Access
40+
file: iam_grant_access.py
41+
show_help: True
42+
- name: IAM Revoke Access
43+
file: iam_revoke_access.py
44+
show_help: True
3945
- name: Get Secret
4046
file: get_secret.py
4147
show_help: True
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2020 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
"""
16+
command line application and sample code for granting access to a secret.
17+
"""
18+
19+
import argparse
20+
21+
22+
# [START secretmanager_iam_grant_access]
23+
def iam_grant_access(project_id, secret_id, member):
24+
"""
25+
Grant the given member access to a secret.
26+
"""
27+
28+
# Import the Secret Manager client library.
29+
from google.cloud import secretmanager_v1beta1 as secretmanager
30+
31+
# Create the Secret Manager client.
32+
client = secretmanager.SecretManagerServiceClient()
33+
34+
# Build the resource name of the secret.
35+
name = client.secret_path(project_id, secret_id)
36+
37+
# Get the current IAM policy.
38+
policy = client.get_iam_policy(name)
39+
40+
# Add the given member with access permissions.
41+
policy.bindings.add(
42+
role='roles/secretmanager.secretAccessor',
43+
members=[member])
44+
45+
# Update the IAM Policy.
46+
new_policy = client.set_iam_policy(name, policy)
47+
48+
# Print data about the secret.
49+
print('Updated IAM policy on {}'.format(secret_id))
50+
# [END secretmanager_iam_grant_access]
51+
52+
return new_policy
53+
54+
55+
if __name__ == '__main__':
56+
parser = argparse.ArgumentParser(
57+
description=__doc__,
58+
formatter_class=argparse.RawDescriptionHelpFormatter)
59+
parser.add_argument('project_id', help='id of the GCP project')
60+
parser.add_argument('secret_id', help='id of the secret to get')
61+
parser.add_argument('member', help='member to grant access')
62+
args = parser.parse_args()
63+
64+
iam_grant_access(args.project_id, args.secret_id, args.member)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2020 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
"""
16+
command line application and sample code for revoking access to a secret.
17+
"""
18+
19+
import argparse
20+
21+
22+
# [START secretmanager_iam_revoke_access]
23+
def iam_revoke_access(project_id, secret_id, member):
24+
"""
25+
Revoke the given member access to a secret.
26+
"""
27+
28+
# Import the Secret Manager client library.
29+
from google.cloud import secretmanager_v1beta1 as secretmanager
30+
31+
# Create the Secret Manager client.
32+
client = secretmanager.SecretManagerServiceClient()
33+
34+
# Build the resource name of the secret.
35+
name = client.secret_path(project_id, secret_id)
36+
37+
# Get the current IAM policy.
38+
policy = client.get_iam_policy(name)
39+
40+
# Remove the given member's access permissions.
41+
accessRole = 'roles/secretmanager.secretAccessor'
42+
for b in list(policy.bindings):
43+
if b.role == accessRole and member in b.members:
44+
b.members.remove(member)
45+
46+
# Update the IAM Policy.
47+
new_policy = client.set_iam_policy(name, policy)
48+
49+
# Print data about the secret.
50+
print('Updated IAM policy on {}'.format(secret_id))
51+
# [END secretmanager_iam_revoke_access]
52+
53+
return new_policy
54+
55+
56+
if __name__ == '__main__':
57+
parser = argparse.ArgumentParser(
58+
description=__doc__,
59+
formatter_class=argparse.RawDescriptionHelpFormatter)
60+
parser.add_argument('project_id', help='id of the GCP project')
61+
parser.add_argument('secret_id', help='id of the secret to get')
62+
parser.add_argument('member', help='member to revoke access')
63+
args = parser.parse_args()
64+
65+
iam_revoke_access(args.project_id, args.secret_id, args.member)

secretmanager/api-client/snippets_test.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@
2323
from destroy_secret_version import destroy_secret_version
2424
from disable_secret_version import disable_secret_version
2525
from enable_secret_version import enable_secret_version
26-
from get_secret_version import get_secret_version
2726
from get_secret import get_secret
27+
from get_secret_version import get_secret_version
28+
from iam_grant_access import iam_grant_access
29+
from iam_revoke_access import iam_revoke_access
2830
from list_secret_versions import list_secret_versions
2931
from list_secrets import list_secrets
3032
from update_secret import update_secret
@@ -43,6 +45,11 @@ def project_id():
4345
return os.environ['GCLOUD_PROJECT']
4446

4547

48+
@pytest.fixture()
49+
def iam_user():
50+
return 'serviceAccount:' + os.environ['GCLOUD_SECRETS_SERVICE_ACCOUNT']
51+
52+
4653
@pytest.fixture()
4754
def secret(client, project_id):
4855
parent = client.project_path(project_id)
@@ -145,6 +152,18 @@ def test_get_secret(client, secret):
145152
assert secret_id in snippet_secret.name
146153

147154

155+
def test_iam_grant_access(client, secret, iam_user):
156+
project_id, secret_id = secret
157+
policy = iam_grant_access(project_id, secret_id, iam_user)
158+
assert any(iam_user in b.members for b in policy.bindings)
159+
160+
161+
def test_iam_revoke_access(client, secret, iam_user):
162+
project_id, secret_id = secret
163+
policy = iam_revoke_access(project_id, secret_id, iam_user)
164+
assert not any(iam_user in b.members for b in policy.bindings)
165+
166+
148167
def test_list_secret_versions(capsys, secret_version, another_secret_version):
149168
project_id, secret_id, version_id = secret_version
150169
_, _, another_version_id = another_secret_version

testing/secrets.tar.enc

-512 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)