diff -rNu buildbot/secrets.orig/providers/__init__.py buildbot/secrets/providers/__init__.py
--- buildbot/secrets.orig/providers/__init__.py	1970-01-01 01:00:00.000000000 +0100
+++ buildbot/secrets/providers/__init__.py	2017-03-28 21:52:03.947803965 +0200
@@ -0,0 +1,14 @@
+# This file is part of Buildbot.  Buildbot is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright Buildbot Team Members
diff -rNu buildbot/secrets.orig/providers/base.py buildbot/secrets/providers/base.py
--- buildbot/secrets.orig/providers/base.py	1970-01-01 01:00:00.000000000 +0100
+++ buildbot/secrets/providers/base.py	2017-03-28 21:52:03.947803965 +0200
@@ -0,0 +1,35 @@
+# This file is part of Buildbot.  Buildbot is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright Buildbot Team Members
+"""
+secret provider interface
+"""
+from __future__ import absolute_import
+from __future__ import print_function
+
+import abc
+
+from buildbot.util.service import BuildbotService
+
+
+class SecretProviderBase(BuildbotService):
+    """
+        Secret provider base
+    """
+
+    @abc.abstractmethod
+    def get(self, *args, **kwargs):
+        """
+        this should be an abstract method
+        """
diff -rNu buildbot/secrets.orig/providers/file.py buildbot/secrets/providers/file.py
--- buildbot/secrets.orig/providers/file.py	1970-01-01 01:00:00.000000000 +0100
+++ buildbot/secrets/providers/file.py	2017-03-28 21:52:03.947803965 +0200
@@ -0,0 +1,82 @@
+# This file is part of Buildbot.  Buildbot is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright Buildbot Team Members
+"""
+file based provider
+"""
+from __future__ import absolute_import
+from __future__ import print_function
+
+import os
+import stat
+
+from buildbot import config
+from buildbot.secrets.providers.base import SecretProviderBase
+
+
+class SecretInAFile(SecretProviderBase):
+    """
+    secret is stored in a separate file under the given directory name
+    """
+    name = "SecretInAFile"
+
+    def checkFileIsReadOnly(self, dirname, secretfile):
+        filepath = os.path.join(dirname, secretfile)
+        obs_stat = stat.S_IMODE(os.stat(filepath).st_mode)
+        if (obs_stat & 0o77) != 0 and os.name == "posix":
+            config.error("Permissions %s on file %s are too open."
+                         " It is required that your secret files are NOT"
+                         " accessible by others!" % (oct(obs_stat),
+                                                     secretfile))
+
+    def checkSecretDirectoryIsAvailableAndReadable(self, dirname, suffixes):
+        if not os.access(dirname, os.F_OK):
+            config.error("directory %s does not exists" % dirname)
+        for secretfile in os.listdir(dirname):
+            for suffix in suffixes:
+                if secretfile.endswith(suffix):
+                    self.checkFileIsReadOnly(dirname, secretfile)
+
+    def loadSecrets(self, dirname, suffixes):
+        secrets = {}
+        for secretfile in os.listdir(dirname):
+            secretvalue = None
+            for suffix in suffixes:
+                if secretfile.endswith(suffix):
+                    with open(os.path.join(dirname, secretfile)) as source:
+                        secretvalue = source.read()
+                    if suffix:
+                        secretfile = secretfile[:-len(suffix)]
+                    secrets[secretfile] = secretvalue
+        return secrets
+
+    def checkConfig(self, dirname, suffixes=None):
+        self._dirname = dirname
+        if suffixes is None:
+            suffixes = [""]
+        self.checkSecretDirectoryIsAvailableAndReadable(dirname,
+                                                        suffixes=suffixes)
+
+    def reconfigService(self, dirname, suffixes=None):
+        self._dirname = dirname
+        self.secrets = {}
+        if suffixes is None:
+            suffixes = [""]
+        self.secrets = self.loadSecrets(self._dirname, suffixes=suffixes)
+
+    def get(self, entry):
+        """
+        get the value from the file identified by 'entry'
+        """
+        return self.secrets.get(entry)
diff -rNu buildbot/secrets.orig/providers/vault.py buildbot/secrets/providers/vault.py
--- buildbot/secrets.orig/providers/vault.py	1970-01-01 01:00:00.000000000 +0100
+++ buildbot/secrets/providers/vault.py	2017-03-28 21:52:03.947803965 +0200
@@ -0,0 +1,67 @@
+# This file is part of Buildbot.  Buildbot is free software: you can
+# redistribute it and/or modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation, version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright Buildbot Team Members
+"""
+vault based providers
+"""
+
+from __future__ import absolute_import
+from __future__ import print_function
+
+from twisted.internet import defer
+
+from buildbot import config
+from buildbot.secrets.providers.base import SecretProviderBase
+from buildbot.util import httpclientservice
+
+
+class HashiCorpVaultSecretProvider(SecretProviderBase):
+    """
+    basic provider where each secret is stored in Vault
+    """
+
+    name = 'SecretInVault'
+
+    def checkConfig(self, vaultServer=None, vaultToken=None, secretsmount=None):
+        if not isinstance(vaultServer, str):
+            config.error("vaultServer must be a string while it is %s" % (type(vaultServer,)))
+        if not isinstance(vaultToken, str):
+            config.error("vaultToken must be a string while it is %s" % (type(vaultToken,)))
+
+    @defer.inlineCallbacks
+    def reconfigService(self, vaultServer=None, vaultToken=None, secretsmount=None):
+        if secretsmount is None:
+            self.secretsmount = "secret"
+        else:
+            self.secretsmount = secretsmount
+        self.vaultServer = vaultServer
+        self.vaultToken = vaultToken
+        if vaultServer.endswith('/'):
+            vaultServer = vaultServer[:-1]
+        self._http = yield httpclientservice.HTTPClientService.getService(
+            self.master, self.vaultServer, headers={'X-Vault-Token': self.vaultToken})
+
+    @defer.inlineCallbacks
+    def get(self, entry):
+        """
+        get the value from vault secret backend
+        """
+        path = self.secretsmount + '/' + entry
+        proj = yield self._http.get('/v1/{0}'.format(path))
+        code = yield proj.code
+        if code != 200:
+            raise KeyError("The key %s does not exist in Vault provider: request"
+                           " return code:%d." % (entry, code))
+        json = yield proj.json()
+        defer.returnValue(json.get(u'data', {}).get('value'))
