Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

architecture: don't require authentication to post metrics #305

Open
JoshBarr opened this issue Nov 23, 2022 · 3 comments
Open

architecture: don't require authentication to post metrics #305

JoshBarr opened this issue Nov 23, 2022 · 3 comments
Labels
enhancement New feature or request

Comments

@JoshBarr
Copy link

When a new user visits my site, CW RUM kicks off a series of steps before sending metrics: the browser obtains an anonymous identity from the Identity Pool, fetches a token for the identity, assumes role via STS, and stashes the credentials in localstorage.

Once an identity is obtained, the client then performs cryptography (sigv4) on every metrics payload before sending it over the wire.

Initially I thought that the credentials obtained from Cognito were used to establish a tracking session, but looking at the code, the generated user ID in the cwr_u cookie, and the session ID in the session cookie are locally generated UUIDs, separate to the Cognito Identity.

Typically RUM solutions are fire-and-forget, not requiring coordination between the collector endpoint and the client. Instead of credentials, the origin URL, device fingerprint (user agent etc) and the monitor ID are sent to the endpoint.

Could you consider an architecture where the collector endpoints are unauthenticated, and take care of any required AWS service authorisation internally?

Client side libraries should aim to do the least amount of work possible, in the fewest bytes.

@qhanam
Copy link
Member

qhanam commented Nov 30, 2022

Hi @JoshBarr thanks for this feedback/feature request! I agree with your points and the short answer is yes, the CloudWatch RUM team does consider (and appreciate!) such requests.

However, let me also shed some light on why we do this, and offer a workaround.

Why CloudWatch RUM uses authentication and authorization

Like most AWS services, the CW RUM endpoint uses AWS authentication and authorization. This gives customers full control over who sends data to their CW RUM app monitor. This is especially useful if your application has authenticated users and you want to gain assurance that only those users can send RUM data to your app monitor.

For example, if your organization is using CW RUM to monitor the front-end of a critical internal system which is only accessible to employees, it might be important to authenticate the RUM data.

However, if you want to collect data from anonymous users, authentication is a barrier. We work around this by using Cognito's unauthenticated identity, which effectively drops authentication but retains authorization.

Workaround using a proxy

To avoid doing the signing step on the end-user device, you can use a proxy. There are CW RUM customers who already do this. The rough steps for this are:

  1. Create a proxy. We recommend using API Gateway + Lambda.
  2. The proxy holds AWS credentials which can send the app monitor data via the PutRumEvents operation.
  3. When the proxy receives a request, the proxy signs it with sigv4 and forwards the request to CW RUM.
  4. Configure the CW RUM web client to use the proxy as the endpoint for RUM data.
  5. Configure the CW RUM web client to disable signing by setting the signing config option to false.

The side benefit of this is that you get your own DNS address for recieving RUM data, which helps avoid data loss due to ad blockers.

@JoshBarr
Copy link
Author

JoshBarr commented Dec 2, 2022

Yeah we have implemented a proxy to do exactly this! It might be nice to add docs about this approach, or a reference that can be copied, as there was some trial-and-error in setting it up. I can pull the relevant parts of our proxy into a sample repo if that's helpful?

One thing I noticed, disabling signing in the client doesn't remove sigv4 and the sha256 polyfill from the library - that code will still get bundled and loaded even though it's unused.

It would be preferable to have a lighter-weight "no-sig" import that could be used instead:

import { RUM } from "aws-rum-web/no-sig"

We could probably generate this ourselves by using patch-package to strip out any imports we're not using. We do a similar thing with Amplify Auth as it also has lots of deps that can't be easily tree-shaken. But it's always preferable not to rewrite library internals that may change over time.

For now, we've written our own tiny RUM client without the crypto stuff included. One benefit of rolling our own client has been to shift the work of parsing the UA into the lambda, which cuts the bundle size down even more.

@sc0ttdav3y
Copy link

Yeah we have implemented a proxy to do exactly this! It might be nice to add docs about this approach, or a reference that can be copied, as there was some trial-and-error in setting it up. I can pull the relevant parts of our proxy into a sample repo if that's helpful?

Hi @JoshBarr, any chance you could provide some details on your proxy implementation?

It would help me in my efforts to work around my own issue with RUM.

Many thanks, Scott

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants