5 Secure Token Service is a web service in AWS that returns a set of temporary security credentials for authenticating federated users.
6 The link to official AWS documentation can be found here: https://docs.aws.amazon.com/STS/latest/APIReference/Welcome.html.
8 Ceph Object Gateway implements a subset of STS APIs that provide temporary credentials for identity and access management.
9 These temporary credentials can be used to make subsequent S3 calls which will be authenticated by the STS engine in Ceph Object Gateway.
10 Permissions of the temporary credentials can be further restricted via an IAM policy passed as a parameter to the STS APIs.
15 The following STS REST APIs have been implemented in Ceph Object Gateway:
17 1. AssumeRole: Returns a set of temporary credentials that can be used for
18 cross-account access. The temporary credentials will have permissions that are
19 allowed by both - permission policies attached with the Role and policy attached
20 with the AssumeRole API.
23 **RoleArn** (String/ Required): ARN of the Role to Assume.
25 **RoleSessionName** (String/ Required): An Identifier for the assumed role
28 **Policy** (String/ Optional): An IAM Policy in JSON format.
30 **DurationSeconds** (Integer/ Optional): The duration in seconds of the session.
31 Its default value is 3600.
33 **ExternalId** (String/ Optional): A unique Id that might be used when a role is
34 assumed in another account.
36 **SerialNumber** (String/ Optional): The Id number of the MFA device associated
37 with the user making the AssumeRole call.
39 **TokenCode** (String/ Optional): The value provided by the MFA device, if the
40 trust policy of the role being assumed requires MFA.
42 2. AssumeRoleWithWebIdentity: Returns a set of temporary credentials for users that
43 have been authenticated by a web/mobile app by an OpenID Connect /OAuth2.0 Identity Provider.
44 Currently Keycloak has been tested and integrated with RGW.
47 **RoleArn** (String/ Required): ARN of the Role to Assume.
49 **RoleSessionName** (String/ Required): An Identifier for the assumed role
52 **Policy** (String/ Optional): An IAM Policy in JSON format.
54 **DurationSeconds** (Integer/ Optional): The duration in seconds of the session.
55 Its default value is 3600.
57 **ProviderId** (String/ Optional): Fully qualified host component of the domain name
58 of the IDP. Valid only for OAuth2.0 tokens (not for OpenID Connect tokens).
60 **WebIdentityToken** (String/ Required): The OpenID Connect/ OAuth2.0 token, which the
61 application gets in return after authenticating its user with an IDP.
66 The following configurable options have to be added for STS integration::
68 [client.radosgw.gateway]
69 rgw sts key = {sts key for encrypting the session token}
70 rgw s3 auth use sts = true
72 The following additional configurables have to be added to use Keycloak for
73 AssumeRoleWithWebIdentity calls::
75 [client.radosgw.gateway]
76 rgw_sts_token_introspection_url = {token introspection URL}
77 rgw_sts_client_id = {client id registered with Keycloak}
78 rgw_sts_client_secret = {client password registered with Keycloak}
80 Note: By default, STS and S3 APIs co-exist in the same namespace, and both S3
81 and STS APIs can be accessed via the same endpoint in Ceph Object Gateway.
86 1. The following is an example of AssumeRole API call, which shows steps to create a role, assign a policy to it
87 (that allows access to S3 resources), assuming a role to get temporary credentials and accessing s3 resources using
88 those credentials. In this example, TESTER1 assumes a role created by TESTER, to access S3 resources owned by TESTER,
89 according to the permission policy attached to the role.
91 .. code-block:: python
95 iam_client = boto3.client('iam',
96 aws_access_key_id=<access_key of TESTER>,
97 aws_secret_access_key=<secret_key of TESTER>,
98 endpoint_url=<IAM URL>,
102 policy_document = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"arn:aws:iam:::user/TESTER1\"]},\"Action\":[\"sts:AssumeRole\"]}]}"
104 role_response = iam_client.create_role(
105 AssumeRolePolicyDocument=policy_document,
110 role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"s3:*\",\"Resource\":\"arn:aws:s3:::*\"}}"
112 response = iam_client.put_role_policy(
114 PolicyName='Policy1',
115 PolicyDocument=role_policy
118 sts_client = boto3.client('sts',
119 aws_access_key_id=<access_key of TESTER1>,
120 aws_secret_access_key=<secret_key of TESTER1>,
121 endpoint_url=<STS URL>,
125 response = sts_client.assume_role(
126 RoleArn=role_response['Role']['Arn'],
127 RoleSessionName='Bob',
131 s3client = boto3.client('s3',
132 aws_access_key_id = response['Credentials']['AccessKeyId'],
133 aws_secret_access_key = response['Credentials']['SecretAccessKey'],
134 aws_session_token = response['Credentials']['SessionToken'],
135 endpoint_url=<S3 URL>,
138 bucket_name = 'my-bucket'
139 s3bucket = s3client.create_bucket(Bucket=bucket_name)
140 resp = s3client.list_buckets()
142 2. The following is an example of AssumeRoleWithWebIdentity API call, where an external app that has users authenticated with
143 an OpenID Connect/ OAuth2 IDP (Keycloak in this example), assumes a role to get back temporary credentials and access S3 resources
144 according to permission policy of the role.
146 .. code-block:: python
150 iam_client = boto3.client('iam',
151 aws_access_key_id=<access_key of TESTER>,
152 aws_secret_access_key=<secret_key of TESTER>,
153 endpoint_url=<IAM URL>,
157 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\"\}\}\}\]\}"
158 role_response = iam_client.create_role(
159 AssumeRolePolicyDocument=policy_document,
164 role_policy = "{\"Version\":\"2012-10-17\",\"Statement\":{\"Effect\":\"Allow\",\"Action\":\"s3:*\",\"Resource\":\"arn:aws:s3:::*\"}}"
166 response = iam_client.put_role_policy(
168 PolicyName='Policy1',
169 PolicyDocument=role_policy
172 sts_client = boto3.client('sts',
173 aws_access_key_id=<access_key of TESTER1>,
174 aws_secret_access_key=<secret_key of TESTER1>,
175 endpoint_url=<STS URL>,
179 response = client.assume_role_with_web_identity(
180 RoleArn=role_response['Role']['Arn'],
181 RoleSessionName='Bob',
182 DurationSeconds=3600,
183 WebIdentityToken=<Web Token>
186 s3client = boto3.client('s3',
187 aws_access_key_id = response['Credentials']['AccessKeyId'],
188 aws_secret_access_key = response['Credentials']['SecretAccessKey'],
189 aws_session_token = response['Credentials']['SessionToken'],
190 endpoint_url=<S3 URL>,
193 bucket_name = 'my-bucket'
194 s3bucket = s3client.create_bucket(Bucket=bucket_name)
195 resp = s3client.list_buckets()
200 More information for role manipulation can be found here
203 Keycloak integration with Radosgw
204 =================================
206 Steps for integrating Radosgw with Keycloak can be found here
211 STSLite has been built on STS, and documentation for the same can be found here