diff --git a/ExpressAPI/prisma/schema.prisma b/ExpressAPI/prisma/schema.prisma
index 8d7143ac874fd4324ce2d1c043f65c2f6e27ba68..b5725fc3c15b590bfb632338f2a681ee60c571ff 100644
--- a/ExpressAPI/prisma/schema.prisma
+++ b/ExpressAPI/prisma/schema.prisma
@@ -4,7 +4,7 @@ generator client {
 
 datasource db {
     provider = "mysql"
-    url      = env("DATABASE_URL")
+    url      = env("mysql://root:9buz7f312479g6234f1gnioubervw79b8z@localhost:59231/dojo")
 }
 
 enum UserRole {
diff --git a/ExpressAPI/src/managers/TagsManager.ts b/ExpressAPI/src/managers/TagsManager.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f404fadc6a264a6c89c71b4e0f883c374985c07a
--- /dev/null
+++ b/ExpressAPI/src/managers/TagsManager.ts
@@ -0,0 +1,39 @@
+import { Prisma }           from '@prisma/client';
+import { Assignment, User } from '../types/DatabaseTypes';
+import db                   from '../helpers/DatabaseHelper';
+
+
+class TagsManager {
+    async isUserAllowedToAccessTag(tag: Tags, user: User): Promise<boolean> {
+        if ( !tag.staff ) {
+            tag.staff = await db.assignment.findUnique({
+                                                                  where: {
+                                                                      name: tag.name
+                                                                  }
+                                                              }).staff() ?? [];
+        }
+        return tag.staff.findIndex(staff => staff.id === user.id) !== -1;
+    }
+
+    async getByName(name: string, include: Prisma.TagInclude | undefined = undefined): Promise<Tag | undefined> {
+        return await db.assignment.findUnique({
+                                                  where     : {
+                                                      name: name
+                                                  }, include: include
+                                              }) as unknown as Tag ?? undefined;
+    }
+
+    getByGitlabLink(gitlabLink: string, include: Prisma.AssignmentInclude | undefined = undefined): Promise<Assignment | undefined> {
+        const name = gitlabLink.replace('.git', '').split('/').pop()!;
+
+        return this.getByName(name, include);
+    }
+
+    get(nameOrUrl: string, include: Prisma.AssignmentInclude | undefined = undefined): Promise<Assignment | undefined> {
+        // We can use the same function for both name and url because the name is the last part of the url and the name extraction from the url doesn't corrupt the name
+        return this.getByGitlabLink(nameOrUrl, include);
+    }
+}
+
+
+export default new TagManager();
diff --git a/ExpressAPI/src/routes/TagsRoutes.ts b/ExpressAPI/src/routes/TagsRoutes.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6c7fd6067c81a33cc7a76fda5c50ce87160c1fcc
--- /dev/null
+++ b/ExpressAPI/src/routes/TagsRoutes.ts
@@ -0,0 +1,70 @@
+import { Express }                    from 'express-serve-static-core';
+import express                        from 'express';
+import * as ExpressValidator          from 'express-validator';
+import { StatusCodes }                from 'http-status-codes';
+import RoutesManager                  from '../express/RoutesManager';
+import ParamsValidatorMiddleware      from '../middlewares/ParamsValidatorMiddleware';
+import SecurityMiddleware             from '../middlewares/SecurityMiddleware';
+import SecurityCheckType              from '../types/SecurityCheckType';
+import GitlabUser                     from '../shared/types/Gitlab/GitlabUser';
+import GitlabManager                  from '../managers/GitlabManager';
+import Config                         from '../config/Config';
+import GitlabMember                   from '../shared/types/Gitlab/GitlabMember';
+import GitlabAccessLevel              from '../shared/types/Gitlab/GitlabAccessLevel';
+import GitlabRepository               from '../shared/types/Gitlab/GitlabRepository';
+import { AxiosError, HttpStatusCode } from 'axios';
+import logger                         from '../shared/logging/WinstonLogger';
+import DojoValidators                 from '../helpers/DojoValidators';
+import { Prisma }                     from '@prisma/client';
+import db                             from '../helpers/DatabaseHelper';
+import { Assignment }                 from '../types/DatabaseTypes';
+import AssignmentManager              from '../managers/AssignmentManager';
+import GitlabVisibility               from '../shared/types/Gitlab/GitlabVisibility';
+import fs                             from 'fs';
+import path                           from 'path';
+import SharedAssignmentHelper         from '../shared/helpers/Dojo/SharedAssignmentHelper';
+import GlobalHelper                   from '../helpers/GlobalHelper';
+import DojoStatusCode                 from '../shared/types/Dojo/DojoStatusCode';
+import TagsManager from 'src/managers/TagsManager';
+
+
+class TagRoutes implements RoutesManager {
+    private readonly tagsValidator: ExpressValidator.Schema = {
+        name: {
+            trim: true,
+            notEmpty: true
+        },
+        type: {
+            custom: {
+                options: (value: string) => Object.values(TagType).includes(value),
+                errorMessage: 'Invalid tag type'
+            }
+        }
+    };
+
+    registerOnBackend(backend: Express) {
+        backend.post('/tags', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.tagsValidator), this.addTag.bind(this));
+        backend.delete('/tags', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.tagsValidator), this.deleteTag.bind(this));
+        backend.get('/tags/proposals', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.tagsValidator), this.getSubmittedTag.bind(this));
+        backend.post('/tags/proposals', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.tagsValidator), this.SubmitTag.bind(this));
+        backend.patch('/tags/proposals/{tagProposalName}', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.tagsValidator), this.validateTag.bind(this));
+    }
+
+    private async addTag(req: express.Request, res: express.Response) {
+        
+    }
+    private async deleteTag(req: express.Request, res: express.Response) {
+        
+    }
+    private async getSubmittedTag(req: express.Request, res: express.Response) {
+        
+    }
+    private async SubmitTag(req: express.Request, res: express.Response) {
+        
+    }
+    private async validateTag(req: express.Request, res: express.Response) {
+        
+    }
+}
+
+export default new TagRoutes();
diff --git a/ExpressAPI/src/types/DatabaseTypes.ts b/ExpressAPI/src/types/DatabaseTypes.ts
index 011d2efc5643f66cefb4da435b26e4579accfc32..716f30bc52acfa037364c9d91ef1dc81e54022d2 100644
--- a/ExpressAPI/src/types/DatabaseTypes.ts
+++ b/ExpressAPI/src/types/DatabaseTypes.ts
@@ -24,6 +24,12 @@ const resultBase = Prisma.validator<Prisma.ResultDefaultArgs>()({
                                                                         exercise: true
                                                                     }
                                                                 });
+// const tagsBase = Prisma.validator<Prisma.TagsDefaultArgs>()({
+//                                                                     include: {
+//                                                                         name: true,
+//                                                                         type: true,
+//                                                                     }
+//                                                                 });
 
 
 export type User = Prisma.UserGetPayload<typeof userBase> & {
@@ -37,4 +43,5 @@ export type Exercise = Prisma.ExerciseGetPayload<typeof exerciseBase> & {
 export type Assignment = Prisma.AssignmentGetPayload<typeof assignmentBase> & {
     corrections: LazyVal<Array<Exercise>>
 }
-export type Result = Prisma.ResultGetPayload<typeof resultBase>
\ No newline at end of file
+export type Result = Prisma.ResultGetPayload<typeof resultBase>
+// export type Tags = Prisma.ResultGetPayload<typeof tagsBase>
\ No newline at end of file
diff --git a/ExpressAPI/src/types/SecurityCheckType.ts b/ExpressAPI/src/types/SecurityCheckType.ts
index 3a0b733103af4604e10f917ec3edc4c7f56b3b66..17d026a253327907355176e847a6ac4a7047922f 100644
--- a/ExpressAPI/src/types/SecurityCheckType.ts
+++ b/ExpressAPI/src/types/SecurityCheckType.ts
@@ -1,5 +1,6 @@
 enum SecurityCheckType {
     TEACHING_STAFF          = 'teachingStaff',
+    ADMIN                   = 'admin',
     ASSIGNMENT_STAFF        = 'assignmentStaff',
     ASSIGNMENT_IS_PUBLISHED = 'assignmentIsPublished',
     EXERCISE_SECRET         = 'exerciseSecret',