Security
SlashDB is based on two levels of authentication and authorization.
- Access to the API (and GUI)
- Access to data
Accordingly
- Each request to the API has to be made on behalf of a certain SlashDB user. In above picture they are John, App1 and App2. These users can be authenticated by passing valid credentials using one of available methods: provide a cookie, basic authentication or API key.
- Each SlashDB user (pictured in blue) can be mapped to a database login (more on that in User Configuration section). As a result, every request from that user will execute queries in the database under privileges the assigned database user (db_user1, db_user2 or db_admin as pictured above in purple). Database permissions are effectively passed on to SlashDB user.
In above example we have 3 common scenarios:
- John is visiting SlashDB API via a browser. He logs in using his SlashDB username and password. He is identified as John and his browser receives a cookie. The cookie is sent with each subsequent request. John's account in SlashDB has been configured to use db_user1 database login when making queries. Effectively John can SELECT or UPDATE data, as those are the privileges that were configured in the database.
- A mobile application sends SlashDB credentials using Basic Authentication method. The credentials identifies the mobile application as SlashDB user App1, which uses database login db_user2 when connecting to the database. Effectively App1 can only SELECT data.
- Another application utilizes an API key to authenticate, which is sent with every request. The application is recognized as SlashDB user App2, which uses database login db_admin. Effectively this application can SELECT, UPDATE, INSERT and DELETE data.
Special accounts
admin
User "admin" is a superuser of SlashDB and is not limited by any rules with regards to configuration. Still to access data the "admin" user has to be mapped to database logins just like a regular user does.
public
SlashDB treats unauthenticated requests as user "public" and we can set grants for that user as any other user using User Configuration.
For example let's give public user access to Chinook database.
Requests that do not provide any authentication will identified as user public.
User public has only mapping for Chinook database thus we'll find only the Chinook on list of available databases.
curl -i 'http://localhost/db.json'
HTTP/1.1 200 OK
{
"Chinook": "/db/Chinook.json",
"__href": "/db.json"
}
When we remove Database Mapping for Chinook we receive 404 Not Found.
curl -i 'http://localhost/db.json'
HTTP/1.1 404 Not Found
Warning: No models for user public.
{"http_code": 404, "description": "No models for user public."}
And if we remove user public completely we'll get 403 Forbidden.
curl -i 'http://localhost/db.json'
HTTP/1.1 403 Forbidden
Warning: Access was denied to this resource. Please log in with your username/password or resend your request with a valid API key.
{"http_code": 403, "description": "Access was denied to this resource. Please log in with your username/password or resend your request with a valid API key."}
Failed Authentication
Whenever a request cannot be assigned to a certain SlashDB user or that user is not authorized to access the resource a HTTP 403 Forbidden response is returned.
- 403 Forbidden
- response header Warning contains error message
- response body contains HTTP status code and description is the same format as request e.g. JSON
curl -i "https://localhost/userdef/admin.json"
HTTP/1.1 403 Forbidden
Server: nginx/1.12.2
Date: Mon, 23 Sep 2019 08:56:41 GMT
Content-Type: application/json
Content-Length: 159
Connection: keep-alive
Warning: Access was denied to this resource. Please log in with your username/password or resend your request with a valid API key.
{"http_code": 403, "description": "Access was denied to this resource. Please log in with your username/password or resend your request with a valid API key."}
More information about status codes can be found in sections about Client Errors and Server Errors.
HTTPS/SSL
HTTPS provides authentication of the web server and encryption of communication between client and server. It's strongly recommended to use it especially that it's easily configurable for SlashDB.
To enable HTTP Secure you will need:
- access the SlashDB instance via SSH
- a private key and a certificate or configure Let's Encrypt service
- modify NGINX configuration in
/etc/slashdb/nginx.conf
Using the Let's Encrypt service
Let's Encrypt is nonprofit Certificate Authority providing free SSL certificates. Visits the Getting Started page to find out how to correctly setup a free and renewable certificate.
Install SSL certificate
When you're in possession of a valid key and certificate for the domain you only need to upload the files to the SlashDB instance and then update nginx configuration.
For testing or development purposes only you may generate a self-signed certificate. Unfortunately the browser and REST clients will complain about insecure communication.
Run below command to create self signed key and certificate and save them in /etc/slashdb
directory
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/slashdb/nginx-selfsigned.key \
-out /etc/slashdb/nginx-selfsigned.crt
Configuring HTTPS in NGINX
Add NGINX directives listen
, ssl_certificate
and ssl_certificate_key
to NGINX configuration file /etc/slashdb/nginx.conf
.
server {
listen 80;
listen 443 ssl;
server_name your-slashdb-domain.com;
ssl_certificate /etc/slashdb/nginx-selfsigned.crt;
ssl_certificate_key /etc/slashdb/nginx-selfsigned.key;
}
It's a good practice to redirect traffic from HTTP to HTTPS. To do so create additional:
- server in NGINX config that returns 301 Moved Permanently that points to HTTPS URL
- comment out
listen 80
on server with HTTPS
server {
listen 80;
server_name your-slashdb-domain.com;
return 301 https://$host$request_uri;
}
server {
#listen 80;
listen 443 ssl;
server_name your-slashdb-domain.com;
ssl_certificate /etc/slashdb/nginx-selfsigned.crt;
ssl_certificate_key /etc/slashdb/nginx-selfsigned.key;
location ~ /db*|/query* {
uwsgi_pass slashdb_app;
include uwsgi_params;
}
}
NGINX server restart is needed to apply changes
sudo /etc/init.d/nginx restart`
It's also important to remember to allow inbound traffic on port 443 especially for Microsoft Azure or Amazon EC2
More detail about using instructions on enabling HTTPS can be found in this tutorial
Use AWS Certificate Manager for EC2 instances of SlashDB
The AWS EC2 instances of SlashDB can be setup with AWS Application Load Balancer to create a single endpoint for the service and AWS Certificate Manager to easily manage SSL/TLS certificates.
For more information please follow documentation of AWS Application Load Balancer and AWS Certificate Manager.
Cross-Origin Resource Sharing (CORS)
CORS mechanism allows to control which origin (domains) are accepted by SlashDB server and what HTTP methods and headers are exposed to those domains.
Those rules can be configured in SlashDB ini settings file /etc/slashdb/slashdb.ini
in section [filter:cors]
. By default SlashDB comes with free policy which allows traffic from any domain.
[filter:cors]
use = egg:wsgicors#middleware
# CORS available policies
# "free" policy
free_origin=copy
free_headers=*
free_expose_headers=Set-Cookie, Warning
free_methods=HEAD, OPTIONS, GET, POST, PUT, DELETE
free_maxage=180
free_credentials=true
# CORS enabled policies
policy=free
Please refer to wsgicors documentation for details on setting up CORS policies.