|
| 1 | +# Troubleshooting CDN Installations |
| 2 | + |
| 3 | +## Events are not being sent by the web client to CloudWatch RUM |
| 4 | + |
| 5 | +### Session sample rate is less than one |
| 6 | + |
| 7 | +If `sessionSampleRate` is less than `1`, events may or may not be emitted for a |
| 8 | +given session. Try setting `sessionSampleRate: 1` in the web client |
| 9 | +configuration. |
| 10 | + |
| 11 | +### No AWS Credentials |
| 12 | + |
| 13 | +The web client requires AWS credentials to sign RUM payloads. When the RUM web |
| 14 | +client does not have AWS credentials, it will not attempt to send events to |
| 15 | +CloudWatch RUM. Your application must either (1) provide the web client with an |
| 16 | +anonymous Cognito identity using `identityPoolId` and `guestRoleArn`, or (2) |
| 17 | +provide the web client with AWS credentials using the `cwr('setAwsCredentials', |
| 18 | +credentials);` command. |
| 19 | + |
| 20 | +--- |
| 21 | +## CloudWatch RUM returns 403 |
| 22 | + |
| 23 | +CloudWatch RUM's `PutRumEvents` API returns 403 when authentication or |
| 24 | +authorization has failed. Since the web client has made the request, we know |
| 25 | +that either (a) the Cognito and STS calls have succeeded, (b) the `cwr_c` |
| 26 | +localStorage key contains AWS credentials, or (3) the application has forwarded |
| 27 | +credentials to the web client using the `cwr('setAwsCredentials', credentials);` |
| 28 | +command. |
| 29 | + |
| 30 | +### Incorrect AWS region |
| 31 | + |
| 32 | +Data must be sent to the same region as the CloudWatch RUM AppMonitor was |
| 33 | +created. For example, if the AppMonitor was created in `us-east-1`, but the web |
| 34 | +client is configured to send data to the endpoint |
| 35 | +`'https://dataplane.rum.us-west-2.amazonaws.com'`, authentication will fail. |
| 36 | +Verify that (1) the region argument is correct and (2) the `endpoint` |
| 37 | +configuration option, if set, is correct. |
| 38 | + |
| 39 | +### Credentials stored in localStorage are for a different AppMonitor |
| 40 | + |
| 41 | +When anonymous authorization is used, the web client stores credentials in |
| 42 | +localStorage. If multiple AppMonitors are used within the same domain, |
| 43 | +authorization will fail when navigating between pages with different |
| 44 | +AppMonitors. |
| 45 | + |
| 46 | +### IAM role is not authorized to call PutRumEvents on AppMonitor |
| 47 | + |
| 48 | +If a new AppMonitor is created and re-uses an existing Cognito Identity Pool and |
| 49 | +IAM Role, the IAM Role will not automatically have permissions to call |
| 50 | +PutRumEvents on the new AppMonitor. |
| 51 | + |
| 52 | +Verify the IAM role has the following permission: |
| 53 | + |
| 54 | +```json |
| 55 | +{ |
| 56 | + "Version": "2012-10-17", |
| 57 | + "Statement": [ |
| 58 | + { |
| 59 | + "Effect": "Allow", |
| 60 | + "Action": "rum:PutRumEvents", |
| 61 | + "Resource": "arn:aws:rum:[region]:[account]:appmonitor/[AppMonitor name]" |
| 62 | + } |
| 63 | + ] |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +--- |
| 68 | +## AWS token vending (Cognito or STS) fails |
| 69 | + |
| 70 | +The CloudWatch RUM web client has a default authorization mechanism that uses a |
| 71 | +a token vended by an unauthenticated Cognito identity to retrieve temporary AWS |
| 72 | +credentials from STS. |
| 73 | + |
| 74 | +### Cognito is not authorized to assume IAM role |
| 75 | + |
| 76 | +If the STS `AssumeRoleWithWebIdentity` operation fails, the Cognito identity may |
| 77 | +not have permission to assume the IAM role. Verify the IAM role has the |
| 78 | +following trust relationship: |
| 79 | + |
| 80 | +```json |
| 81 | +{ |
| 82 | + "Version": "2012-10-17", |
| 83 | + "Statement": [ |
| 84 | + { |
| 85 | + "Effect": "Allow", |
| 86 | + "Principal": { |
| 87 | + "Federated": "cognito-identity.amazonaws.com" |
| 88 | + }, |
| 89 | + "Action": "sts:AssumeRoleWithWebIdentity", |
| 90 | + "Condition": { |
| 91 | + "StringEquals": { |
| 92 | + "cognito-identity.amazonaws.com:aud": "[cognito identity pool id]" |
| 93 | + }, |
| 94 | + "ForAnyValue:StringLike": { |
| 95 | + "cognito-identity.amazonaws.com:amr": "unauthenticated" |
| 96 | + } |
| 97 | + } |
| 98 | + } |
| 99 | + ] |
| 100 | +} |
| 101 | +``` |
| 102 | + |
| 103 | +### Cognito's basic authflow is not enabled |
| 104 | + |
| 105 | +When the CloudWatch RUM web client is provided with both `identityPoolId` and `guestRoleArn`, the web client will use Cognito's [basic (classic) authflow](https://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flow.html). If the Cognito `GetCredentialsForIdentity` operation fails, this may be because the basic (classic) authflow is not enabled for the identity pool. In this case, the response may look similar to the following: |
| 106 | + |
| 107 | +``` |
| 108 | +<Error> |
| 109 | + <Type>Sender</Type> |
| 110 | + <Code>InvalidIdentityToken</Code> |
| 111 | + <Message>The ID Token provided is not a valid JWT. (You may see this error if you sent an Access Token)</Message> |
| 112 | +</Error> |
| 113 | +``` |
| 114 | + |
| 115 | +Using the Amazon Cognito console or CLI (i.e, the `aws cognito-identity |
| 116 | +describe-identity-pool` command), verify that the identity pool |
| 117 | +configuration does **not** contain `AllowClassicFlow: false`. If it does, then |
| 118 | +update the configuration so that it contains `AllowClassicFlow: true`. |
| 119 | + |
| 120 | +See also: |
| 121 | +1. `AllowClassicFlow` in the [update-identity-pool CLI reference](https://docs.aws.amazon.com/cli/latest/reference/cognito-identity/update-identity-pool.html). |
| 122 | +1. [Identity pool (federated identities) authentication flow](https://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flow.html). |
| 123 | + |
| 124 | +--- |
| 125 | +## Content security policy blocks the web client |
| 126 | + |
| 127 | +If your web application uses a content security policy, it likely needs to be |
| 128 | +amended to support the RUM web client. By default, a content security policy |
| 129 | +blocks unsafe inline scripts such as the code snippet used to install the RUM |
| 130 | +web client. You can use a hash or an nonce to allow the snippet. See [MDN Web |
| 131 | +Docs: CSP: |
| 132 | +script-src](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#sources) |
| 133 | +for more information. |
| 134 | + |
| 135 | +The hash method is the recommended method for adding the RUM web client |
| 136 | +installation snippet to the `script-src` directive. A complete CSP for the rum |
| 137 | +web client will contain the following directives and values: |
| 138 | + |
| 139 | +| Directive | Value | |
| 140 | +| --- | --- | |
| 141 | +| script-src | `'sha256-[snippet hash]'`<br/>`https://client.rum.us-east-1.amazonaws.com` | |
| 142 | +| connect-src | `https://dataplane.rum.[region].amazonaws.com`<br/>`https://cognito-identity.[region].amazonaws.com`<br/>`https://sts.[region].amazonaws.com` | |
| 143 | + |
| 144 | +A hash of the snippet can be generated from the command line using openssl: |
| 145 | + |
| 146 | +```bash |
| 147 | +SNIPPET='(function(n,i,v,r,s,c,u,x,z){x=window.AwsRumClient={q:[],n:n,i:i,v:v,r:r,c:c,u:u};window[n]=function(c,p){x.q.push({c:c,p:p});};z=document.createElement('script');z.async=true;z.src=s;document.head.insertBefore(z,document.getElementsByTagName('script')[0]);})('cwr','00000000-0000-0000-0000-000000000000','1.0.0','us-west-2','https://client.rum.us-east-1.amazonaws.com/1.0.2/cwr.js',{sessionSampleRate:1,guestRoleArn:'arn:aws:iam::000000000000:role/RUM-Monitor-us-west-2-000000000000-00xx-Unauth',identityPoolId:'us-west-2:00000000-0000-0000-0000-000000000000',endpoint:'https://dataplane.rum.us-west-2.amazonaws.com',telemetries:['errors','http','performance'],allowCookies:true});' |
| 148 | +echo $SNIPPET | openssl sha256 -binary | openssl base64 |
| 149 | +``` |
| 150 | + |
| 151 | +In this case, the output of this command is the following, however the output for your snippet will differ: |
| 152 | +``` |
| 153 | +dhFqvDHwFpO34BJSlFlEdnhKI/jmMD2Yl50PvxjyLN0= |
| 154 | +``` |
| 155 | +Place the hash in the `'sha256-[snippet hash]'` directive value above. In this |
| 156 | +case, the directive will be `script-src |
| 157 | +sha256-dhFqvDHwFpO34BJSlFlEdnhKI/jmMD2Yl50PvxjyLN0=`. |
| 158 | + |
| 159 | +--- |
| 160 | +## X-Ray tracing does not connect client-side trace with server-side trace |
| 161 | + |
| 162 | +To connect client-side and server-side traces, you must set the |
| 163 | +`addXRayTraceIdHeader` to `true` in the `http` telemetry configuration. The web |
| 164 | +client will then add the `X-Amzn-Trace-Id` header in each HTTP request. The |
| 165 | +example below shows what this configuration looks like, with all other |
| 166 | +configurations removed for readability. |
| 167 | + |
| 168 | +> :warning: Enabling `addXRayTraceIdHeader` will cause a new header to be added |
| 169 | +to all HTTP requests. Adding headers can modify CORS behavior, including causing |
| 170 | +the request to fail. Adding headers after SigV4 signing will invalidate the |
| 171 | +request signature, causing the request to fail. Test your application with this |
| 172 | +header enabled before enabling this option in a production environment. |
| 173 | + |
| 174 | +```html |
| 175 | +<script> |
| 176 | + (function(n,i,v,r,s,c,u,x,z){...})( |
| 177 | + 'cwr', |
| 178 | + '00000000-0000-0000-0000-000000000000', |
| 179 | + '1.0.0', |
| 180 | + 'us-west-2', |
| 181 | + 'https://client.rum.us-east-1.amazonaws.com/1.0.2/cwr.js', |
| 182 | + { |
| 183 | + enableXRay: true, |
| 184 | + telemetries: [ |
| 185 | + [ 'http', { addXRayTraceIdHeader: true } ] |
| 186 | + ] |
| 187 | + } |
| 188 | + ); |
| 189 | +</script> |
| 190 | +``` |
0 commit comments