PureStorage-OpenConnect / pure-exporter

Prometheus exporter for Pure Storage FlashArray and FlashBlade. DEPRECATED IN FAVOR OF FA AND FB OPENMETRICS EXPORTERS
Apache License 2.0
29 stars 20 forks source link

Sending the API token as http Authorization header rather than a request parameter #28

Closed sakshigupta3 closed 3 years ago

sakshigupta3 commented 3 years ago

Hello,

We are trying to set this up as a part of a k8s cluster. What bothers us is the security issues around Pure API token since currently the exporter exposes it as a GET request parameter. The ideal way would have been to use the HTTP Authorization header since the Pure API also supports that. With the above changes, Prometheus could use the "bearer_token" configuration option https://prometheus.io/docs/prometheus/latest/configuration/configuration/ for embedding this http header.

Let me know your opinions/suggestion around this.

genegr commented 3 years ago

Hello, If you intend to use just the basic Pure API token in your Prometheus k8s config, what you suggest is certainly feasible. If instead your aim is to use the OAuth2 JWT authentication available in the REST API 2.x, that is unfortunately not possible, as by its nature the token expires at regular interval and needs to be systematically regenerated. So, assuming it is fine with you to go for the simple API token generated by the array and that without applying any encryption to that token, for each array you want to scrape you can store the token in a k8s secret and assign it to the related entry in the Prometheus config, which will probably be under control of the Prometheus operator. In that case I can easily modify the code to read the HTTP Authorization header as an alternative to the request param. In addition to that, since each array has its own API token, you will have to define a job for each array.

sakshigupta3 commented 3 years ago

We are using Flashblade. And yes, it is fine for us to generate an API token, adding that as a secret to kubernetes which need not be changed at regular intervals as such. It would be great if you can add an alternative method as well to read the authorisation header.

However, if you're short on time, I can as well help you with this change. I initially tried using this property https://flask.palletsprojects.com/en/1.1.x/api/#flask.Request.authorization and then send a request using curl -vvL -H "Authorization: Bearer <pure_api_token>" http://localhost:9491/metrics/flashblade?endpoint=<pure_host> But the property was being set to NULL. Then I used token=request.headers.get('authorization').split(" ")[1] and it worked.

genegr commented 3 years ago

I have updated the code to use the Authorization header as the main method to obtain the API token and kept the query parameter as a secondary option. The new version is not published yet as I have to fix the issue #27, but hope to release it by today, so stay tuned. And by the way, thanks for requesting this enhancement.

sakshigupta3 commented 3 years ago

Thanks to you too for the quick actions!

genegr commented 3 years ago

Fixed in release v1.2.5