elency-config is a http application built on the node.js platform to provide configuration management for multi-tenant applications hosted on any platform.
- Prerequisites
- Install
- Configuration
- MongoDb
- How does it work?
- Security
- Ping endpoint
- Health endpoint
- Users/Roles
- LDAP
- Keys
- Configuration Data
- License
This document assumes you will be installing elency-config on a linux based system.
elency-config is built with nodejs and has the following dependencies.
- nodejs, the minimum supported
LTSversion is8.9.0. - mongoDB, the minimum supported version is
3.0. It ishighlyrecommended that the mongo server being connected to is locked down and requires credentials.
This document assumes you will be installing elency-config on a linux based system.
The server should be setup with a reverse proxy in front of it over https and using valid SSL certificates.
-
Download elency-config-server.
-
Extract the above
tar.gzfile into a desired location on your machine.tar xzf ./elency-config-server-0.0.22-beta.tar.gz -
Create and add the relevant config and security files to the
configandsecdirectories. Refer to the Configuration section. -
Run the application
Execute the
startscript this will expose a node/express app on port3000. The port can be overriden by executing with aPORTenvironment variable.The start script installs
PM2and also sets up aservice../start -
Stopping the application
Execute the
stop script./stop
If you would like to run the server in a docker containerised environment you can make use of docker images.
Docker images exist for the server but as it is dependent on configuration data. Refer to the Configuration section.
Retrieval of configuration data to be injected into containers should be carried out following your company guidelines. Please refer to the security section about storage of secure information.
Firstly within a directory you will need a docker-compose.yml which contains some of the following yml:
version: '3'
services:
app:
container_name: elency-config-server
image: croweman/elency-config-server:0.0.22-beta
restart: "on-failure:10"
volumes:
- ./configuration_files:/app/configuration_files
ports:
- "3000:3000"
environment:
CONFIG_JSON_VALUE:
KEYS_JSON_VALUE:
PRIVATE_PEM_VALUE:
PUBLIC_PEM_VALUE:Configuration can be injected into the container in either of the following 2 ways.
In a directory create a local configuration_files directory and copy the 4 configuration files into it at the root.
To bring up the container execute.
docker-compose up
You would need to read the relevant configuration values into environment variables and inject them into the container when bringing it up
CONFIG_JSON_VALUE=`cat ./config.json`
KEYS_JSON_VALUE=`cat ./keys.json`
PRIVATE_PEM_VALUE=`cat ./elency-config.private.pem`
PUBLIC_PEM_VALUE=`cat ./elency-config.public.pem`
rm ./config.json
rm ./keys.json
rm ./elency-config.private.pem
rm ./elency-config.public.pem
CONFIG_JSON_VALUE=$CONFIG_JSON_VALUE KEYS_JSON_VALUE=$KEYS_JSON_VALUE PRIVATE_PEM_VALUE=$PRIVATE_PEM_VALUE PUBLIC_PEM_VALUE=$PUBLIC_PEM_VALUE docker-compose up
The server is dependent on 4 configuration files. These files and content (encrypted/decrypted) should be stored securely following your company guidelines. Please refer to the security section about storage of secure information.
-
You will need to generate a
publicandprivatekey pair.This key pair will be used to encrypt/decrypt configuration files and some mongo data.
These files should live within the
secfolder.cd ./elency-config-server openssl genrsa -out ./sec/elency-config.private.pem 2048 openssl rsa -in ./sec/elency-config.private.pem -outform PEM -pubout -out ./sec/elency-config.public.pem -
Create
config.jsonconfiguration file.Create a
config.jsonfile within theconfigfolder and update its settings!If running
locallyorproxied(overhttp, nothttps) the UI routes will not work ifrunOverHttphas a value offalse, you will need to change this totrue!{ "mongoUrl": "mongodb://localhost:27017/elency-config", "HMACAuthorizationKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "exposeUIRoutes": true, "maxJsonPostSize": "1mb", "runOverHttp": false, "sessionLifeTimeInMinutes": 20160, "validateAuthorizationTokenWindow": true, "authorizationTokenValidationWindowInSeconds": 300 }mongoUrl: Defines the mongo url, it is recommended you use credentials and lock down the mongo db.HMACAuthorizationKey: This is the key used for creating authorization headers. It should be a32characterbase64encoding string.exposeUIRoutes: (default: false) Defines whether the admin interface should be exposed.maxJsonPostSize: (default:1mb) Defines the max payload size that can be posted.runOverHttp: (default: false) Defines whether the web application is running over http (not https) and should create non secure cookies.sessionLifeTimeInMinutes: (default: 20160 (14 days)) Defines the life time of a session cookie.validateAuthorizationTokenWindow: (default: false) Defines whether the authorization token timestamp should be validated.authorizationTokenValidationWindowInSeconds: (default: 300) Defines the authorization token validation window in seconds.
-
Create
keys.jsonconfiguration file.Create a
keys.jonfile within theconfig folderand update its settings!{ "configEncryptionKey": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" }configEncryptionKey: This is the key used for some encryption. It should be a32characterbase64encoding string.
-
run the
encrypt-configuration-filestoolExecute either the node or bash
encrypt-configuration-filestool to encrypt and decrypt the configuration files (config.jsonandkeys.json).node:
// encrypt node ./encrypt-configuration-files.js // decrypt node ./encrypt-configuration-files.js -dThe file can be found here.
The data storage mechanism used is mongoDB. elency-config is dependent on a number of collections and indexes.
If the connection string you are using is locked down to a specific account and this account does not have permissions to create indexes then these will have to be manually created!
Index definitions can be found here.
The server provides a REST API for retrieving configuration data for a team/application. It also optionally provides a Web UI for administering various data.
Essentially clients are used and configured to connect to the REST API and utilise access tokens and decryption keys. These clients will request configuration data from a server based on an appId, environment and version e.g. 1.0.0.
The server will process the following rules to determine what configuration (if any) should be returned:
- The configuration is
published. - the
configuration versionisless than or equal tothe givenversion. - the
configuration versionreturned is the highest of all matches of the above criteria. - the
configurationreturned is the most recent revision of the above criteria.
The server allows you to configure many things, some of which are the following:
- Teams
- Applications
- Environments
- Users (Optionally LDAP)
- Permissions
- Configuration Data
- Keys
The best way to see how it works is to have a play.
The server stores all of its data with in a mongo database, some of which is hashed or encrypted.
When installing the server, setting up the admin user or creating any keys, it is recommended you store sensitive data and the .pem key files, keys and configuration files securely following your company guidelines. As you may need to recover them following a failure.
The following recommendations are advised:
-
The
mongoDBserver being connected to should be locked down to require credentials in the connection string. These would be configured in theconfig.jsonfile which will be encrypted. -
The
servershould be exposed overhttpsfor secure communication of sensitive data. ValidSSL certificatesshould be used. -
All types of
keysshouldnotbe stored incode basesorsource controlproviders. -
When creating
configurationentries anyentriesthat potentially containsecuredata should be marked asSecure. These are encrypted and will need to be decrypted by clients. -
Clients that consume the server
REST APIand make use ofHMAC AuthorizationandConfiguration Encryptionkeys should retrieve thekeysfollowing best practises andnotbe stored in code bases.
A ping endpoint is provided so that you can determine whether the application is up and exposing routes e.g. http://address/private/ping.
The endpoint will return a 200 status code and a pong in the response.
A health endpoint is provided so that you can determine whether the application is up and exposing routes but also healthy e.g. http://address/private/health.
The endpoint will return a 200 status code if the application is healthy.
On the initial first run of the server you will have to setup a password for the admin user. This user has permissions to:
- Create users
- Edit users
- Change passwords.
The following roles are available for a user:
administrator: Can create/edit users, change settings, create teams, create keys.team-writer: Can create teams and apps.key-writer: Can create keys.
Additional roles can be created.
Setting permissions to be able to create applications, environments and configuration is configured per user/role.
These permissions may be set per team or per app and will be to:
- Read
- Write
- Publish
LDAP security can be configured by an administrator by configuring Settings.
When creating environments they will need a key associated with them.
Keys can be created through the admin ui.
When editing a key. Its value can be decrypted by having access to the elency-config.private.pem file.
Keys should be 32 character base64 encoded strings.
These can be generated through the ui or by using key-generator.js.
Configuration is stored under a applications configured environment.
An application environment can have many configurations associated with it.
Configuration data is stored in key value pairs and can be encrypted.
The validity of configuration data can be optionally enforced through JSON Schemas which can be configured at application or application environment level.
If a JSON Schema is configured at both application and application environment level then the application environment JSON Schema takes precidence.
An example JSON Schema may look like this:
{
"properties": {
"LOG_LEVEL": {
"type": "string",
"enum": ["info", "debug", "warn", "error", "fatal"]
},
"MONGODB_URL": {
"type": "string",
"minLength": 1,
"secure": true
}
},
"required": [
"LOG_LEVEL",
"MONGODB_URL"
]
}"secure": true indicates that the property must be marked as Encrypted in the admin UI.
(The MIT License)
Copyright (c) 2020 Lee Crowe a.k.a. croweman
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.