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.
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:
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.
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:
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 -X "X-Api-Key: my-secret-key" https://myproject.dieselapps.com/diesel/react/my.message
This works in conjunction with the message visibility:
diesel.xapikeyconfigured, then anyone can call it
diesel.xapikeyconfigured, then it must be passed in
The better approach is to have a specific user be assigned when the proper api key is used and designate it like so:
This user will be used when successfuly executing messages. If this user is not found or defined, a default internal user will be used.
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)
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.
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.
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
organizationand 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: