Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRIVERS-1746 Add native support for AWS IAM Roles for service accounts, EKS in particular #9

Merged
merged 6 commits into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ About
=====

MONGODB-AWS authentication support for PyMongo. pymongo-auth-aws uses
`botocore`_ and `requests`_.
`boto3`_, `botocore`_, and `requests`_.

Support / Feedback
==================
Expand Down
30 changes: 30 additions & 0 deletions pymongo_auth_aws/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from base64 import standard_b64encode
from collections import namedtuple

import boto3
import requests

from botocore.auth import SigV4Auth
Expand All @@ -45,6 +46,19 @@ def _aws_temp_credentials():
if access_key and secret_key:
return AwsCredential(
access_key, secret_key, os.environ.get('AWS_SESSION_TOKEN'))
# Check if environment variables exposed by IAM Roles for Service Accounts (IRSA) are present.
# See https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html for details.
irsa_web_id_file = os.getenv('AWS_WEB_IDENTITY_TOKEN_FILE')
irsa_role_arn = os.getenv('AWS_ROLE_ARN')
if irsa_web_id_file and irsa_role_arn:
try:
with open(irsa_web_id_file) as f:
irsa_web_id_token = f.read()
return _irsa_assume_role(irsa_role_arn, irsa_web_id_token, 'pymongo-auth-aws')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is RoleSessionName=pymongo-auth-aws important for your use case? Are we free to change this string in a future release without warning?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically, I'm wondering if we're going to need to standardize this name across all language apis for MongoDB. Perhaps "mongodb-aws" or "MONGODB-AWS" may be a better name?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html I believe this should be os.getenv('AWS_ROLE_SESSION_NAME'):

AWS_ROLE_SESSION_NAME
Specifies the name to attach to the role session. This value is provided to the RoleSessionName parameter when the AWS CLI calls the AssumeRole operation, and becomes part of the assumed role user ARN: arn:aws:sts::123456789012:assumed-role/role_name/role_session_name. This is an optional parameter. If you do not provide this value, a session name is generated automatically. This name appears in AWS CloudTrail logs for entries associated with this session.

If defined, this environment variable overrides the value for the profile setting role_session_name.

Used with the AWS_ROLE_ARN and AWS_WEB_IDENTITY_TOKEN_FILE environment variables.

For more information on using web identities, see Assume role with web identity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not wedded to the name, but I wouldn't count on that environment variable being present in all deployments. At present, AWS_ROLE_SESSION_NAME isn't provided by a default IRSA deployment; from https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html:

The Amazon EKS Pod Identity Webhook on the cluster watches for pods that are associated with service accounts with this annotation and applies the following environment variables to them.

AWS_ROLE_ARN=arn:aws:iam::111122223333:role/iam-role-name
AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token

So, would it make sense to check for this env var and default to pymongo-auth-aws if not set?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed a commit to handle this. If the user cares enough, they can specify the env var to suit their own bookkeeping purposes this way.

except Exception as exc:
raise PyMongoAuthAwsError(
'temporary MONGODB-AWS credentials could not be obtained, '
'error: %s' % (exc,))
# If the environment variable
# AWS_CONTAINER_CREDENTIALS_RELATIVE_URI is set then drivers MUST
# assume that it was set by an AWS ECS agent and use the URI
Expand Down Expand Up @@ -101,6 +115,22 @@ def _aws_temp_credentials():
return AwsCredential(temp_user, temp_password, token)


def _irsa_assume_role(role_arn, token, role_session_name):
"""Call sts:AssumeRoleWithWebIdentity and return temporary credentials."""
sts_client = boto3.client('sts')
resp = sts_client.assume_role_with_web_identity(
RoleArn=role_arn,
RoleSessionName=role_session_name,
WebIdentityToken=token
)
creds = resp['Credentials']
access_key = creds['AccessKeyId']
secret_key = creds['SecretAccessKey']
session_token = creds['SessionToken']

return AwsCredential(access_key, secret_key, session_token)


_AWS4_HMAC_SHA256 = 'AWS4-HMAC-SHA256'
_AWS_SERVICE = 'sts'

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
description="MONGODB-AWS authentication support for PyMongo",
long_description=LONG_DESCRIPTION,
packages=find_packages(exclude=['test']),
install_requires=['requests<3.0.0', 'botocore'],
install_requires=['requests<3.0.0', 'boto3', 'botocore'],
author="Shane Harvey",
author_email="drivers-python-noreply@mongodb.com",
url="https://github.com/mongodb/pymongo-auth-aws",
Expand Down