From: Pritha Srivastava Date: Tue, 11 Sep 2018 05:40:33 +0000 (+0530) Subject: rgw: Adding documentation for STS Lite. X-Git-Tag: v14.0.1~113^2~6 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=15efabc78d85d40d579ff812d6f93bfd0cdd46d2;p=ceph-ci.git rgw: Adding documentation for STS Lite. Signed-off-by: Pritha Srivastava --- diff --git a/doc/radosgw/STSLite.rst b/doc/radosgw/STSLite.rst new file mode 100644 index 00000000000..3ce53a5b38e --- /dev/null +++ b/doc/radosgw/STSLite.rst @@ -0,0 +1,214 @@ +========= +STS Lite +========= + +Ceph Object Gateway provides support for a subset of Amazon Secure Token Service +(STS) APIs. STS Lite provides access to a set of temporary credentials for +Identity and Access Management. + +STS authentication mechanism has been integrated with Keystone in Ceph Object +Gateway. A set of temporary security credentials is returned after authenticating +a set of AWS credentials with Keystone. These temporary credentials can be used +to make subsequent S3 calls which will be authenticated by the STS engine, +resulting in less load on the Keystone server. + +STS Lite REST APIs +================== + +The following STS Lite REST APIs have been implemented in Ceph Object Gateway: + +1. GetSessionToken: Returns a set of temporary credentials for a set of AWS +credentials. This API can be used for initial authentication with Keystone +and the temporary credentials returned can be used to make subsequent S3 +calls. The temporary credentials will have the same permission as that of the +AWS credentials. + +Parameters: + **DurationSeconds** (Integer/ Optional): The duration in seconds for which the + credentials should remain valid. Its default value is 3600. Its default max + value is 43200 which is can be configured using rgw sts max session duration. + + **SerialNumber** (String/ Optional): The Id number of the MFA device associated + with the user making the GetSessionToken call. + + **TokenCode** (String/ Optional): The value provided by the MFA device, if the + trust policy of the role being assumed requires MFA. + + +2. AssumeRole: Returns a set of temporary credentials that can be used for +cross-account access. The temporary credentials will have permissions that are +allowed by both - permission policies attached with the Role and policy attached +with the AssumeRole API. + +Parameters: + **RoleArn** (String/ Required): ARN of the Role to Assume. + + **RoleSessionName** (String/ Required): An Identifier for the assumed role + session. + + **Policy** (String/ Optional): An IAM Policy in JSON format. + + **DurationSeconds** (Integer/ Optional): The duration in seconds of the session. + Its default value is 3600. + + **ExternalId** (String/ Optional): A unique Id that might be used when a role is + assumed in another account. + + **SerialNumber** (String/ Optional): The Id number of the MFA device associated + with the user making the AssumeRole call. + + **TokenCode** (String/ Optional): The value provided by the MFA device, if the + trust policy of the role being assumed requires MFA. + + +STS Lite Configuration +====================== + +The following configurable options are available for STS Lite integration:: + + [client.radosgw.gateway] + rgw sts key = {sts key for encrypting the session token} + rgw s3 auth use sts = true + +The above STS configurables can be used with the Keystone configurables if one +needs to use STS Lite in conjunction with Keystone. The complete set of +configurable options will be:: + + [client.radosgw.gateway] + rgw sts key = {sts key for encrypting/ decrypting the session token} + rgw s3 auth use sts = true + + rgw keystone url = {keystone server url:keystone server admin port} + rgw keystone admin project = {keystone admin project name} + rgw keystone admin tenant = {keystone service tenant name} + rgw keystone admin domain = {keystone admin domain name} + rgw keystone api version = {keystone api version} + rgw keystone implicit tenants = {true for private tenant for each new user} + rgw keystone admin password = {keystone service tenant user name} + rgw keystone admin user = keystone service tenant user password} + rgw keystone accepted roles = {accepted user roles} + rgw keystone token cache size = {number of tokens to cache} + rgw keystone revocation interval = {number of seconds before checking revoked tickets} + rgw s3 auth use keystone = true + rgw nss db path = {path to nss db} + +Note: By default, STS and S3 APIs co-exist in the same namespace, and both S3 +and STS APIs can be accessed via the same endpoint in Ceph Object Gateway. + +Example showing how to Use STS Lite with Keystone +================================================= + +The following are the steps needed to use STS Lite with Keystone. Boto 3.x has +been used to write an example code to show the integration of STS Lite with +Keystone. + +1. Generate EC2 credentials : + +.. code-block:: javascript + + openstack ec2 credentials create + +------------+--------------------------------------------------------+ + | Field | Value | + +------------+--------------------------------------------------------+ + | access | b924dfc87d454d15896691182fdeb0ef | + | links | {u'self': u'http://192.168.0.15/identity/v3/users/ | + | | 40a7140e424f493d8165abc652dc731c/credentials/ | + | | OS-EC2/b924dfc87d454d15896691182fdeb0ef'} | + | project_id | c703801dccaf4a0aaa39bec8c481e25a | + | secret | 6a2142613c504c42a94ba2b82147dc28 | + | trust_id | None | + | user_id | 40a7140e424f493d8165abc652dc731c | + +------------+--------------------------------------------------------+ + +2. Use the credentials created in the step 1. to get back a set of temporary + credentials using GetSessionToken API. + +.. code-block:: python + + import boto3 + + access_key = + secret_key = + + client = boto3.client('sts', + aws_access_key_id=access_key, + aws_secret_access_key=secret_key, + endpoint_url=, + region_name='', + ) + + response = client.get_session_token( + DurationSeconds=43200 + ) + +3. The temporary credentials obtained in step 2. can be used for making S3 calls: + +.. code-block:: python + + s3client = boto3.client('s3', + aws_access_key_id = response['Credentials']['AccessKeyId'], + aws_secret_access_key = response['Credentials']['SecretAccessKey'], + aws_session_token = response['Credentials']['SessionToken'], + endpoint_url=, + region_name='') + + bucket = s3client.create_bucket(Bucket='my-new-shiny-bucket') + response = s3client.list_buckets() + for bucket in response["Buckets"]: + print "{name}\t{created}".format( + name = bucket['Name'], + created = bucket['CreationDate'], + ) + +Limitations and Workarounds +=========================== + +1. Keystone currently supports only S3 requests, hence in order to successfully +authenticate an STS request, the following workaround needs to be added to boto +to the following file - botocore/auth.py + +Lines 13-16 have been added as a workaround in the code block below: + +.. code-block:: python + + class SigV4Auth(BaseSigner): + """ + Sign a request with Signature V4. + """ + REQUIRES_REGION = True + + def __init__(self, credentials, service_name, region_name): + self.credentials = credentials + # We initialize these value here so the unit tests can have + # valid values. But these will get overriden in ``add_auth`` + # later for real requests. + self._region_name = region_name + if service_name == 'sts': + self._service_name = 's3' + else: + self._service_name = service_name + +2. Currently boto does not include the payload hash with the request, but uses +it to calculate the signature for STS requests, which results in an incorrect +signature at the server side. The workaround is to send the payload hash in the +request itself. The changes are in the file – botocore/auth.py. + +Lines 14-15 have been added as a workaround in the code block below: + +.. code-block:: python + + def _modify_request_before_signing(self, request): + if 'Authorization' in request.headers: + del request.headers['Authorization'] + self._set_necessary_date_headers(request) + if self.credentials.token: + if 'X-Amz-Security-Token' in request.headers: + del request.headers['X-Amz-Security-Token'] + request.headers['X-Amz-Security-Token'] = self.credentials.token + + if not request.context.get('payload_signing_enabled', True): + if 'X-Amz-Content-SHA256' in request.headers: + del request.headers['X-Amz-Content-SHA256'] + request.headers['X-Amz-Content-SHA256'] = UNSIGNED_PAYLOAD + else: + request.headers['X-Amz-Content-SHA256'] = self.payload(request) diff --git a/doc/radosgw/index.rst b/doc/radosgw/index.rst index 59ea7b4ba1b..13ccc76565b 100644 --- a/doc/radosgw/index.rst +++ b/doc/radosgw/index.rst @@ -61,6 +61,7 @@ you may write data with one API and retrieve it with the other. Multi factor authentication Sync Modules Data Layout in RADOS + STS Lite troubleshooting Manpage radosgw <../../man/8/radosgw> Manpage radosgw-admin <../../man/8/radosgw-admin>