diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index cdcfe04d36..84d7e0f475 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -59,7 +59,7 @@ jobs:
       redis:
         image: redis:4.0.14
         ports:
-          - 6379:6379
+          - 6380:6379
 
     steps:
     - uses: actions/checkout@v1
diff --git a/docker-compose.yml b/docker-compose.yml
index 77fed323d3..4b12a85dee 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -39,9 +39,4 @@ services:
   redis:
     image: "redis:4.0.14"
     ports:
-      - "6379:6379"
-
-  adminer:
-    image: adminer
-    ports:
-      - 8080:8080
\ No newline at end of file
+      - "6380:6379"
\ No newline at end of file
diff --git a/docs/authentication-and-access-control/session-tokens.md b/docs/authentication-and-access-control/session-tokens.md
index 35eaccb438..e13b88e1a8 100644
--- a/docs/authentication-and-access-control/session-tokens.md
+++ b/docs/authentication-and-access-control/session-tokens.md
@@ -478,18 +478,15 @@ This store uses the default TypeORM connection which is usually specified in `or
 npm install @foal/redis
 ```
 
-In order to use this store, you must provide the redis URI in either:
-- a configuration file
-
-    *Example with config/default.yml*
-    ```yaml
-    redis:
-      uri: 'redis://localhost:6379'
-    ```
-- or in a `.env` file or in an environment variable:
-    ```
-    REDIS_URI=redis://localhost:6379
-    ```
+In order to use this store, you must provide the redis URI in either a configuration file
+
+*Example with config/default.yml*
+```yaml
+settings:
+  redis:
+    uri: 'redis://localhost:6379'
+```
+
 
 ### MongoDBStore
 
@@ -497,21 +494,14 @@ In order to use this store, you must provide the redis URI in either:
 npm install @foal/mongodb
 ```
 
-This store saves your session states in a MongoDB database (using the collection `sessions`). In order to use it, you must provide the MongoDB URI in either:
-
-- a configuration file
-
-    *Example with config/default.yml*
-    ```yaml
-    mongodb:
-      uri: 'mongodb://localhost:27017'
-    ```
-- or in a `.env` file or in an environment variable:
-    ```
-    MONGODB_URI=mongodb://localhost:27017
-    ```
-
+This store saves your session states in a MongoDB database (using the collection `sessions`). In order to use it, you must provide the MongoDB URI a configuration file:
 
+*Example with config/default.yml*
+```yaml
+settings:
+  mongodb:
+    uri: 'mongodb://localhost:27017'
+```
 
 ### Custom Store
 
diff --git a/packages/acceptance-tests/src/authentication/jwt.cookie.spec.ts b/packages/acceptance-tests/src/authentication/jwt.cookie.spec.ts
index 48cbed582f..1b945b2dce 100644
--- a/packages/acceptance-tests/src/authentication/jwt.cookie.spec.ts
+++ b/packages/acceptance-tests/src/authentication/jwt.cookie.spec.ts
@@ -99,7 +99,7 @@ describe('[Authentication|JWT|cookie|no redirection] Users', () => {
     async logout() {
       return new HttpResponseNoContent()
         .setCookie(
-          Config.get('settings.jwt.cookieName', 'string', 'auth'),
+          Config.get('settings.jwt.cookie.name', 'string', 'auth'),
           '',
           { ...cookieOptions, maxAge: 0 }
         );
@@ -123,7 +123,7 @@ describe('[Authentication|JWT|cookie|no redirection] Users', () => {
       });
       return new HttpResponseNoContent()
         .setCookie(
-          Config.get('settings.jwt.cookieName', 'string', 'auth'),
+          Config.get('settings.jwt.cookie.name', 'string', 'auth'),
           token,
           { ...cookieOptions, maxAge: 3600 }
         );
@@ -138,7 +138,8 @@ describe('[Authentication|JWT|cookie|no redirection] Users', () => {
   }
 
   before(async () => {
-    process.env.SETTINGS_JWT_SECRET = 'session-secret';
+    Config.set('settings.jwt.secret', 'session-secret');
+
     await createConnection({
       database: 'e2e_db.sqlite',
       dropSchema: true,
@@ -154,7 +155,8 @@ describe('[Authentication|JWT|cookie|no redirection] Users', () => {
 
   after(async () => {
     await getConnection().close();
-    delete process.env.SETTINGS_JWT_SECRET;
+
+    Config.remove('settings.jwt.secret');
   });
 
   it('cannot access protected routes if they are not logged in.', () => {
diff --git a/packages/acceptance-tests/src/authentication/jwt.token.spec.ts b/packages/acceptance-tests/src/authentication/jwt.token.spec.ts
index 64a6e315bd..38934e324e 100644
--- a/packages/acceptance-tests/src/authentication/jwt.token.spec.ts
+++ b/packages/acceptance-tests/src/authentication/jwt.token.spec.ts
@@ -11,9 +11,9 @@ import * as request from 'supertest';
 
 // FoalTS
 import {
-  Context, controller, createApp,
-  Get, hashPassword, HttpResponseOK,
-  HttpResponseUnauthorized, Post, ValidateBody, verifyPassword
+  Config, Context, controller,
+  createApp, Get, hashPassword,
+  HttpResponseOK, HttpResponseUnauthorized, Post, ValidateBody, verifyPassword
 } from '@foal/core';
 import { getSecretOrPrivateKey, JWTRequired } from '@foal/jwt';
 import { fetchUser } from '@foal/typeorm';
@@ -120,7 +120,8 @@ describe('[Authentication|JWT|no cookie|no redirection] Users', () => {
   }
 
   before(async () => {
-    process.env.SETTINGS_JWT_SECRET = 'session-secret';
+    Config.set('settings.jwt.secret', 'session-secret');
+
     await createConnection({
       database: 'e2e_db.sqlite',
       dropSchema: true,
@@ -136,7 +137,8 @@ describe('[Authentication|JWT|no cookie|no redirection] Users', () => {
 
   after(async () => {
     await getConnection().close();
-    delete process.env.SETTINGS_JWT_SECRET;
+
+    Config.remove('settings.jwt.secret');
   });
 
   it('cannot access protected routes if they are not logged in.', () => {
diff --git a/packages/acceptance-tests/src/examples/security/csrf/regular-web-app.stateful.spec.ts b/packages/acceptance-tests/src/examples/security/csrf/regular-web-app.stateful.spec.ts
index b122a54a76..3fbb167b9c 100644
--- a/packages/acceptance-tests/src/examples/security/csrf/regular-web-app.stateful.spec.ts
+++ b/packages/acceptance-tests/src/examples/security/csrf/regular-web-app.stateful.spec.ts
@@ -7,6 +7,7 @@ import * as request from 'supertest';
 
 // FoalTS
 import {
+  Config,
   Context,
   controller,
   createApp,
@@ -123,8 +124,8 @@ describe('Feature: Stateful CSRF protection in a Regular Web App', () => {
   let csrfToken: string;
 
   before(async () => {
-    process.env.SETTINGS_SESSION_CSRF_ENABLED = 'true';
-    process.env.SETTINGS_SESSION_CSRF_COOKIE_NAME = csrfCookieName;
+    Config.set('settings.session.csrf.enabled', true);
+    Config.set('settings.session.csrf.cookie.name', csrfCookieName);
 
     connection = await createTestConnection([ User, DatabaseSession ]);
 
@@ -135,8 +136,8 @@ describe('Feature: Stateful CSRF protection in a Regular Web App', () => {
   });
 
   after(async () => {
-    delete process.env.SETTINGS_SESSION_CSRF_ENABLED;
-    delete process.env.SETTINGS_SESSION_CSRF_COOKIE_NAME;
+    Config.remove('settings.session.csrf.enabled');
+    Config.remove('settings.session.csrf.cookie.name');
 
     await connection.close();
   });
diff --git a/packages/acceptance-tests/src/examples/security/csrf/spa.stateful.spec.ts b/packages/acceptance-tests/src/examples/security/csrf/spa.stateful.spec.ts
index 9d386a5da1..dfe0aa4db5 100644
--- a/packages/acceptance-tests/src/examples/security/csrf/spa.stateful.spec.ts
+++ b/packages/acceptance-tests/src/examples/security/csrf/spa.stateful.spec.ts
@@ -7,6 +7,7 @@ import * as request from 'supertest';
 
 // FoalTS
 import {
+  Config,
   Context,
   controller,
   createApp,
@@ -91,8 +92,8 @@ describe('Feature: Stateful CSRF protection in a Single-Page Application', () =>
   let csrfToken: string;
 
   before(async () => {
-    process.env.SETTINGS_SESSION_CSRF_ENABLED = 'true';
-    process.env.SETTINGS_SESSION_CSRF_COOKIE_NAME = csrfCookieName;
+    Config.set('settings.session.csrf.enabled', true);
+    Config.set('settings.session.csrf.cookie.name', csrfCookieName);
 
     connection = await createTestConnection([ User, DatabaseSession ]);
 
@@ -103,8 +104,8 @@ describe('Feature: Stateful CSRF protection in a Single-Page Application', () =>
   });
 
   after(async () => {
-    delete process.env.SETTINGS_SESSION_CSRF_ENABLED;
-    delete process.env.SETTINGS_SESSION_CSRF_COOKIE_NAME;
+    Config.remove('settings.session.csrf.enabled');
+    Config.remove('settings.session.csrf.cookie.name');
 
     await connection.close();
   });
diff --git a/packages/acceptance-tests/src/examples/security/csrf/spa.stateless.spec.ts b/packages/acceptance-tests/src/examples/security/csrf/spa.stateless.spec.ts
index 06b6808747..cb0e036af0 100644
--- a/packages/acceptance-tests/src/examples/security/csrf/spa.stateless.spec.ts
+++ b/packages/acceptance-tests/src/examples/security/csrf/spa.stateless.spec.ts
@@ -8,6 +8,7 @@ import * as request from 'supertest';
 
 // FoalTS
 import {
+  Config,
   Context,
   controller,
   createApp,
@@ -91,9 +92,9 @@ describe('Feature: Stateless CSRF protection in a Single-Page Application', () =
   let csrfToken: string;
 
   before(async () => {
-    process.env.SETTINGS_JWT_SECRET = 'jwtSecret';
-    process.env.SETTINGS_JWT_CSRF_ENABLED = 'true';
-    process.env.SETTINGS_JWT_CSRF_COOKIE_NAME = csrfCookieName;
+    Config.set('settings.jwt.secret', 'jwtSecret');
+    Config.set('settings.jwt.csrf.enabled', true);
+    Config.set('settings.jwt.csrf.cookie.name', csrfCookieName);
 
     connection = await createTestConnection([ User ]);
 
@@ -104,9 +105,9 @@ describe('Feature: Stateless CSRF protection in a Single-Page Application', () =
   });
 
   after(async () => {
-    delete process.env.SETTINGS_JWT_SECRET;
-    delete process.env.SETTINGS_JWT_CSRF_ENABLED;
-    delete process.env.SETTINGS_JWT_CSRF_COOKIE_NAME;
+    Config.remove('settings.jwt.secret');
+    Config.remove('settings.jwt.csrf.enabled');
+    Config.remove('settings.jwt.csrf.cookie.name');
 
     await connection.close();
   });
diff --git a/packages/acceptance-tests/src/session.config.spec.ts b/packages/acceptance-tests/src/session.config.spec.ts
index ce2363677e..19036ed4ed 100644
--- a/packages/acceptance-tests/src/session.config.spec.ts
+++ b/packages/acceptance-tests/src/session.config.spec.ts
@@ -1,4 +1,5 @@
 import {
+  Config,
   Context,
   createApp,
   createSession,
@@ -21,14 +22,14 @@ describe('The session store', () => {
 
   beforeEach(() => {
     // Use ".." to remove the "build/" directory.
-    process.env.SETTINGS_SESSION_STORE = './../node_modules/@foal/redis';
-    process.env.SETTINGS_SESSION_SECRET = 'secret';
+    Config.set('settings.session.store', './../node_modules/@foal/redis');
+    Config.set('settings.session.secret', 'secret');
     serviceManager = new ServiceManager();
   });
 
   afterEach(() => {
-    delete process.env.SETTINGS_SESSION_STORE;
-    delete process.env.SETTINGS_SESSION_SECRET;
+    Config.remove('settings.session.store');
+    Config.remove('settings.session.secret');
     // Hack to close the redis connection in this test.
     (serviceManager as any).map.forEach((value: any) => {
       if (value.service.close) {
diff --git a/packages/acceptance-tests/src/typeorm.mongodb-store.spec.ts b/packages/acceptance-tests/src/typeorm.mongodb-store.spec.ts
index 251ac0f0f1..52c63c92e8 100644
--- a/packages/acceptance-tests/src/typeorm.mongodb-store.spec.ts
+++ b/packages/acceptance-tests/src/typeorm.mongodb-store.spec.ts
@@ -3,6 +3,7 @@ import { strictEqual } from 'assert';
 
 // 3p
 import {
+  Config,
   Context,
   createAndInitApp,
   createSession,
@@ -136,7 +137,8 @@ describe('[Sample] TypeORM & MongoDB Store', async () => {
   let connection: Connection;
 
   before(async () => {
-    process.env.MONGODB_URI = 'mongodb://localhost:27017/e2e_db';
+    Config.set('settings.mongodb.uri', 'mongodb://localhost:27017/e2e_db');
+
     connection = await createConnection({
       database: 'e2e_db',
       dropSchema: true,
@@ -160,7 +162,8 @@ describe('[Sample] TypeORM & MongoDB Store', async () => {
   });
 
   after(async () => {
-    delete process.env.MONGODB_URI;
+    Config.remove('settings.mongodb.uri');
+
     return Promise.all([
       connection.close(),
       app.foal.services.get(MongoDBStore).close(),
diff --git a/packages/acceptance-tests/src/typeorm.redis-store.spec.ts b/packages/acceptance-tests/src/typeorm.redis-store.spec.ts
index f6f32bcca5..b7e0d5647d 100644
--- a/packages/acceptance-tests/src/typeorm.redis-store.spec.ts
+++ b/packages/acceptance-tests/src/typeorm.redis-store.spec.ts
@@ -3,6 +3,7 @@ import { strictEqual } from 'assert';
 
 // 3p
 import {
+  Config,
   Context,
   createAndInitApp,
   createSession,
@@ -134,7 +135,8 @@ describe('[Sample] MongoDB & Redis Store', async () => {
   let connection: Connection;
 
   before(async () => {
-    process.env.MONGODB_URI = 'mongodb://localhost:27017/e2e_db';
+    Config.set('settings.mongodb.uri', 'mongodb://localhost:27017/e2e_db');
+
     connection = await createConnection({
       database: 'e2e_db',
       dropSchema: true,
@@ -165,7 +167,8 @@ describe('[Sample] MongoDB & Redis Store', async () => {
   });
 
   after(() => {
-    delete process.env.MONGODB_URI;
+    Config.remove('settings.mongodb.uri');
+
     return Promise.all([
       connection.close(),
       app.foal.services.get(RedisStore).close(),
diff --git a/packages/aws-s3/src/s3-disk.service.spec.ts b/packages/aws-s3/src/s3-disk.service.spec.ts
index add057624a..442dc27a06 100644
--- a/packages/aws-s3/src/s3-disk.service.spec.ts
+++ b/packages/aws-s3/src/s3-disk.service.spec.ts
@@ -67,20 +67,21 @@ describe('S3Disk', () => {
   }));
 
   beforeEach(() => {
-    process.env.SETTINGS_DISK_S3_BUCKET = bucketName;
+    Config.set('settings.disk.s3.bucket', bucketName);
 
     disk = createService(S3Disk);
   });
 
   afterEach(async () => {
-    delete process.env.SETTINGS_DISK_S3_BUCKET;
-    delete process.env.SETTINGS_AWS_ENDPOINT;
+    Config.remove('settings.disk.s3.bucket');
+    Config.remove('settings.aws.endpoint');
     await rmObjectsIfExist(s3);
   });
 
   it('should accept a S3 custom endpoint in the config.', async () => {
     // This test assumes that the "delete" method tries at least to connect to AWS.
-    process.env.SETTINGS_AWS_ENDPOINT = 'foobar';
+    Config.set('settings.aws.endpoint', 'foobar');
+
     try {
       await disk.delete('foo/test.txt');
       throw new Error('An error should have been thrown.');
@@ -95,7 +96,8 @@ describe('S3Disk', () => {
   describe('has a "write" method that', () => {
 
     it('should throw an Error if no bucket is specified in the config.', async () => {
-      delete process.env.SETTINGS_DISK_S3_BUCKET;
+      Config.remove('settings.disk.s3.bucket');
+
       try {
         await disk.write('foo', Buffer.from('hello', 'utf8'));
         throw new Error('An error should have been thrown.');
@@ -160,7 +162,8 @@ describe('S3Disk', () => {
   describe('has a "read" method that', () => {
 
     it('should throw an Error if no bucket is specified in the config.', async () => {
-      delete process.env.SETTINGS_DISK_S3_BUCKET;
+      Config.remove('settings.disk.s3.bucket');
+
       try {
         await disk.read('foo', 'buffer');
         throw new Error('An error should have been thrown.');
@@ -247,7 +250,8 @@ describe('S3Disk', () => {
   describe('has a "readSize" method that', () => {
 
     it('should throw an Error if no bucket is specified in the config.', async () => {
-      delete process.env.SETTINGS_DISK_S3_BUCKET;
+      Config.remove('settings.disk.s3.bucket');
+
       try {
         await disk.readSize('foo');
         throw new Error('An error should have been thrown.');
@@ -288,7 +292,8 @@ describe('S3Disk', () => {
   describe('has a "delete" method that', () => {
 
     it('should throw an Error if no bucket is specified in the config.', async () => {
-      delete process.env.SETTINGS_DISK_S3_BUCKET;
+      Config.remove('settings.disk.s3.bucket');
+
       try {
         await disk.delete('foo');
         throw new Error('An error should have been thrown.');
diff --git a/packages/core/src/common/utils/get-ajv-instance.spec.ts b/packages/core/src/common/utils/get-ajv-instance.spec.ts
index 42ef536858..24cb01c063 100644
--- a/packages/core/src/common/utils/get-ajv-instance.spec.ts
+++ b/packages/core/src/common/utils/get-ajv-instance.spec.ts
@@ -1,5 +1,5 @@
 import { deepStrictEqual, strictEqual } from 'assert';
-import { ConfigTypeError } from '../../core';
+import { Config, ConfigTypeError } from '../../core';
 import { _instanceWrapper, getAjvInstance } from './get-ajv-instance';
 
 describe('getAjvInstance', () => {
@@ -45,11 +45,11 @@ describe('getAjvInstance', () => {
 
     beforeEach(() => {
       delete _instanceWrapper.instance;
-      process.env.SETTINGS_AJV_COERCE_TYPES = 'false';
-      process.env.SETTINGS_AJV_REMOVE_ADDITIONAL = 'false';
-      process.env.SETTINGS_AJV_USE_DEFAULTS = 'false';
-      process.env.SETTINGS_AJV_NULLABLE = 'true';
-      process.env.SETTINGS_AJV_ALL_ERRORS = 'true';
+      Config.set('settings.ajv.coerceTypes', false);
+      Config.set('settings.ajv.removeAdditional', false);
+      Config.set('settings.ajv.useDefaults', false);
+      Config.set('settings.ajv.nullable', true);
+      Config.set('settings.ajv.allErrors', true);
     });
 
     it('should accept custom configuration from the Config.', () => {
@@ -119,7 +119,7 @@ describe('getAjvInstance', () => {
     });
 
     it('should throw a ConfigTypeError when the value of `settings.ajv.coerceTypes` has an invalid type.', () => {
-      process.env.SETTINGS_AJV_COERCE_TYPES = 'hello';
+      Config.set('settings.ajv.coerceTypes', 'hello');
 
       try {
         getAjvInstance().validate({}, {});
@@ -137,7 +137,7 @@ describe('getAjvInstance', () => {
     });
 
     it('should throw a ConfigTypeError when the value of `settings.ajv.nullable` has an invalid type.', () => {
-      process.env.SETTINGS_AJV_NULLABLE = 'hello';
+      Config.set('settings.ajv.nullable', 'hello');
 
       try {
         getAjvInstance().validate({}, {});
@@ -155,7 +155,7 @@ describe('getAjvInstance', () => {
     });
 
     it('should throw a ConfigTypeError when the value of `settings.ajv.allErrors` has an invalid type.', () => {
-      process.env.SETTINGS_AJV_ALL_ERRORS = 'hello';
+      Config.set('settings.ajv.allErrors', 'hello');
 
       try {
         getAjvInstance().validate({}, {});
@@ -174,11 +174,11 @@ describe('getAjvInstance', () => {
 
     after(() => {
       delete _instanceWrapper.instance;
-      delete process.env.SETTINGS_AJV_COERCE_TYPES;
-      delete process.env.SETTINGS_AJV_REMOVE_ADDITIONAL;
-      delete process.env.SETTINGS_AJV_USE_DEFAULTS;
-      delete process.env.SETTINGS_AJV_NULLABLE;
-      delete process.env.SETTINGS_AJV_ALL_ERRORS;
+      Config.remove('settings.ajv.coerceTypes');
+      Config.remove('settings.ajv.removeAdditional');
+      Config.remove('settings.ajv.useDefaults');
+      Config.remove('settings.ajv.nullable');
+      Config.remove('settings.ajv.allErrors');
     });
 
   });
diff --git a/packages/core/src/common/utils/render-error.util.spec.ts b/packages/core/src/common/utils/render-error.util.spec.ts
index 7c0dfffe11..f401dbac3e 100644
--- a/packages/core/src/common/utils/render-error.util.spec.ts
+++ b/packages/core/src/common/utils/render-error.util.spec.ts
@@ -2,7 +2,7 @@
 import { strictEqual } from 'assert';
 
 // FoalTS
-import { Context, isHttpResponseInternalServerError } from '../../core';
+import { Config, Context, isHttpResponseInternalServerError } from '../../core';
 import { renderError } from './render-error.util';
 
 describe('renderError', () => {
@@ -11,7 +11,7 @@ describe('renderError', () => {
 
   before(() => ctx = new Context({}));
 
-  afterEach(() => delete process.env.SETTINGS_DEBUG);
+  afterEach(() => Config.remove('settings.debug'));
 
   const default500page = '<html><head><title>INTERNAL SERVER ERROR</title></head><body>'
   + '<h1>500 - INTERNAL SERVER ERROR</h1></body></html>';
@@ -29,7 +29,7 @@ describe('renderError', () => {
 
   it('should return a response which body is the default html 500 page with no stack'
       + ' if debug is false.', async () => {
-    process.env.SETTINGS_DEBUG = 'false';
+    Config.set('settings.debug', false);
 
     const response = await renderError(new Error(), ctx);
     strictEqual(response.body, default500page);
@@ -37,7 +37,8 @@ describe('renderError', () => {
 
   it('should return a response which body is the debug html 500 page with a stack'
       + ' if debug is true.', async () => {
-    process.env.SETTINGS_DEBUG = 'true';
+    Config.set('settings.debug', true);
+
     const err = new Error('This is an error');
     const response = await renderError(err, ctx);
 
diff --git a/packages/core/src/common/utils/render.util.spec.ts b/packages/core/src/common/utils/render.util.spec.ts
index f4acb1746c..c75cb1d03b 100644
--- a/packages/core/src/common/utils/render.util.spec.ts
+++ b/packages/core/src/common/utils/render.util.spec.ts
@@ -4,7 +4,7 @@ import { existsSync, mkdirSync, rmdirSync, unlinkSync, writeFileSync } from 'fs'
 import { join } from 'path';
 
 // FoalTS
-import { HttpResponseOK } from '../../core';
+import { Config, HttpResponseOK } from '../../core';
 import { render, renderToString } from './render.util';
 
 const ejsTemplate = 'Hello <%= name %>! How are you?';
@@ -94,10 +94,11 @@ describe('render', () => {
 
   describe('given the configuration key "settings.templateEngine" is defined', () => {
 
-    afterEach(() => delete process.env.SETTINGS_TEMPLATE_ENGINE);
+    afterEach(() => Config.remove('settings.templateEngine'));
 
     it('should throw an Error if the given template engine is not compatible with Foal.', async () => {
-      process.env.SETTINGS_TEMPLATE_ENGINE = 'rimraf'; // A random package
+      Config.set('settings.templateEngine', 'rimraf'); // A random package
+
       try {
         await render('./templates/template.default.html', {}, __dirname);
         throw new Error('An error should have been thrown');
@@ -110,7 +111,8 @@ describe('render', () => {
     });
 
     it('should render the template with the given template engine (renderToString).', async () => {
-      process.env.SETTINGS_TEMPLATE_ENGINE = '@foal/ejs';
+      Config.set('settings.templateEngine', '@foal/ejs');
+
       const name = 'Foobar';
       const expected = `Hello ${name}! How are you?`;
       const actual = await render('./templates/template.ejs.html', { name }, __dirname);
@@ -119,7 +121,8 @@ describe('render', () => {
     });
 
     it('should render the template with the given template engine (Express).', async () => {
-      process.env.SETTINGS_TEMPLATE_ENGINE = 'ejs';
+      Config.set('settings.templateEngine', 'ejs');
+
       const name = 'Foobar';
       const expected = `Hello ${name}! How are you?`;
       const actual = await render('./templates/template.ejs.html', { name }, __dirname);
@@ -128,7 +131,8 @@ describe('render', () => {
     });
 
     it('should render the template with the given template engine (Express: twig).', async () => {
-      process.env.SETTINGS_TEMPLATE_ENGINE = 'twig';
+      Config.set('settings.templateEngine', 'twig');
+
       const users = [ { name: 'John' }, { name: 'Mary'} ];
       const expected = ' John  Mary ';
       const actual = await render('./templates/template.twig.html', { users }, __dirname);
@@ -137,7 +141,8 @@ describe('render', () => {
     });
 
     it('should throw errors returned by the given template engine (renderToString).', async () => {
-      process.env.SETTINGS_TEMPLATE_ENGINE = '@foal/ejs';
+      Config.set('settings.templateEngine', '@foal/ejs');
+
       try {
         await render('./templates/template.ejs.html', {}, __dirname);
         throw new Error('An error should have been thrown');
@@ -147,7 +152,8 @@ describe('render', () => {
     });
 
     it('should throw errors returned by the given template engine (Express).', async () => {
-      process.env.SETTINGS_TEMPLATE_ENGINE = 'ejs';
+      Config.set('settings.templateEngine', 'ejs');
+
       try {
         await render('./templates/template.ejs.html', {}, __dirname);
         throw new Error('An error should have been thrown');
diff --git a/packages/core/src/core/config/config.spec.ts b/packages/core/src/core/config/config.spec.ts
index 7f14d2c11e..8beb6fc2df 100644
--- a/packages/core/src/core/config/config.spec.ts
+++ b/packages/core/src/core/config/config.spec.ts
@@ -95,6 +95,16 @@ describe('Config', () => {
         strictEqual(Config.get('a.b.c'), 2);
       });
 
+      context('given the static method "remove" has been called after', () => {
+
+        beforeEach(() => Config.remove('a.b.c'));
+
+        it('should not return the configuration value.', () => {
+          strictEqual(Config.get('a.b.c'), undefined);
+        });
+
+      });
+
     });
 
     function testConfigFile(path: string, fileContent: string, nodeEnv?: string): void {
diff --git a/packages/core/src/core/config/config.ts b/packages/core/src/core/config/config.ts
index 749a4c9090..1c6c757126 100644
--- a/packages/core/src/core/config/config.ts
+++ b/packages/core/src/core/config/config.ts
@@ -134,6 +134,10 @@ export class Config {
     this.testConfig.set(key, value);
   }
 
+  static remove(key: string): void {
+    this.testConfig.delete(key);
+  }
+
   private static yaml: any;
   private static config: { [key: string ]: any } | null = null;
   private static testConfig: Map<string, string|number|boolean> = new Map();
diff --git a/packages/core/src/core/hooks.spec.ts b/packages/core/src/core/hooks.spec.ts
index 3c157fd752..a1c4e29f1b 100644
--- a/packages/core/src/core/hooks.spec.ts
+++ b/packages/core/src/core/hooks.spec.ts
@@ -5,6 +5,7 @@ import { deepStrictEqual, strictEqual } from 'assert';
 import 'reflect-metadata';
 
 // FoalTS
+import { Config } from './config';
 import { getHookFunction, getHookFunctions, Hook, HookFunction, MergeHooks } from './hooks';
 import { ApiUseTag, getApiUsedTags } from './openapi';
 
@@ -13,7 +14,7 @@ describe('Hook', () => {
   const hook1: HookFunction = () => { return; };
   const hook2: HookFunction = () => undefined;
 
-  afterEach(() => delete process.env.SETTINGS_OPENAPI_USE_HOOKS);
+  afterEach(() => Config.remove('settings.openapi.useHooks'));
 
   it('should add the hook to the metadata hooks on the method class.', () => {
     class Foobar {
@@ -54,7 +55,8 @@ describe('Hook', () => {
   it(
     'should apply the OpenAPI decorators if options.openapi is undefined and settings.openapi.useHooks is true.',
     () => {
-      process.env.SETTINGS_OPENAPI_USE_HOOKS = 'true';
+      Config.set('settings.openapi.useHooks', true);
+
       class Foobar {
         @Hook(hook1, [
           ApiUseTag('tag1'),
@@ -71,7 +73,8 @@ describe('Hook', () => {
   it(
     'should NOT apply the OpenAPI decorators if options.openapi is undefined and settings.openapi.useHooks is false.',
     () => {
-      process.env.SETTINGS_OPENAPI_USE_HOOKS = 'false';
+      Config.set('settings.openapi.useHooks', false);
+
       class Foobar {
         @Hook(hook1, [
           ApiUseTag('tag1'),
@@ -104,7 +107,8 @@ describe('Hook', () => {
   it(
     'should apply the OpenAPI decorators if options.openapi is true and settings.openapi.useHooks is true.',
     () => {
-      process.env.SETTINGS_OPENAPI_USE_HOOKS = 'true';
+      Config.set('settings.openapi.useHooks', true);
+
       class Foobar {
         @Hook(hook1, [
           ApiUseTag('tag1'),
@@ -121,7 +125,8 @@ describe('Hook', () => {
   it(
     'should apply the OpenAPI decorators if options.openapi is true and settings.openapi.useHooks is false.',
     () => {
-      process.env.SETTINGS_OPENAPI_USE_HOOKS = 'false';
+      Config.set('settings.openapi.useHooks', false);
+
       class Foobar {
         @Hook(hook1, [
           ApiUseTag('tag1'),
@@ -154,7 +159,8 @@ describe('Hook', () => {
   it(
     'should NOT apply the OpenAPI decorators if options.openapi is false and settings.openapi.useHooks is true.',
     () => {
-      process.env.SETTINGS_OPENAPI_USE_HOOKS = 'true';
+      Config.set('settings.openapi.useHooks', true);
+
       class Foobar {
         @Hook(hook1, [
           ApiUseTag('tag1'),
@@ -171,7 +177,8 @@ describe('Hook', () => {
   it(
     'should NOT apply the OpenAPI decorators if options.openapi is false and settings.openapi.useHooks is false.',
     () => {
-      process.env.SETTINGS_OPENAPI_USE_HOOKS = 'false';
+      Config.set('settings.openapi.useHooks', false);
+
       class Foobar {
         @Hook(hook1, [
           ApiUseTag('tag1'),
diff --git a/packages/core/src/core/openapi/openapi.service.spec.ts b/packages/core/src/core/openapi/openapi.service.spec.ts
index fab078c990..c44b09867e 100644
--- a/packages/core/src/core/openapi/openapi.service.spec.ts
+++ b/packages/core/src/core/openapi/openapi.service.spec.ts
@@ -2,6 +2,7 @@
 import { deepStrictEqual, strictEqual, throws } from 'assert';
 
 // FoalTS
+import { Config } from '../config';
 import { createService } from '../service-manager';
 import { IApiComponents, IOpenAPI } from './interfaces';
 import { OpenApi } from './openapi.service';
@@ -11,11 +12,11 @@ describe('OpenApi', () => {
   let service: OpenApi;
 
   beforeEach(() => {
-    process.env.SETTINGS_OPENAPI_ENABLED = 'true';
+    Config.set('settings.openapi.enabled', true);
     service = createService(OpenApi);
   });
 
-  afterEach(() => delete process.env.SETTINGS_OPENAPI_ENABLED);
+  afterEach(() => Config.remove('settings.openapi.enabled'));
 
   describe('has a "addDocument" method that', () => {
 
diff --git a/packages/core/src/core/routes/make-controller-routes.spec.ts b/packages/core/src/core/routes/make-controller-routes.spec.ts
index 1734c59a9d..b13ce02289 100644
--- a/packages/core/src/core/routes/make-controller-routes.spec.ts
+++ b/packages/core/src/core/routes/make-controller-routes.spec.ts
@@ -3,6 +3,7 @@ import { deepStrictEqual, notDeepStrictEqual, notStrictEqual, ok, strictEqual, t
 
 // FoalTS
 import { controller } from '../../common/utils/controller.util';
+import { Config } from '../config';
 import { Hook, HookFunction } from '../hooks';
 import { Context, Get, HttpResponseOK, Post } from '../http';
 import {
@@ -337,9 +338,9 @@ describe('makeControllerRoutes', () => {
     };
     const openApi = services.get(OpenApi);
 
-    beforeEach(() => process.env.SETTINGS_OPENAPI_ENABLED = 'true');
+    beforeEach(() => Config.set('settings.openapi.enabled', true));
 
-    afterEach(() => delete process.env.SETTINGS_OPENAPI_ENABLED);
+    afterEach(() => Config.remove('settings.openapi.enabled'));
 
     it('but not the other controllers.', () => {
       @ApiInfo(infoMetadata)
diff --git a/packages/core/src/core/service-manager.spec.ts b/packages/core/src/core/service-manager.spec.ts
index 00f134497e..d21874352e 100644
--- a/packages/core/src/core/service-manager.spec.ts
+++ b/packages/core/src/core/service-manager.spec.ts
@@ -7,7 +7,7 @@ import { ConcreteSessionStore } from '@foal/internal-test';
 // FoalTS
 import { existsSync, mkdirSync, rmdirSync, unlinkSync, writeFileSync } from 'fs';
 import { join } from 'path';
-import { ConfigNotFoundError } from './config';
+import { Config, ConfigNotFoundError } from './config';
 import { createService, dependency, Dependency, IDependency, ServiceManager } from './service-manager';
 
 describe('dependency', () => {
@@ -508,7 +508,7 @@ describe('ServiceManager', () => {
 
       describe('and if it has a static property "concreteClassConfigPath"', () => {
 
-        beforeEach(() => delete process.env.SETTINGS_TOTO);
+        beforeEach(() => Config.remove('settings.toto'));
 
         it('should throw an Error if Service.concreteClassConfigPath is not a string.', () => {
           abstract class Foobar {
@@ -525,7 +525,7 @@ describe('ServiceManager', () => {
         });
 
         it('should throw an Error if Service.concreteClassName is not defined.', () => {
-          process.env.SETTINGS_TOTO = '@foal/internal-test';
+          Config.set('settings.toto', '@foal/internal-test');
 
           abstract class Foobar {
             static concreteClassConfigPath = 'settings.toto';
@@ -540,7 +540,7 @@ describe('ServiceManager', () => {
         });
 
         it('should throw an Error if Service.concreteClassName is not a string.', () => {
-          process.env.SETTINGS_TOTO = '@foal/internal-test';
+          Config.set('settings.toto', '@foal/internal-test');
 
           abstract class Foobar {
             static concreteClassConfigPath = 'settings.toto';
@@ -558,7 +558,7 @@ describe('ServiceManager', () => {
         describe('when the concrete class path is a package name (does not start by "./")', () => {
 
           it('should throw an Error if the package is not installed.', () => {
-            process.env.SETTINGS_TOTO = 'uninstalledPackage';
+            Config.set('settings.toto', 'uninstalledPackage');
 
             abstract class Foobar {
               static concreteClassConfigPath = 'settings.toto';
@@ -574,7 +574,7 @@ describe('ServiceManager', () => {
           });
 
           it('should throw an Error if the specified concrete class is not found in the package.', () => {
-            process.env.SETTINGS_TOTO = '@foal/internal-test';
+            Config.set('settings.toto', '@foal/internal-test');
 
             abstract class Foobar {
               static concreteClassConfigPath = 'settings.toto';
@@ -591,7 +591,7 @@ describe('ServiceManager', () => {
           });
 
           it('should throw an Error if the specified concrete class is actually not a class.', () => {
-            process.env.SETTINGS_TOTO = '@foal/internal-test';
+            Config.set('settings.toto', '@foal/internal-test');
 
             abstract class Foobar {
               static concreteClassConfigPath = 'settings.toto';
@@ -607,7 +607,7 @@ describe('ServiceManager', () => {
           });
 
           it('should return the concrete class instance.', () => {
-            process.env.SETTINGS_TOTO = '@foal/internal-test';
+            Config.set('settings.toto', '@foal/internal-test');
 
             abstract class Foobar {
               static concreteClassConfigPath = 'settings.toto';
@@ -745,7 +745,7 @@ describe('ServiceManager', () => {
 
         describe('when the concrete class path is "local"', () => {
 
-          beforeEach(() => process.env.SETTINGS_TOTO = 'local');
+          beforeEach(() => Config.set('settings.toto', 'local'));
 
           it('should throw an error if Service.defaultConcreteClassPath is not defined.', () => {
             abstract class Foobar {
@@ -789,7 +789,7 @@ describe('ServiceManager', () => {
           });
 
           it('should throw an Error if the file does not exist.', () => {
-            process.env.SETTINGS_TOTO = './foo';
+            Config.set('settings.toto', './foo');
 
             abstract class Foobar {
               static concreteClassConfigPath = 'settings.toto';
@@ -805,7 +805,7 @@ describe('ServiceManager', () => {
           });
 
           it('should throw an Error if the specified concrete class is not found in the package.', () => {
-            process.env.SETTINGS_TOTO = './service-manager.test2';
+            Config.set('settings.toto', './service-manager.test2');
 
             abstract class Foobar {
               static concreteClassConfigPath = 'settings.toto';
@@ -822,7 +822,7 @@ describe('ServiceManager', () => {
           });
 
           it('should throw an Error if the specified concrete class is actually not a class.', () => {
-            process.env.SETTINGS_TOTO = './service-manager.test2';
+            Config.set('settings.toto', './service-manager.test2');
 
             abstract class Foobar {
               static concreteClassConfigPath = 'settings.toto';
@@ -839,7 +839,7 @@ describe('ServiceManager', () => {
           });
 
           it('should return the concrete class instance.', () => {
-            process.env.SETTINGS_TOTO = './service-manager.test2';
+            Config.set('settings.toto', './service-manager.test2');
 
             abstract class Foobar {
               static concreteClassConfigPath = 'settings.toto';
diff --git a/packages/core/src/express/create-app.spec.ts b/packages/core/src/express/create-app.spec.ts
index 881d3b6815..78ee62159b 100644
--- a/packages/core/src/express/create-app.spec.ts
+++ b/packages/core/src/express/create-app.spec.ts
@@ -9,7 +9,7 @@ import * as request from 'supertest';
 // FoalTS
 import { existsSync, mkdirSync, rmdirSync, unlinkSync, writeFileSync } from 'fs';
 import {
-  Context, Delete, dependency, Get, Head, HttpResponseOK, OpenApi, Options, Patch, Post, Put, ServiceManager
+  Config, Context, Delete, dependency, Get, Head, HttpResponseOK, OpenApi, Options, Patch, Post, Put, ServiceManager
 } from '../core';
 import { createAndInitApp, createApp, OPENAPI_SERVICE_ID } from './create-app';
 
@@ -20,12 +20,12 @@ describe('createApp', () => {
       mkdirSync('test-public');
     }
     writeFileSync('test-public/hello-world.html', '<h1>Hello world!</h1>', 'utf8');
-    process.env.SETTINGS_STATIC_PATH = 'test-public';
+    Config.set('settings.staticPath', 'test-public');
   });
 
   after(() => {
-    delete process.env.SETTINGS_STATIC_PATH;
-    delete process.env.SETTINGS_DEBUG;
+    Config.remove('settings.staticPath');
+    Config.remove('settings.debug');
     if (existsSync('test-public/hello-world.html')) {
       unlinkSync('test-public/hello-world.html');
     }
@@ -35,9 +35,9 @@ describe('createApp', () => {
   });
 
   afterEach(() => {
-    delete process.env.SETTINGS_STATIC_PATH_PREFIX;
-    delete process.env.SETTING_DEBUG;
-    delete process.env.SETTINGS_BODY_PARSER_LIMIT;
+    Config.remove('settings.staticPathPrefix');
+    Config.remove('settings.debug');
+    Config.remove('settings.bodyParser.limit');
   });
 
   it('should include security headers in HTTP responses.', async () => {
@@ -87,7 +87,7 @@ describe('createApp', () => {
   });
 
   it('should support custom path prefix when serving static files.', async () => {
-    process.env.SETTINGS_STATIC_PATH_PREFIX = '/prefix';
+    Config.set('settings.staticPathPrefix', '/prefix');
 
     const app = createApp(class { });
     await request(app)
@@ -231,7 +231,7 @@ describe('createApp', () => {
   });
 
   it('should accept higher or lower request body size if this is specified in the configuration.', async () => {
-    process.env.SETTINGS_BODY_PARSER_LIMIT = '10';
+    Config.set('settings.bodyParser.limit', 10);
 
     class MyController {
       @Post('/foo')
@@ -315,7 +315,7 @@ describe('createApp', () => {
   });
 
   it('should use the optional postMiddlewares if they are given (in good time).', () => {
-    process.env.SETTINGS_DEBUG = 'true';
+    Config.set('settings.debug', true);
 
     class AppController {
       @Get('/a')
diff --git a/packages/core/src/express/handle-errors.spec.ts b/packages/core/src/express/handle-errors.spec.ts
index 53bffb658e..351e73ff86 100644
--- a/packages/core/src/express/handle-errors.spec.ts
+++ b/packages/core/src/express/handle-errors.spec.ts
@@ -6,7 +6,7 @@ import * as express from 'express';
 import * as request from 'supertest';
 
 // FoalTS
-import { Context, HttpResponseOK } from '../core';
+import { Config, Context, HttpResponseOK } from '../core';
 import { CreateAppOptions } from './create-app';
 import { handleErrors } from './handle-errors';
 
@@ -14,7 +14,7 @@ describe('handleErrors', () => {
 
   describe('should return an error-handling middleware which', () => {
 
-    afterEach(() => delete process.env.SETTINGS_LOG_ERRORS);
+    afterEach(() => Config.remove('settings.logErrors'));
 
     it('should ignore Express client errors and forward them to the new error-handling middleware.', () => {
       const app = express()
@@ -49,7 +49,8 @@ describe('handleErrors', () => {
     });
 
     it('should not log the error if the value of the configuration key settings.logErrors is false.', async () => {
-      process.env.SETTINGS_LOG_ERRORS = 'false';
+      Config.set('settings.logErrors', false);
+
       let str = null;
       const logFn = (msg: string) => str = msg;
       const err = new Error();
diff --git a/packages/core/src/sessions/remove-session-cookie.spec.ts b/packages/core/src/sessions/remove-session-cookie.spec.ts
index 49eb5bc0d5..6f24ee237f 100644
--- a/packages/core/src/sessions/remove-session-cookie.spec.ts
+++ b/packages/core/src/sessions/remove-session-cookie.spec.ts
@@ -1,5 +1,5 @@
 import { strictEqual } from 'assert';
-import { HttpResponse, HttpResponseOK } from '../core';
+import { Config, HttpResponse, HttpResponseOK } from '../core';
 import {
   SESSION_DEFAULT_COOKIE_HTTP_ONLY,
   SESSION_DEFAULT_COOKIE_NAME,
@@ -63,22 +63,22 @@ describe('removeSessionCookie', () => {
       const cookieName = SESSION_DEFAULT_COOKIE_NAME + '2';
 
       beforeEach(() => {
-        process.env.SETTINGS_SESSION_COOKIE_NAME = cookieName;
-        process.env.SETTINGS_SESSION_COOKIE_DOMAIN = 'example.com';
-        process.env.SETTINGS_SESSION_COOKIE_HTTP_ONLY = 'false';
-        process.env.SETTINGS_SESSION_COOKIE_PATH = '/foo';
-        process.env.SETTINGS_SESSION_COOKIE_SAME_SITE = 'strict';
-        process.env.SETTINGS_SESSION_COOKIE_SECURE = 'true';
+        Config.set('settings.session.cookie.name', cookieName);
+        Config.set('settings.session.cookie.domain', 'example.com');
+        Config.set('settings.session.cookie.httpOnly', false);
+        Config.set('settings.session.cookie.path', '/foo');
+        Config.set('settings.session.cookie.sameSite', 'strict');
+        Config.set('settings.session.cookie.secure', true);
         removeSessionCookie(response);
       });
 
       afterEach(() => {
-        delete process.env.SETTINGS_SESSION_COOKIE_NAME;
-        delete process.env.SETTINGS_SESSION_COOKIE_DOMAIN;
-        delete process.env.SETTINGS_SESSION_COOKIE_HTTP_ONLY;
-        delete process.env.SETTINGS_SESSION_COOKIE_PATH;
-        delete process.env.SETTINGS_SESSION_COOKIE_SAME_SITE;
-        delete process.env.SETTINGS_SESSION_COOKIE_SECURE;
+        Config.remove('settings.session.cookie.name');
+        Config.remove('settings.session.cookie.domain');
+        Config.remove('settings.session.cookie.httpOnly');
+        Config.remove('settings.session.cookie.path');
+        Config.remove('settings.session.cookie.sameSite');
+        Config.remove('settings.session.cookie.secure');
       });
 
       it('with the proper default name and value.', () => {
@@ -122,9 +122,9 @@ describe('removeSessionCookie', () => {
 
   context('given the CSRF protection is enabled in the config', () => {
 
-    beforeEach(() => process.env.SETTINGS_SESSION_CSRF_ENABLED = 'true');
+    beforeEach(() => Config.set('settings.session.csrf.enabled', true));
 
-    afterEach(() => delete process.env.SETTINGS_SESSION_CSRF_ENABLED);
+    afterEach(() => Config.remove('settings.session.csrf.enabled'));
 
     describe('should set a session cookie in the response', () => {
 
@@ -142,13 +142,11 @@ describe('removeSessionCookie', () => {
       context('given configuration options are provided', () => {
 
         beforeEach(() => {
-          process.env.SETTINGS_SESSION_COOKIE_SAME_SITE = 'strict';
+          Config.set('settings.session.cookie.sameSite', 'strict');
           removeSessionCookie(response);
         });
 
-        afterEach(() => {
-          delete process.env.SETTINGS_SESSION_COOKIE_SAME_SITE;
-        });
+        afterEach(() => Config.remove('settings.session.cookie.sameSite'));
 
         it('with the proper default "sameSite" directive.', () => {
           const { options } = response.getCookie(SESSION_DEFAULT_COOKIE_NAME);
@@ -207,22 +205,22 @@ describe('removeSessionCookie', () => {
         const csrfCookieName = SESSION_DEFAULT_CSRF_COOKIE_NAME + '2';
 
         beforeEach(() => {
-          process.env.SETTINGS_SESSION_CSRF_COOKIE_NAME = csrfCookieName;
-          process.env.SETTINGS_SESSION_COOKIE_DOMAIN = 'example.com';
-          process.env.SETTINGS_SESSION_COOKIE_HTTP_ONLY = 'true';
-          process.env.SETTINGS_SESSION_COOKIE_PATH = '/foo';
-          process.env.SETTINGS_SESSION_COOKIE_SAME_SITE = 'strict';
-          process.env.SETTINGS_SESSION_COOKIE_SECURE = 'true';
+          Config.set('settings.session.csrf.cookie.name', csrfCookieName);
+          Config.set('settings.session.cookie.domain', 'example.com');
+          Config.set('settings.session.cookie.httpOnly', true);
+          Config.set('settings.session.cookie.path', '/foo');
+          Config.set('settings.session.cookie.sameSite', 'strict');
+          Config.set('settings.session.cookie.secure', 'true');
           removeSessionCookie(response);
         });
 
         afterEach(() => {
-          delete process.env.SETTINGS_SESSION_CSRF_COOKIE_NAME;
-          delete process.env.SETTINGS_SESSION_COOKIE_DOMAIN;
-          delete process.env.SETTINGS_SESSION_COOKIE_HTTP_ONLY;
-          delete process.env.SETTINGS_SESSION_COOKIE_PATH;
-          delete process.env.SETTINGS_SESSION_COOKIE_SAME_SITE;
-          delete process.env.SETTINGS_SESSION_COOKIE_SECURE;
+          Config.remove('settings.session.csrf.cookie.name');
+          Config.remove('settings.session.cookie.domain');
+          Config.remove('settings.session.cookie.httpOnly');
+          Config.remove('settings.session.cookie.path');
+          Config.remove('settings.session.cookie.sameSite');
+          Config.remove('settings.session.cookie.secure');
         });
 
         it('with the proper default name and value.', () => {
diff --git a/packages/core/src/sessions/session.spec.ts b/packages/core/src/sessions/session.spec.ts
index 36603c2dbd..5fd7eaf921 100644
--- a/packages/core/src/sessions/session.spec.ts
+++ b/packages/core/src/sessions/session.spec.ts
@@ -2,7 +2,7 @@
 import { deepStrictEqual, notStrictEqual, rejects, strictEqual } from 'assert';
 
 // FoalTS
-import { ConfigTypeError, createService } from '../core';
+import { Config, ConfigTypeError, createService } from '../core';
 import { SESSION_DEFAULT_ABSOLUTE_TIMEOUT, SESSION_DEFAULT_INACTIVITY_TIMEOUT } from './constants';
 import { Session } from './session';
 import { SessionState } from './session-state.interface';
@@ -86,8 +86,8 @@ describe('Session', () => {
   describe('has a "isExpired" property that', () => {
 
     afterEach(() => {
-      delete process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY;
-      delete process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_ABSOLUTE;
+      Config.remove('settings.session.expirationTimeouts.inactivity');
+      Config.remove('settings.session.expirationTimeouts.absolute');
     });
 
     it('should return false is the session has not expired.', () => {
@@ -131,7 +131,7 @@ describe('Session', () => {
 
     it('should return true is the session has expired (inactivity, custom timeout).', () => {
       const timeout = Math.floor(SESSION_DEFAULT_INACTIVITY_TIMEOUT / 2);
-      process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY = timeout.toString();
+      Config.set('settings.session.expirationTimeouts.inactivity', timeout);
 
       const session = new Session(
         store,
@@ -147,7 +147,7 @@ describe('Session', () => {
 
     it('should return true is the session has expired (absolute, custom timeout).', () => {
       const timeout = Math.floor(SESSION_DEFAULT_ABSOLUTE_TIMEOUT / 2);
-      process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_ABSOLUTE = timeout.toString();
+      Config.set('settings.session.expirationTimeouts.absolute', timeout);
 
       const session = new Session(
         store,
@@ -166,8 +166,8 @@ describe('Session', () => {
   describe('has an "expirationTime" property that', () => {
 
     afterEach(() => {
-      delete process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY;
-      delete process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_ABSOLUTE;
+      Config.get('settings.session.expirationTimeouts.inactivity');
+      Config.get('settings.session.expirationTimeouts.absolute');
     });
 
     describe('should return the session expiration time in seconds', () => {
@@ -191,7 +191,7 @@ describe('Session', () => {
 
       it('when updatedAt + timeout < createdAt + timeout (custom timeout).', () => {
         const timeout = Math.floor(SESSION_DEFAULT_INACTIVITY_TIMEOUT / 2);
-        process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY = timeout.toString();
+        Config.set('settings.session.expirationTimeouts.inactivity', timeout);
 
         const state: SessionState = {
           ...createState(),
@@ -224,7 +224,7 @@ describe('Session', () => {
 
       it('when createdAt + timeout < updatedAt + timeout (custom timeout).', () => {
         const timeout = Math.floor(SESSION_DEFAULT_ABSOLUTE_TIMEOUT / 2);
-        process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_ABSOLUTE = timeout.toString();
+        Config.set('settings.session.expirationTimeouts.absolute', timeout);
 
         const state: SessionState = {
           ...createState(),
@@ -538,7 +538,7 @@ describe('Session', () => {
 
       describe('providing an idle timeout', () => {
 
-        afterEach(() => delete process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY);
+        afterEach(() => Config.remove('settings.session.expirationTimeouts.inactivity'));
 
         it('from the framework default values.', async () => {
           await session.commit();
@@ -547,7 +547,7 @@ describe('Session', () => {
         });
 
         it('from the configuration.', async () => {
-          process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY = '1';
+          Config.set('settings.session.expirationTimeouts.inactivity', 1);
 
           await session.commit();
           // tslint:disable-next-line
@@ -555,7 +555,7 @@ describe('Session', () => {
         });
 
         it('and should throw an error if the configuration value is not a number.', async () => {
-          process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY = 'a';
+          Config.set('settings.session.expirationTimeouts.inactivity', 'a');
 
           await rejects(
             () => session.commit(),
@@ -564,7 +564,7 @@ describe('Session', () => {
         });
 
         it('and should throw an error if the configuration value is negative.', async () => {
-          process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY = '-1';
+          Config.set('settings.session.expirationTimeouts.inactivity', -1);
 
           await rejects(
             () => session.commit(),
@@ -780,13 +780,14 @@ describe('Session', () => {
       });
 
       afterEach(() => {
-        delete process.env.SETTINGS_SESSION_GARBAGE_COLLECTOR_PERIODICITY;
-        delete process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY;
-        delete process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_ABSOLUTE;
+        Config.remove('settings.session.garbageCollection.periodicity');
+        Config.remove('settings.session.expirationTimeouts.inactivity');
+        Config.remove('settings.session.expirationTimeouts.absolute');
       });
 
       it('with a frequency defined in the configuration (periodicity = 1).', async () => {
-        process.env.SETTINGS_SESSION_GARBAGE_COLLECTOR_PERIODICITY = '1';
+        Config.set('settings.session.garbageCollector.periodicity', 1);
+
         await session.commit();
 
         deepStrictEqual(store.cleanUpExpiredSessionsCalledWith, {
@@ -796,14 +797,15 @@ describe('Session', () => {
       });
 
       it('with a frequency defined in the configuration (periodicity = 1 000 000 000).', async () => {
-        process.env.SETTINGS_SESSION_GARBAGE_COLLECTOR_PERIODICITY = '1000000000';
+        Config.set('settings.session.garbageCollector.periodicity', 1000000000);
+
         await session.commit();
 
         strictEqual(store.cleanUpExpiredSessionsCalledWith, undefined);
       });
 
       it('and should throw an error if the periodicity provided in the configuration is not a number.', async () => {
-        process.env.SETTINGS_SESSION_GARBAGE_COLLECTOR_PERIODICITY = 'a';
+        Config.set('settings.session.garbageCollector.periodicity', 'a');
 
         await rejects(
           () => session.commit(),
@@ -812,10 +814,10 @@ describe('Session', () => {
       });
 
       it('with idle and absolute timeouts defined in the configuration.', async () => {
-        process.env.SETTINGS_SESSION_GARBAGE_COLLECTOR_PERIODICITY = '1';
+        Config.set('settings.session.garbageCollector.periodicity', 1);
 
-        process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY = '15';
-        process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_ABSOLUTE = '30';
+        Config.set('settings.session.expirationTimeouts.inactivity', 15);
+        Config.set('settings.session.expirationTimeouts.absolute', 30);
 
         await session.commit();
 
@@ -828,7 +830,7 @@ describe('Session', () => {
       it(
         'and should throw an error if the inactivity timeout provided in the configuration is not a number.',
         async () => {
-          process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY = 'a';
+          Config.set('settings.session.expirationTimeouts.inactivity', 'a');
 
           await rejects(
             () => session.commit(),
@@ -838,7 +840,7 @@ describe('Session', () => {
       );
 
       it('and should throw an error the inactivity timeout provided in the configuration is negative.', async () => {
-        process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVITY = '-1';
+        Config.set('settings.session.expirationTimeouts.inactivity', -1);
 
         await rejects(
           () => session.commit(),
@@ -849,7 +851,7 @@ describe('Session', () => {
       it(
         'and should throw an error if the absolute timeout provided in the configuration is not a number.',
         async () => {
-          process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_ABSOLUTE = 'a';
+          Config.set('settings.session.expirationTimeouts.absolute', 'a');
 
           await rejects(
             () => session.commit(),
@@ -859,7 +861,7 @@ describe('Session', () => {
       );
 
       it('and should throw an error the inactivity timeout provided in the configuration is negative.', async () => {
-        process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_ABSOLUTE = '-1';
+        Config.set('settings.session.expirationTimeouts.absolute', -1);
 
         await rejects(
           () => session.commit(),
@@ -871,8 +873,8 @@ describe('Session', () => {
         'and should throw an error if the absolute timeout provided in the configuration is lower '
         + 'than the inactivity timeout.',
         async () => {
-          process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_INACTIVTY = '2';
-          process.env.SETTINGS_SESSION_EXPIRATION_TIMEOUTS_ABSOLUTE = '1';
+          Config.set('settings.session.expirationTimeouts.inactivity', 2);
+          Config.set('settings.session.expirationTimeouts.absolute', 1);
 
           await rejects(
             () => session.commit(),
diff --git a/packages/core/src/sessions/set-session-cookie.spec.ts b/packages/core/src/sessions/set-session-cookie.spec.ts
index 5dc0481539..5eb3377555 100644
--- a/packages/core/src/sessions/set-session-cookie.spec.ts
+++ b/packages/core/src/sessions/set-session-cookie.spec.ts
@@ -1,5 +1,5 @@
 import { deepStrictEqual, strictEqual } from 'assert';
-import { HttpResponse, HttpResponseOK } from '../core';
+import { Config, HttpResponse, HttpResponseOK } from '../core';
 import {
   SESSION_DEFAULT_COOKIE_HTTP_ONLY,
   SESSION_DEFAULT_COOKIE_NAME,
@@ -85,22 +85,22 @@ describe('setSessionCookie', () => {
       const cookieName = SESSION_DEFAULT_COOKIE_NAME + '2';
 
       beforeEach(() => {
-        process.env.SETTINGS_SESSION_COOKIE_NAME = cookieName;
-        process.env.SETTINGS_SESSION_COOKIE_DOMAIN = 'example.com';
-        process.env.SETTINGS_SESSION_COOKIE_HTTP_ONLY = 'false';
-        process.env.SETTINGS_SESSION_COOKIE_PATH = '/foo';
-        process.env.SETTINGS_SESSION_COOKIE_SAME_SITE = 'strict';
-        process.env.SETTINGS_SESSION_COOKIE_SECURE = 'true';
+        Config.set('settings.session.cookie.name', cookieName);
+        Config.set('settings.session.cookie.domain', 'example.com');
+        Config.set('settings.session.cookie.httpOnly', false);
+        Config.set('settings.session.cookie.path', '/foo');
+        Config.set('settings.session.cookie.sameSite', 'strict');
+        Config.set('settings.session.cookie.secure', true);
         setSessionCookie(response, session);
       });
 
       afterEach(() => {
-        delete process.env.SETTINGS_SESSION_COOKIE_NAME;
-        delete process.env.SETTINGS_SESSION_COOKIE_DOMAIN;
-        delete process.env.SETTINGS_SESSION_COOKIE_HTTP_ONLY;
-        delete process.env.SETTINGS_SESSION_COOKIE_PATH;
-        delete process.env.SETTINGS_SESSION_COOKIE_SAME_SITE;
-        delete process.env.SETTINGS_SESSION_COOKIE_SECURE;
+        Config.remove('settings.session.cookie.name');
+        Config.remove('settings.session.cookie.domain');
+        Config.remove('settings.session.cookie.httpOnly');
+        Config.remove('settings.session.cookie.path');
+        Config.remove('settings.session.cookie.sameSite');
+        Config.remove('settings.session.cookie.secure');
       });
 
       it('with the proper default name and value.', () => {
@@ -144,9 +144,9 @@ describe('setSessionCookie', () => {
 
   context('given the CSRF protection is enabled in the config', () => {
 
-    beforeEach(() => process.env.SETTINGS_SESSION_CSRF_ENABLED = 'true');
+    beforeEach(() => Config.set('settings.session.csrf.enabled', true));
 
-    afterEach(() => delete process.env.SETTINGS_SESSION_CSRF_ENABLED);
+    afterEach(() => Config.remove('settings.session.csrf.enabled'));
 
     describe('should set a session cookie in the response', () => {
 
@@ -164,12 +164,12 @@ describe('setSessionCookie', () => {
       context('given configuration options are provided', () => {
 
         beforeEach(() => {
-          process.env.SETTINGS_SESSION_COOKIE_SAME_SITE = 'strict';
+          Config.set('settings.session.cookie.sameSite', 'strict');
           setSessionCookie(response, session);
         });
 
         afterEach(() => {
-          delete process.env.SETTINGS_SESSION_COOKIE_SAME_SITE;
+          Config.remove('settings.session.cookie.sameSite')
         });
 
         it('with the proper default "sameSite" directive.', () => {
@@ -229,22 +229,22 @@ describe('setSessionCookie', () => {
         const csrfCookieName = SESSION_DEFAULT_CSRF_COOKIE_NAME + '2';
 
         beforeEach(() => {
-          process.env.SETTINGS_SESSION_CSRF_COOKIE_NAME = csrfCookieName;
-          process.env.SETTINGS_SESSION_COOKIE_DOMAIN = 'example.com';
-          process.env.SETTINGS_SESSION_COOKIE_HTTP_ONLY = 'true';
-          process.env.SETTINGS_SESSION_COOKIE_PATH = '/foo';
-          process.env.SETTINGS_SESSION_COOKIE_SAME_SITE = 'strict';
-          process.env.SETTINGS_SESSION_COOKIE_SECURE = 'true';
+          Config.set('settings.session.csrf.cookie.name', csrfCookieName);
+          Config.set('settings.session.cookie.domain', 'example.com');
+          Config.set('settings.session.cookie.httpOnly', true);
+          Config.set('settings.session.cookie.path', '/foo');
+          Config.set('settings.session.cookie.sameSite', 'strict');
+          Config.set('settings.session.cookie.secure', true);
           setSessionCookie(response, session);
         });
 
         afterEach(() => {
-          delete process.env.SETTINGS_SESSION_CSRF_COOKIE_NAME;
-          delete process.env.SETTINGS_SESSION_COOKIE_DOMAIN;
-          delete process.env.SETTINGS_SESSION_COOKIE_HTTP_ONLY;
-          delete process.env.SETTINGS_SESSION_COOKIE_PATH;
-          delete process.env.SETTINGS_SESSION_COOKIE_SAME_SITE;
-          delete process.env.SETTINGS_SESSION_COOKIE_SECURE;
+          Config.remove('settings.session.csrf.cookie.name');
+          Config.remove('settings.session.cookie.domain');
+          Config.remove('settings.session.cookie.httpOnly');
+          Config.remove('settings.session.cookie.path');
+          Config.remove('settings.session.cookie.sameSite');
+          Config.remove('settings.session.cookie.secure');
         });
 
         it('with the proper default name and value.', () => {
diff --git a/packages/core/src/sessions/token.hook.spec.ts b/packages/core/src/sessions/token.hook.spec.ts
index 9a83311f5a..4dda165e87 100644
--- a/packages/core/src/sessions/token.hook.spec.ts
+++ b/packages/core/src/sessions/token.hook.spec.ts
@@ -3,6 +3,7 @@ import { deepStrictEqual, doesNotReject, rejects, strictEqual } from 'assert';
 
 // FoalTS
 import {
+  Config,
   ConfigNotFoundError,
   Context,
   getApiComponents,
@@ -118,8 +119,8 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
   });
 
   afterEach(() => {
-    delete process.env.SETTINGS_SESSION_COOKIE_NAME;
-    delete process.env.SETTINGS_SESSION_STORE;
+    Config.remove('settings.session.cookie.name');
+    Config.remove('settings.session.store');
   });
 
   context('given no session store class is provided as option', () => {
@@ -134,7 +135,7 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
     });
 
     it('should use the session store package provided in settings.session.store.', () => {
-      process.env.SETTINGS_SESSION_STORE = '@foal/internal-test';
+      Config.set('settings.session.store', '@foal/internal-test');
 
       return doesNotReject(() => hook(ctx, services));
     });
@@ -352,10 +353,10 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
     context('given settings.session.csrf.enabled is true', () => {
 
       beforeEach(() => {
-        process.env.SETTINGS_SESSION_CSRF_ENABLED = 'true';
+        Config.set('settings.session.csrf.enabled', true);
       });
 
-      afterEach(() => delete process.env.SETTINGS_SESSION_CSRF_ENABLED);
+      afterEach(() => Config.remove('settings.session.csrf.enabled'));
 
       context('given options.cookie is false or not defined', () => {
 
@@ -498,7 +499,7 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
 
   describe('should set Context.session', () => {
 
-    afterEach(() => delete process.env.SETTINGS_SESSION_COOKIE_NAME);
+    afterEach(() => Config.remove('settings.session.cookie.name'));
 
     it('with the session.', async () => {
       ctx = createContext({ Authorization: `Bearer ${anonymousSessionID}`});
@@ -516,7 +517,7 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
 
     // This test might be put in a better place.
     it('with the session (custom cookie name).', async () => {
-      process.env.SETTINGS_SESSION_COOKIE_NAME = 'auth2';
+      Config.set('settings.session.cookie.name', 'auth2');
 
       ctx = createContext({}, { auth2: anonymousSessionID });
       hook = getHookFunction(Token({ store: Store, cookie: true }));
@@ -905,7 +906,7 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
 
   describe('should define an API specification', () => {
 
-    afterEach(() => delete process.env.SETTINGS_SESSION_CSRF_ENABLED);
+    afterEach(() => Config.remove('settings.session.csrf.enabled'));
 
     it('unless options.openapi is false.', () => {
       @Token({ openapi: false })
@@ -934,7 +935,8 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
     });
 
     it('with the proper security scheme (cookie) (cookie name different).', () => {
-      process.env.SETTINGS_SESSION_COOKIE_NAME = 'auth2';
+      Config.set('settings.session.cookie.name', 'auth2');
+
       @Token({ cookie: true })
       class Foobar {}
 
@@ -1005,7 +1007,8 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
       });
 
       it('with the proper API responses (no cookie & csrf protection).', () => {
-        process.env.SETTINGS_SESSION_CSRF_ENABLED = 'true';
+        Config.set('settings.session.csrf.enabled', true);
+
         testResponses({ cookie: false });
       });
 
@@ -1014,7 +1017,8 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
       });
 
       it('with the proper API responses (cookie & csrf protection).', () => {
-        process.env.SETTINGS_SESSION_CSRF_ENABLED = 'true';
+        Config.set('settings.session.csrf.enabled', true);
+
         @Token({ cookie: true })
         class Foobar {}
 
@@ -1056,7 +1060,8 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
       });
 
       it('with the proper API responses (no cookie & csrf protection).', () => {
-        process.env.SETTINGS_SESSION_CSRF_ENABLED = 'true';
+        Config.set('settings.session.csrf.enabled', true);
+
         testResponses({ cookie: false });
       });
 
@@ -1065,7 +1070,8 @@ export function testSuite(Token: typeof TokenRequired|typeof TokenOptional, requ
       });
 
       it('with the proper API responses (cookie & csrf protection).', () => {
-        process.env.SETTINGS_SESSION_CSRF_ENABLED = 'true';
+        Config.set('settings.session.csrf.enabled', true);
+
         @Token({ cookie: true })
         class Foobar {}
 
diff --git a/packages/graphql/src/acceptance-test.spec.ts b/packages/graphql/src/acceptance-test.spec.ts
index aed5407cf5..07ce18c573 100644
--- a/packages/graphql/src/acceptance-test.spec.ts
+++ b/packages/graphql/src/acceptance-test.spec.ts
@@ -20,7 +20,7 @@ import { existsSync, mkdirSync, rmdirSync, unlinkSync, writeFileSync } from 'fs'
 import { get, Server } from 'http';
 
 // 3p
-import { controller, createApp, dependency } from '@foal/core';
+import { Config, controller, createApp, dependency } from '@foal/core';
 import { InMemoryCache } from 'apollo-cache-inmemory';
 import { ApolloClient } from 'apollo-client';
 import { HttpLink } from 'apollo-link-http';
@@ -57,7 +57,7 @@ describe('[Acceptance test] GraphQLController', () => {
     if (server) {
       server.close();
     }
-    delete process.env.SETTINGS_DEBUG;
+    Config.remove('settings.debug');
   });
 
   describe('should support common GraphQL clients such as', () => {
@@ -166,7 +166,7 @@ describe('[Acceptance test] GraphQLController', () => {
   });
 
   it('should include in the documentation an example on how to handle errors in resolvers.', async () => {
-    process.env.SETTINGS_DEBUG = 'false';
+    Config.set('settings.debug', false);
 
     class Resolvers {
       @FormatError()
diff --git a/packages/graphql/src/mask-and-log-error.spec.ts b/packages/graphql/src/mask-and-log-error.spec.ts
index 8cd953ec4d..93a0347dd5 100644
--- a/packages/graphql/src/mask-and-log-error.spec.ts
+++ b/packages/graphql/src/mask-and-log-error.spec.ts
@@ -1,15 +1,19 @@
 // std
 import { strictEqual } from 'assert';
 
+// 3p
+import { Config } from '@foal/core';
+
 // FoalTS
 import { maskAndLogError } from './mask-and-log-error';
 
 describe('maskAndLogError', () => {
 
-  afterEach(() => delete process.env.SETTINGS_DEBUG);
+  afterEach(() => Config.remove('settings.debug'));
 
   it('should return the error if the config key settings.debug is true.', () => {
-    process.env.SETTINGS_DEBUG = 'true';
+    Config.set('settings.debug', true);
+
     const err = new Error('This is an error (that should be shown in the logs)');
 
     const result = maskAndLogError(err);
diff --git a/packages/jwt/src/get-secret-or-private-key.util.spec.ts b/packages/jwt/src/get-secret-or-private-key.util.spec.ts
index db51a456bb..7d123420c6 100644
--- a/packages/jwt/src/get-secret-or-private-key.util.spec.ts
+++ b/packages/jwt/src/get-secret-or-private-key.util.spec.ts
@@ -1,4 +1,4 @@
-import { ConfigTypeError } from '@foal/core';
+import { Config, ConfigTypeError } from '@foal/core';
 import { deepStrictEqual, strictEqual, throws } from 'assert';
 import { getSecretOrPrivateKey } from './get-secret-or-private-key.util';
 
@@ -8,12 +8,13 @@ describe('getSecretOrPrivateKey', () => {
 
     const secret = 'secretX';
 
-    beforeEach(() => process.env.SETTINGS_JWT_SECRET = secret);
+    beforeEach(() => Config.set('settings.jwt.secret', secret));
 
-    afterEach(() => delete process.env.SETTINGS_JWT_SECRET);
+    afterEach(() => Config.remove('settings.jwt.secret'));
+
+    it('should throw a ConfigTypeError if the value is not a string.', () => {
+      Config.set('settings.jwt.secret', 2);
 
-    xit('should throw a ConfigTypeError if the value is not a string.', () => {
-      process.env.SETTINGS_JWT_SECRET = 2 as any;
       return throws(
         () => getSecretOrPrivateKey(),
         new ConfigTypeError('settings.jwt.secret', 'string', 'number'),
@@ -33,12 +34,13 @@ describe('getSecretOrPrivateKey', () => {
 
       const encoding = 'base64';
 
-      beforeEach(() => process.env.SETTINGS_JWT_SECRET_ENCODING = 'base64');
+      beforeEach(() => Config.set('settings.jwt.secretEncoding', 'base64'));
+
+      afterEach(() => Config.remove('settings.jwt.secretEncoding'));
 
-      afterEach(() => delete process.env.SETTINGS_JWT_SECRET_ENCODING);
+      it('should throw a ConfigTypeError if the value is not a string.', () => {
+        Config.set('settings.jwt.secretEncoding', 2);
 
-      xit('should throw a ConfigTypeError if the value is not a string.', () => {
-        process.env.SETTINGS_JWT_SECRET_ENCODING = 2 as any;
         return throws(
           () => getSecretOrPrivateKey(),
           new ConfigTypeError('settings.jwt.secretEncoding', 'string', 'number'),
@@ -62,12 +64,13 @@ describe('getSecretOrPrivateKey', () => {
 
     const privateKey = 'privateKeyX';
 
-    beforeEach(() => process.env.SETTINGS_JWT_PRIVATE_KEY = privateKey);
+    beforeEach(() => Config.set('settings.jwt.privateKey', privateKey));
+
+    afterEach(() => Config.remove('settings.jwt.privateKey'));
 
-    afterEach(() => delete process.env.SETTINGS_JWT_PRIVATE_KEY);
+    it('should throw a ConfigTypeError if the value is not a string.', () => {
+      Config.set('settings.jwt.privateKey', 2);
 
-    xit('should throw a ConfigTypeError if the value is not a string.', () => {
-      process.env.SETTINGS_JWT_PRIVATE_KEY = 2 as any;
       return throws(
         () => getSecretOrPrivateKey(),
         new ConfigTypeError('settings.jwt.privateKey', 'string', 'number'),
diff --git a/packages/jwt/src/get-secret-or-public-key.util.spec.ts b/packages/jwt/src/get-secret-or-public-key.util.spec.ts
index 9df9274d55..b158a7d966 100644
--- a/packages/jwt/src/get-secret-or-public-key.util.spec.ts
+++ b/packages/jwt/src/get-secret-or-public-key.util.spec.ts
@@ -1,4 +1,4 @@
-import { ConfigTypeError } from '@foal/core';
+import { Config, ConfigTypeError } from '@foal/core';
 import { deepStrictEqual, strictEqual, throws } from 'assert';
 import { getSecretOrPublicKey } from './get-secret-or-public-key.util';
 
@@ -8,12 +8,13 @@ describe('getSecretOrPublicKey', () => {
 
     const secret = 'secretX';
 
-    beforeEach(() => process.env.SETTINGS_JWT_SECRET = secret);
+    beforeEach(() => Config.set('settings.jwt.secret', secret));
 
-    afterEach(() => delete process.env.SETTINGS_JWT_SECRET);
+    afterEach(() => Config.remove('settings.jwt.secret'));
+
+    it('should throw a ConfigTypeError if the value is not a string.', () => {
+      Config.set('settings.jwt.secret', 2);
 
-    xit('should throw a ConfigTypeError if the value is not a string.', () => {
-      process.env.SETTINGS_JWT_SECRET = 2 as any;
       return throws(
         () => getSecretOrPublicKey(),
         new ConfigTypeError('settings.jwt.secret', 'string', 'number'),
@@ -33,12 +34,13 @@ describe('getSecretOrPublicKey', () => {
 
       const encoding = 'base64';
 
-      beforeEach(() => process.env.SETTINGS_JWT_SECRET_ENCODING = 'base64');
+      beforeEach(() => Config.set('settings.jwt.secretEncoding', 'base64'));
+
+      afterEach(() => Config.remove('settings.jwt.secretEncoding'));
 
-      afterEach(() => delete process.env.SETTINGS_JWT_SECRET_ENCODING);
+      it('should throw a ConfigTypeError if the value is not a string.', () => {
+        Config.set('settings.jwt.secretEncoding', 2);
 
-      xit('should throw a ConfigTypeError if the value is not a string.', () => {
-        process.env.SETTINGS_JWT_SECRET_ENCODING = 2 as any;
         return throws(
           () => getSecretOrPublicKey(),
           new ConfigTypeError('settings.jwt.secretEncoding', 'string', 'number'),
@@ -62,12 +64,13 @@ describe('getSecretOrPublicKey', () => {
 
     const publicKey = 'publicKeyX';
 
-    beforeEach(() => process.env.SETTINGS_JWT_PUBLIC_KEY = publicKey);
+    beforeEach(() => Config.set('settings.jwt.publicKey', publicKey));
+
+    afterEach(() => Config.remove('settings.jwt.publicKey'));
 
-    afterEach(() => delete process.env.SETTINGS_JWT_PUBLIC_KEY);
+    it('should throw a ConfigTypeError if the value is not a string.', () => {
+      Config.set('settings.jwt.publicKey', 2);
 
-    xit('should throw a ConfigTypeError if the value is not a string.', () => {
-      process.env.SETTINGS_JWT_PUBLIC_KEY = 2 as any;
       return throws(
         () => getSecretOrPublicKey(),
         new ConfigTypeError('settings.jwt.publicKey', 'string', 'number'),
diff --git a/packages/jwt/src/jwt-optional.hook.ts b/packages/jwt/src/jwt-optional.hook.ts
index 3bc88fb645..23b8140188 100644
--- a/packages/jwt/src/jwt-optional.hook.ts
+++ b/packages/jwt/src/jwt-optional.hook.ts
@@ -23,7 +23,7 @@ import { JWT, JWTOptions } from './jwt.hook';
  * @param {(token: string) => boolean|Promise<boolean>} [options.blacklist] - A function that takes a token
  * and returns true or false. If the returned value is true, then the hook returns a 401 error.
  * @param {boolean} [options.cookie] - If true, the hook expects the token to be sent in a cookie
- * named `auth`. You can change the cookie name with the key `settings.jwt.cookieName` in the configuration.
+ * named `auth`. You can change the cookie name with the key `settings.jwt.cookie.name` in the configuration.
  * @param {VerifyOptions} [verifyOptions={}] - Options of the `jsonwebtoken` package.
  * @returns {HookDecorator} The hook.
  */
diff --git a/packages/jwt/src/jwt-required.hook.ts b/packages/jwt/src/jwt-required.hook.ts
index db0325fa72..6319fd1fe0 100644
--- a/packages/jwt/src/jwt-required.hook.ts
+++ b/packages/jwt/src/jwt-required.hook.ts
@@ -23,7 +23,7 @@ import { JWT, JWTOptions } from './jwt.hook';
  * @param {(token: string) => boolean|Promise<boolean>} [options.blacklist] - A function that takes a token
  * and returns true or false. If the returned value is true, then the hook returns a 401 error.
  * @param {boolean} [options.cookie] - If true, the hook expects the token to be sent in a cookie
- * named `auth`. You can change the cookie name with the key `settings.jwt.cookieName` in the configuration.
+ * named `auth`. You can change the cookie name with the key `settings.jwt.cookie.name` in the configuration.
  * @param {VerifyOptions} [verifyOptions={}] - Options of the `jsonwebtoken` package.
  * @returns {HookDecorator} The hook.
  */
diff --git a/packages/jwt/src/jwt.hook.spec.ts b/packages/jwt/src/jwt.hook.spec.ts
index 2a9d85479f..778459d235 100644
--- a/packages/jwt/src/jwt.hook.spec.ts
+++ b/packages/jwt/src/jwt.hook.spec.ts
@@ -3,6 +3,7 @@ import { deepStrictEqual, notStrictEqual, rejects, strictEqual } from 'assert';
 
 // 3p
 import {
+  Config,
   Context,
   getApiComponents,
   getApiParameters,
@@ -115,13 +116,13 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
     hook = getHookFunction(JWT({ user: fetchUser }));
     services = new ServiceManager();
 
-    process.env.SETTINGS_JWT_SECRET = secret;
+    Config.set('settings.jwt.secret', secret);
   });
 
   afterEach(() => {
-    delete process.env.SETTINGS_JWT_SECRET;
-    delete process.env.SETTINGS_JWT_PUBLIC_KEY;
-    delete process.env.SETTINGS_JWT_COOKIE_NAME;
+    Config.remove('settings.jwt.secret');
+    Config.remove('settings.jwt.publicKey');
+    Config.remove('settings.jwt.cookie.name');
   });
 
   describe('should validate the request and', () => {
@@ -340,7 +341,7 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
 
   describe('should verify the token and', () => {
 
-    afterEach(() => delete process.env.SETTINGS_JWT_SECRET_ENCODING);
+    afterEach(() => Config.remove('settings.jwt.secretEncoding'));
 
     it('should return an HttpResponseUnauthorized object if the signature is invalid.', async () => {
       const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9'
@@ -365,7 +366,7 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
     it('should throw an error if no secret or public key is set in the Config and options.secretOrPublicKey is'
         + ' not defined.', async () => {
       // Remove the secret.
-      delete process.env.SETTINGS_JWT_SECRET;
+      Config.remove('settings.jwt.secret');
 
       const token = sign({}, secret);
       ctx = createContext({ Authorization: `Bearer ${token}` });
@@ -403,7 +404,7 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
       + ' (different secret encoding).', async () => {
         const hook = getHookFunction(JWT());
 
-        process.env.SETTINGS_JWT_SECRET_ENCODING = 'base64';
+        Config.set('settings.jwt.secretEncoding', 'base64');
         const token = sign({}, Buffer.from(secret, 'base64'));
         ctx = createContext({ Authorization: `Bearer ${token}` });
 
@@ -486,10 +487,11 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
         sub = 'subX';
         token = sign({ foo: 'bar' }, secret, { subject: sub });
         csrfToken = sign({ foo2: 'bar' }, secret, { subject: sub });
-        process.env.SETTINGS_JWT_CSRF_ENABLED = 'true';
+
+        Config.set('settings.jwt.csrf.enabled', true);
       });
 
-      afterEach(() => delete process.env.SETTINGS_JWT_CSRF_ENABLED);
+      afterEach(() => Config.remove('settings.jwt.csrf.enabled'));
 
       context('given options.cookie is false or not defined', () => {
 
@@ -686,9 +688,9 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
 
               const csrfCookieName = JWT_DEFAULT_CSRF_COOKIE_NAME + '2';
 
-              beforeEach(() => process.env.SETTINGS_JWT_CSRF_COOKIE_NAME = csrfCookieName);
+              beforeEach(() => Config.set('settings.jwt.csrf.cookie.name', csrfCookieName));
 
-              afterEach(() => delete process.env.SETTINGS_JWT_CSRF_COOKIE_NAME);
+              afterEach(() => Config.remove('settings.jwt.csrf.cookie.name'));
 
               testCsrkToken((requestCsrfToken, cookieCsrfToken) => createContext(
                 { 'X-XSRF-Token': requestCsrfToken },
@@ -743,7 +745,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
       });
 
       it('with the decoded payload (header & secret from options.secretOrPublicKey).', async () => {
-        delete process.env.SETTINGS_JWT_SECRET;
+        Config.remove('settings.jwt.secret');
+
         const secretOrPublicKey = async (header: any, payload: any) => {
           deepStrictEqual(header, {
             alg: 'HS256',
@@ -764,8 +767,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
       });
 
       it('with the decoded payload (header & public key).', async () => {
-        delete process.env.SETTINGS_JWT_SECRET;
-        process.env.SETTINGS_JWT_PUBLIC_KEY = publicKey;
+        Config.remove('settings.jwt.secret');
+        Config.set('settings.jwt.publicKey', publicKey);
 
         const hook = getHookFunction(JWT());
 
@@ -791,7 +794,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
       });
 
       it('with the decoded payload (cookie with a custom name & secret).', async () => {
-        process.env.SETTINGS_JWT_COOKIE_NAME = 'xxx';
+        Config.set('settings.jwt.cookie.name', 'xxx');
+
         const hook = getHookFunction(JWT({ cookie: true }));
 
         const jwt = sign({ foo: 'bar' }, secret, {});
@@ -864,8 +868,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
     const csrfCookieName = JWT_DEFAULT_CSRF_COOKIE_NAME + '2';
 
     afterEach(() => {
-      delete process.env.SETTINGS_JWT_CSRF_ENABLED;
-      delete process.env.SETTINGS_JWT_CSRF_COOKIE_NAME;
+      Config.remove('settings.jwt.csrf.enabled');
+      Config.remove('settings.jwt.csrf.cookie.name');
     });
 
     it('unless options.openapi is false.', () => {
@@ -895,7 +899,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
     });
 
     it('with the proper security scheme (cookie name different).', () => {
-      process.env.SETTINGS_JWT_COOKIE_NAME = 'auth2';
+      Config.set('settings.jwt.cookie.name', 'auth2');
+
       @JWT({ cookie: true })
       class Foobar {}
 
@@ -967,7 +972,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
       });
 
       it('with the proper API responses (no cookie & csrf protection).', () => {
-        process.env.SETTINGS_JWT_CSRF_ENABLED = 'true';
+        Config.set('settings.jwt.csrf.enabled', true);
+
         testResponses({ cookie: false });
       });
 
@@ -976,7 +982,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
       });
 
       it('with the proper API responses (cookie & csrf protection).', () => {
-        process.env.SETTINGS_JWT_CSRF_ENABLED = 'true';
+        Config.set('settings.jwt.csrf.enabled', true);
+
         @JWT({ cookie: true })
         class Foobar {}
 
@@ -1018,7 +1025,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
       });
 
       it('with the proper API responses (no cookie & csrf protection).', () => {
-        process.env.SETTINGS_JWT_CSRF_ENABLED = 'true';
+        Config.set('settings.jwt.csrf.enabled', true);
+
         testResponses({ cookie: false });
       });
 
@@ -1027,7 +1035,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
       });
 
       it('with the proper API responses (cookie & csrf protection).', () => {
-        process.env.SETTINGS_JWT_CSRF_ENABLED = 'true';
+        Config.set('settings.jwt.csrf.enabled', true);
+
         @JWT({ cookie: true })
         class Foobar {}
 
@@ -1051,7 +1060,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
     });
 
     it('with the proper API parameters (no cookie & csrf protection).', () => {
-      process.env.SETTINGS_JWT_CSRF_ENABLED = 'true';
+      Config.set('settings.jwt.csrf.enabled', true);
+
       testParameters({ cookie: false });
     });
 
@@ -1060,7 +1070,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
     });
 
     it('with the proper API parameters (cookie & csrf protection).', () => {
-      process.env.SETTINGS_JWT_CSRF_ENABLED = 'true';
+      Config.set('settings.jwt.csrf.enabled', true);
+
       @JWT({ cookie: true })
       class Foobar {}
 
@@ -1073,8 +1084,8 @@ export function testSuite(JWT: typeof JWTOptional|typeof JWTRequired, required:
     });
 
     it('with the proper API parameters (cookie & csrf protection & custom name).', () => {
-      process.env.SETTINGS_JWT_CSRF_ENABLED = 'true';
-      process.env.SETTINGS_JWT_CSRF_COOKIE_NAME = csrfCookieName;
+      Config.set('settings.jwt.csrf.enabled', true);
+      Config.set('settings.jwt.csrf.cookie.name', csrfCookieName);
 
       @JWT({ cookie: true })
       class Foobar {}
diff --git a/packages/jwt/src/jwt.hook.ts b/packages/jwt/src/jwt.hook.ts
index 8d8d3c8b04..24561e49f8 100644
--- a/packages/jwt/src/jwt.hook.ts
+++ b/packages/jwt/src/jwt.hook.ts
@@ -73,7 +73,7 @@ export function JWT(required: boolean, options: JWTOptions, verifyOptions: Verif
   async function hook(ctx: Context) {
     let token: string;
     if (options.cookie) {
-      const cookieName = Config.get('settings.jwt.cookieName', 'string', JWT_DEFAULT_COOKIE_NAME);
+      const cookieName = Config.get('settings.jwt.cookie.name', 'string', JWT_DEFAULT_COOKIE_NAME);
       const content = ctx.request.cookies[cookieName] as string|undefined;
 
       if (!content) {
@@ -210,7 +210,7 @@ export function JWT(required: boolean, options: JWTOptions, verifyOptions: Verif
   if (options.cookie) {
     const securityScheme: IApiSecurityScheme = {
       in: 'cookie',
-      name: Config.get('settings.jwt.cookieName', 'string', JWT_DEFAULT_COOKIE_NAME),
+      name: Config.get('settings.jwt.cookie.name', 'string', JWT_DEFAULT_COOKIE_NAME),
       type: 'apiKey',
     };
     openapi.push(ApiDefineSecurityScheme('cookieAuth', securityScheme));
diff --git a/packages/jwt/src/remove-auth-cookie.spec.ts b/packages/jwt/src/remove-auth-cookie.spec.ts
index 315a6128a1..7f03fc7bd8 100644
--- a/packages/jwt/src/remove-auth-cookie.spec.ts
+++ b/packages/jwt/src/remove-auth-cookie.spec.ts
@@ -2,7 +2,7 @@
 import { strictEqual } from 'assert';
 
 // 3p
-import { HttpResponse, HttpResponseOK } from '@foal/core';
+import { Config, HttpResponse, HttpResponseOK } from '@foal/core';
 
 // FoalTS
 import {
@@ -67,22 +67,22 @@ describe('removeAuthCookie', () => {
       const cookieName = JWT_DEFAULT_COOKIE_NAME + '2';
 
       beforeEach(() => {
-        process.env.SETTINGS_JWT_COOKIE_NAME = cookieName;
-        process.env.SETTINGS_JWT_COOKIE_DOMAIN = 'example.com';
-        process.env.SETTINGS_JWT_COOKIE_HTTP_ONLY = 'false';
-        process.env.SETTINGS_JWT_COOKIE_PATH = '/foo';
-        process.env.SETTINGS_JWT_COOKIE_SAME_SITE = 'strict';
-        process.env.SETTINGS_JWT_COOKIE_SECURE = 'true';
+        Config.set('settings.jwt.cookie.name', cookieName);
+        Config.set('settings.jwt.cookie.domain', 'example.com');
+        Config.set('settings.jwt.cookie.httpOnly', false);
+        Config.set('settings.jwt.cookie.path', '/foo');
+        Config.set('settings.jwt.cookie.sameSite', 'strict');
+        Config.set('settings.jwt.cookie.secure', true);
         removeAuthCookie(response);
       });
 
       afterEach(() => {
-        delete process.env.SETTINGS_JWT_COOKIE_NAME;
-        delete process.env.SETTINGS_JWT_COOKIE_DOMAIN;
-        delete process.env.SETTINGS_JWT_COOKIE_HTTP_ONLY;
-        delete process.env.SETTINGS_JWT_COOKIE_PATH;
-        delete process.env.SETTINGS_JWT_COOKIE_SAME_SITE;
-        delete process.env.SETTINGS_JWT_COOKIE_SECURE;
+        Config.remove('settings.jwt.cookie.name');
+        Config.remove('settings.jwt.cookie.domain');
+        Config.remove('settings.jwt.cookie.httpOnly');
+        Config.remove('settings.jwt.cookie.path');
+        Config.remove('settings.jwt.cookie.sameSite');
+        Config.remove('settings.jwt.cookie.secure');
       });
 
       it('with the proper default name and value.', () => {
@@ -126,9 +126,9 @@ describe('removeAuthCookie', () => {
 
   context('given the CSRF protection is enabled in the config', () => {
 
-    beforeEach(() => process.env.SETTINGS_JWT_CSRF_ENABLED = 'true');
+    beforeEach(() => Config.set('settings.jwt.csrf.enabled', true));
 
-    afterEach(() => delete process.env.SETTINGS_JWT_CSRF_ENABLED);
+    afterEach(() => Config.remove('settings.jwt.csrf.enabled'));
 
     describe('should set an auth cookie in the response', () => {
 
@@ -146,12 +146,12 @@ describe('removeAuthCookie', () => {
       context('given configuration options are provided', () => {
 
         beforeEach(() => {
-          process.env.SETTINGS_JWT_COOKIE_SAME_SITE = 'strict';
+          Config.set('settings.jwt.cookie.sameSite', 'strict');
           removeAuthCookie(response);
         });
 
         afterEach(() => {
-          delete process.env.SETTINGS_JWT_COOKIE_SAME_SITE;
+          Config.remove('settings.jwt.cookie.sameSite');
         });
 
         it('with the proper default "sameSite" directive.', () => {
@@ -211,22 +211,22 @@ describe('removeAuthCookie', () => {
         const csrfCookieName = JWT_DEFAULT_CSRF_COOKIE_NAME + '2';
 
         beforeEach(() => {
-          process.env.SETTINGS_JWT_CSRF_COOKIE_NAME = csrfCookieName;
-          process.env.SETTINGS_JWT_COOKIE_DOMAIN = 'example.com';
-          process.env.SETTINGS_JWT_COOKIE_HTTP_ONLY = 'true';
-          process.env.SETTINGS_JWT_COOKIE_PATH = '/foo';
-          process.env.SETTINGS_JWT_COOKIE_SAME_SITE = 'strict';
-          process.env.SETTINGS_JWT_COOKIE_SECURE = 'true';
+          Config.set('settings.jwt.csrf.cookie.name', csrfCookieName);
+          Config.set('settings.jwt.cookie.domain', 'example.com');
+          Config.set('settings.jwt.cookie.httpOnly', true);
+          Config.set('settings.jwt.cookie.path', '/foo');
+          Config.set('settings.jwt.cookie.sameSite', 'strict');
+          Config.set('settings.jwt.cookie.secure', true);
           removeAuthCookie(response);
         });
 
         afterEach(() => {
-          delete process.env.SETTINGS_JWT_CSRF_COOKIE_NAME;
-          delete process.env.SETTINGS_JWT_COOKIE_DOMAIN;
-          delete process.env.SETTINGS_JWT_COOKIE_HTTP_ONLY;
-          delete process.env.SETTINGS_JWT_COOKIE_PATH;
-          delete process.env.SETTINGS_JWT_COOKIE_SAME_SITE;
-          delete process.env.SETTINGS_JWT_COOKIE_SECURE;
+          Config.remove('settings.jwt.csrf.cookie.name');
+          Config.remove('settings.jwt.cookie.domain');
+          Config.remove('settings.jwt.cookie.httpOnly');
+          Config.remove('settings.jwt.cookie.path');
+          Config.remove('settings.jwt.cookie.sameSite');
+          Config.remove('settings.jwt.cookie.secure');
         });
 
         it('with the proper default name and value.', () => {
diff --git a/packages/jwt/src/set-auth-cookie.spec.ts b/packages/jwt/src/set-auth-cookie.spec.ts
index 670285d82f..e7eeef95f3 100644
--- a/packages/jwt/src/set-auth-cookie.spec.ts
+++ b/packages/jwt/src/set-auth-cookie.spec.ts
@@ -2,7 +2,7 @@
 import { deepStrictEqual, notStrictEqual, rejects, strictEqual } from 'assert';
 
 // 3p
-import { HttpResponse, HttpResponseOK } from '@foal/core';
+import { Config, HttpResponse, HttpResponseOK } from '@foal/core';
 import { decode, sign, verify } from 'jsonwebtoken';
 
 // FoalTS
@@ -134,22 +134,22 @@ describe('setAuthCookie', () => {
       const cookieName = JWT_DEFAULT_COOKIE_NAME + '2';
 
       beforeEach(async () => {
-        process.env.SETTINGS_JWT_COOKIE_NAME = cookieName;
-        process.env.SETTINGS_JWT_COOKIE_DOMAIN = 'example.com';
-        process.env.SETTINGS_JWT_COOKIE_HTTP_ONLY = 'false';
-        process.env.SETTINGS_JWT_COOKIE_PATH = '/foo';
-        process.env.SETTINGS_JWT_COOKIE_SAME_SITE = 'strict';
-        process.env.SETTINGS_JWT_COOKIE_SECURE = 'true';
+        Config.set('settings.jwt.cookie.name', cookieName);
+        Config.set('settings.jwt.cookie.domain', 'example.com');
+        Config.set('settings.jwt.cookie.httpOnly', false);
+        Config.set('settings.jwt.cookie.path', '/foo');
+        Config.set('settings.jwt.cookie.sameSite', 'strict');
+        Config.set('settings.jwt.cookie.secure', true);
         await setAuthCookie(response, token);
       });
 
       afterEach(() => {
-        delete process.env.SETTINGS_JWT_COOKIE_NAME;
-        delete process.env.SETTINGS_JWT_COOKIE_DOMAIN;
-        delete process.env.SETTINGS_JWT_COOKIE_HTTP_ONLY;
-        delete process.env.SETTINGS_JWT_COOKIE_PATH;
-        delete process.env.SETTINGS_JWT_COOKIE_SAME_SITE;
-        delete process.env.SETTINGS_JWT_COOKIE_SECURE;
+        Config.remove('settings.jwt.cookie.name');
+        Config.remove('settings.jwt.cookie.domain');
+        Config.remove('settings.jwt.cookie.httpOnly');
+        Config.remove('settings.jwt.cookie.path');
+        Config.remove('settings.jwt.cookie.sameSite');
+        Config.remove('settings.jwt.cookie.secure');
       });
 
       it('with the proper default name and value.', () => {
@@ -198,14 +198,14 @@ describe('setAuthCookie', () => {
   context('given the CSRF protection is enabled in the config', () => {
 
     beforeEach(() => {
-      process.env.SETTINGS_JWT_CSRF_ENABLED = 'true';
-      process.env.SETTINGS_JWT_PRIVATE_KEY = privateKey;
+      Config.set('settings.jwt.csrf.enabled', true);
+      Config.set('settings.jwt.privateKey', privateKey);
     });
 
     afterEach(() => {
-      delete process.env.SETTINGS_JWT_CSRF_ENABLED;
-      delete process.env.SETTINGS_JWT_PRIVATE_KEY;
-      delete process.env.SETTINGS_JWT_SECRET;
+      Config.remove('settings.jwt.csrf.enabled');
+      Config.remove('settings.jwt.privateKey');
+      Config.remove('settings.jwt.secret');
     });
 
     describe('should set an auth cookie in the response', () => {
@@ -224,12 +224,12 @@ describe('setAuthCookie', () => {
       context('given configuration options are provided', () => {
 
         beforeEach(async () => {
-          process.env.SETTINGS_JWT_COOKIE_SAME_SITE = 'strict';
+          Config.set('settings.jwt.cookie.sameSite', 'strict');
           await setAuthCookie(response, token);
         });
 
         afterEach(() => {
-          delete process.env.SETTINGS_JWT_COOKIE_SAME_SITE;
+          Config.remove('settings.jwt.cookie.sameSite');
         });
 
         it('with the proper default "sameSite" directive.', () => {
@@ -293,8 +293,8 @@ describe('setAuthCookie', () => {
           });
 
           it('should use the algorithm of the given JWT.', async () => {
-            delete process.env.SETTINGS_JWT_PRIVATE_KEY;
-            process.env.SETTINGS_JWT_SECRET = secret;
+            Config.remove('settings.jwt.privateKey');
+            Config.set('settings.jwt.secret', secret);
 
             await setAuthCookie(response, tokenSignedWithSecret);
 
@@ -372,22 +372,22 @@ describe('setAuthCookie', () => {
         const csrfCookieName = JWT_DEFAULT_CSRF_COOKIE_NAME + '2';
 
         beforeEach(async () => {
-          process.env.SETTINGS_JWT_CSRF_COOKIE_NAME = csrfCookieName;
-          process.env.SETTINGS_JWT_COOKIE_DOMAIN = 'example.com';
-          process.env.SETTINGS_JWT_COOKIE_HTTP_ONLY = 'true';
-          process.env.SETTINGS_JWT_COOKIE_PATH = '/foo';
-          process.env.SETTINGS_JWT_COOKIE_SAME_SITE = 'strict';
-          process.env.SETTINGS_JWT_COOKIE_SECURE = 'true';
+          Config.set('settings.jwt.csrf.cookie.name', csrfCookieName);
+          Config.set('settings.jwt.cookie.domain', 'example.com');
+          Config.set('settings.jwt.cookie.httpOnly', true);
+          Config.set('settings.jwt.cookie.path', '/foo');
+          Config.set('settings.jwt.cookie.sameSite', 'strict');
+          Config.set('settings.jwt.cookie.secure', true);
           await setAuthCookie(response, token);
         });
 
         afterEach(() => {
-          delete process.env.SETTINGS_JWT_CSRF_COOKIE_NAME;
-          delete process.env.SETTINGS_JWT_COOKIE_DOMAIN;
-          delete process.env.SETTINGS_JWT_COOKIE_HTTP_ONLY;
-          delete process.env.SETTINGS_JWT_COOKIE_PATH;
-          delete process.env.SETTINGS_JWT_COOKIE_SAME_SITE;
-          delete process.env.SETTINGS_JWT_COOKIE_SECURE;
+          Config.remove('settings.jwt.csrf.cookie.name');
+          Config.remove('settings.jwt.cookie.domain');
+          Config.remove('settings.jwt.cookie.httpOnly');
+          Config.remove('settings.jwt.cookie.path');
+          Config.remove('settings.jwt.cookie.sameSite');
+          Config.remove('settings.jwt.cookie.secure');
         });
 
         describe('with the proper default name and value', () => {
diff --git a/packages/mongodb/src/mongodb-store.service.spec.ts b/packages/mongodb/src/mongodb-store.service.spec.ts
index 685b871d9a..3daa66a1e0 100644
--- a/packages/mongodb/src/mongodb-store.service.spec.ts
+++ b/packages/mongodb/src/mongodb-store.service.spec.ts
@@ -2,7 +2,7 @@
 import { deepStrictEqual, doesNotReject, rejects, strictEqual } from 'assert';
 
 // 3p
-import { ConfigNotFoundError, createService, createSession, SessionAlreadyExists, SessionState } from '@foal/core';
+import { Config, ConfigNotFoundError, createService, createSession, SessionAlreadyExists, SessionState } from '@foal/core';
 import { MongoClient } from 'mongodb';
 
 // FoalTS
@@ -40,19 +40,19 @@ describe('MongoDBStore', () => {
   }
 
   before(async () => {
-      process.env.MONGODB_URI = MONGODB_URI;
-
-      mongoDBClient = await MongoClient.connect(MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true });
-      try {
-        await mongoDBClient.db().collection(COLLECTION_NAME).dropIndexes();
-      } catch (error) {
-        if (!(error.message.includes('ns not found'))) {
-          throw error;
-        }
+    Config.set('settings.mongodb.uri', MONGODB_URI);
+
+    mongoDBClient = await MongoClient.connect(MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true });
+    try {
+      await mongoDBClient.db().collection(COLLECTION_NAME).dropIndexes();
+    } catch (error) {
+      if (!(error.message.includes('ns not found'))) {
+        throw error;
       }
-      store = createService(MongoDBStore);
-      await store.boot();
-    });
+    }
+    store = createService(MongoDBStore);
+    await store.boot();
+  });
 
   beforeEach(async () => {
     state = createState();
@@ -65,7 +65,7 @@ describe('MongoDBStore', () => {
   });
 
   after(() => {
-    delete process.env.MONGODB_URI;
+    Config.remove('settings.mongodb.uri');
 
     return Promise.all([
       mongoDBClient.close(),
@@ -103,11 +103,12 @@ describe('MongoDBStore', () => {
   describe('has a "boot" method that', () => {
 
     it('should throw a ConfigNotFoundError if no MongoDB URI is provided.', () => {
-      delete process.env.MONGODB_URI;
+      Config.remove('settings.mongodb.uri');
+
       return rejects(
         () => createService(MongoDBStore).boot(),
         new ConfigNotFoundError(
-          'mongodb.uri',
+          'settings.mongodb.uri',
           'You must provide the URI of your database when using MongoDBStore.',
         )
       );
diff --git a/packages/mongodb/src/mongodb-store.service.ts b/packages/mongodb/src/mongodb-store.service.ts
index 5e760d6575..aea64efed4 100644
--- a/packages/mongodb/src/mongodb-store.service.ts
+++ b/packages/mongodb/src/mongodb-store.service.ts
@@ -20,7 +20,7 @@ export class MongoDBStore extends SessionStore {
 
   async boot() {
     const mongoDBURI = Config.getOrThrow(
-      'mongodb.uri',
+      'settings.mongodb.uri',
       'string',
       'You must provide the URI of your database when using MongoDBStore.'
     );
diff --git a/packages/redis/src/redis-store.service.spec.ts b/packages/redis/src/redis-store.service.spec.ts
index 96657e36e3..04850a4a81 100644
--- a/packages/redis/src/redis-store.service.spec.ts
+++ b/packages/redis/src/redis-store.service.spec.ts
@@ -1,5 +1,5 @@
 // 3p
-import { createService, createSession, SessionAlreadyExists, SessionState } from '@foal/core';
+import { Config, createService, createSession, SessionAlreadyExists, SessionState } from '@foal/core';
 import { createClient } from 'redis';
 
 // FoalTS
@@ -8,7 +8,7 @@ import { RedisStore } from './redis-store.service';
 
 describe('RedisStore', () => {
 
-  const REDIS_URI = 'redis://localhost:6379';
+  const REDIS_URI = 'redis://localhost:6380';
   const COLLECTION_NAME =  'sessions';
 
   let store: RedisStore;
@@ -36,7 +36,7 @@ describe('RedisStore', () => {
   }
 
   before(async () => {
-    process.env.REDIS_URI = REDIS_URI;
+    Config.set('settings.redis.uri', REDIS_URI);
 
     redisClient = createClient(REDIS_URI);
     store = createService(RedisStore);
@@ -50,7 +50,7 @@ describe('RedisStore', () => {
   });
 
   after(() => {
-    delete process.env.REDIS_URI;
+    Config.remove('settings.redis.uri');
 
     return Promise.all([
       redisClient.end(true),
diff --git a/packages/redis/src/redis-store.service.ts b/packages/redis/src/redis-store.service.ts
index d48d4710fc..b4230517a0 100644
--- a/packages/redis/src/redis-store.service.ts
+++ b/packages/redis/src/redis-store.service.ts
@@ -13,7 +13,7 @@ export class RedisStore extends SessionStore {
   private redisClient: any;
 
   boot() {
-    const redisURI = Config.get('redis.uri', 'string');
+    const redisURI = Config.get('settings.redis.uri', 'string');
     this.redisClient = createClient(redisURI);
   }
 
diff --git a/packages/social/src/abstract-provider.service.spec.ts b/packages/social/src/abstract-provider.service.spec.ts
index e6f8305cab..9919c23160 100644
--- a/packages/social/src/abstract-provider.service.spec.ts
+++ b/packages/social/src/abstract-provider.service.spec.ts
@@ -5,6 +5,7 @@ import { URLSearchParams } from 'url';
 
 // 3p
 import {
+  Config,
   Context,
   createApp,
   createService,
@@ -138,18 +139,19 @@ describe('AbstractProvider', () => {
   const redirectUri = 'https://example.com/callback';
 
   beforeEach(() => {
-    process.env.SETTINGS_SOCIAL_EXAMPLE_CLIENT_ID = clientId;
-    process.env.SETTINGS_SOCIAL_EXAMPLE_CLIENT_SECRET = clientSecret;
-    process.env.SETTINGS_SOCIAL_EXAMPLE_REDIRECT_URI = redirectUri;
+    Config.set('settings.social.example.clientId', clientId);
+    Config.set('settings.social.example.clientSecret', clientSecret);
+    Config.set('settings.social.example.redirectUri', redirectUri);
+    Config.set('settings.loggerFormat', 'none');
 
     provider = createService(ConcreteProvider);
   });
 
   afterEach(() => {
-    delete process.env.SETTINGS_SOCIAL_EXAMPLE_CLIENT_ID;
-    delete process.env.SETTINGS_SOCIAL_EXAMPLE_CLIENT_SECRET;
-    delete process.env.SETTINGS_SOCIAL_EXAMPLE_REDIRECT_URI;
-    delete process.env.SETTINGS_SOCIAL_COOKIE_SECURE;
+    Config.remove('settings.social.example.clientId');
+    Config.remove('settings.social.example.clientSecret');
+    Config.remove('settings.social.example.redirectUri');
+    Config.remove('settings.social.cookie.secure');
   });
 
   describe('has a "redirect" method that', () => {
@@ -245,7 +247,7 @@ describe('AbstractProvider', () => {
       });
 
       it('with a generated state in a cookie whose secure option is defined with the config.', async () => {
-        process.env.SETTINGS_SOCIAL_COOKIE_SECURE = 'true';
+        Config.set('settings.social.cookie.secure', true);
 
         const response = await provider.redirect();
         const { options } = response.getCookie(STATE_COOKIE_NAME);
diff --git a/packages/social/src/facebook-provider.service.spec.ts b/packages/social/src/facebook-provider.service.spec.ts
index 8f010aee42..9118ca65fb 100644
--- a/packages/social/src/facebook-provider.service.spec.ts
+++ b/packages/social/src/facebook-provider.service.spec.ts
@@ -3,7 +3,7 @@ import { deepStrictEqual, strictEqual } from 'assert';
 import { Server } from 'http';
 
 // 3p
-import { Context, createApp, createService, Get, HttpResponseBadRequest, HttpResponseOK } from '@foal/core';
+import { Config, Context, createApp, createService, Get, HttpResponseBadRequest, HttpResponseOK } from '@foal/core';
 
 // FoalTS
 import { SocialTokens } from './abstract-provider.service';
@@ -23,9 +23,11 @@ describe('FacebookProvider', () => {
 
     beforeEach(() => {
       provider = createService(FacebookProvider2);
+      Config.set('settings.loggerFormat', 'none');
     });
 
     afterEach(() => {
+      Config.remove('settings.loggerFormat');
       if (server) {
         server.close();
       }
diff --git a/packages/social/src/github-provider.service.spec.ts b/packages/social/src/github-provider.service.spec.ts
index b4337a0f28..cb48092dde 100644
--- a/packages/social/src/github-provider.service.spec.ts
+++ b/packages/social/src/github-provider.service.spec.ts
@@ -3,7 +3,7 @@ import { deepStrictEqual, strictEqual } from 'assert';
 import { Server } from 'http';
 
 // 3p
-import { Context, createApp, createService, Get, HttpResponseBadRequest, HttpResponseOK } from '@foal/core';
+import { Config, Context, createApp, createService, Get, HttpResponseBadRequest, HttpResponseOK } from '@foal/core';
 
 // FoalTS
 import { SocialTokens } from './abstract-provider.service';
@@ -23,9 +23,11 @@ describe('GithubProvider', () => {
 
     beforeEach(() => {
       provider = createService(GithubProvider2);
+      Config.set('settings.loggerFormat', 'none');
     });
 
     afterEach(() => {
+      Config.remove('settings.loggerFormat');
       if (server) {
         server.close();
       }
diff --git a/packages/social/src/linkedin-provider.service.spec.ts b/packages/social/src/linkedin-provider.service.spec.ts
index 7ea3de08ea..9da762aa41 100644
--- a/packages/social/src/linkedin-provider.service.spec.ts
+++ b/packages/social/src/linkedin-provider.service.spec.ts
@@ -3,7 +3,7 @@ import { deepStrictEqual, strictEqual } from 'assert';
 import { Server } from 'http';
 
 // 3p
-import { Context, createApp, createService, Get, HttpResponseBadRequest, HttpResponseOK } from '@foal/core';
+import { Config, Context, createApp, createService, Get, HttpResponseBadRequest, HttpResponseOK } from '@foal/core';
 import { SocialTokens } from './abstract-provider.service';
 import { LinkedInProvider } from './linkedin-provider.service';
 import { UserInfoError } from './user-info.error';
@@ -21,9 +21,11 @@ describe('LinkedInProvider', () => {
 
     beforeEach(() => {
       provider = createService(LinkedInProvider2);
+      Config.set('settings.loggerFormat', 'none');
     });
 
     afterEach(() => {
+      Config.remove('settings.loggerFormat');
       if (server) {
         server.close();
       }
diff --git a/packages/storage/src/local-disk.service.spec.ts b/packages/storage/src/local-disk.service.spec.ts
index 467a315324..71c9bf4b55 100644
--- a/packages/storage/src/local-disk.service.spec.ts
+++ b/packages/storage/src/local-disk.service.spec.ts
@@ -5,7 +5,7 @@ import { join } from 'path';
 import { Readable } from 'stream';
 
 // 3p
-import { ConfigNotFoundError, createService } from '@foal/core';
+import { Config, ConfigNotFoundError, createService } from '@foal/core';
 
 // FoalTS
 import { FileDoesNotExist } from './abstract-disk.service';
@@ -44,7 +44,7 @@ describe('LocalDisk', () => {
   let disk: LocalDisk;
 
   beforeEach(() => {
-    process.env.SETTINGS_DISK_LOCAL_DIRECTORY = 'uploaded';
+    Config.set('settings.disk.local.directory', 'uploaded');
     if (!existsSync('uploaded')) {
       mkdirSync('uploaded');
     }
@@ -56,14 +56,15 @@ describe('LocalDisk', () => {
   });
 
   afterEach(() => {
-    delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
+    Config.remove('settings.disk.local.directory');
     rmDirAndFilesIfExist('uploaded');
   });
 
   describe('has a "write" method that', () => {
 
     it('should throw an ConfigNotFoundError if no directory is specified in the config.', async () => {
-      delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
+      Config.remove('settings.disk.local.directory');
+
       try {
         await disk.write('foo', Buffer.from('hello', 'utf8'));
         throw new Error('An error should have been thrown.');
@@ -118,7 +119,8 @@ describe('LocalDisk', () => {
   describe('has a "read" method that', () => {
 
     it('should throw an ConfigNotFoundError if no directory is specified in the config.', async () => {
-      delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
+      Config.remove('settings.disk.local.directory');
+
       try {
         await disk.read('foo', 'buffer');
         throw new Error('An error should have been thrown.');
@@ -193,7 +195,8 @@ describe('LocalDisk', () => {
   describe('has a "readSize" method that', () => {
 
     it('should throw an ConfigNotFoundError if no directory is specified in the config.', async () => {
-      delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
+      Config.remove('settings.disk.local.directory');
+
       try {
         await disk.readSize('foo');
         throw new Error('An error should have been thrown.');
@@ -231,7 +234,8 @@ describe('LocalDisk', () => {
   describe('has a "delete" method that', () => {
 
     it('should throw an ConfigNotFoundError if no directory is specified in the config.', async () => {
-      delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
+      Config.remove('settings.disk.local.directory');
+
       try {
         await disk.delete('foo');
         throw new Error('An error should have been thrown.');
diff --git a/packages/storage/src/validate-multipart-form-data-body.hook.spec.ts b/packages/storage/src/validate-multipart-form-data-body.hook.spec.ts
index ba365124ba..41ec117cf3 100644
--- a/packages/storage/src/validate-multipart-form-data-body.hook.spec.ts
+++ b/packages/storage/src/validate-multipart-form-data-body.hook.spec.ts
@@ -5,7 +5,7 @@ import { join } from 'path';
 
 // 3p
 import {
-  Context, createApp, createService, getApiRequestBody, HttpResponseOK, IApiRequestBody, Post
+  Config, Context, createApp, createService, getApiRequestBody, HttpResponseOK, IApiRequestBody, Post
 } from '@foal/core';
 import * as request from 'supertest';
 
@@ -17,13 +17,13 @@ import { MultipartFormDataSchema, ValidateMultipartFormDataBody } from './valida
 describe('ValidateMultipartFormDataBody', () => {
 
   beforeEach(() => {
-    process.env.SETTINGS_LOGGER_FORMAT = 'none';
-    process.env.SETTINGS_DISK_DRIVER = 'local';
+    Config.set('settings.loggerFormat', 'none');
+    Config.set('settings.disk.driver', 'local');
   });
 
   afterEach(() => {
-    delete process.env.SETTINGS_LOGGER_FORMAT;
-    delete process.env.SETTINGS_DISK_DRIVER;
+    Config.remove('settings.loggerFormat');
+    Config.remove('settings.disk.driver');
   });
 
   // Note: Unfortunatly, in order to have a multipart request object,
@@ -100,14 +100,14 @@ describe('ValidateMultipartFormDataBody', () => {
   describe('when the fields are not validated against the given schema', () => {
 
     beforeEach(() => {
-      process.env.SETTINGS_DISK_LOCAL_DIRECTORY = 'uploaded';
+      Config.set('settings.disk.local.directory', 'uploaded');
 
       mkdirSync('uploaded');
       mkdirSync('uploaded/images');
     });
 
     afterEach(() => {
-      delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
+      Config.remove('settings.disk.local.directory');
 
       const contents = readdirSync('uploaded/images');
       for (const content of contents) {
@@ -202,18 +202,16 @@ describe('ValidateMultipartFormDataBody', () => {
   describe('when the max file size has been reached', () => {
 
     beforeEach(() => {
-      process.env.SETTINGS_MULTIPART_REQUESTS_FILE_SIZE_LIMIT = '200000';
-
-      process.env.SETTINGS_DISK_LOCAL_DIRECTORY = 'uploaded';
+      Config.set('settings.multipartRequests.fileSizeLimit', 200000);
+      Config.set('settings.disk.local.directory', 'uploaded');
 
       mkdirSync('uploaded');
       mkdirSync('uploaded/images');
     });
 
     afterEach(() => {
-      delete process.env.SETTINGS_MULTIPART_REQUESTS_FILE_SIZE_LIMIT;
-
-      delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
+      Config.remove('settings.multipartRequests.fileSizeLimit');
+      Config.remove('settings.disk.local.directory');
 
       const contents = readdirSync('uploaded/images');
       for (const content of contents) {
@@ -266,18 +264,16 @@ describe('ValidateMultipartFormDataBody', () => {
   describe('when the max number of files has been reached', () => {
 
     beforeEach(() => {
-      process.env.SETTINGS_MULTIPART_REQUESTS_FILE_NUMBER_LIMIT = '1';
-
-      process.env.SETTINGS_DISK_LOCAL_DIRECTORY = 'uploaded';
+      Config.set('settings.multipartRequests.fileNumberLimit', 1);
+      Config.set('settings.disk.local.directory', 'uploaded');
 
       mkdirSync('uploaded');
       mkdirSync('uploaded/images');
     });
 
     afterEach(() => {
-      delete process.env.SETTINGS_MULTIPART_REQUESTS_FILE_NUMBER_LIMIT;
-
-      delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
+      Config.remove('settings.multipartRequests.fileNumberLimit');
+      Config.remove('settings.disk.local.directory');
 
       const contents = readdirSync('uploaded/images');
       for (const content of contents) {
@@ -400,14 +396,14 @@ describe('ValidateMultipartFormDataBody', () => {
   describe('when a file is not uploaded but it is required', () => {
 
     beforeEach(() => {
-      process.env.SETTINGS_DISK_LOCAL_DIRECTORY = 'uploaded';
+      Config.set('settings.disk.local.directory', 'uploaded');
 
       mkdirSync('uploaded');
       mkdirSync('uploaded/images');
     });
 
     afterEach(() => {
-      delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
+      Config.remove('settings.disk.local.directory');
 
       const contents = readdirSync('uploaded/images');
       for (const content of contents) {
@@ -584,8 +580,8 @@ describe('ValidateMultipartFormDataBody', () => {
     let disk: Disk;
 
     beforeEach(() => {
-      process.env.SETTINGS_DISK_LOCAL_DIRECTORY = 'uploaded';
-      process.env.SETTINGS_LOG_ERRORS = 'false';
+      Config.set('settings.disk.local.directory', 'uploaded');
+      Config.set('settings.logErrors', false);
 
       mkdirSync('uploaded');
       mkdirSync('uploaded/images');
@@ -594,8 +590,8 @@ describe('ValidateMultipartFormDataBody', () => {
     });
 
     afterEach(() => {
-      delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
-      delete process.env.SETTINGS_LOG_ERRORS;
+      Config.remove('settings.disk.local.directory');
+      Config.remove('settings.logErrors');
 
       const contents = readdirSync('uploaded/images');
       for (const content of contents) {
@@ -606,7 +602,7 @@ describe('ValidateMultipartFormDataBody', () => {
     });
 
     it('should not kill the process if Disk.write throws an error.', async () => {
-      process.env.SETTINGS_DISK_DRIVER = '@foal/internal-test';
+      Config.set('settings.disk.driver', '@foal/internal-test');
 
       const actual: { body: any } = { body: null };
       const app = createAppWithHook({
@@ -623,7 +619,7 @@ describe('ValidateMultipartFormDataBody', () => {
     });
 
     it('should not kill the process if Disk.write rejects an error.', async () => {
-      delete process.env.SETTINGS_DISK_LOCAL_DIRECTORY;
+      Config.remove('settings.disk.local.directory');
 
       const actual: { body: any } = { body: null };
       const app = createAppWithHook({