diff --git a/nomad/api/__main__.py b/nomad/api/__main__.py
index 9113d57b0570829413e960eaeadb53c0c26ac716..edb51b3e9784503454822193e819c50174804607 100644
--- a/nomad/api/__main__.py
+++ b/nomad/api/__main__.py
@@ -12,8 +12,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import nomad.api
+from werkzeug.wsgi import DispatcherMiddleware
+
+from nomad.api import app
+from nomad import config
+
+
+def run_dev_server(*args, **kwargs):
+    def simple(env, resp):
+        resp(b'200 OK', [(b'Content-Type', b'text/plain')])
+        return [
+            ('Development nomad api server. Api is served under %s/.' %
+                config.services.api_base_path).encode('utf-8')]
+
+    app.wsgi_app = DispatcherMiddleware(simple, {config.services.api_base_path: app.wsgi_app})
+    app.run(*args, **kwargs)
 
 
 if __name__ == '__main__':
-    nomad.api.app.run(debug=True, port=8000)
+    run_dev_server(debug=True, port=8000)
diff --git a/nomad/api/admin.py b/nomad/api/admin.py
index d846f01c12e9cc6e0cc142bcd74c32cade61e3c4..91a7f1bb2936ac7d8aa37a5dd25bf1234199d45f 100644
--- a/nomad/api/admin.py
+++ b/nomad/api/admin.py
@@ -12,35 +12,52 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from flask_restplus import abort
-
-from nomad import infrastructure
-from nomad.processing import Upload
-
-from .app import app, base_path
-
-
-# TODO in production this requires authorization
-@app.route('%s/admin/<string:operation>' % base_path, methods=['POST'])
-def call_admin_operation(operation):
-    """
-    Allows to perform administrative operations on the nomad services. The possible
-    operations are *repair_uploads*
-    (cleans incomplete or otherwise unexpectedly failed uploads), *reset* (clears all
-    databases and resets nomad).
-
-    .. :quickref: Allows to perform administrative operations on the nomad services.
-
-    :param string operation: the operation to perform
-    :status 400: unknown operation
-    :status 200: operation successfully started
-    :returns: an authentication token that is valid for 10 minutes.
-    """
-    if operation == 'repair_uploads':
-        Upload.repair_all()
-    if operation == 'reset':
-        infrastructure.reset()
-    else:
-        abort(400, message='Unknown operation %s' % operation)
-
-    return 'done', 200
+from flask import g
+from flask_restplus import abort, Resource
+
+from nomad import infrastructure, config
+
+from .app import api
+from .auth import login_really_required
+
+
+ns = api.namespace('admin', description='Administrative operations')
+
+
+@ns.route('/<string:operation>')
+@api.doc(params={'operation': 'The operation to perform.'})
+class AdminOperationsResource(Resource):
+    # TODO in production this requires authorization
+    @api.response(200, 'Operation performed')
+    @api.response(404, 'Operation does not exist')
+    @api.response(400, 'Operation not available/disabled')
+    @login_really_required
+    def post(self, operation):
+        """
+        Allows to perform administrative operations on the nomad services.
+
+        The possible operations are ``reset`` and ``remove``.
+
+        The ``reset`` operation will attempt to clear the contents of all databased and
+        indices.
+
+        The ``remove``operation will attempt to remove all databases. Expect the
+        api to stop functioning after this request.
+
+        Reset and remove can be disabled.
+        """
+        if g.user.email != 'admin':
+            abort(401, message='Only the admin user can perform this operation.')
+
+        if operation == 'reset':
+            if config.services.disable_reset:
+                abort(400, message='Operation is disabled')
+            infrastructure.reset()
+        elif operation == 'remove':
+            if config.services.disable_reset:
+                abort(400, message='Operation is disabled')
+            infrastructure.remove()
+        else:
+            abort(404, message='Unknown operation %s' % operation)
+
+        return dict(messager='Operation %s performed.' % operation), 200
diff --git a/nomad/api/app.py b/nomad/api/app.py
index 1d536317e8bb14bbd94092847e447882ce43f998..1c81c9761c7e7f44f1f3df1f2277f63eee468bbd 100644
--- a/nomad/api/app.py
+++ b/nomad/api/app.py
@@ -33,9 +33,11 @@ app = Flask(
     static_folder=os.path.abspath(os.path.join(os.path.dirname(__file__), '../../docs/.build/html')))
 """ The Flask app that serves all APIs. """
 
+app.config.setdefault('APPLICATION_ROOT', base_path)
 app.config.setdefault('RESTPLUS_MASK_HEADER', False)
 app.config.setdefault('RESTPLUS_MASK_SWAGGER', False)
 
+
 CORS(app)
 
 api = Api(
diff --git a/nomad/api/archive.py b/nomad/api/archive.py
index 470f60fa1f174ab13c9b186e86ba3a5b1c7004ec..465ec092f63b1d320fa555880d7e921a2a756801 100644
--- a/nomad/api/archive.py
+++ b/nomad/api/archive.py
@@ -26,14 +26,13 @@ from nomad import config
 from nomad.files import ArchiveFile, ArchiveLogFile
 from nomad.utils import get_logger
 
-from .app import api, base_path
+from .app import api
 from .auth import login_if_available
 from .common import calc_route
 
 ns = api.namespace(
-    '%s/archive' % base_path[1:] if base_path is not '' else 'archive',
-    description='Access archive data and archive processing logs.'
-)
+    'archive',
+    description='Access archive data and archive processing logs.')
 
 
 @calc_route(ns, '/logs')
diff --git a/nomad/api/auth.py b/nomad/api/auth.py
index 29ccbcf2b520854df9f5114f4346d7d0d9f64853..b46d1fba14ff86bad2ebf9f21ccc9c2e3ca00f58 100644
--- a/nomad/api/auth.py
+++ b/nomad/api/auth.py
@@ -42,7 +42,7 @@ from flask_httpauth import HTTPBasicAuth
 from nomad import config
 from nomad.coe_repo import User, LoginException
 
-from .app import app, api, base_path
+from .app import app, api
 
 app.config['SECRET_KEY'] = config.services.api_secret
 auth = HTTPBasicAuth()
@@ -121,9 +121,8 @@ def login_really_required(func):
 
 
 ns = api.namespace(
-    '%s/auth' % base_path[1:] if base_path is not '' else 'auth',
-    description='Authentication related endpoints.'
-)
+    'auth',
+    description='Authentication related endpoints.')
 
 
 @ns.route('/token')
diff --git a/nomad/api/raw.py b/nomad/api/raw.py
index a5672ad376390d90ecde44bb37d2cae0a152a58c..0052ed137b020adfd980aef572d1731a9e75c270 100644
--- a/nomad/api/raw.py
+++ b/nomad/api/raw.py
@@ -29,13 +29,10 @@ from werkzeug.exceptions import HTTPException
 from nomad.files import RepositoryFile
 from nomad.utils import get_logger
 
-from .app import api, base_path
+from .app import api
 from .auth import login_if_available
 
-ns = api.namespace(
-    '%s/raw' % base_path[1:] if base_path is not '' else 'raw',
-    description='Downloading raw data files.'
-)
+ns = api.namespace('raw', description='Downloading raw data files.')
 
 
 def fix_file_paths(path):
diff --git a/nomad/api/upload.py b/nomad/api/upload.py
index f2ba368ab73ba08d3f0f0d0e0857cc19ff51539c..35d5c52b62f84b3874adaddcda1ca2bf556534ea 100644
--- a/nomad/api/upload.py
+++ b/nomad/api/upload.py
@@ -27,13 +27,13 @@ from nomad.processing import NotAllowedDuringProcessing
 from nomad.utils import get_logger
 from nomad.files import UploadFile
 
-from .app import api, base_path
+from .app import api
 from .auth import login_really_required
 from .common import pagination_request_parser, pagination_model
 
 
 ns = api.namespace(
-    '%s/uploads' % base_path[1:] if base_path is not '' else 'uploads',
+    'uploads',
     description='Uploading data and tracing uploaded data and its processing.')
 
 
diff --git a/nomad/client.py b/nomad/client.py
index 5129837c29bdc74911a7919dbf2a98a06ff4b13b..b23a7fe7a6ed47399454c8396a9bb8a6ef329bee 100644
--- a/nomad/client.py
+++ b/nomad/client.py
@@ -327,9 +327,10 @@ def worker():
 @run.command(help='Run the nomad development api.')
 def api():
     config.service = 'nomad_api'
-    from nomad import infrastructure, api
+    from nomad import infrastructure
+    from nomad.api.__main__ import run_dev_server
     infrastructure.setup()
-    api.app.run(debug=True, port=8000)
+    run_dev_server(debug=True, port=8000)
 
 
 @cli.command(help='Runs tests and linting. Useful before commit code.')
diff --git a/nomad/coe_repo.py b/nomad/coe_repo.py
index 751b3ca861941edb6998072dbe85d55925f6c557..616728b67950dda51dc3970e46d55038c148c31c 100644
--- a/nomad/coe_repo.py
+++ b/nomad/coe_repo.py
@@ -346,3 +346,10 @@ def ensure_test_user(email):
     assert session.token == email, 'Test user %s session has unexpected token.' % email
 
     return existing
+
+
+def admin_user():
+    repo_db = infrastructure.repository_db
+    admin = repo_db.query(User).filter_by(user_id=1).first()
+    assert admin, 'Admin user does not exist.'
+    return admin
diff --git a/nomad/config.py b/nomad/config.py
index d50ac6aac73854861bdd3b0657180538c0b66631..bb1c7a379982a6fa4994579ed4968ff68a2f32a8 100644
--- a/nomad/config.py
+++ b/nomad/config.py
@@ -43,7 +43,7 @@ MongoConfig = namedtuple('MongoConfig', ['host', 'port', 'db_name'])
 LogstashConfig = namedtuple('LogstashConfig', ['enabled', 'host', 'tcp_port', 'level'])
 """ Used to configure and enable/disable the ELK based centralized logging. """
 
-NomadServicesConfig = namedtuple('NomadServicesConfig', ['api_host', 'api_port', 'api_base_path', 'api_secret'])
+NomadServicesConfig = namedtuple('NomadServicesConfig', ['api_host', 'api_port', 'api_base_path', 'api_secret', 'admin_password', 'disable_reset'])
 """ Used to configure nomad services: worker, handler, api """
 
 files = FilesConfig(
@@ -108,7 +108,9 @@ services = NomadServicesConfig(
     api_host=os.environ.get('NOMAD_API_HOST', 'localhost'),
     api_port=int(os.environ.get('NOMAD_API_PORT', 8000)),
     api_base_path=os.environ.get('NOMAD_API_BASE_PATH', '/nomad/api'),
-    api_secret=os.environ.get('NOMAD_API_SECRET', 'defaultApiSecret')
+    api_secret=os.environ.get('NOMAD_API_SECRET', 'defaultApiSecret'),
+    admin_password=os.environ.get('NOMAD_API_ADMIN_PASSWORD', 'password'),
+    disable_reset=os.environ.get('NOMAD_API_DISABLE_RESET', 'true') == 'false'
 )
 
 console_log_level = get_loglevel_from_env('NOMAD_CONSOLE_LOGLEVEL', default_level=logging.INFO)
diff --git a/nomad/empty_repository_db.sql b/nomad/empty_repository_db.sql
index 4eb25451994404645ca60fca4576ab653bac26bf..01290f59626d9abef58730e4061c8898e9bd3ee0 100644
--- a/nomad/empty_repository_db.sql
+++ b/nomad/empty_repository_db.sql
@@ -11,14 +11,14 @@ SET check_function_bodies = false;
 SET client_min_messages = warning;
 
 --
--- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: 
+-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner:
 --
 
 CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
 
 
 --
--- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: 
+-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner:
 --
 
 COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
@@ -41,7 +41,7 @@ SET default_tablespace = '';
 SET default_with_oids = false;
 
 --
--- Name: affiliations; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: affiliations; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.affiliations (
@@ -76,7 +76,7 @@ ALTER SEQUENCE public.affiliations_a_id_seq OWNED BY public.affiliations.a_id;
 
 
 --
--- Name: alembic_version; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: alembic_version; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.alembic_version (
@@ -87,7 +87,7 @@ CREATE TABLE public.alembic_version (
 ALTER TABLE public.alembic_version OWNER TO postgres;
 
 --
--- Name: atoms; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: atoms; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.atoms (
@@ -127,7 +127,7 @@ ALTER SEQUENCE public.atoms_atom_id_seq OWNED BY public.atoms.atom_id;
 
 
 --
--- Name: basis_sets; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: basis_sets; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.basis_sets (
@@ -145,7 +145,7 @@ CREATE TABLE public.basis_sets (
 ALTER TABLE public.basis_sets OWNER TO postgres;
 
 --
--- Name: calcsets; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: calcsets; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.calcsets (
@@ -157,7 +157,7 @@ CREATE TABLE public.calcsets (
 ALTER TABLE public.calcsets OWNER TO postgres;
 
 --
--- Name: calculations; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: calculations; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.calculations (
@@ -195,7 +195,7 @@ ALTER SEQUENCE public.calculations_calc_id_seq OWNED BY public.calculations.calc
 
 
 --
--- Name: charges; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: charges; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.charges (
@@ -212,7 +212,7 @@ CREATE TABLE public.charges (
 ALTER TABLE public.charges OWNER TO postgres;
 
 --
--- Name: citations; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: citations; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.citations (
@@ -246,7 +246,7 @@ ALTER SEQUENCE public.citations_citation_id_seq OWNED BY public.citations.citati
 
 
 --
--- Name: coauthorships; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: coauthorships; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.coauthorships (
@@ -258,7 +258,7 @@ CREATE TABLE public.coauthorships (
 ALTER TABLE public.coauthorships OWNER TO postgres;
 
 --
--- Name: codefamilies; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: codefamilies; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.codefamilies (
@@ -291,7 +291,7 @@ ALTER SEQUENCE public.codefamilies_family_id_seq OWNED BY public.codefamilies.fa
 
 
 --
--- Name: codeversions; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: codeversions; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.codeversions (
@@ -325,7 +325,7 @@ ALTER SEQUENCE public.codeversions_version_id_seq OWNED BY public.codeversions.v
 
 
 --
--- Name: doi_mapping; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: doi_mapping; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.doi_mapping (
@@ -358,7 +358,7 @@ ALTER SEQUENCE public.doi_mapping_calc_id_seq OWNED BY public.doi_mapping.calc_i
 
 
 --
--- Name: eigenvalues; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: eigenvalues; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.eigenvalues (
@@ -396,7 +396,7 @@ ALTER SEQUENCE public.eigenvalues_eid_seq OWNED BY public.eigenvalues.eid;
 
 
 --
--- Name: electrons; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: electrons; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.electrons (
@@ -409,7 +409,7 @@ CREATE TABLE public.electrons (
 ALTER TABLE public.electrons OWNER TO postgres;
 
 --
--- Name: energies; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: energies; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.energies (
@@ -422,7 +422,7 @@ CREATE TABLE public.energies (
 ALTER TABLE public.energies OWNER TO postgres;
 
 --
--- Name: forces; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: forces; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.forces (
@@ -434,7 +434,7 @@ CREATE TABLE public.forces (
 ALTER TABLE public.forces OWNER TO postgres;
 
 --
--- Name: grid; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: grid; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.grid (
@@ -446,7 +446,7 @@ CREATE TABLE public.grid (
 ALTER TABLE public.grid OWNER TO postgres;
 
 --
--- Name: lattices; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: lattices; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.lattices (
@@ -472,7 +472,7 @@ CREATE TABLE public.lattices (
 ALTER TABLE public.lattices OWNER TO postgres;
 
 --
--- Name: login_tokens; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: login_tokens; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.login_tokens (
@@ -485,7 +485,7 @@ CREATE TABLE public.login_tokens (
 ALTER TABLE public.login_tokens OWNER TO postgres;
 
 --
--- Name: metadata; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: metadata; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.metadata (
@@ -506,7 +506,7 @@ CREATE TABLE public.metadata (
 ALTER TABLE public.metadata OWNER TO postgres;
 
 --
--- Name: metadata_citations; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: metadata_citations; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.metadata_citations (
@@ -518,7 +518,7 @@ CREATE TABLE public.metadata_citations (
 ALTER TABLE public.metadata_citations OWNER TO postgres;
 
 --
--- Name: ownerships; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: ownerships; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.ownerships (
@@ -530,7 +530,7 @@ CREATE TABLE public.ownerships (
 ALTER TABLE public.ownerships OWNER TO postgres;
 
 --
--- Name: phonons; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: phonons; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.phonons (
@@ -541,7 +541,7 @@ CREATE TABLE public.phonons (
 ALTER TABLE public.phonons OWNER TO postgres;
 
 --
--- Name: pottypes; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: pottypes; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.pottypes (
@@ -574,7 +574,7 @@ ALTER SEQUENCE public.pottypes_pottype_id_seq OWNED BY public.pottypes.pottype_i
 
 
 --
--- Name: pragma; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: pragma; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.pragma (
@@ -585,7 +585,7 @@ CREATE TABLE public.pragma (
 ALTER TABLE public.pragma OWNER TO postgres;
 
 --
--- Name: recipintegs; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: recipintegs; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.recipintegs (
@@ -600,7 +600,7 @@ CREATE TABLE public.recipintegs (
 ALTER TABLE public.recipintegs OWNER TO postgres;
 
 --
--- Name: sessions; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: sessions; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.sessions (
@@ -615,7 +615,7 @@ CREATE TABLE public.sessions (
 ALTER TABLE public.sessions OWNER TO postgres;
 
 --
--- Name: shareships; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: shareships; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.shareships (
@@ -627,7 +627,7 @@ CREATE TABLE public.shareships (
 ALTER TABLE public.shareships OWNER TO postgres;
 
 --
--- Name: spacegroups; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: spacegroups; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.spacegroups (
@@ -639,7 +639,7 @@ CREATE TABLE public.spacegroups (
 ALTER TABLE public.spacegroups OWNER TO postgres;
 
 --
--- Name: struct_optimisation; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: struct_optimisation; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.struct_optimisation (
@@ -652,7 +652,7 @@ CREATE TABLE public.struct_optimisation (
 ALTER TABLE public.struct_optimisation OWNER TO postgres;
 
 --
--- Name: struct_ratios; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: struct_ratios; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.struct_ratios (
@@ -668,7 +668,7 @@ CREATE TABLE public.struct_ratios (
 ALTER TABLE public.struct_ratios OWNER TO postgres;
 
 --
--- Name: structures; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: structures; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.structures (
@@ -703,7 +703,7 @@ ALTER SEQUENCE public.structures_struct_id_seq OWNED BY public.structures.struct
 
 
 --
--- Name: tags; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: tags; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.tags (
@@ -715,7 +715,7 @@ CREATE TABLE public.tags (
 ALTER TABLE public.tags OWNER TO postgres;
 
 --
--- Name: topics; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: topics; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.topics (
@@ -749,7 +749,7 @@ ALTER SEQUENCE public.topics_tid_seq OWNED BY public.topics.tid;
 
 
 --
--- Name: uploads; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: uploads; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.uploads (
@@ -788,7 +788,7 @@ ALTER SEQUENCE public.uploads_upload_id_seq OWNED BY public.uploads.upload_id;
 
 
 --
--- Name: user_metadata; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: user_metadata; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.user_metadata (
@@ -801,7 +801,7 @@ CREATE TABLE public.user_metadata (
 ALTER TABLE public.user_metadata OWNER TO postgres;
 
 --
--- Name: users; Type: TABLE; Schema: public; Owner: postgres; Tablespace: 
+-- Name: users; Type: TABLE; Schema: public; Owner: postgres; Tablespace:
 --
 
 CREATE TABLE public.users (
@@ -1155,8 +1155,8 @@ INSERT INTO public.pragma VALUES ('4.59');
 -- Data for Name: sessions; Type: TABLE DATA; Schema: public; Owner: postgres
 --
 
-INSERT INTO public.sessions VALUES ('leonard.hofstadter@nomad-fairdi.tests.de', 2, '2100-12-17 09:00:00+00', NULL, NULL);
-INSERT INTO public.sessions VALUES ('sheldon.cooper@nomad-fairdi.tests.de', 1, '2100-12-17 09:00:00+00', NULL, NULL);
+INSERT INTO public.sessions VALUES ('leonard.hofstadter@nomad-fairdi.tests.de', 3, '2100-12-17 09:00:00+00', NULL, NULL);
+INSERT INTO public.sessions VALUES ('sheldon.cooper@nomad-fairdi.tests.de', 2, '2100-12-17 09:00:00+00', NULL, NULL);
 
 
 --
@@ -1238,8 +1238,9 @@ SELECT pg_catalog.setval('public.uploads_upload_id_seq', 1, false);
 -- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: postgres
 --
 
-INSERT INTO public.users VALUES (1, 'Sheldon', 'Cooper', 'sheldon.cooper', 'sheldon.cooper@nomad-fairdi.tests.de', NULL, '$2y$12$jths1LQPsLofuBQ3evVIluhQeQ/BZfbdTSZHFcPGdcNmHz2WvDj.y', NULL);
-INSERT INTO public.users VALUES (2, 'Leonard', 'Hofstadter', 'leonard.hofstadter', 'leonard.hofstadter@nomad-fairdi.tests.de', NULL, '$2y$12$jths1LQPsLofuBQ3evVIluhQeQ/BZfbdTSZHFcPGdcNmHz2WvDj.y', NULL);
+INSERT INTO public.users VALUES (1, 'admin', 'admin', 'admin', 'admin', NULL, NULL, NULL);
+INSERT INTO public.users VALUES (2, 'Sheldon', 'Cooper', 'sheldon.cooper', 'sheldon.cooper@nomad-fairdi.tests.de', NULL, '$2y$12$jths1LQPsLofuBQ3evVIluhQeQ/BZfbdTSZHFcPGdcNmHz2WvDj.y', NULL);
+INSERT INTO public.users VALUES (3, 'Leonard', 'Hofstadter', 'leonard.hofstadter', 'leonard.hofstadter@nomad-fairdi.tests.de', NULL, '$2y$12$jths1LQPsLofuBQ3evVIluhQeQ/BZfbdTSZHFcPGdcNmHz2WvDj.y', NULL);
 
 
 --
@@ -1250,7 +1251,7 @@ SELECT pg_catalog.setval('public.users_user_id_seq', 1, true);
 
 
 --
--- Name: affiliations_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: affiliations_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.affiliations
@@ -1258,7 +1259,7 @@ ALTER TABLE ONLY public.affiliations
 
 
 --
--- Name: atoms_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: atoms_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.atoms
@@ -1266,7 +1267,7 @@ ALTER TABLE ONLY public.atoms
 
 
 --
--- Name: basis_sets_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: basis_sets_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.basis_sets
@@ -1274,7 +1275,7 @@ ALTER TABLE ONLY public.basis_sets
 
 
 --
--- Name: calculations_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: calculations_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.calculations
@@ -1282,7 +1283,7 @@ ALTER TABLE ONLY public.calculations
 
 
 --
--- Name: charges_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: charges_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.charges
@@ -1290,7 +1291,7 @@ ALTER TABLE ONLY public.charges
 
 
 --
--- Name: citations_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: citations_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.citations
@@ -1298,7 +1299,7 @@ ALTER TABLE ONLY public.citations
 
 
 --
--- Name: citations_value_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: citations_value_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.citations
@@ -1306,7 +1307,7 @@ ALTER TABLE ONLY public.citations
 
 
 --
--- Name: codefamilies_content_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: codefamilies_content_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.codefamilies
@@ -1314,7 +1315,7 @@ ALTER TABLE ONLY public.codefamilies
 
 
 --
--- Name: codefamilies_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: codefamilies_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.codefamilies
@@ -1322,7 +1323,7 @@ ALTER TABLE ONLY public.codefamilies
 
 
 --
--- Name: codeversions_content_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: codeversions_content_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.codeversions
@@ -1330,7 +1331,7 @@ ALTER TABLE ONLY public.codeversions
 
 
 --
--- Name: codeversions_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: codeversions_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.codeversions
@@ -1338,7 +1339,7 @@ ALTER TABLE ONLY public.codeversions
 
 
 --
--- Name: doi_mapping_id_str_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: doi_mapping_id_str_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.doi_mapping
@@ -1346,7 +1347,7 @@ ALTER TABLE ONLY public.doi_mapping
 
 
 --
--- Name: doi_mapping_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: doi_mapping_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.doi_mapping
@@ -1354,7 +1355,7 @@ ALTER TABLE ONLY public.doi_mapping
 
 
 --
--- Name: eigenvalues_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: eigenvalues_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.eigenvalues
@@ -1362,7 +1363,7 @@ ALTER TABLE ONLY public.eigenvalues
 
 
 --
--- Name: electrons_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: electrons_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.electrons
@@ -1370,7 +1371,7 @@ ALTER TABLE ONLY public.electrons
 
 
 --
--- Name: energies_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: energies_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.energies
@@ -1378,7 +1379,7 @@ ALTER TABLE ONLY public.energies
 
 
 --
--- Name: forces_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: forces_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.forces
@@ -1386,7 +1387,7 @@ ALTER TABLE ONLY public.forces
 
 
 --
--- Name: grid_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: grid_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.grid
@@ -1394,7 +1395,7 @@ ALTER TABLE ONLY public.grid
 
 
 --
--- Name: lattices_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: lattices_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.lattices
@@ -1402,7 +1403,7 @@ ALTER TABLE ONLY public.lattices
 
 
 --
--- Name: login_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: login_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.login_tokens
@@ -1410,7 +1411,7 @@ ALTER TABLE ONLY public.login_tokens
 
 
 --
--- Name: metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.metadata
@@ -1418,7 +1419,7 @@ ALTER TABLE ONLY public.metadata
 
 
 --
--- Name: phonons_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: phonons_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.phonons
@@ -1426,7 +1427,7 @@ ALTER TABLE ONLY public.phonons
 
 
 --
--- Name: pottypes_name_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: pottypes_name_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.pottypes
@@ -1434,7 +1435,7 @@ ALTER TABLE ONLY public.pottypes
 
 
 --
--- Name: pottypes_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: pottypes_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.pottypes
@@ -1442,7 +1443,7 @@ ALTER TABLE ONLY public.pottypes
 
 
 --
--- Name: pragma_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: pragma_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.pragma
@@ -1450,7 +1451,7 @@ ALTER TABLE ONLY public.pragma
 
 
 --
--- Name: recipintegs_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: recipintegs_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.recipintegs
@@ -1458,7 +1459,7 @@ ALTER TABLE ONLY public.recipintegs
 
 
 --
--- Name: sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: sessions_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.sessions
@@ -1466,7 +1467,7 @@ ALTER TABLE ONLY public.sessions
 
 
 --
--- Name: spacegroups_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: spacegroups_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.spacegroups
@@ -1474,7 +1475,7 @@ ALTER TABLE ONLY public.spacegroups
 
 
 --
--- Name: struct_optimisation_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: struct_optimisation_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.struct_optimisation
@@ -1482,7 +1483,7 @@ ALTER TABLE ONLY public.struct_optimisation
 
 
 --
--- Name: struct_ratios_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: struct_ratios_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.struct_ratios
@@ -1490,7 +1491,7 @@ ALTER TABLE ONLY public.struct_ratios
 
 
 --
--- Name: structures_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: structures_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.structures
@@ -1498,7 +1499,7 @@ ALTER TABLE ONLY public.structures
 
 
 --
--- Name: topics_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: topics_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.topics
@@ -1506,7 +1507,7 @@ ALTER TABLE ONLY public.topics
 
 
 --
--- Name: u_children_parent_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_children_parent_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.calcsets
@@ -1514,7 +1515,7 @@ ALTER TABLE ONLY public.calcsets
 
 
 --
--- Name: u_coauthorships_calc_id_user; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_coauthorships_calc_id_user; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.coauthorships
@@ -1522,7 +1523,7 @@ ALTER TABLE ONLY public.coauthorships
 
 
 --
--- Name: u_coauthorships_user_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_coauthorships_user_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.coauthorships
@@ -1530,7 +1531,7 @@ ALTER TABLE ONLY public.coauthorships
 
 
 --
--- Name: u_metadata_citations_calc_citation; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_metadata_citations_calc_citation; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.metadata_citations
@@ -1538,7 +1539,7 @@ ALTER TABLE ONLY public.metadata_citations
 
 
 --
--- Name: u_metadata_citations_citation_calc; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_metadata_citations_citation_calc; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.metadata_citations
@@ -1546,7 +1547,7 @@ ALTER TABLE ONLY public.metadata_citations
 
 
 --
--- Name: u_ownerships_calc_id_user; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_ownerships_calc_id_user; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.ownerships
@@ -1554,7 +1555,7 @@ ALTER TABLE ONLY public.ownerships
 
 
 --
--- Name: u_ownerships_user_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_ownerships_user_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.ownerships
@@ -1562,7 +1563,7 @@ ALTER TABLE ONLY public.ownerships
 
 
 --
--- Name: u_parent_children_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_parent_children_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.calcsets
@@ -1570,7 +1571,7 @@ ALTER TABLE ONLY public.calcsets
 
 
 --
--- Name: u_shareships_calc_id_user; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_shareships_calc_id_user; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.shareships
@@ -1578,7 +1579,7 @@ ALTER TABLE ONLY public.shareships
 
 
 --
--- Name: u_shareships_user_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_shareships_user_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.shareships
@@ -1586,7 +1587,7 @@ ALTER TABLE ONLY public.shareships
 
 
 --
--- Name: u_tags_calc_id_tid; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_tags_calc_id_tid; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.tags
@@ -1594,7 +1595,7 @@ ALTER TABLE ONLY public.tags
 
 
 --
--- Name: u_tags_tid_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: u_tags_tid_calc_id; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.tags
@@ -1602,7 +1603,7 @@ ALTER TABLE ONLY public.tags
 
 
 --
--- Name: uploads_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: uploads_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.uploads
@@ -1610,7 +1611,7 @@ ALTER TABLE ONLY public.uploads
 
 
 --
--- Name: user_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: user_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.user_metadata
@@ -1618,7 +1619,7 @@ ALTER TABLE ONLY public.user_metadata
 
 
 --
--- Name: users_email_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: users_email_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.users
@@ -1626,7 +1627,7 @@ ALTER TABLE ONLY public.users
 
 
 --
--- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: users_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.users
@@ -1634,7 +1635,7 @@ ALTER TABLE ONLY public.users
 
 
 --
--- Name: users_username_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: 
+-- Name: users_username_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace:
 --
 
 ALTER TABLE ONLY public.users
diff --git a/nomad/infrastructure.py b/nomad/infrastructure.py
index 4dfc3c56ae745febd63811f5a30682ebcd51d735..41ffa53a1ca0a9604c8c9d929046e6082ebef11d 100644
--- a/nomad/infrastructure.py
+++ b/nomad/infrastructure.py
@@ -27,6 +27,7 @@ from sqlalchemy.orm import Session
 from elasticsearch.exceptions import RequestError
 from elasticsearch_dsl import connections
 from mongoengine import connect
+from passlib.hash import bcrypt
 
 from nomad import config, utils
 
@@ -128,6 +129,13 @@ def setup_repository_db():
                 "where table_name='users')")
             exists = cur.fetchone()[0]
 
+    # set the admin user password
+    with repository_db_connection() as conn:
+        with conn.cursor() as cur:
+            cur.execute(
+                "UPDATE public.users SET password='%s' WHERE user_id=1;" %
+                bcrypt.encrypt(config.services.admin_password, ident='2y'))
+
     if not exists:
         logger.info('repository db postgres schema does not exists')
         reset_repository_db()
@@ -262,7 +270,14 @@ def repository_db_connection(dbname=None, with_trans=True):
 
 def reset_repository_db():
     """ Drops the existing NOMAD-coe repository postgres schema and creates a new minimal one. """
-    with repository_db_connection() as conn:
+    if repository_db is not None:
+        repository_db.expunge_all()
+        repository_db.invalidate()
+
+    if repository_db_conn is not None:
+        repository_db_conn.close()
+
+    with repository_db_connection(with_trans=False) as conn:
         with conn.cursor() as cur:
             cur.execute(
                 "DROP SCHEMA public CASCADE;"
@@ -272,9 +287,3 @@ def reset_repository_db():
             sql_file = os.path.join(os.path.dirname(__file__), 'empty_repository_db.sql')
             cur.execute(open(sql_file, 'r').read())
             logger.info('(re-)created repository db postgres schema')
-
-
-if __name__ == '__main__':
-    # setup()
-    remove()
-    # reset_repository_db()
diff --git a/nomad/processing/data.py b/nomad/processing/data.py
index 26c8f76de80aeda12fd9805f3482f1a4b03b7ce4..8b2edd3e757567ce085693814b630ef3c295df01 100644
--- a/nomad/processing/data.py
+++ b/nomad/processing/data.py
@@ -28,14 +28,13 @@ from typing import List, Any, ContextManager, Tuple, Generator
 from elasticsearch.exceptions import NotFoundError
 from mongoengine import StringField, BooleanField, DateTimeField, DictField, IntField
 import logging
-import time
 from structlog import wrap_logger
 from contextlib import contextmanager
 
 from nomad import utils, coe_repo
 from nomad.files import UploadFile, ArchiveFile, ArchiveLogFile, File
 from nomad.repo import RepoCalc
-from nomad.processing.base import Proc, Chord, process, task, PENDING, SUCCESS, FAILURE, RUNNING
+from nomad.processing.base import Proc, Chord, process, task, PENDING, SUCCESS, FAILURE
 from nomad.parsing import parsers, parser_dict
 from nomad.normalizing import normalizers
 from nomad.utils import lnr
@@ -548,23 +547,3 @@ class Upload(Chord):
 
     def all_calcs(self, start, end, order_by='mainfile'):
         return Calc.objects(upload_id=self.upload_id)[start:end].order_by(order_by)
-
-    @staticmethod
-    def repair_all():
-        """
-        Utitlity function that will look for suspiciously looking conditions in
-        all uncompleted downloads. It ain't a perfect world.
-        """
-        # TODO this was added as a quick fix to #37.
-        # Even though it might be strictly necessary, there should be a tested backup
-        # solution for it Chords to not work properly due to failed to fail processings
-        uploads = Upload.objects(status__in=[PENDING, RUNNING])
-        for upload in uploads:
-            completed = upload.processed_calcs
-            total = upload.total
-            pending = upload.pending_calcs
-
-            if completed + pending == total:
-                time.sleep(2)
-                if pending == upload.pending_calcs:
-                    Calc.objects(upload_id=upload.upload_id, status=PENDING).delete()
diff --git a/ops/helm/nomad/templates/api-deployment.yaml b/ops/helm/nomad/templates/api-deployment.yaml
index 1475fdafa7f3a69d6dfeff07d759af40cb2ef029..b345f59368ab8607a29cee80a7f486f64c2ba205 100644
--- a/ops/helm/nomad/templates/api-deployment.yaml
+++ b/ops/helm/nomad/templates/api-deployment.yaml
@@ -46,6 +46,10 @@ spec:
           value: "{{ .Values.proxy.external.path }}/api"
         - name: NOMAD_API_SECRET
           value: "{{ .Values.api.secret }}"
+        - name: NOMAD_API_ADMIN_PASSWORD
+          value: "{{ .Values.api.adminPassword }}"
+        - name: NOMAD_API_DISABLE_RESET
+          value: "{{ .Values.api.disableReset }}"
         - name: NOMAD_RABBITMQ_HOST
           value: "{{ .Release.Name }}-rabbitmq"
         - name: NOMAD_ELASTIC_HOST
diff --git a/ops/helm/nomad/values.yaml b/ops/helm/nomad/values.yaml
index c8827fc838e92191db5afc5316165d0b845a6542..496f6a7dca33a15e7b5cdea12880e37e3c15c88d 100644
--- a/ops/helm/nomad/values.yaml
+++ b/ops/helm/nomad/values.yaml
@@ -32,6 +32,10 @@ api:
   logstash_loglevel: INFO
   ## Secret used as cryptographic seed
   secret: "defaultApiSecret"
+  ## The adminstrator password (only way to ever set/change it)
+  adminPassword: "password"
+  ## Disable the dangerous reset (delete all data) function
+  disableReset: "true"
 
 ## Everthing concerning the nomad worker
 worker:
diff --git a/tests/conftest.py b/tests/conftest.py
index 12d33ef6ee636dd7784b7966fd0131c373845e88..cfc1e0e57cf0efe086158de773177f7ec9518990 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -117,6 +117,18 @@ def repository_db(monkeysession):
     session.close()
 
 
+@pytest.fixture(scope='function')
+def repair_repository_db():
+    """
+    Binds a new connectino to the existing session repository db.
+    Necessary if tests delete the connection.
+    """
+    yield None
+    olddb = infrastructure.repository_db
+    infrastructure.setup_repository_db()
+    olddb.bind = infrastructure.repository_db_conn
+
+
 @pytest.fixture(scope='session')
 def test_user(repository_db):
     return coe_repo.ensure_test_user(email='sheldon.cooper@nomad-fairdi.tests.de')
@@ -127,6 +139,11 @@ def other_test_user(repository_db):
     return coe_repo.ensure_test_user(email='leonard.hofstadter@nomad-fairdi.tests.de')
 
 
+@pytest.fixture(scope='session')
+def admin_user(repository_db):
+    return coe_repo.admin_user()
+
+
 @pytest.fixture(scope='function')
 def mocksearch(monkeypatch):
     uploads_by_hash = {}
diff --git a/tests/test_api.py b/tests/test_api.py
index 9df6e643d816a42e988344d662b7e7fd27873605..f41ba5dea3c0aad855373c6f9669ff4cd4886104 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -63,6 +63,50 @@ def test_other_user_auth(other_test_user: User):
     return create_auth_headers(other_test_user)
 
 
+class TestAdmin:
+
+    @pytest.fixture(scope='session')
+    def admin_user_auth(self, admin_user: User):
+        return create_auth_headers(admin_user)
+
+    @pytest.mark.timeout(10)
+    def test_reset(self, client, admin_user_auth, repair_repository_db):
+        rv = client.post('/admin/reset', headers=admin_user_auth)
+        assert rv.status_code == 200
+
+    # TODO disabled as this will destroy the session repository_db beyond repair.
+    # @pytest.mark.timeout(10)
+    # def test_remove(self, client, admin_user_auth, repair_repository_db):
+    #     rv = client.post('/admin/remove', headers=admin_user_auth)
+    #     assert rv.status_code == 200
+
+    def test_doesnotexist(self, client, admin_user_auth):
+        rv = client.post('/admin/doesnotexist', headers=admin_user_auth)
+        assert rv.status_code == 404
+
+    def test_only_admin(self, client, test_user_auth):
+        rv = client.post('/admin/doesnotexist', headers=test_user_auth)
+        assert rv.status_code == 401
+
+    @pytest.fixture(scope='function')
+    def disable_reset(self, monkeypatch):
+        old_config = config.services
+        new_config = config.NomadServicesConfig(
+            config.services.api_host,
+            config.services.api_port,
+            config.services.api_base_path,
+            config.services.api_secret,
+            config.services.admin_password,
+            True)
+        monkeypatch.setattr(config, 'services', new_config)
+        yield None
+        monkeypatch.setattr(config, 'services', old_config)
+
+    def test_disabled(self, client, admin_user_auth, disable_reset):
+        rv = client.post('/admin/reset', headers=admin_user_auth)
+        assert rv.status_code == 400
+
+
 class TestAuth:
     def test_xtoken_auth(self, client, test_user: User, no_warn):
         rv = client.get('/uploads/', headers={
@@ -185,6 +229,7 @@ class TestUploads:
         rv = client.get('/uploads/123456789012123456789012', headers=test_user_auth)
         assert rv.status_code == 404
 
+    @pytest.mark.timeout(30)
     @pytest.mark.parametrize('file', example_files)
     @pytest.mark.parametrize('mode', ['multipart', 'stream', 'local_path'])
     @pytest.mark.parametrize('name', [None, 'test_name'])