About security Pub

It's important to pay attention to security, especially as you start to define test messages that proxy an actual system... you may be tempted to code some security tokens in here and then you can easily get in trouble.

Message visibility

The message visibility is by default public. This means that no additional security is required to invoke the messages via REST or from other projects.

You can change the default visibility by adding this property to your Reactor configuration:

diesel.visibility=member

When doing this, the default visibility of all messages changes to member, in which case they can only be called by someone that's logged in and member of your project - the credentials can be passed in by a browser (if copying an API URL in the browser address, the browser will send in the authentication cookies along) OR by passing in the curl request the basic auth credentials (username and password - lookup "http basic auth"). Or by someone that passes in the appropriate credentials, see below.

Client API Keys

You have the added ability to use client API keys.

The simplest way is to configure an api key for the entire project, by adding this to the reactor configuration:

diesel.xapikey=my-secret-key

With this, all non-members have to pass this key back when calling the API, as an HTTP request header OR query parm, i.e.:

curl https://myproject.dieselapps.com/diesel/react/my.message?X-Api-Key=my-secret-key

or

curl -X "X-Api-Key: my-secret-key" https://myproject.dieselapps.com/diesel/react/my.message

This works in conjunction with the message visibility:

  • if a message is public and there is no diesel.xapikey configured, then anyone can call it
  • if a message is public and there is diesel.xapikey configured, then it must be passed in
  • if a message is not public, it cannot be called by non-members

User-specific API keys

The better approach is to have a specific user be assigned when the proper api key is used and designate it like so:

diesel.xapikeyUserEmail=harry@racerkidz.com

This user will be used when successfuly executing messages. If this user is not found or defined, a default internal user will be used.

TODO Alternatively each user can get an API key in their own user profile.

Client-specific API keys

Instead of a project-level static key, you can enforce client-specific keys, with a simple message structure - in your own database just store keys per users and then have the public entry points first lookup the keys, something like:

$when <public> my.api.entry1 (a,b,c)
=> my.client.auth(a,b)
=> my.actual.entry1(c)

$when <public> my.api.entry2 (a,b,c)
=> my.client.auth(a,b)
=> my.actual.entry2(c)

$when my.client.auth(a,b)
=> my.db.lookup(a,b)
=> $if (payload is empty) diesel.return(payload="oops, not auth")
=> (client=payload.clientName)

Caring for API keys

Just as a quick note on API Keys: when using static keys, make sure you never use them in exposed clients. An example of an exposed client is JS code inside an HTML page... if you embed the keys in there, anyone looking at that page can see your keys...

It is customary to protect the page itself with a temporary token and store the client keys on the server. Or - see the section on "trusted portals" below.

Otherwise, on the server, usual security concerns apply: you should store the keys encrypted and safe etc.

Trusted portals

Another way to take advantage of the built-in authentication mechanism is by trusting other realms. Let's say you have a project myApi which defines API messages. This is exposed to your developers.

Another project/reactor myPortal, uses myApi but is exposed to another set of users: your clients.

  • You don't want your clients to make calls to your internal API, only through their respective portals - this adds a layer of security and easy multi-hosting
  • one of the parameters of your API calls would be say organization, used to filter the results and this would be sent in by the various portals but could be potentially hacked by a client when calling the API directly
  • your clients would register to their respective portals, which are coded to send in the appropriate organization and then you just setup project trust or realm trust

When using message visibility as member you can also trust the members of the client project, by adding this in the myApi reactor configuration:

diesel.trust=myPortal1, myPortal2 etc

At this point, users of myPortal can call the public methods from myApi, without providing any additional security above just being logged in. However, they can only do so from their portals:

  • user logs into the myPortal1
  • user clicks on a page
  • myPortal1 makes an API call on behalf of the user
  • that call is allowed


Was this useful?    

By: Razie | 2018-08-18 .. 2020-10-03 | Tags: academy , reference


Viewed 161 times ( | Print ) this page.

You need to log in to post a comment!

© Copyright DieselApps, 2012-2021, all rights reserved.