diff --git a/README.md b/README.md
index e0e475f..5a168e5 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,9 @@
     - username: admin
     - password: admin
     
+> **重要提示**: `master` 分支在开发过程中可能处于 *不稳定的状态* 。
+请通过[releases](https://github.com/pycook/cmdb/releases)获取
+    
 Overview
 ----
 ![基础资源视图](https://raw.githubusercontent.com/pycook/cmdb/master/ui/public/cmdb01.jpeg)
diff --git a/api/lib/database.py b/api/lib/database.py
index 82c6c62..7b50d38 100644
--- a/api/lib/database.py
+++ b/api/lib/database.py
@@ -10,9 +10,9 @@ from api.lib.exception import CommitException
 
 class FormatMixin(object):
     def to_dict(self):
-        return dict([(k.name,
-                      getattr(self, k.name) if not isinstance(getattr(self, k.name), datetime.datetime) else getattr(
-                          self, k.name).strftime('%Y-%m-%d %H:%M:%S')) for k in getattr(self, "__table__").columns])
+        return dict([(k.name, isinstance(getattr(self, k.name), datetime.datetime) and
+                      getattr(self, k.name).strftime('%Y-%m-%d %H:%M:%S')) or
+                     getattr(self, k.name) for k in getattr(self, "__table__").columns])
 
     @classmethod
     def get_columns(cls):
diff --git a/api/lib/perm/acl/user.py b/api/lib/perm/acl/user.py
index 5832a47..178502c 100644
--- a/api/lib/perm/acl/user.py
+++ b/api/lib/perm/acl/user.py
@@ -1,7 +1,12 @@
 # -*- coding:utf-8 -*-
 
 
+import uuid
+import string
+import random
+
 from flask import abort
+from flask import g
 
 from api.extensions import db
 from api.lib.perm.acl.cache import UserCache
@@ -20,12 +25,21 @@ class UserCRUD(object):
         return numfound, query.offset((page - 1) * page_size).limit(page_size)
 
     @staticmethod
-    def add(**kwargs):
+    def _gen_key_secret():
+        key = uuid.uuid4().hex
+        secret = ''.join(random.sample(string.ascii_letters + string.digits + '~!@#$%^&*?', 32))
+
+        return key, secret
+
+    @classmethod
+    def add(cls, **kwargs):
         existed = User.get_by(username=kwargs['username'], email=kwargs['email'])
         existed and abort(400, "User <{0}> is already existed".format(kwargs['username']))
 
-        kwargs['nickname'] = kwargs['username'] if not kwargs.get('nickname') else kwargs['nickname']
+        kwargs['nickname'] = kwargs.get('nickname') or kwargs['username']
         kwargs['block'] = 0
+        kwargs['key'], kwargs['secret'] = cls._gen_key_secret()
+
         return User.create(**kwargs)
 
     @staticmethod
@@ -36,6 +50,13 @@ class UserCRUD(object):
 
         return user.update(**kwargs)
 
+    @classmethod
+    def reset_key_secret(cls):
+        key, secret = cls._gen_key_secret()
+        g.user.update(key=key, secret=secret)
+
+        return key, secret
+
     @classmethod
     def delete(cls, uid):
         user = User.get_by_id(uid) or abort(404, "User <{0}> does not exist".format(uid))
diff --git a/api/models/acl.py b/api/models/acl.py
index d1b3056..b6e43e0 100644
--- a/api/models/acl.py
+++ b/api/models/acl.py
@@ -11,6 +11,7 @@ from flask_sqlalchemy import BaseQuery
 from api.extensions import db
 from api.lib.database import CRUDModel
 from api.lib.database import Model
+from api.lib.database import SoftDeleteMixin
 
 
 class App(Model):
@@ -34,6 +35,7 @@ class UserQuery(BaseQuery):
             authenticated = user.check_password(password)
         else:
             authenticated = False
+
         return user, authenticated
 
     def authenticate_with_key(self, key, secret, args, path):
@@ -45,6 +47,7 @@ class UserQuery(BaseQuery):
             authenticated = True
         else:
             authenticated = False
+
         return user, authenticated
 
     def search(self, key):
@@ -55,18 +58,21 @@ class UserQuery(BaseQuery):
 
     def get_by_username(self, username):
         user = self.filter(User.username == username).first()
+
         return user
 
     def get_by_nickname(self, nickname):
         user = self.filter(User.nickname == nickname).first()
+
         return user
 
     def get(self, uid):
         user = self.filter(User.uid == uid).first()
+
         return copy.deepcopy(user)
 
 
-class User(CRUDModel):
+class User(CRUDModel, SoftDeleteMixin):
     __tablename__ = 'users'
     __bind_key__ = "user"
     query_class = UserQuery
@@ -107,9 +113,7 @@ class User(CRUDModel):
     def _set_password(self, password):
         self._password = hashlib.md5(password.encode('utf-8')).hexdigest()
 
-    password = db.synonym("_password",
-                          descriptor=property(_get_password,
-                                              _set_password))
+    password = db.synonym("_password", descriptor=property(_get_password, _set_password))
 
     def check_password(self, password):
         if self.password is None:
diff --git a/api/views/acl/user.py b/api/views/acl/user.py
index 9e0d576..e564535 100644
--- a/api/views/acl/user.py
+++ b/api/views/acl/user.py
@@ -6,8 +6,8 @@ from flask import session
 from flask_login import current_user
 
 from api.lib.decorator import args_required
-from api.lib.perm.acl.user import UserCRUD
 from api.lib.perm.acl.role import RoleRelationCRUD
+from api.lib.perm.acl.user import UserCRUD
 from api.lib.utils import get_page
 from api.lib.utils import get_page_size
 from api.resource import APIView
@@ -36,11 +36,17 @@ class UserView(APIView):
 
         id2parents = RoleRelationCRUD.get_parents(uids=[i.uid for i in users])
 
+        users = [i.to_dict() for i in users]
+        for u in users:
+            u.pop('password', None)
+            u.pop('key', None)
+            u.pop('secret', None)
+
         return self.jsonify(numfound=numfound,
                             page=page,
                             page_size=page_size,
                             id2parents=id2parents,
-                            users=[i.to_dict() for i in users])
+                            users=users)
 
     @args_required('username')
     @args_required('email')
@@ -58,3 +64,15 @@ class UserView(APIView):
         UserCRUD.delete(uid)
 
         return self.jsonify(uid=uid)
+
+
+class UserResetKeySecretView(APIView):
+    url_prefix = "/users/reset_key_secret"
+
+    def post(self):
+        key, secret = UserCRUD.reset_key_secret()
+
+        return self.jsonify(key=key, secret=secret)
+
+    def put(self):
+        return self.post()