- Published on
IAM Policy to Allow Team Wide and User Level Permissions on AWS Secrets Manager
- Authors
- Name
- Ruan Bekker
- @ruanbekker
In this post we will simulate a scenario where a team would like to have access to create secrets under a team path name like /security-team/prod/*
and /security-team/dev/*
and allow all the users from that team to be able to write and read secrets from that path. Then have individual users create and read secrets from their own isolated path: /security-team/personal/aws-username/*
so they can create their personal secrets.
Our Scenario:
- Create IAM Policy
- Create 2 IAM Users:
jack.smith
andsteve.adams
- Create IAM Group, Associate IAM Policy to the Group
- Attach 2 Users to the Group
The IAM Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1541597166491",
"Action": [
"secretsmanager:CreateSecret",
"secretsmanager:DeleteSecret",
"secretsmanager:DescribeSecret",
"secretsmanager:GetRandomPassword",
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecretVersionIds",
"secretsmanager:ListSecrets",
"secretsmanager:PutSecretValue",
"secretsmanager:TagResource",
"secretsmanager:UpdateSecret"
],
"Effect": "Allow",
"Resource": [
"arn:aws:secretsmanager:eu-west-1:123456789012:secret:/security-team/prod/*",
"arn:aws:secretsmanager:eu-west-1:123456789012:secret:/security-team/dev/*",
"arn:aws:secretsmanager:eu-west-1:123456789012:secret:/security-team/personal/${aws:username}/*"
]
}
]
}
Either configure the access keys and secret keys into the credential provider using aws cli, or for this demonstration I will use them inside the code. But never hardcode your credentials.
Create Secrets with Secrets Manager in AWS using Python Boto3
Instantiate user1 and user2:
>>> import boto3
>>> jack = boto3.Session(aws_access_key_id='ya', aws_secret_access_key='xx', region_name='eu-west-1').client('secretsmanager')
>>> steve = boto3.Session(aws_access_key_id='yb', aws_secret_access_key='xx', region_name='eu-west-1').client('secretsmanager')
Create a team wide secret with jack:
>>> jack.create_secret(Name='/security-team/prod/app1/username', SecretString='appreader')
{'ResponseMetadata': {'RetryAttempts': 0, 'HTTPStatusCode': 200, 'RequestId': 'x', 'HTTPHeaders': {'date': 'Thu, 08 Nov 2018 07:50:35 GMT', 'x-amzn-requestid': 'x', 'content-length': '193', 'content-type': 'application/x-amz-json-1.1', 'connection': 'keep-alive'}}, u'VersionId': u'x', u'Name': u'/security-team/prod/app1/username', u'ARN': u'arn:aws:secretsmanager:eu-west-1:123456789012:secret:/security-team/prod/app1/username-12ABC00'}
Let jack and steve try to read the secret:
>>> jack.get_secret_value(SecretId='/security-team/prod/app1/username')['SecretString']
'appreader'
>>> steve.get_secret_value(SecretId='/security-team/prod/app1/username')['SecretString']
'appreader'
Now let jack create a personal secret, let him read it:
>>> jack.create_secret(Name='/security-team/personal/jack.smith/svc1/password', SecretString='secret')
>>> jack.get_secret_value(SecretId='/security-team/personal/jack.smith/svc1/password')['SecretString']
'secret'
Now let steve try to read the secret and you will see that access is denied:
>>> steve.get_secret_value(SecretId='/security-team/personal/jack.smith/username')['SecretString']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
...
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the GetSecretValue operation: User: arn:aws:iam::123456789012:user/steve.adams is not authorized to perform: secretsmanager:GetSecretValue on resource: arn:aws:secretsmanager:eu-west-1:123456789012:secret:/security-team/personal/jack.smith/svc1/password-a1234b
Thats it for this post
Thank You
Thanks for reading, feel free to check out my website, and subscribe to my newsletter or follow me at @ruanbekker on Twitter.
- Linktree: https://go.ruan.dev/links
- Patreon: https://go.ruan.dev/patreon