diff --git a/config/ClientsSharedConfig.ts b/config/ClientsSharedConfig.ts
index 77f1053b62aa98d6703a8d441e583657c24f7f5b..6e65968d2069b8381c8fb9d0ae22163317627707 100644
--- a/config/ClientsSharedConfig.ts
+++ b/config/ClientsSharedConfig.ts
@@ -1,48 +1,128 @@
+import axios               from 'axios';
+import DojoBackendResponse from '../../shared/types/Dojo/DojoBackendResponse';
+import ApiRoute            from '../types/Dojo/ApiRoute';
+
+
+interface ClientsConfig {
+    gitlabUrl: string,
+    gitlabAccountId: number,
+    gitlabAccountUsername: string,
+    loginGitlabClientId: string
+}
+
+
 class ClientsSharedConfig {
-    public apiURL: string;
+    private static config: ClientsSharedConfig | undefined = undefined;
 
-    public assignment: {
-        filename: string, neededFiles: Array<string>
+    public apiURL!: string;
+
+
+    public gitlab!: {
+        URL: string, dojoAccount: { id: number; username: string; };
     };
 
-    public gitlab: {
-        dojoAccount: { id: number; username: string; };
+    public login!: {
+        gitlab: {
+            client: {
+                id: string
+            }, url: {
+                redirect: string, token: string
+            }
+        }
     };
 
-    public readonly dockerCompose: {
+
+    public assignment!: {
+        filename: string, neededFiles: Array<string>
+    };
+
+    public dockerCompose!: {
         projectName: string
     };
 
-    public readonly exerciseResultsFolderMaxSizeInBytes: number;
+    public exerciseResultsFolderMaxSizeInBytes!: number;
 
-    public readonly filenames: {
+    public filenames!: {
         results: string;
     };
 
 
-    constructor() {
-        this.apiURL = process.env.API_URL ?? '';
+    public constructor() {
+        this.login = {
+            gitlab: {
+                client: {
+                    id: ''
+                },
+                url   : {
+                    redirect: '',
+                    token   : ''
+                }
+            }
+        };
+    }
 
-        this.assignment = {
-            filename   : process.env.ASSIGNMENT_FILENAME ?? '',
-            neededFiles: JSON.parse(process.env.EXERCISE_NEEDED_FILES ?? '[]')
+    public envVarGetter(): (envName: string, defaultValue: string) => string {
+        return (envName: string, defaultValue: string) => {
+            let value = process.env[envName] ?? defaultValue;
+
+            if ( value.includes('{{GITLAB_URL}}') ) {
+                value = value.replace('{{GITLAB_URL}}', this.gitlab.URL);
+            }
+
+            if ( value.includes('{{GITLAB_ACCOUNT_ID}}') ) {
+                value = value.replace('{{GITLAB_ACCOUNT_ID}}', String(this.gitlab.dojoAccount.id));
+            }
+
+            if ( value.includes('{{GITLAB_ACCOUNT_USERNAME}}') ) {
+                value = value.replace('{{GITLAB_ACCOUNT_USERNAME}}', this.gitlab.dojoAccount.username);
+            }
+
+            if ( value.includes('{{LOGIN_GITLAB_CLIENT_ID}}') ) {
+                value = value.replace('{{LOGIN_GITLAB_CLIENT_ID}}', this.login.gitlab.client.id);
+            }
+
+            return value;
         };
+    }
+
+    private async fetchConfigFromApi() {
+        const downloadedConfig: ClientsConfig = (await axios.get<DojoBackendResponse<ClientsConfig>>(`${ this.apiURL }${ ApiRoute.CLIENTS_CONFIG }`)).data.data;
 
         this.gitlab = {
+            URL        : downloadedConfig.gitlabUrl,
             dojoAccount: {
-                id      : Number(process.env.GITLAB_DOJO_ACCOUNT_ID ?? -1),
-                username: process.env.GITLAB_DOJO_ACCOUNT_USERNAME ?? ''
+                id      : downloadedConfig.gitlabAccountId,
+                username: downloadedConfig.gitlabAccountUsername
             }
         };
 
+        this.login.gitlab.client.id = downloadedConfig.loginGitlabClientId;
+    }
+
+    async init(apiUrl: string) {
+        this.apiURL = apiUrl;
+
+        await this.fetchConfigFromApi();
+        const getEnvVar = this.envVarGetter();
+
+        this.login.gitlab.url = {
+            redirect: getEnvVar('LOGIN_GITLAB_URL_REDIRECT', ''),
+            token   : getEnvVar('LOGIN_GITLAB_URL_TOKEN', '')
+        };
+
+        this.assignment = {
+            filename   : getEnvVar('ASSIGNMENT_FILENAME', ''),
+            neededFiles: JSON.parse(getEnvVar('EXERCISE_NEEDED_FILES', '[]'))
+        };
+
         this.dockerCompose = {
-            projectName: process.env.DOCKER_COMPOSE_PROJECT_NAME ?? ''
+            projectName: getEnvVar('DOCKER_COMPOSE_PROJECT_NAME', '')
         };
 
-        this.exerciseResultsFolderMaxSizeInBytes = Number(process.env.EXERCISE_RESULTS_FOLDER_MAX_SIZE_IN_BYTES ?? 0);
+        this.exerciseResultsFolderMaxSizeInBytes = Number(getEnvVar('EXERCISE_RESULTS_FOLDER_MAX_SIZE_IN_BYTES', '0'));
 
         this.filenames = {
-            results: process.env.EXERCISE_RESULTS_FILENAME ?? ''
+            results: getEnvVar('EXERCISE_RESULTS_FILENAME', '')
         };
     }
 }
diff --git a/helpers/Dojo/AssignmentValidator.ts b/helpers/Dojo/AssignmentValidator.ts
index 0ac4f467433283a5188cdd16ee722e3f91bfad11..1a92994be6fd82280a5ac89a77910fdec486e65f 100644
--- a/helpers/Dojo/AssignmentValidator.ts
+++ b/helpers/Dojo/AssignmentValidator.ts
@@ -4,13 +4,13 @@ import SharedAssignmentHelper    from '../../../shared/helpers/Dojo/SharedAssign
 import path                      from 'node:path';
 import AssignmentCheckerError    from '../../../shared/types/Dojo/AssignmentCheckerError.js';
 import fs                        from 'fs-extra';
-import ClientsSharedConfig       from '../../config/ClientsSharedConfig.js';
 import YAML                      from 'yaml';
 import DojoDockerCompose         from '../../types/Dojo/DojoDockerCompose.js';
 import { exec, spawn }           from 'child_process';
 import AssignmentFile            from '../../../shared/types/Dojo/AssignmentFile.js';
 import ExerciseDockerCompose     from './ExerciseDockerCompose.js';
 import util                      from 'util';
+import ClientsSharedConfig       from '../../config/ClientsSharedConfig';
 
 
 const execAsync = util.promisify(exec);
diff --git a/helpers/Dojo/DojoBackendHelper.ts b/helpers/Dojo/DojoBackendHelper.ts
index 025c3876bc73bd9a6887279171a27668963f990f..bde35222d821e5d1da4024f17c0de00d79cf8837 100644
--- a/helpers/Dojo/DojoBackendHelper.ts
+++ b/helpers/Dojo/DojoBackendHelper.ts
@@ -1,5 +1,5 @@
 import ApiRoute            from '../../types/Dojo/ApiRoute.js';
-import ClientsSharedConfig from '../../config/ClientsSharedConfig.js';
+import ClientsSharedConfig from '../../config/ClientsSharedConfig';
 
 
 class DojoBackendHelper {
diff --git a/helpers/Dojo/ExerciseResultsSanitizerAndValidator.ts b/helpers/Dojo/ExerciseResultsSanitizerAndValidator.ts
index b44014dd582092c4fea7b6954a4a256eea21deb6..8350db8cf45c40008a0acdf827d80dca1080e86e 100644
--- a/helpers/Dojo/ExerciseResultsSanitizerAndValidator.ts
+++ b/helpers/Dojo/ExerciseResultsSanitizerAndValidator.ts
@@ -2,12 +2,12 @@ import { TypedEmitter }      from 'tiny-typed-emitter';
 import ExerciseRunningEvents from '../../types/Dojo/ExerciseRunningEvents.js';
 import ExerciseCheckerError  from '../../../shared/types/Dojo/ExerciseCheckerError.js';
 import path                  from 'node:path';
-import ClientsSharedConfig   from '../../config/ClientsSharedConfig.js';
 import Toolbox               from '../../../shared/helpers/Toolbox.js';
 import * as fs               from 'fs-extra';
 import ExerciseResultsFile   from '../../../shared/types/Dojo/ExerciseResultsFile.js';
 import JSON5                 from 'json5';
 import Json5FileValidator    from '../../../shared/helpers/Json5FileValidator.js';
+import ClientsSharedConfig   from '../../config/ClientsSharedConfig';
 
 
 class ExerciseResultsSanitizerAndValidator {
diff --git a/types/Dojo/ApiRoute.ts b/types/Dojo/ApiRoute.ts
index 33ccfbbdb9aafd4cc603fb08e64d1e02f4a77287..709f1c17fc7f824bba508df568ded0fbb1ba657c 100644
--- a/types/Dojo/ApiRoute.ts
+++ b/types/Dojo/ApiRoute.ts
@@ -1,4 +1,5 @@
 enum ApiRoute {
+    CLIENTS_CONFIG                      = '/clients_config',
     LOGIN                               = '/login',
     REFRESH_TOKENS                      = '/refresh_tokens',
     TEST_SESSION                        = '/test_session',