Community Conundrum 28: News Engagement is live! Read More

Securing access to webapp back-ends from outside of DSS

Level 2
Securing access to webapp back-ends from outside of DSS

Hi,

I'm trying to figure out how to restrict access to API back-ends when creating custom Python webapps.

If I create a webapp with Python backend, the flask routes are accessible to anyone outside of DSS who knows the url (/web-apps-backends/PROJECTID/APPID/some/endpoint).

Is there a way to force users to attach an API key? Ideally I would like users to use their Dataiku Personal API Keys and then infer the user making the request from the personal key in Python. Is this possible (or is there a better way to enforce authentication)?

0 Kudos
4 Replies
Dataiker
Dataiker

Hi,

When the request is made to the backend, if it's done from a properly identified user, your browser will automatically send authenticating information.

You can then use the authentication information Python API of DSS in order to verify that the browser possesses such authentication, and to identify (and possibly authorize) the user.

We have a sample on this here: https://github.com/dataiku/dss-code-samples/tree/master/visualization/flask-webapps/authenticate-cal...

With reference here: https://doc.dataiku.com/dss/latest/python-api/rest-api-client/authinfo.html

0 Kudos
Level 2
Author

Hi, thanks for a quck response!

This does require the user to be logged in and assumes that we access the backend via a browser, doesn't it? Or am I misunderstanding something?

What if was to access the back-end using, say, python requests module?

 

 

0 Kudos
Dataiker
Dataiker

Hi,

Indeed, this sample requires access to the backend from a logged browser, which is the primary use case for webapps.

For programmatic access, we'd simply recommend that the caller pass a DSS API key, and that the backend uses this API key to make calls to DSS, which will validate the validity of the API key, and can validate the identity of the user (if it's a personal API key).

Something like (pseudo-code):

@app.route("/sensitive-data")
def get_sensitive_data():
   api_key_sent_by_client = request.headers.get("X-DKU-APIKey")

   # Replace by your DSS port
   api_client = dataikuapi.DSSClient("http://127.0.0.1:10000", api_key_sent_by_client)
   # If the API was not valid, this call will fail
   auth_info = api_client.get_auth_info()

   return json.dumps({"you_are": auth_info["authIdentifier"]})

 

With client code like:

resp = requests.get("/web-app-backend/..../sensitive-data", headers= {"X-DKU-APIKey": "219DSGJLSKDAZEOKJ12390dskfe23"})

print("I am: %s" % resp.json())

 

Level 2
Author

This is exactly what I needed, thanks!

A banner prompting to get Dataiku DSS