CORS breakage in Grafana 10

I have a datasource plugin that is working well in Grafana 9, but fails with Grafana 10 due to an invalid request header that’s being set. The error I’m seeing is as follows:

Access to fetch at 'https://...' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field x-grafana-device-id is not allowed by Access-Control-Allow-Headers in preflight response.

The Access-Control-Allow-Headers header in the pre-flight from my API looks like this:

Access-Control-Allow-Headers: appd-principal-id,appd-principal-type,appd-vanity-url,appd-tenant-id,auth0-client,Content-Type,Accept,Authorization

which indeed doesn’t include x-grafana-device-id.

Shouldn’t Grafana respect the CORS configuration of the remote API and exclude this header automatically when not accepted? How do I configure Grafana to not include this header? I’m making API requests using getBackendSrv().fetch(...) and, obviously, am not including this problem header myself.

Grafana doesn’t know anything about cors config of your API.
Grafana initiates request and browser then verifies if API owner allowed all request headers (that CORS part). Some API owners allow all headers, but it looks like your API owner doesn’t (which is OK from the security perspective). You should contact API owner and request to whitelist also that new header.

Complementing @jangaraj which is correct on their response, you can avoid all that kind of cors problems using proxy routes in your datasource.

In a nutshell, instead of fetching in the browser fetch(remoteAPIURL) which is subject to cors you’ll be fetching something like fetch(localGrafanaUrlWithAPIURLProxy) and the request will go first to the grafana server, then from the server to the remote API and back. Because the request is sent from the server it won’t be subject to the browser’s CORS validations.

See the docs here Add authentication for data source plugins | Grafana Plugin Tools

1 Like

I don’t control the API, so while I can ask for the header to be whitelisted, I can’t predict if that request will be honored. That’s why I’m trying to find a solution from the Grafana / plugin side.

I’ve heard about using a proxy to work around CORS issues, but I have customers reporting that my plugin stops working when they upgrade from 9 to 10, and telling them they’ll have to set that up to fix it isn’t ideal.

I tracked down where the header is coming from: grafana/public/app/core/services/backend_srv.ts at 5e88d29814184d2a7cee70c581c373ecab6ee972 · grafana/grafana · GitHub

There’s nothing there that supports configuration to disable the header, so unless I can override deviceID to be falsey somehow I’ll have to submit a PR to make this behaviour configurable :-/

@laurieh The proper solution to this problem is to use the datasource proxy as I mentioned before, it should require very little code changes to your datasource.

Regarding the header you mention in the code. Have you inspected the network request that goes to your API and confirmed that this header you mention is there?

1 Like