diff --git a/package.json b/package.json
index acc29cd2e3d6ff9a605fde13cfaa6774243b6307..a7056dc915f19875538b5f4de96bda8d4fa764d9 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
   },
   "dependencies": {
     "apicache": "0.0.14",
+    "bcrypt": "^0.8.7",
     "body-parser": "^1.13.1",
     "chai": "^3.5.0",
     "chai-http": "^3.0.0",
@@ -23,11 +24,13 @@
     "faker": "^2.1.5",
     "forever": "^0.15.2",
     "js2xmlparser": "^1.0.0",
+    "jwt-simple": "^0.5.0",
     "method-override": "^2.3.3",
     "mocha": "^2.5.3",
     "monetdb-pool": "0.0.8",
     "mongoose": "^4.6.0",
     "nconf": "^0.6.x",
+    "passport": "^0.3.2",
     "squel": "^5.4.2",
     "winston": "^2.2.0"
   },
diff --git a/src/libs/app.js b/src/libs/app.js
index 5133df46dc0ebe60b00718ae57e9aea0dd6cbaf3..fa685039b525ff430eca6841908666b40d8b0300 100644
--- a/src/libs/app.js
+++ b/src/libs/app.js
@@ -16,7 +16,9 @@ const cache = require('apicache').options({ debug: config.debug }).middleware;
 
 const app = express();
 
-const api = require(`${libs}/routes/api`);
+const api = require('./routes/api');
+
+const passport = require('passport');
 
 const mongoose = require(`${libs}/db/mongoose`);
 
@@ -28,8 +30,6 @@ app.use(cookieParser());
 // Enable Cross-Origin Resource Sharing (CORS)
 app.use(cors());
 app.use(methodOverride());
-// Enable cache for 1 day
-app.use(cache('1 day'));
 // Enable maximum compression
 app.use(compression(9));
 // Middleware tha adds the squel object to req
diff --git a/src/libs/db/mongoose.js b/src/libs/db/mongoose.js
index 5be072989a67d56b69a9ce0cb184581ae4ecc42c..400898c67fc7d43cfa0cf3f2b9faa9176166a088 100644
--- a/src/libs/db/mongoose.js
+++ b/src/libs/db/mongoose.js
@@ -6,6 +6,8 @@ const log = require(`${libs}/log`)(module);
 
 const mongoose = require('mongoose');
 
+mongoose.Promise = global.Promise;
+
 module.exports = () => {
     // Get mongodb URI (ip and port) in config file
     const mongoUri = process.env.MONGO_URI || config.mongodb.uri;
diff --git a/src/libs/middlewares/passport.js b/src/libs/middlewares/passport.js
new file mode 100644
index 0000000000000000000000000000000000000000..76cdf5988286f2851c1a11c5f6d4cafc34308b51
--- /dev/null
+++ b/src/libs/middlewares/passport.js
@@ -0,0 +1,28 @@
+const JwtStrategy = require('passport-jwt').Strategy;
+const ExtractJwt = require('passport-jwt').ExtractJwt;
+const libs = `${process.cwd()}/libs`;
+const config = require(`${libs}/config`);
+const User = require(`${libs}/models/user`)
+
+module.exports = function(passport){
+    var opts = {};
+    opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
+    opts.secretOrKey = config.get('mongodb:secret');
+    passport.use(new JwtStrategy(opts, function(jwt_payload, done){
+        User.find({id: jwt_payload.id}, function(err, user){
+            if (err) {
+                return done(err);
+            }
+
+            if (!user) {
+                return done(null, false, {message: 'Unknown user'});
+            }
+
+            if (!user.comparePassword(password)) {
+                return done(null, false, {message: 'Invalid password'});
+            }
+
+            return done(null, user);
+        });
+    }));
+};
diff --git a/src/libs/models/user.js b/src/libs/models/user.js
new file mode 100644
index 0000000000000000000000000000000000000000..8c4f92a204ef9c3b410fb656c16c4af9ad6c7152
--- /dev/null
+++ b/src/libs/models/user.js
@@ -0,0 +1,89 @@
+const mongoose = require('mongoose');
+const bcrypt = require('bcrypt');
+const libs = `${process.cwd()}/libs`;
+const log = require(`${libs}/log`)(module);
+const Schema = mongoose.Schema;
+
+// set up a mongoose model
+var UserSchema = new Schema({
+    email: {
+        type: String,
+        unique: true,
+        required: true
+    },
+    password: {
+        type: String,
+        required: true
+    },
+    name: {
+        type: String,
+        required: true
+    },
+    cpf:{
+        type: String,
+        unique: true,
+        required: true
+    },
+    schooling: {
+        type: String,
+        required: true
+    },
+    course: {
+        type: String,
+    },
+    segment: {
+        type: String,
+        required: true
+    },
+    role: {
+        type: String,
+        required: true
+    },
+    institution_name: {
+        type: String,
+        required: true
+    },
+    state: {
+        type: String,
+        required: true
+    },
+    city: {
+        type: String,
+        required: true
+    },
+    receive_emails: {
+        type: Boolean
+    }
+
+});
+
+UserSchema.pre('save', function (next) {
+    var user = this;
+    if (this.isModified('password') || this.isNew) {
+        bcrypt.genSalt(10, function (err, salt) {
+            if (err) {
+                return next(err);
+            }
+            bcrypt.hash(user.password, salt, function (err, hash) {
+                if (err) {
+                    return next(err);
+                }
+                user.password = hash;
+                next();
+            });
+        });
+    } else {
+        return next();
+    }
+});
+
+UserSchema.methods.comparePassword = function (passw, cb) {
+    bcrypt.compare(passw, this.password, function (err, isMatch) {
+        if (err) {
+            return cb(err);
+        }
+        cb(null, isMatch);
+    });
+};
+
+module.exports = mongoose.model('User', UserSchema);
diff --git a/src/libs/routes/api.js b/src/libs/routes/api.js
index cb474d86ccf45991988531055fa016f083896296..4fc68cf2276302f91d8950720b90cffe5c0eea41 100644
--- a/src/libs/routes/api.js
+++ b/src/libs/routes/api.js
@@ -2,6 +2,12 @@ const express = require('express');
 
 const api = express();
 
+const libs = `${process.cwd()}/libs`;
+
+const config = require(`${libs}/config`);
+
+const cache = require('apicache').options({ debug: config.get('debug') }).middleware;
+
 const enrollment = require('./enrollment');
 
 const state = require('./state');
@@ -14,16 +20,20 @@ const school = require('./school');
 
 const simulation = require('./simulation');
 
+const user = require('./user');
+
 api.get('/', (req, res) => {
     res.json({ msg: 'SimCAQ API is running' });
 });
 
 // mount API routes
-api.use('/enrollment', enrollment);
-api.use('/state', state);
-api.use('/region', region);
-api.use('/city', city);
-api.use('/school', school);
+
+api.use('/user', user);
 api.use('/simulation', simulation);
+api.use('/enrollment', cache('1 day'), enrollment);
+api.use('/state', cache('15 day'), state);
+api.use('/region', cache('15 day'), region);
+api.use('/city', cache('15 day'), city);
+api.use('/school', cache('15 day'), school);
 
 module.exports = api;
diff --git a/src/libs/routes/user.js b/src/libs/routes/user.js
new file mode 100644
index 0000000000000000000000000000000000000000..c043a66b029197b592469d6ec10c26c7c33c819e
--- /dev/null
+++ b/src/libs/routes/user.js
@@ -0,0 +1,113 @@
+const express = require('express');
+
+const userApp = express();
+
+const libs = `${process.cwd()}/libs`;
+
+const config = require(`${libs}/config`);
+
+const log = require(`${libs}/log`)(module);
+
+const User = require(`${libs}/models/user`);
+
+const jwt = require('jwt-simple');
+
+const required_fields = ["email", "password", "name", "cpf", "schooling", "segment", "role", "institution_name", "state", "city"];
+
+
+function emailSyntax(email) {
+    const regex = /^(([^<>()\[\]\.,;:\s@\"]+(\.[^<>()\[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
+    return regex.test(email);
+}
+
+userApp.post('/', (req, res, next) => {
+    if (!req.body.email) {
+        res.json({success: false, msg: 'Please pass email.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    if (!req.body.password) {
+        res.json({success: false, msg: 'Please pass password.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    if(!emailSyntax(req.body.email)){
+        res.json({success: false, msg: 'Invalid email syntax.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    for (let property of required_fields){
+        // if(!Object.prototype.hasOwnProperty.call(req.body, property)){
+        //     res.json({success: false, msg: 'Please fill out all mandatory fields.'});
+        //     return;
+        // }
+    }
+    next();
+}, (req, res, next) => {
+    var newUser = new User({
+        email: req.body.email,
+        password: req.body.password,
+        name: req.body.name,
+        cpf: req.body.cpf,
+        schooling: req.body.schooling,
+        course: req.body.course,
+        segment: req.body.segment,
+        role: req.body.role,
+        institution_name: req.body.institution_name,
+        state: req.body.state,
+        city: req.body.city,
+        receive_emails: req.body.receive_emails
+    });
+
+    // save the user
+    newUser.save((err) => {
+        if (err) {
+            res.json({success: false, msg: 'Email already in use.'});
+        } else {
+            res.json({success: true, msg: 'Successful created new user.'});
+        }
+    });
+});
+
+userApp.post('/authenticate', (req, res, next) => {
+    if (!req.body.email || !req.body.password) {
+        res.json({success: false, msg: 'Please pass email and password.'});
+    } else {
+        next();
+    }
+
+}, (req, res, next) => {
+    User.findOne({
+        email: req.body.email
+    }, (err, user) => {
+        if (err) throw err;
+
+        if(!user){
+            res.json({success: false, msg: 'Authentication failed. User not found.'});
+        }
+        else {
+            user.comparePassword(req.body.password, (err, isMatch) => {
+                if (isMatch && !err) {
+                    var secret = config.get('mongodb:secret');
+
+                    // if user is found and password is right create a token
+                    var token = jwt.encode(user, secret);
+
+                    //returns user info including token as json
+                    res.json({success: true, token: 'JWT ' + token});
+                }
+                else {
+                    res.json({success: false, msg: 'Authentication failed. Wrong password'});
+                }
+            });
+        }
+    });
+});
+
+module.exports = userApp;