1 // Code generated by smithy-go-codegen DO NOT EDIT.
2 3 package sts
4 5 import (
6 "context"
7 "fmt"
8 awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
9 "github.com/aws/aws-sdk-go-v2/service/sts/types"
10 "github.com/aws/smithy-go/middleware"
11 smithyhttp "github.com/aws/smithy-go/transport/http"
12 )
13 14 // Returns a set of temporary security credentials for users who have been
15 // authenticated in a mobile or web application with a web identity provider.
16 // Example providers include the OAuth 2.0 providers Login with Amazon and
17 // Facebook, or any OpenID Connect-compatible identity provider such as Google or [Amazon Cognito federated identities].
18 //
19 // For mobile applications, we recommend that you use Amazon Cognito. You can use
20 // Amazon Cognito with the [Amazon Web Services SDK for iOS Developer Guide]and the [Amazon Web Services SDK for Android Developer Guide] to uniquely identify a user. You can also
21 // supply the user with a consistent identity throughout the lifetime of an
22 // application.
23 //
24 // To learn more about Amazon Cognito, see [Amazon Cognito identity pools] in Amazon Cognito Developer Guide.
25 //
26 // Calling AssumeRoleWithWebIdentity does not require the use of Amazon Web
27 // Services security credentials. Therefore, you can distribute an application (for
28 // example, on mobile devices) that requests temporary security credentials without
29 // including long-term Amazon Web Services credentials in the application. You also
30 // don't need to deploy server-based proxy services that use long-term Amazon Web
31 // Services credentials. Instead, the identity of the caller is validated by using
32 // a token from the web identity provider. For a comparison of
33 // AssumeRoleWithWebIdentity with the other API operations that produce temporary
34 // credentials, see [Requesting Temporary Security Credentials]and [Compare STS credentials] in the IAM User Guide.
35 //
36 // The temporary security credentials returned by this API consist of an access
37 // key ID, a secret access key, and a security token. Applications can use these
38 // temporary security credentials to sign calls to Amazon Web Services service API
39 // operations.
40 //
41 // # Session Duration
42 //
43 // By default, the temporary security credentials created by
44 // AssumeRoleWithWebIdentity last for one hour. However, you can use the optional
45 // DurationSeconds parameter to specify the duration of your session. You can
46 // provide a value from 900 seconds (15 minutes) up to the maximum session duration
47 // setting for the role. This setting can have a value from 1 hour to 12 hours. To
48 // learn how to view the maximum value for your role, see [Update the maximum session duration for a role]in the IAM User Guide.
49 // The maximum session duration limit applies when you use the AssumeRole* API
50 // operations or the assume-role* CLI commands. However the limit does not apply
51 // when you use those operations to create a console URL. For more information, see
52 // [Using IAM Roles]in the IAM User Guide.
53 //
54 // # Permissions
55 //
56 // The temporary security credentials created by AssumeRoleWithWebIdentity can be
57 // used to make API calls to any Amazon Web Services service with the following
58 // exception: you cannot call the STS GetFederationToken or GetSessionToken API
59 // operations.
60 //
61 // (Optional) You can pass inline or managed [session policies] to this operation. You can pass a
62 // single JSON policy document to use as an inline session policy. You can also
63 // specify up to 10 managed policy Amazon Resource Names (ARNs) to use as managed
64 // session policies. The plaintext that you use for both inline and managed session
65 // policies can't exceed 2,048 characters. Passing policies to this operation
66 // returns new temporary credentials. The resulting session's permissions are the
67 // intersection of the role's identity-based policy and the session policies. You
68 // can use the role's temporary credentials in subsequent Amazon Web Services API
69 // calls to access resources in the account that owns the role. You cannot use
70 // session policies to grant more permissions than those allowed by the
71 // identity-based policy of the role that is being assumed. For more information,
72 // see [Session Policies]in the IAM User Guide.
73 //
74 // # Tags
75 //
76 // (Optional) You can configure your IdP to pass attributes into your web identity
77 // token as session tags. Each session tag consists of a key name and an associated
78 // value. For more information about session tags, see [Passing session tags using AssumeRoleWithWebIdentity]in the IAM User Guide.
79 //
80 // You can pass up to 50 session tags. The plaintext session tag keys can’t exceed
81 // 128 characters and the values can’t exceed 256 characters. For these and
82 // additional limits, see [IAM and STS Character Limits]in the IAM User Guide.
83 //
84 // An Amazon Web Services conversion compresses the passed inline session policy,
85 // managed policy ARNs, and session tags into a packed binary format that has a
86 // separate limit. Your request can fail for this limit even if your plaintext
87 // meets the other requirements. The PackedPolicySize response element indicates
88 // by percentage how close the policies and tags for your request are to the upper
89 // size limit.
90 //
91 // You can pass a session tag with the same key as a tag that is attached to the
92 // role. When you do, the session tag overrides the role tag with the same key.
93 //
94 // An administrator must grant you the permissions necessary to pass session tags.
95 // The administrator can also create granular permissions to allow you to pass only
96 // specific session tags. For more information, see [Tutorial: Using Tags for Attribute-Based Access Control]in the IAM User Guide.
97 //
98 // You can set the session tags as transitive. Transitive tags persist during role
99 // chaining. For more information, see [Chaining Roles with Session Tags]in the IAM User Guide.
100 //
101 // # Identities
102 //
103 // Before your application can call AssumeRoleWithWebIdentity , you must have an
104 // identity token from a supported identity provider and create a role that the
105 // application can assume. The role that your application assumes must trust the
106 // identity provider that is associated with the identity token. In other words,
107 // the identity provider must be specified in the role's trust policy.
108 //
109 // Calling AssumeRoleWithWebIdentity can result in an entry in your CloudTrail
110 // logs. The entry includes the [Subject]of the provided web identity token. We recommend
111 // that you avoid using any personally identifiable information (PII) in this
112 // field. For example, you could instead use a GUID or a pairwise identifier, as [suggested in the OIDC specification].
113 //
114 // For more information about how to use OIDC federation and the
115 // AssumeRoleWithWebIdentity API, see the following resources:
116 //
117 // [Using Web Identity Federation API Operations for Mobile Apps]
118 // - and [Federation Through a Web-based Identity Provider].
119 //
120 // [Amazon Web Services SDK for iOS Developer Guide]
121 // - and [Amazon Web Services SDK for Android Developer Guide]. These toolkits contain sample apps that show how to invoke the
122 // identity providers. The toolkits then show how to use the information from these
123 // providers to get and use temporary security credentials.
124 //
125 // [Amazon Web Services SDK for iOS Developer Guide]: http://aws.amazon.com/sdkforios/
126 // [Passing session tags using AssumeRoleWithWebIdentity]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_adding-assume-role-idp
127 // [Amazon Web Services SDK for Android Developer Guide]: http://aws.amazon.com/sdkforandroid/
128 // [IAM and STS Character Limits]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-limits.html#reference_iam-limits-entity-length
129 // [session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
130 // [Requesting Temporary Security Credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html
131 // [Compare STS credentials]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html
132 // [Subject]: http://openid.net/specs/openid-connect-core-1_0.html#Claims
133 // [Tutorial: Using Tags for Attribute-Based Access Control]: https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_attribute-based-access-control.html
134 // [Amazon Cognito identity pools]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html
135 // [Federation Through a Web-based Identity Provider]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#api_assumerolewithwebidentity
136 // [Using IAM Roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html
137 // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
138 // [Amazon Cognito federated identities]: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-identity.html
139 // [Chaining Roles with Session Tags]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html#id_session-tags_role-chaining
140 // [Update the maximum session duration for a role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-settings.html#id_roles_update-session-duration
141 // [Using Web Identity Federation API Operations for Mobile Apps]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_manual.html
142 // [suggested in the OIDC specification]: http://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
143 func (c *Client) AssumeRoleWithWebIdentity(ctx context.Context, params *AssumeRoleWithWebIdentityInput, optFns ...func(*Options)) (*AssumeRoleWithWebIdentityOutput, error) {
144 if params == nil {
145 params = &AssumeRoleWithWebIdentityInput{}
146 }
147 148 result, metadata, err := c.invokeOperation(ctx, "AssumeRoleWithWebIdentity", params, optFns, c.addOperationAssumeRoleWithWebIdentityMiddlewares)
149 if err != nil {
150 return nil, err
151 }
152 153 out := result.(*AssumeRoleWithWebIdentityOutput)
154 out.ResultMetadata = metadata
155 return out, nil
156 }
157 158 type AssumeRoleWithWebIdentityInput struct {
159 160 // The Amazon Resource Name (ARN) of the role that the caller is assuming.
161 //
162 // Additional considerations apply to Amazon Cognito identity pools that assume [cross-account IAM roles].
163 // The trust policies of these roles must accept the cognito-identity.amazonaws.com
164 // service principal and must contain the cognito-identity.amazonaws.com:aud
165 // condition key to restrict role assumption to users from your intended identity
166 // pools. A policy that trusts Amazon Cognito identity pools without this condition
167 // creates a risk that a user from an unintended identity pool can assume the role.
168 // For more information, see [Trust policies for IAM roles in Basic (Classic) authentication]in the Amazon Cognito Developer Guide.
169 //
170 // [cross-account IAM roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies-cross-account-resource-access.html
171 // [Trust policies for IAM roles in Basic (Classic) authentication]: https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html#trust-policies
172 //
173 // This member is required.
174 RoleArn *string
175 176 // An identifier for the assumed role session. Typically, you pass the name or
177 // identifier that is associated with the user who is using your application. That
178 // way, the temporary security credentials that your application will use are
179 // associated with that user. This session name is included as part of the ARN and
180 // assumed role ID in the AssumedRoleUser response element.
181 //
182 // For security purposes, administrators can view this field in [CloudTrail logs] to help identify
183 // who performed an action in Amazon Web Services. Your administrator might require
184 // that you specify your user name as the session name when you assume the role.
185 // For more information, see [sts:RoleSessionName]sts:RoleSessionName .
186 //
187 // The regex used to validate this parameter is a string of characters consisting
188 // of upper- and lower-case alphanumeric characters with no spaces. You can also
189 // include underscores or any of the following characters: =,.@-
190 //
191 // [CloudTrail logs]: https://docs.aws.amazon.com/IAM/latest/UserGuide/cloudtrail-integration.html#cloudtrail-integration_signin-tempcreds
192 // [sts:RoleSessionName]: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#ck_rolesessionname
193 //
194 // This member is required.
195 RoleSessionName *string
196 197 // The OAuth 2.0 access token or OpenID Connect ID token that is provided by the
198 // identity provider. Your application must get this token by authenticating the
199 // user who is using your application with a web identity provider before the
200 // application makes an AssumeRoleWithWebIdentity call. Timestamps in the token
201 // must be formatted as either an integer or a long integer. Tokens must be signed
202 // using either RSA keys (RS256, RS384, or RS512) or ECDSA keys (ES256, ES384, or
203 // ES512).
204 //
205 // This member is required.
206 WebIdentityToken *string
207 208 // The duration, in seconds, of the role session. The value can range from 900
209 // seconds (15 minutes) up to the maximum session duration setting for the role.
210 // This setting can have a value from 1 hour to 12 hours. If you specify a value
211 // higher than this setting, the operation fails. For example, if you specify a
212 // session duration of 12 hours, but your administrator set the maximum session
213 // duration to 6 hours, your operation fails. To learn how to view the maximum
214 // value for your role, see [View the Maximum Session Duration Setting for a Role]in the IAM User Guide.
215 //
216 // By default, the value is set to 3600 seconds.
217 //
218 // The DurationSeconds parameter is separate from the duration of a console
219 // session that you might request using the returned credentials. The request to
220 // the federation endpoint for a console sign-in token takes a SessionDuration
221 // parameter that specifies the maximum length of the console session. For more
222 // information, see [Creating a URL that Enables Federated Users to Access the Amazon Web Services Management Console]in the IAM User Guide.
223 //
224 // [View the Maximum Session Duration Setting for a Role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html#id_roles_use_view-role-max-session
225 // [Creating a URL that Enables Federated Users to Access the Amazon Web Services Management Console]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_enable-console-custom-url.html
226 DurationSeconds *int32
227 228 // An IAM policy in JSON format that you want to use as an inline session policy.
229 //
230 // This parameter is optional. Passing policies to this operation returns new
231 // temporary credentials. The resulting session's permissions are the intersection
232 // of the role's identity-based policy and the session policies. You can use the
233 // role's temporary credentials in subsequent Amazon Web Services API calls to
234 // access resources in the account that owns the role. You cannot use session
235 // policies to grant more permissions than those allowed by the identity-based
236 // policy of the role that is being assumed. For more information, see [Session Policies]in the IAM
237 // User Guide.
238 //
239 // The plaintext that you use for both inline and managed session policies can't
240 // exceed 2,048 characters. The JSON policy characters can be any ASCII character
241 // from the space character to the end of the valid character list (\u0020 through
242 // \u00FF). It can also include the tab (\u0009), linefeed (\u000A), and carriage
243 // return (\u000D) characters.
244 //
245 // For more information about role session permissions, see [Session policies].
246 //
247 // An Amazon Web Services conversion compresses the passed inline session policy,
248 // managed policy ARNs, and session tags into a packed binary format that has a
249 // separate limit. Your request can fail for this limit even if your plaintext
250 // meets the other requirements. The PackedPolicySize response element indicates
251 // by percentage how close the policies and tags for your request are to the upper
252 // size limit.
253 //
254 // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
255 // [Session policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
256 Policy *string
257 258 // The Amazon Resource Names (ARNs) of the IAM managed policies that you want to
259 // use as managed session policies. The policies must exist in the same account as
260 // the role.
261 //
262 // This parameter is optional. You can provide up to 10 managed policy ARNs.
263 // However, the plaintext that you use for both inline and managed session policies
264 // can't exceed 2,048 characters. For more information about ARNs, see [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]in the
265 // Amazon Web Services General Reference.
266 //
267 // An Amazon Web Services conversion compresses the passed inline session policy,
268 // managed policy ARNs, and session tags into a packed binary format that has a
269 // separate limit. Your request can fail for this limit even if your plaintext
270 // meets the other requirements. The PackedPolicySize response element indicates
271 // by percentage how close the policies and tags for your request are to the upper
272 // size limit.
273 //
274 // Passing policies to this operation returns new temporary credentials. The
275 // resulting session's permissions are the intersection of the role's
276 // identity-based policy and the session policies. You can use the role's temporary
277 // credentials in subsequent Amazon Web Services API calls to access resources in
278 // the account that owns the role. You cannot use session policies to grant more
279 // permissions than those allowed by the identity-based policy of the role that is
280 // being assumed. For more information, see [Session Policies]in the IAM User Guide.
281 //
282 // [Session Policies]: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html#policies_session
283 // [Amazon Resource Names (ARNs) and Amazon Web Services Service Namespaces]: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html
284 PolicyArns []types.PolicyDescriptorType
285 286 // The fully qualified host component of the domain name of the OAuth 2.0 identity
287 // provider. Do not specify this value for an OpenID Connect identity provider.
288 //
289 // Currently www.amazon.com and graph.facebook.com are the only supported identity
290 // providers for OAuth 2.0 access tokens. Do not include URL schemes and port
291 // numbers.
292 //
293 // Do not specify this value for OpenID Connect ID tokens.
294 ProviderId *string
295 296 noSmithyDocumentSerde
297 }
298 299 // Contains the response to a successful AssumeRoleWithWebIdentity request, including temporary Amazon Web
300 // Services credentials that can be used to make Amazon Web Services requests.
301 type AssumeRoleWithWebIdentityOutput struct {
302 303 // The Amazon Resource Name (ARN) and the assumed role ID, which are identifiers
304 // that you can use to refer to the resulting temporary security credentials. For
305 // example, you can reference these credentials as a principal in a resource-based
306 // policy by using the ARN or assumed role ID. The ARN and ID include the
307 // RoleSessionName that you specified when you called AssumeRole .
308 AssumedRoleUser *types.AssumedRoleUser
309 310 // The intended audience (also known as client ID) of the web identity token. This
311 // is traditionally the client identifier issued to the application that requested
312 // the web identity token.
313 Audience *string
314 315 // The temporary security credentials, which include an access key ID, a secret
316 // access key, and a security token.
317 //
318 // The size of the security token that STS API operations return is not fixed. We
319 // strongly recommend that you make no assumptions about the maximum size.
320 Credentials *types.Credentials
321 322 // A percentage value that indicates the packed size of the session policies and
323 // session tags combined passed in the request. The request fails if the packed
324 // size is greater than 100 percent, which means the policies and tags exceeded the
325 // allowed space.
326 PackedPolicySize *int32
327 328 // The issuing authority of the web identity token presented. For OpenID Connect
329 // ID tokens, this contains the value of the iss field. For OAuth 2.0 access
330 // tokens, this contains the value of the ProviderId parameter that was passed in
331 // the AssumeRoleWithWebIdentity request.
332 Provider *string
333 334 // The value of the source identity that is returned in the JSON web token (JWT)
335 // from the identity provider.
336 //
337 // You can require users to set a source identity value when they assume a role.
338 // You do this by using the sts:SourceIdentity condition key in a role trust
339 // policy. That way, actions that are taken with the role are associated with that
340 // user. After the source identity is set, the value cannot be changed. It is
341 // present in the request for all actions that are taken by the role and persists
342 // across [chained role]sessions. You can configure your identity provider to use an attribute
343 // associated with your users, like user name or email, as the source identity when
344 // calling AssumeRoleWithWebIdentity . You do this by adding a claim to the JSON
345 // web token. To learn more about OIDC tokens and claims, see [Using Tokens with User Pools]in the Amazon
346 // Cognito Developer Guide. For more information about using source identity, see [Monitor and control actions taken with assumed roles]
347 // in the IAM User Guide.
348 //
349 // The regex used to validate this parameter is a string of characters consisting
350 // of upper- and lower-case alphanumeric characters with no spaces. You can also
351 // include underscores or any of the following characters: =,.@-
352 //
353 // [chained role]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html#id_roles_terms-and-concepts
354 // [Monitor and control actions taken with assumed roles]: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html
355 // [Using Tokens with User Pools]: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html
356 SourceIdentity *string
357 358 // The unique user identifier that is returned by the identity provider. This
359 // identifier is associated with the WebIdentityToken that was submitted with the
360 // AssumeRoleWithWebIdentity call. The identifier is typically unique to the user
361 // and the application that acquired the WebIdentityToken (pairwise identifier).
362 // For OpenID Connect ID tokens, this field contains the value returned by the
363 // identity provider as the token's sub (Subject) claim.
364 SubjectFromWebIdentityToken *string
365 366 // Metadata pertaining to the operation's result.
367 ResultMetadata middleware.Metadata
368 369 noSmithyDocumentSerde
370 }
371 372 func (c *Client) addOperationAssumeRoleWithWebIdentityMiddlewares(stack *middleware.Stack, options Options) (err error) {
373 if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil {
374 return err
375 }
376 err = stack.Serialize.Add(&awsAwsquery_serializeOpAssumeRoleWithWebIdentity{}, middleware.After)
377 if err != nil {
378 return err
379 }
380 err = stack.Deserialize.Add(&awsAwsquery_deserializeOpAssumeRoleWithWebIdentity{}, middleware.After)
381 if err != nil {
382 return err
383 }
384 if err := addProtocolFinalizerMiddlewares(stack, options, "AssumeRoleWithWebIdentity"); err != nil {
385 return fmt.Errorf("add protocol finalizers: %v", err)
386 }
387 388 if err = addlegacyEndpointContextSetter(stack, options); err != nil {
389 return err
390 }
391 if err = addSetLoggerMiddleware(stack, options); err != nil {
392 return err
393 }
394 if err = addClientRequestID(stack); err != nil {
395 return err
396 }
397 if err = addComputeContentLength(stack); err != nil {
398 return err
399 }
400 if err = addResolveEndpointMiddleware(stack, options); err != nil {
401 return err
402 }
403 if err = addRetry(stack, options); err != nil {
404 return err
405 }
406 if err = addRawResponseToMetadata(stack); err != nil {
407 return err
408 }
409 if err = addRecordResponseTiming(stack); err != nil {
410 return err
411 }
412 if err = addSpanRetryLoop(stack, options); err != nil {
413 return err
414 }
415 if err = addClientUserAgent(stack, options); err != nil {
416 return err
417 }
418 if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
419 return err
420 }
421 if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
422 return err
423 }
424 if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil {
425 return err
426 }
427 if err = addTimeOffsetBuild(stack, c); err != nil {
428 return err
429 }
430 if err = addUserAgentRetryMode(stack, options); err != nil {
431 return err
432 }
433 if err = addCredentialSource(stack, options); err != nil {
434 return err
435 }
436 if err = addOpAssumeRoleWithWebIdentityValidationMiddleware(stack); err != nil {
437 return err
438 }
439 if err = stack.Initialize.Add(newServiceMetadataMiddleware_opAssumeRoleWithWebIdentity(options.Region), middleware.Before); err != nil {
440 return err
441 }
442 if err = addRecursionDetection(stack); err != nil {
443 return err
444 }
445 if err = addRequestIDRetrieverMiddleware(stack); err != nil {
446 return err
447 }
448 if err = addResponseErrorMiddleware(stack); err != nil {
449 return err
450 }
451 if err = addRequestResponseLogging(stack, options); err != nil {
452 return err
453 }
454 if err = addDisableHTTPSMiddleware(stack, options); err != nil {
455 return err
456 }
457 if err = addInterceptBeforeRetryLoop(stack, options); err != nil {
458 return err
459 }
460 if err = addInterceptAttempt(stack, options); err != nil {
461 return err
462 }
463 if err = addInterceptors(stack, options); err != nil {
464 return err
465 }
466 return nil
467 }
468 469 func newServiceMetadataMiddleware_opAssumeRoleWithWebIdentity(region string) *awsmiddleware.RegisterServiceMetadata {
470 return &awsmiddleware.RegisterServiceMetadata{
471 Region: region,
472 ServiceID: ServiceID,
473 OperationName: "AssumeRoleWithWebIdentity",
474 }
475 }
476