]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw: adding documentation for AssumeRoleWithWebIdentity.
authorPritha Srivastava <prsrivas@redhat.com>
Wed, 4 Dec 2019 04:57:05 +0000 (10:27 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Fri, 13 Dec 2019 05:14:04 +0000 (10:44 +0530)
Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
doc/radosgw/STS.rst [new file with mode: 0644]
doc/radosgw/STSLite.rst
doc/radosgw/index.rst
doc/radosgw/keycloak.rst [new file with mode: 0644]

diff --git a/doc/radosgw/STS.rst b/doc/radosgw/STS.rst
new file mode 100644 (file)
index 0000000..0fbe41d
--- /dev/null
@@ -0,0 +1,212 @@
+===========
+STS in Ceph
+===========
+
+Secure Token Service is a web service in AWS that returns a set of temporary security credentials for authenticating federated users.
+The link to official AWS documentation can be found here: https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html.
+
+Ceph Object Gateway implements a subset of STS APIs that provide temporary credentials for identity and access management.
+These temporary credentials can be used to make subsequent S3 calls which will be authenticated by the STS engine in Ceph Object Gateway.
+Permissions of the temporary credentials can be further restricted via an IAM policy passed as a parameter to the STS APIs.
+
+STS REST APIs
+=============
+
+The following STS REST APIs have been implemented in Ceph Object Gateway:
+
+1. 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.
+
+2. AssumeRoleWithWebIdentity: Returns a set of temporary credentials for users that
+have been authenticated by a web/mobile app by an OpenID Connect /OAuth2.0 Identity Provider.
+Currently Keycloak has been tested and integrated with RGW.
+
+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.
+
+    **ProviderId** (String/ Optional): Fully qualified host component of the domain name
+    of the IDP. Valid only for OAuth2.0 tokens (not for OpenID Connect tokens).
+
+    **WebIdentityToken** (String/ Required): The OpenID Connect/ OAuth2.0 token, which the
+    application gets in return after authenticating its user with an IDP.
+
+STS Configuration
+=================
+
+The following configurable options have to be added for STS integration::
+
+  [client.radosgw.gateway]
+  rgw sts key = {sts key for encrypting the session token}
+  rgw s3 auth use sts = true
+
+The following additional configurables have to be added to use Keycloak for
+AssumeRoleWithWebIdentity calls::
+
+  [client.radosgw.gateway]
+  rgw_sts_token_introspection_url = {token introspection URL}
+  rgw_sts_client_id = {client id registered with Keycloak}
+  rgw_sts_client_secret = {client password registered with Keycloak}
+
+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.
+
+Examples
+========
+
+1. The following is an example of AssumeRole API call, which shows steps to create a role, assign a policy to it
+(that allows access to S3 resources), assuming a role to get temporary credentials and accessing s3 resources using
+those credentials. In this example, TESTER1 assumes a role created by TESTER, to access S3 resources owned by TESTER,
+according to the permission policy attached to the role.
+
+.. code-block:: python
+
+    import boto3
+
+    iam_client = boto3.client('iam',
+    aws_access_key_id=<access_key of TESTER>,
+    aws_secret_access_key=<secret_key of TESTER>,
+    endpoint_url=<IAM URL>,
+    region_name=''
+    )
+
+    policy_document = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"arn:aws:iam:::user/TESTER1\"]},\"Action\":[\"sts:AssumeRole\"]}]}"
+
+    role_response = iam_client.create_role(
+    AssumeRolePolicyDocument=policy_document,
+    Path='/',
+    RoleName='S3Access',
+    )
+
+    role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"s3:*\",\"Resource\":\"arn:aws:s3:::*\"}}"
+
+    response = iam_client.put_role_policy(
+    RoleName='S3Access',
+    PolicyName='Policy1',
+    PolicyDocument=role_policy
+    )
+
+    sts_client = boto3.client('sts',
+    aws_access_key_id=<access_key of TESTER1>,
+    aws_secret_access_key=<secret_key of TESTER1>,
+    endpoint_url=<STS URL>,
+    region_name='',
+    )
+
+    response = sts_client.assume_role(
+    RoleArn=role_response['Role']['Arn'],
+    RoleSessionName='Bob',
+    DurationSeconds=3600
+    )
+
+    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=<S3 URL>,
+    region_name='',)
+
+    bucket_name = 'my-bucket'
+    s3bucket = s3client.create_bucket(Bucket=bucket_name)
+    resp = s3client.list_buckets()
+
+2. The following is an example of AssumeRoleWithWebIdentity API call, where an external app that has users authenticated with
+an OpenID Connect/ OAuth2 IDP (Keycloak in this example), assumes a role to get back temporary credentials and access S3 resources
+according to permission policy of the role.
+
+.. code-block:: python
+
+    import boto3
+
+    iam_client = boto3.client('iam',
+    aws_access_key_id=<access_key of TESTER>,
+    aws_secret_access_key=<secret_key of TESTER>,
+    endpoint_url=<IAM URL>,
+    region_name=''
+    )
+
+    policy_document = "{\"Version\":\"2012-10-17\",\"Statement\":\[\{\"Effect\":\"Allow\",\"Principal\":\{\"Federated\":\[\"arn:aws:iam:::oidc-provider/localhost:8080/auth/realms/demo\"\]\},\"Action\":\[\"sts:AssumeRoleWithWebIdentity\"\],\"Condition\":\{\"StringEquals\":\{\"localhost:8080/auth/realms/demo:app_id\":\"customer-portal\"\}\}\}\]\}"
+    role_response = iam_client.create_role(
+    AssumeRolePolicyDocument=policy_document,
+    Path='/',
+    RoleName='S3Access',
+    )
+
+    role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"s3:*\",\"Resource\":\"arn:aws:s3:::*\"}}"
+
+    response = iam_client.put_role_policy(
+        RoleName='S3Access',
+        PolicyName='Policy1',
+        PolicyDocument=role_policy
+    )
+
+    sts_client = boto3.client('sts',
+    aws_access_key_id=<access_key of TESTER1>,
+    aws_secret_access_key=<secret_key of TESTER1>,
+    endpoint_url=<STS URL>,
+    region_name='',
+    )
+
+    response = client.assume_role_with_web_identity(
+    RoleArn=role_response['Role']['Arn'],
+    RoleSessionName='Bob',
+    DurationSeconds=3600,
+    WebIdentityToken=<Web Token>
+    )
+
+    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=<S3 URL>,
+    region_name='',)
+
+    bucket_name = 'my-bucket'
+    s3bucket = s3client.create_bucket(Bucket=bucket_name)
+    resp = s3client.list_buckets()
+
+Roles in RGW
+============
+
+More information for role manipulation can be found here
+:doc:`role`.
+
+Keycloak integration with Radosgw
+=================================
+
+Steps for integrating Radosgw with Keycloak can be found here
+:doc:`keycloak`.
+
+STSLite
+=======
+STSLite has been built on STS, and documentation for the same can be found here
+:doc:`STSLite`.
\ No newline at end of file
index cc34e305f85f6d1da969917cf21da174620d691b..350e36bc6100f72b1180689ca3d812c0c665efac 100644 (file)
@@ -3,25 +3,26 @@ 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) APIs. STS Lite is an extension of STS and builds upon one of its APIs to
+decrease the load on external IDPs like Keystone and LDAP.
 
-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.
+A set of temporary security credentials is returned after authenticating
+a set of AWS credentials with the external IDP. These temporary credentials can be used
+to make subsequent S3 calls which will be authenticated by the STS engine in Ceph,
+resulting in less load on the Keystone/ LDAP server.
+
+Temporary and limited privileged credentials can be obtained for a local user
+also using the STS Lite API.
 
 STS Lite REST APIs
 ==================
 
-The following STS Lite REST APIs have been implemented in Ceph Object Gateway:
+The following STS Lite REST API is part of STS Lite 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.
+credentials. After initial authentication with Keystone/ LDAP, 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
@@ -44,32 +45,6 @@ The user attaching the policy needs to have admin caps. For example::
 
     radosgw-admin caps add --uid="TESTER" --caps="user-policy=*"
 
-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
 ======================
 
@@ -99,6 +74,26 @@ configurable options will be::
   rgw keystone token cache size = {number of tokens to cache}
   rgw s3 auth use keystone = true
 
+The details of the integrating ldap with Ceph Object Gateway can be found here:
+:doc:`keystone`
+
+The complete set of configurables to use STS Lite with LDAP are::
+
+  [client.radosgw.gateway]
+  rgw sts key = {sts key for encrypting/ decrypting the session token}
+  rgw s3 auth use sts = true
+
+  rgw_s3_auth_use_ldap = true
+  rgw_ldap_uri = {LDAP server to use}
+  rgw_ldap_binddn = {Distinguished Name (DN) of the service account}
+  rgw_ldap_secret = {password for the service account}
+  rgw_ldap_searchdn = {base in the directory information tree for searching users}
+  rgw_ldap_dnattr = {attribute being used in the constructed search filter to match a username}
+  rgw_ldap_searchfilter = {search filter}
+
+The details of the integrating ldap with Ceph Object Gateway can be found here:
+:doc:`ldap-auth`
+
 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.
 
@@ -167,30 +162,7 @@ Keystone.
                     created = bucket['CreationDate'],
     )
 
-4. The following is an example of AssumeRole API call:
-
-.. code-block:: python
-
-    import boto3
-
-    access_key = <ec2 access key>
-    secret_key = <ec2 secret key>
-
-    client = boto3.client('sts',
-    aws_access_key_id=access_key,
-    aws_secret_access_key=secret_key,
-    endpoint_url=<STS URL>,
-    region_name='',
-    )
-
-    response = client.assume_role(
-    RoleArn='arn:aws:iam:::role/application_abc/component_xyz/S3Access',
-    RoleSessionName='Bob',
-    DurationSeconds=3600
-    )
-
-
-Note: A role 'S3Access', needs to be created before calling the AssumeRole API.
+Similar steps can be performed for using GetSessionToken with LDAP.
 
 Limitations and Workarounds
 ===========================
index 22b882f3ed06fc22f4602e994c9b7ae45601093d..86957c5f7651ed817a958373c90144723142f205 100644 (file)
@@ -64,7 +64,9 @@ you may write data with one API and retrieve it with the other.
    Sync Modules <sync-modules>
    Bucket Notifications <notifications>
    Data Layout in RADOS <layout>
+   STS <STS>
    STS Lite <STSLite>
+   Keycloak <keycloak>
    Role <role>
    troubleshooting
    Manpage radosgw <../../man/8/radosgw>
diff --git a/doc/radosgw/keycloak.rst b/doc/radosgw/keycloak.rst
new file mode 100644 (file)
index 0000000..b160c43
--- /dev/null
@@ -0,0 +1,56 @@
+=================================
+Keycloak integration with RadosGW
+=================================
+
+Keycloak can be setup as an OpenID Connect Identity Provider, which can be used by mobile/ web apps
+to authenticate their users. The Web token returned as a result of authentication can be used by the
+mobile/ web app to call AssumeRoleWithWebIdentity to get back a set of temporary S3 credentials,
+which can be used by the app to make S3 calls.
+
+Setting up Keycloak
+====================
+
+Installing and bringing up Keycloak can be found here: https://www.keycloak.org/docs/latest/server_installation/.
+
+Configuring Keycloak to talk to RGW
+===================================
+
+The following configurables have to be added for RGW to talk to Keycloak. 
+The format of token inspection url is https://[base-server-url]/token/introspect::
+
+  [client.radosgw.gateway]
+  rgw sts key = {sts key for encrypting/ decrypting the session token}
+  rgw s3 auth use sts = true
+  rgw_sts_token_introspection_url = {url for token introspection}
+  rgw_sts_client_id = {client-id}
+  rgw_sts_client_secret = {client-password}
+
+Example showing how to fetch a web token from Keycloak
+======================================================
+
+Several examples of apps authenticating with Keycloak are given here: https://github.com/keycloak/keycloak/tree/master/examples/demo-template
+Taking the example of customer-portal app given in the link above, its client secret and client password, can be used to fetch the
+access token (web token) as given below::
+
+    KC_REALM=demo
+    KC_CLIENT=customer-portal
+    KC_CLIENT_SECRET=password
+    KC_SERVER=<host>:8080
+    KC_CONTEXT=auth
+
+    # Request Tokens for credentials
+    KC_RESPONSE=$( \
+    curl -k -v -X POST \
+    -H "Content-Type: application/x-www-form-urlencoded" \
+    -d "scope=openid" \
+    -d "grant_type=client_credentials" \
+    -d "client_id=$KC_CLIENT" \
+    -d "client_secret=$KC_CLIENT_SECRET" \
+    "http://$KC_SERVER/$KC_CONTEXT/realms/$KC_REALM/protocol/openid-connect/token" \
+    | jq .
+    )
+
+    KC_ACCESS_TOKEN=$(echo $KC_RESPONSE| jq -r .access_token)
+
+KC_ACCESS_TOKEN can be used to invoke AssumeRoleWithWebIdentity as given in
+:doc:`STS`.