diff --git a/.gitignore b/.gitignore
index 59dedfa1e92ba13bfdca4fd313daf478c4736b43..8b26d49e3c0a0a970755e1167be3baf931e6b91c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,11 @@
 /.pnp
 .pnp.js
 
+# gitlab-ci-local
+.gitlab-ci-local
+cache
+builds
+
 # testing
 /coverage
 
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 51be4471b7373cec6e311acb50f8a96d0174f120..25c676d5691e1c22752eb55ec000e8d6d458e750 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,8 +1,11 @@
 variables:
   CONTAINER_IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME"
   NODE_IMAGE: "node:16.14.0"
+  CYPRESS_IMAGE: "cypress/browsers:node16.14.0-slim-chrome99-ff97"
+  CYPRESS_CACHE_FOLDER: "cache/Cypress"
 
 stages:
+  - dependencies
   - build
   - lint
   - test
@@ -14,17 +17,26 @@ default:
   tags:
     - docker
 
+dependencies:
+  stage: dependencies
+  image: $NODE_IMAGE
+  script:
+    - npm install
+  artifacts:
+    expire_in: 1 hour
+    paths:
+      - node_modules
+      - ${CYPRESS_CACHE_FOLDER}
+
 build:
   stage: build
   image: $NODE_IMAGE
-  script: 
-    - npm install
+  script:
     - CI=false npm run build
   artifacts:
     expire_in: 1 hour
     paths:
       - build
-      - node_modules/
 
 lint:
   stage: lint
@@ -35,7 +47,13 @@ lint:
     reports:
       codequality: gl-codequality.json
 
-test:
+test-components-chrome:
+  stage: test
+  image: $CYPRESS_IMAGE
+  script:
+    - npx cypress run-ct --browser chrome
+
+test-jest:
   stage: test
   image: $NODE_IMAGE
   script:
diff --git a/cypress.json b/cypress.json
index 99a692f3f822fce3b86e2bc6d319d649b7b7a907..0a5edd497bed80b6e473fffbd49d50b21a1ce17b 100644
--- a/cypress.json
+++ b/cypress.json
@@ -1,4 +1,7 @@
 {
-  "ignoreTestFiles": "*.js",
-  "testFiles": "**/*.{feature,features}"
+  "testFiles": "**/*.{feature,features}",
+  "component": {
+    "componentFolder": "src",
+    "testFiles": "**/*.spec.{js,jsx,ts,tsx}"
+  }
 }
\ No newline at end of file
diff --git a/cypress/fixtures/ccce-api.json b/cypress/fixtures/ccce-api.json
new file mode 100644
index 0000000000000000000000000000000000000000..cd1e192b494bcf68d026932d01f95e026d843764
--- /dev/null
+++ b/cypress/fixtures/ccce-api.json
@@ -0,0 +1,4608 @@
+{
+  "openapi": "3.0.1",
+  "info": {
+    "title": "CCCE API",
+    "description": "CCCE backend",
+    "version": "0.0.1"
+  },
+  "servers": [
+    {
+      "url": "http://localhost:8080",
+      "description": "CCCE Deployment Backend"
+    }
+  ],
+  "tags": [
+    {
+      "name": "Broadcasts"
+    },
+    {
+      "name": "IOCs"
+    },
+    {
+      "name": "Naming"
+    },
+    {
+      "name": "Authentication"
+    },
+    {
+      "name": "AWX"
+    },
+    {
+      "name": "Statistics"
+    },
+    {
+      "name": "Hosts"
+    },
+    {
+      "name": "Deployments"
+    },
+    {
+      "name": "Git"
+    },
+    {
+      "name": "Monitoring"
+    }
+  ],
+  "paths": {
+    "/api/v1/iocs/{iocId}": {
+      "get": {
+        "tags": [
+          "IOCs"
+        ],
+        "summary": "Find IOC details by ID",
+        "operationId": "getIoc",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "path",
+            "description": "Unique ID of IOC",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "Found IOC",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/IocDetails"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Ioc not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      },
+      "put": {
+        "tags": [
+          "IOCs"
+        ],
+        "summary": "Updating an IOC by ID",
+        "operationId": "updateIoc",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "path",
+            "description": "Unique ID of IOC",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/IOCUpdateRequest"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden: User doesn't have the necessary permissions",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "422": {
+            "description": "Unprocessable request",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Ioc not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "IOC updated",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Ioc"
+                }
+              }
+            }
+          },
+          "409": {
+            "description": "IOC already created or concurrent deployment, undeployment, start or stop for IOC is ongoing",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      },
+      "delete": {
+        "tags": [
+          "IOCs"
+        ],
+        "summary": "Deletes a single IOC based on the ID supplied",
+        "operationId": "deleteIoc",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "path",
+            "description": "Id of IOC to delete",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden: User doesn't have the necessary permissions",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "204": {
+            "description": "IOC deleted",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "string"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "IOC not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "409": {
+            "description": "Concurrent deployment, undeployment, start or stop for IOC is ongoing",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/deployments/undeploy-in-db/{iocId}": {
+      "put": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Undeploy in DB",
+        "description": "Marks an IOC in DB as undeployed - will not call AWX",
+        "operationId": "unDeployInDb",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "path",
+            "description": "The id of the IOC to undeploy",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "422": {
+            "description": "IOC is not deployed",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "409": {
+            "description": "Ongoing deployment, or undeployment for IOC",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden: user doesn't have the necessary permissions to undeploy",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Undeployment created",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/Deployment"
+                  }
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/awx/jobs": {
+      "put": {
+        "tags": [
+          "AWX"
+        ],
+        "summary": "Update an AWX job's status",
+        "operationId": "updateJob",
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/AwxJobMeta"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Job not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Job updated",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "apiKey": []
+          }
+        ]
+      }
+    },
+    "/api/v1/awx/commands": {
+      "put": {
+        "tags": [
+          "AWX"
+        ],
+        "summary": "Update an AWX ad-hoc command's status",
+        "operationId": "updateCommand",
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/AwxJobMeta"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Command not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Command updated",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "apiKey": []
+          }
+        ]
+      }
+    },
+    "/api/v1/iocs": {
+      "get": {
+        "tags": [
+          "IOCs"
+        ],
+        "summary": "List IOCs",
+        "operationId": "listIocs",
+        "parameters": [
+          {
+            "name": "owner",
+            "in": "query",
+            "description": "User name",
+            "required": false,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "query",
+            "in": "query",
+            "description": "Search text (Search for Naming name, Owner)",
+            "required": false,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "orderBy",
+            "in": "query",
+            "description": "Order by",
+            "required": false,
+            "schema": {
+              "type": "string",
+              "enum": [
+                "ID",
+                "OWNER",
+                "IOC_NAME",
+                "GIT_REFERENCE"
+              ]
+            }
+          },
+          {
+            "name": "isAsc",
+            "in": "query",
+            "description": "Order Ascending",
+            "required": false,
+            "schema": {
+              "type": "boolean"
+            }
+          },
+          {
+            "name": "page",
+            "in": "query",
+            "description": "Page offset",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32"
+            }
+          },
+          {
+            "name": "limit",
+            "in": "query",
+            "description": "Page size",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "A paged array of IOCs",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/PagedIocResponse"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      },
+      "post": {
+        "tags": [
+          "IOCs"
+        ],
+        "summary": "Create a new IOC",
+        "operationId": "createIoc",
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/CreateIoc"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "424": {
+            "description": "Metadata file not found, or not processable",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "409": {
+            "description": "IOC already created",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "422": {
+            "description": "Unprocessable request",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "400": {
+            "description": "Incomplete request",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "201": {
+            "description": "IOC created",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Ioc"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden: User doesn't have the necessary permissions in Gitlab",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/deployments/{iocId}": {
+      "post": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Update and deploy an existing IOC",
+        "operationId": "updateAndDeployIoc",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "path",
+            "description": "The id of the IOC to deploy",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/UpdateAndDeployIoc"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "201": {
+            "description": "Deployment created",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Deployment"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "424": {
+            "description": "Metadata file not found, or not processable",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "400": {
+            "description": "Incomplete request",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "422": {
+            "description": "CSEntry host not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "IOC not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "409": {
+            "description": "Concurrent deployment, undeployment, start or stop for IOC is ongoing",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden: User doesn't have the necessary permissions in Gitlab",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/deployments/{iocId}/stop": {
+      "post": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Stop an existing IOC",
+        "operationId": "stopIoc",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "path",
+            "description": "The id of the IOC to stop",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "201": {
+            "description": "IOC stop initiated",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/AdHocCommand"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "IOC not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "409": {
+            "description": "Concurrent deployment, undeployment, start or stop for IOC is ongoing",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "422": {
+            "description": "IOC has no active deployment",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden: User doesn't have the necessary permissions in Gitlab",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/deployments/{iocId}/start": {
+      "post": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Start an existing IOC",
+        "operationId": "startIoc",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "path",
+            "description": "The id of the IOC to start",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "201": {
+            "description": "IOC start initiated",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/AdHocCommand"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "IOC not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "409": {
+            "description": "Concurrent deployment, undeployment, start or stop for IOC is ongoing",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "422": {
+            "description": "IOC has no active deployment",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden: User doesn't have the necessary permissions in Gitlab",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/deployments/undeploy/{iocId}": {
+      "post": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Start undeployment",
+        "operationId": "createUndeployment",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "path",
+            "description": "The id of the IOC to undeploy",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/Undeployment"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Forbidden: user doesn't have the necessary permissions in Gitlab",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "422": {
+            "description": "IOC is not deployed",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "409": {
+            "description": "Concurrent deployment, undeployment, start or stop for IOC is ongoing",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "201": {
+            "description": "Undeployment created",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/Deployment"
+                  }
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/authentication/renew": {
+      "post": {
+        "tags": [
+          "Authentication"
+        ],
+        "summary": "Renewing JWT token",
+        "description": "Renewing valid, non-expired JWT token",
+        "operationId": "tokenRenew",
+        "responses": {
+          "503": {
+            "description": "Login server unavailable",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Ok",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/LoginResponse"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/authentication/login": {
+      "post": {
+        "tags": [
+          "Authentication"
+        ],
+        "summary": "Login user and acquire JWT token",
+        "description": "Login user with username, and password in order to acquire JWT token",
+        "operationId": "login",
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/Login"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "503": {
+            "description": "Login server unavailable",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "403": {
+            "description": "Bad username, and/or password",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Ok",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/LoginResponse"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/healthcheck": {
+      "get": {
+        "tags": [
+          "health-check-controller"
+        ],
+        "operationId": "getHealthCheck",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "*/*": {
+                "schema": {
+                  "type": "string"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/statistics/my-iocs": {
+      "get": {
+        "tags": [
+          "Statistics"
+        ],
+        "summary": "Own IOCs' statistics",
+        "operationId": "personalStatistics",
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Personal statistics",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/PersonalStatisticsResponse"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/statistics/general": {
+      "get": {
+        "tags": [
+          "Statistics"
+        ],
+        "summary": "Set of statistics",
+        "operationId": "generalStatistics",
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Statistics about IOCs, deployments, and hosts",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralStatisticsResponse"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/statistics/general/iocStatistics": {
+      "get": {
+        "tags": [
+          "Statistics"
+        ],
+        "summary": "IOC statistics",
+        "operationId": "iocStatistics",
+        "responses": {
+          "200": {
+            "description": "Statistics about IOCs deployed to hosts",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/DeploymentOnHost"
+                  }
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/statistics/general/deploymentStatistics": {
+      "get": {
+        "tags": [
+          "Statistics"
+        ],
+        "summary": "Deployment statistics",
+        "operationId": "deploymentStatistics",
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Statistics about IOCs, deployments, and hosts",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/DeploymentStatisticsResponse"
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/statistics/general/deployedIocHistory": {
+      "get": {
+        "tags": [
+          "Statistics"
+        ],
+        "summary": "Deployed IOC history from DB for statistics",
+        "operationId": "iocDeploymentHistory",
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "History about deployed IOCs from DB for statistics",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/ActiveIOCSForHistoryResponse"
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/statistics/general/activeIocStatistics": {
+      "get": {
+        "tags": [
+          "Statistics"
+        ],
+        "summary": "Currently active IOC statistics",
+        "operationId": "currentlyActiveIocs",
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Statistics about currently active IOCs",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/ActiveIocStatisticsResponse"
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/statistics/general/activeIocHistory": {
+      "get": {
+        "tags": [
+          "Statistics"
+        ],
+        "summary": "Active IOC history from Prometheus for statistics",
+        "operationId": "activeIocHistory",
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "History about active IOCs for statistics",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/ActiveIOCSForHistoryResponse"
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/naming/IOCNamesByName": {
+      "get": {
+        "tags": [
+          "Naming"
+        ],
+        "summary": "Fetches IOC names by name from CCDB",
+        "operationId": "fetchIOCByName",
+        "parameters": [
+          {
+            "name": "iocName",
+            "in": "query",
+            "description": "IOC name",
+            "required": false,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Naming names, and IDs from CCDB",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/NameResponse"
+                  }
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service unreachable",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/monitoring/syslog/host/{hostName}": {
+      "get": {
+        "tags": [
+          "Monitoring"
+        ],
+        "summary": "Fetches syslog lines for a specific host",
+        "operationId": "fetchSyslogLines",
+        "parameters": [
+          {
+            "name": "hostName",
+            "in": "path",
+            "description": "Host name (without network part)",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "timeRange",
+            "in": "query",
+            "description": "Time range (in minutes)",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Logging server unavailable",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Log lines",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/LokiResponse"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/monitoring/status/ioc": {
+      "get": {
+        "tags": [
+          "Monitoring"
+        ],
+        "summary": "Fetches the Prometheus status of the IOC",
+        "operationId": "fetchIocStatus",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "query",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Log lines",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/IocStatusResponse"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/monitoring/procserv/host/{hostName}": {
+      "get": {
+        "tags": [
+          "Monitoring"
+        ],
+        "summary": "Fetches procServ Log lines for a specific host",
+        "operationId": "fetchProcServLogLines",
+        "parameters": [
+          {
+            "name": "hostName",
+            "in": "path",
+            "description": "Host name (without network part)",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "iocName",
+            "in": "query",
+            "description": "Name of the IOC to get procServ logs",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "timeRange",
+            "in": "query",
+            "description": "Time range (in minutes)",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Logging server unavailable",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Log lines",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/LokiResponse"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/iocs/my-iocs-with-alarms": {
+      "get": {
+        "tags": [
+          "IOCs"
+        ],
+        "summary": "List own IOCs with alarms",
+        "operationId": "listOwnIocsWithAlarms",
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Array of own IOC with alarms",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/IocWithAlarm"
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/hosts": {
+      "get": {
+        "tags": [
+          "Hosts"
+        ],
+        "summary": "List CSEntry hosts",
+        "operationId": "listHosts",
+        "parameters": [
+          {
+            "name": "query",
+            "in": "query",
+            "description": "Search text, this query string is passed directly to Elasticsearch. E.g.: To search all hosts where the string \"archiver\" appears in any field, use \"archiver\".To restrict the search to only the name field, use \"name:archiver\".Note that if you pass \"name:arch\", this will not match archiver as elasticsearch uses keywords for string matching. In this case you’d need to use a wildcard: \"name:arch*\".",
+            "required": false,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "page",
+            "in": "query",
+            "description": "Page offset",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32"
+            }
+          },
+          {
+            "name": "limit",
+            "in": "query",
+            "description": "Page size",
+            "required": false,
+            "schema": {
+              "maximum": 100,
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "A paged array of CSEntry hosts",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/PagedCSEntryHostResponse"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote server exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/hosts/{hostCSEntryId}/iocs": {
+      "get": {
+        "tags": [
+          "Hosts"
+        ],
+        "summary": "Find associated IOCs for the host",
+        "operationId": "findAssociatedIocsByHostId",
+        "parameters": [
+          {
+            "name": "hostCSEntryId",
+            "in": "path",
+            "description": "Unique CSEntry ID of the host",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          },
+          {
+            "name": "page",
+            "in": "query",
+            "description": "Page offset",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32"
+            }
+          },
+          {
+            "name": "limit",
+            "in": "query",
+            "description": "Page size",
+            "required": false,
+            "schema": {
+              "maximum": 100,
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Found Host",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/PagedAssociatedIocs"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/hosts/with-status/{hostCSEntryId}": {
+      "get": {
+        "tags": [
+          "Hosts"
+        ],
+        "summary": "Find host by CSEntry ID and get status",
+        "operationId": "findHostById",
+        "parameters": [
+          {
+            "name": "hostCSEntryId",
+            "in": "path",
+            "description": "Unique CSEntry ID of the host",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Found Host",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/CSEntryHostWithStatus"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote server exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/hosts/csentry": {
+      "get": {
+        "tags": [
+          "Hosts"
+        ],
+        "summary": "Find host by CSEntry ID",
+        "operationId": "findCSentryHostById",
+        "parameters": [
+          {
+            "name": "hostCSEntryId",
+            "in": "query",
+            "description": "Unique CSEntry ID of the host",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Found Host",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/TargetHost"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/gitHelper/userInfo": {
+      "get": {
+        "tags": [
+          "Git"
+        ],
+        "summary": "Current-user information",
+        "operationId": "userInfo",
+        "responses": {
+          "200": {
+            "description": "Information about the current user",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/UserInfoResponse"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Git exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/gitHelper/userInfo/{userName}": {
+      "get": {
+        "tags": [
+          "Git"
+        ],
+        "summary": "User information",
+        "operationId": "infoFromUserName",
+        "parameters": [
+          {
+            "name": "userName",
+            "in": "path",
+            "description": "The username to retrieve info from",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "Information about the current user",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/UserInfoResponse"
+                  }
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Git exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/gitHelper/tagsAndCommitIds": {
+      "get": {
+        "tags": [
+          "Git"
+        ],
+        "summary": "List Tags and CommitIds",
+        "operationId": "listTagsAndCommitIds",
+        "parameters": [
+          {
+            "name": "projectId",
+            "in": "query",
+            "description": "Git repo project ID",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          },
+          {
+            "name": "reference",
+            "in": "query",
+            "description": "Git reference",
+            "required": false,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "List of Tags and CommitIds for a specific GitLab repo",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/GitReference"
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Git exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/gitHelper/projects": {
+      "get": {
+        "tags": [
+          "Git"
+        ],
+        "summary": "List IOC projects",
+        "operationId": "listProjects",
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "List of Gitlab projects of allowed groups",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "$ref": "#/components/schemas/GitProject"
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Git exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/deployments": {
+      "get": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "List deployments",
+        "operationId": "listDeployments",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "query",
+            "description": "IOC ID",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          },
+          {
+            "name": "hostCSEntryId",
+            "in": "query",
+            "description": "Host CSEntry ID",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          },
+          {
+            "name": "status",
+            "in": "query",
+            "description": "Status",
+            "required": false,
+            "schema": {
+              "type": "string",
+              "enum": [
+                "QUEUED",
+                "PENDING",
+                "RUNNING",
+                "SUCCESSFUL",
+                "FAILED",
+                "FINISHED"
+              ]
+            }
+          },
+          {
+            "name": "user",
+            "in": "query",
+            "description": "User name",
+            "required": false,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "query",
+            "in": "query",
+            "description": "Search text (Search for IOC name, IOC version, Host name, Description, Created by)",
+            "required": false,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "orderBy",
+            "in": "query",
+            "description": "Order by",
+            "required": false,
+            "schema": {
+              "type": "string",
+              "enum": [
+                "ID",
+                "CREATED_BY",
+                "CREATED_AT",
+                "START_TIME",
+                "FINISHED_AT",
+                "IOC_NAME",
+                "GIT_REFERENCE"
+              ]
+            }
+          },
+          {
+            "name": "isAsc",
+            "in": "query",
+            "description": "Order Ascending",
+            "required": false,
+            "schema": {
+              "type": "boolean"
+            }
+          },
+          {
+            "name": "page",
+            "in": "query",
+            "description": "Page offset",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32"
+            }
+          },
+          {
+            "name": "limit",
+            "in": "query",
+            "description": "Page size",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "A paged array of deployments",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/PagedDeploymentResponse"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/deployments/{deploymentId}": {
+      "get": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Get deployment details",
+        "operationId": "fetchDeployment",
+        "parameters": [
+          {
+            "name": "deploymentId",
+            "in": "path",
+            "description": "Unique ID of deployment",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "A deployment with details",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/DeploymentInfoDetails"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Deployment not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/deployments/jobs/{awxJobId}": {
+      "get": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Get deployment job details",
+        "operationId": "fetchDeploymentJobDetails",
+        "parameters": [
+          {
+            "name": "awxJobId",
+            "in": "path",
+            "description": "Unique ID of AWX job",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Deployment not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "AWX job details",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/AwxJobDetails"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/deployments/commands": {
+      "get": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Get ad-hoc command list for a specific deployment",
+        "operationId": "listCommandsByDeployment",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "query",
+            "description": "Unique ID of IOC",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          },
+          {
+            "name": "deploymentId",
+            "in": "query",
+            "description": "Unique ID of deployment",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          },
+          {
+            "name": "page",
+            "in": "query",
+            "description": "Page offset",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32"
+            }
+          },
+          {
+            "name": "limit",
+            "in": "query",
+            "description": "Page size",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Deployment not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "A command with details",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/PagedCommandResponse"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/deployments/commands/{commandId}": {
+      "get": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Get ad-hoc command",
+        "operationId": "fetchCommand",
+        "parameters": [
+          {
+            "name": "commandId",
+            "in": "path",
+            "description": "Unique ID of command",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Ad-hoc command not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "A command descriptor",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/AdHocCommand"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/deployments/commands/ongoing/{iocId}": {
+      "get": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Get list of ongoing ad-hoc commands for a specific IOC",
+        "operationId": "ongoingCommandByIoc",
+        "parameters": [
+          {
+            "name": "iocId",
+            "in": "path",
+            "description": "Unique ID of the IOC",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "IOC not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Ongoing command (if exists)",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/AdHocCommand"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/deployments/commands/jobs/{awxCommandId}": {
+      "get": {
+        "tags": [
+          "Deployments"
+        ],
+        "summary": "Get ad-hoc command details",
+        "operationId": "fetchCommandDetails",
+        "parameters": [
+          {
+            "name": "awxCommandId",
+            "in": "path",
+            "description": "Unique ID of AWX command",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "AWX command not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Remote service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "A command with details",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/AwxCommandDetails"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/broadcasts/announcements": {
+      "get": {
+        "tags": [
+          "Broadcasts"
+        ],
+        "summary": "Get announcements",
+        "operationId": "fetchAnnouncements",
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Announcements text",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/Announcements"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/v1/authentication/users": {
+      "get": {
+        "tags": [
+          "Authentication"
+        ],
+        "summary": "Get Deployment Tool users",
+        "description": "Get Deployment Tool users from authorization service",
+        "operationId": "getToolUsers",
+        "parameters": [
+          {
+            "name": "query",
+            "in": "query",
+            "description": "User name query",
+            "required": false,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Role not found by authorization service",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Login server unavailable",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Ok",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "type": "string"
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/authentication/roles": {
+      "get": {
+        "tags": [
+          "Authentication"
+        ],
+        "summary": "Get user roles",
+        "description": "Get user roles from authorization service",
+        "operationId": "getUserRoles",
+        "responses": {
+          "401": {
+            "description": "Unauthorized",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Login server unavailable",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Ok",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "array",
+                  "items": {
+                    "type": "string"
+                  }
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    },
+    "/api/v1/authentication/logout": {
+      "delete": {
+        "tags": [
+          "Authentication"
+        ],
+        "summary": "Logout",
+        "description": "Logging out the user",
+        "operationId": "logout",
+        "responses": {
+          "403": {
+            "description": "Logout error",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "503": {
+            "description": "Login server unavailable",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Ok",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          },
+          "500": {
+            "description": "Service exception",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/GeneralException"
+                }
+              }
+            }
+          }
+        },
+        "security": [
+          {
+            "bearerAuth": []
+          }
+        ]
+      }
+    }
+  },
+  "components": {
+    "schemas": {
+      "IOCUpdateRequest": {
+        "type": "object",
+        "properties": {
+          "owner": {
+            "type": "string"
+          },
+          "externalNameId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "gitProjectId": {
+            "type": "integer",
+            "format": "int64"
+          }
+        }
+      },
+      "GeneralException": {
+        "type": "object",
+        "properties": {
+          "error": {
+            "type": "string"
+          },
+          "description": {
+            "type": "string"
+          }
+        }
+      },
+      "Alert": {
+        "type": "object",
+        "properties": {
+          "type": {
+            "type": "string",
+            "enum": [
+              "ERROR",
+              "WARNING"
+            ]
+          },
+          "message": {
+            "type": "string"
+          }
+        }
+      },
+      "Deployment": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "createdBy": {
+            "type": "string"
+          },
+          "startDate": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "status": {
+            "type": "string",
+            "enum": [
+              "QUEUED",
+              "PENDING",
+              "RUNNING",
+              "SUCCESSFUL",
+              "FAILED",
+              "FINISHED"
+            ]
+          },
+          "undeployment": {
+            "type": "boolean"
+          },
+          "namingName": {
+            "type": "string"
+          },
+          "gitProjectId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "sourceVersion": {
+            "type": "string"
+          },
+          "endDate": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "comment": {
+            "type": "string"
+          },
+          "iocName": {
+            "type": "string"
+          },
+          "host": {
+            "$ref": "#/components/schemas/Host"
+          },
+          "awxJobId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "sourceUrl": {
+            "type": "string"
+          },
+          "sourceVersionShort": {
+            "type": "string"
+          }
+        }
+      },
+      "Host": {
+        "type": "object",
+        "properties": {
+          "csEntryId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "fqdn": {
+            "type": "string"
+          },
+          "hostName": {
+            "type": "string"
+          },
+          "network": {
+            "type": "string"
+          }
+        }
+      },
+      "Ioc": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "description": {
+            "type": "string"
+          },
+          "owner": {
+            "type": "string"
+          },
+          "createdBy": {
+            "type": "string"
+          },
+          "namingName": {
+            "type": "string"
+          },
+          "externalNameId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "gitProjectId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "sourceUrl": {
+            "type": "string"
+          },
+          "sourceVersion": {
+            "type": "string"
+          },
+          "sourceVersionShort": {
+            "type": "string"
+          },
+          "activeDeployment": {
+            "$ref": "#/components/schemas/Deployment"
+          },
+          "alerts": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/Alert"
+            }
+          },
+          "active": {
+            "type": "boolean"
+          }
+        }
+      },
+      "AwxJobMeta": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "started": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "finished": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "status": {
+            "type": "string",
+            "enum": [
+              "pending",
+              "waiting",
+              "running",
+              "failed",
+              "canceled",
+              "successful"
+            ]
+          }
+        },
+        "description": "Command to update"
+      },
+      "CreateIoc": {
+        "type": "object",
+        "properties": {
+          "externalNameId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "gitProjectId": {
+            "type": "integer",
+            "format": "int64"
+          }
+        },
+        "description": "IOC to create"
+      },
+      "UpdateAndDeployIoc": {
+        "type": "object",
+        "properties": {
+          "comment": {
+            "type": "string"
+          },
+          "sourceVersion": {
+            "type": "string"
+          },
+          "hostCSEntryId": {
+            "type": "integer",
+            "format": "int64"
+          }
+        },
+        "description": "IOC to update"
+      },
+      "AdHocCommand": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "type": {
+            "type": "string",
+            "enum": [
+              "START",
+              "STOP"
+            ]
+          },
+          "createdBy": {
+            "type": "string"
+          },
+          "startDate": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "endDate": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "status": {
+            "type": "string",
+            "enum": [
+              "PENDING",
+              "RUNNING",
+              "SUCCESSFUL",
+              "FAILED"
+            ]
+          },
+          "iocName": {
+            "type": "string"
+          },
+          "awxCommandId": {
+            "type": "integer",
+            "format": "int64"
+          }
+        }
+      },
+      "Undeployment": {
+        "type": "object",
+        "properties": {
+          "comment": {
+            "type": "string"
+          }
+        },
+        "description": "Undeployment parameters"
+      },
+      "LoginResponse": {
+        "type": "object",
+        "properties": {
+          "token": {
+            "type": "string"
+          }
+        }
+      },
+      "Login": {
+        "type": "object",
+        "properties": {
+          "userName": {
+            "type": "string"
+          },
+          "password": {
+            "type": "string"
+          }
+        }
+      },
+      "PersonalStatisticsResponse": {
+        "type": "object",
+        "properties": {
+          "numberOfActiveIocs": {
+            "type": "integer",
+            "format": "int64"
+          }
+        }
+      },
+      "GeneralStatisticsResponse": {
+        "type": "object",
+        "properties": {
+          "numberOfActiveHosts": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "numberOfCreatedIocs": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "numberOfActiveIocs": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "numberOfDeployments": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "numberOfActiveDeployments": {
+            "type": "integer",
+            "format": "int64"
+          }
+        }
+      },
+      "DeploymentCount": {
+        "type": "object",
+        "properties": {
+          "iocCount": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "countingDate": {
+            "type": "string",
+            "format": "date-time"
+          }
+        }
+      },
+      "DeploymentOnHost": {
+        "type": "object",
+        "properties": {
+          "network": {
+            "type": "string"
+          },
+          "deployments": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/DeploymentCount"
+            }
+          }
+        }
+      },
+      "DeploymentStatisticsResponse": {
+        "type": "object",
+        "properties": {
+          "deploymentDate": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "numberOfDeployments": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "successfulDeployments": {
+            "type": "integer",
+            "format": "int64"
+          }
+        }
+      },
+      "ActiveIOCSForHistoryResponse": {
+        "type": "object",
+        "properties": {
+          "iocCount": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "historyDate": {
+            "type": "string",
+            "format": "date-time"
+          }
+        }
+      },
+      "ActiveIocStatisticsResponse": {
+        "type": "object",
+        "properties": {
+          "network": {
+            "type": "string"
+          },
+          "iocCount": {
+            "type": "integer",
+            "format": "int64"
+          }
+        }
+      },
+      "NameResponse": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "name": {
+            "type": "string"
+          },
+          "description": {
+            "type": "string"
+          }
+        }
+      },
+      "LokiMessage": {
+        "type": "object",
+        "properties": {
+          "logDate": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "logMessage": {
+            "type": "string"
+          }
+        }
+      },
+      "LokiResponse": {
+        "type": "object",
+        "properties": {
+          "lines": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/LokiMessage"
+            }
+          }
+        }
+      },
+      "IocStatusResponse": {
+        "type": "object",
+        "properties": {
+          "iocId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "alertSeverity": {
+            "type": "string",
+            "enum": [
+              "ERROR",
+              "WARNING"
+            ]
+          },
+          "alerts": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/Alert"
+            }
+          },
+          "active": {
+            "type": "boolean"
+          }
+        }
+      },
+      "ActiveDeployment": {
+        "type": "object",
+        "properties": {
+          "host": {
+            "$ref": "#/components/schemas/DeploymentHostInfo"
+          }
+        }
+      },
+      "DeploymentHostInfo": {
+        "type": "object",
+        "properties": {
+          "externalHostId": {
+            "type": "integer",
+            "format": "int64"
+          }
+        }
+      },
+      "IocInfo": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "namingName": {
+            "type": "string"
+          },
+          "owner": {
+            "type": "string"
+          },
+          "gitProjectId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "sourceVersion": {
+            "type": "string"
+          },
+          "activeDeployment": {
+            "$ref": "#/components/schemas/ActiveDeployment"
+          }
+        }
+      },
+      "PagedIocResponse": {
+        "type": "object",
+        "properties": {
+          "totalCount": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "listSize": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "pageNumber": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "limit": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "iocList": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/IocInfo"
+            }
+          }
+        }
+      },
+      "IocDetails": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "description": {
+            "type": "string"
+          },
+          "owner": {
+            "type": "string"
+          },
+          "createdBy": {
+            "type": "string"
+          },
+          "namingName": {
+            "type": "string"
+          },
+          "externalNameId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "gitProjectId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "sourceUrl": {
+            "type": "string"
+          },
+          "sourceVersion": {
+            "type": "string"
+          },
+          "sourceVersionShort": {
+            "type": "string"
+          },
+          "activeDeployment": {
+            "$ref": "#/components/schemas/Deployment"
+          },
+          "alerts": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/Alert"
+            }
+          },
+          "operationInProgress": {
+            "type": "boolean"
+          },
+          "active": {
+            "type": "boolean"
+          }
+        }
+      },
+      "IocWithAlarm": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "description": {
+            "type": "string"
+          },
+          "owner": {
+            "type": "string"
+          },
+          "createdBy": {
+            "type": "string"
+          },
+          "namingName": {
+            "type": "string"
+          },
+          "externalNameId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "gitProjectId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "sourceUrl": {
+            "type": "string"
+          },
+          "sourceVersion": {
+            "type": "string"
+          },
+          "sourceVersionShort": {
+            "type": "string"
+          },
+          "activeDeployment": {
+            "$ref": "#/components/schemas/Deployment"
+          },
+          "alerts": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/Alert"
+            }
+          },
+          "alert": {
+            "type": "string",
+            "enum": [
+              "ERROR",
+              "WARNING"
+            ]
+          },
+          "active": {
+            "type": "boolean"
+          }
+        }
+      },
+      "HostInfo": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "fqdn": {
+            "type": "string"
+          },
+          "name": {
+            "type": "string"
+          },
+          "scope": {
+            "type": "string"
+          },
+          "description": {
+            "type": "string"
+          },
+          "network": {
+            "type": "string"
+          },
+          "deviceType": {
+            "type": "string"
+          }
+        }
+      },
+      "HostInfoWithStatus": {
+        "type": "object",
+        "properties": {
+          "csEntryHost": {
+            "$ref": "#/components/schemas/HostInfo"
+          },
+          "status": {
+            "type": "string",
+            "enum": [
+              "AVAILABLE",
+              "UNREACHABLE"
+            ]
+          },
+          "alert": {
+            "type": "string",
+            "enum": [
+              "ERROR",
+              "WARNING"
+            ]
+          }
+        }
+      },
+      "PagedCSEntryHostResponse": {
+        "type": "object",
+        "properties": {
+          "totalCount": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "listSize": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "pageNumber": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "limit": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "csEntryHosts": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/HostInfoWithStatus"
+            }
+          }
+        }
+      },
+      "PagedAssociatedIocs": {
+        "type": "object",
+        "properties": {
+          "totalCount": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "listSize": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "pageNumber": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "limit": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "deployedIocs": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/IocInfo"
+            }
+          }
+        }
+      },
+      "CSEntryHost": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "fqdn": {
+            "type": "string"
+          },
+          "name": {
+            "type": "string"
+          },
+          "scope": {
+            "type": "string"
+          },
+          "description": {
+            "type": "string"
+          },
+          "user": {
+            "type": "string"
+          },
+          "interfaces": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/CSEntryInterface"
+            }
+          },
+          "is_ioc": {
+            "type": "boolean"
+          },
+          "device_type": {
+            "type": "string"
+          },
+          "created_at": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "ansible_vars": {
+            "type": "object",
+            "additionalProperties": {
+              "type": "object"
+            }
+          },
+          "ansible_groups": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          }
+        }
+      },
+      "CSEntryHostWithStatus": {
+        "type": "object",
+        "properties": {
+          "csEntryHost": {
+            "$ref": "#/components/schemas/CSEntryHost"
+          },
+          "assigned": {
+            "type": "boolean"
+          },
+          "status": {
+            "type": "string",
+            "enum": [
+              "AVAILABLE",
+              "UNREACHABLE"
+            ]
+          },
+          "alerts": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/Alert"
+            }
+          }
+        }
+      },
+      "CSEntryInterface": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "name": {
+            "type": "string"
+          },
+          "network": {
+            "type": "string"
+          },
+          "domain": {
+            "type": "string"
+          },
+          "ip": {
+            "type": "string"
+          },
+          "mac": {
+            "type": "string"
+          },
+          "host": {
+            "type": "string"
+          },
+          "cnames": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          },
+          "is_main": {
+            "type": "boolean"
+          }
+        }
+      },
+      "TargetHost": {
+        "type": "object",
+        "properties": {
+          "externalId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "fqdn": {
+            "type": "string"
+          },
+          "hostName": {
+            "type": "string"
+          },
+          "network": {
+            "type": "string"
+          }
+        }
+      },
+      "UserInfoResponse": {
+        "type": "object",
+        "properties": {
+          "fullName": {
+            "type": "string"
+          },
+          "loginName": {
+            "type": "string"
+          },
+          "avatar": {
+            "type": "string"
+          },
+          "email": {
+            "type": "string"
+          }
+        }
+      },
+      "GitReference": {
+        "type": "object",
+        "properties": {
+          "reference": {
+            "type": "string"
+          },
+          "shortReference": {
+            "type": "string"
+          }
+        }
+      },
+      "GitProject": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "url": {
+            "type": "string"
+          }
+        }
+      },
+      "DeploymentInfo": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "createdBy": {
+            "type": "string"
+          },
+          "startDate": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "status": {
+            "type": "string",
+            "enum": [
+              "QUEUED",
+              "PENDING",
+              "RUNNING",
+              "SUCCESSFUL",
+              "FAILED",
+              "FINISHED"
+            ]
+          },
+          "undeployment": {
+            "type": "boolean"
+          },
+          "namingName": {
+            "type": "string"
+          },
+          "gitProjectId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "sourceVersion": {
+            "type": "string"
+          },
+          "host": {
+            "$ref": "#/components/schemas/DeploymentHostInfo"
+          }
+        }
+      },
+      "PagedDeploymentResponse": {
+        "type": "object",
+        "properties": {
+          "totalCount": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "listSize": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "pageNumber": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "limit": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "deployments": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/DeploymentInfo"
+            }
+          }
+        }
+      },
+      "DeploymentInfoDetails": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "createdBy": {
+            "type": "string"
+          },
+          "startDate": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "status": {
+            "type": "string",
+            "enum": [
+              "QUEUED",
+              "PENDING",
+              "RUNNING",
+              "SUCCESSFUL",
+              "FAILED",
+              "FINISHED"
+            ]
+          },
+          "undeployment": {
+            "type": "boolean"
+          },
+          "namingName": {
+            "type": "string"
+          },
+          "gitProjectId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "sourceVersion": {
+            "type": "string"
+          },
+          "endDate": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "comment": {
+            "type": "string"
+          },
+          "host": {
+            "$ref": "#/components/schemas/HostWithFqdn"
+          },
+          "awxJobId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "iocId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "awxJobUrl": {
+            "type": "string"
+          },
+          "sourceUrl": {
+            "type": "string"
+          },
+          "sourceVersionShort": {
+            "type": "string"
+          }
+        }
+      },
+      "HostWithFqdn": {
+        "type": "object",
+        "properties": {
+          "csEntryId": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "fqdn": {
+            "type": "string"
+          }
+        }
+      },
+      "AwxJobDetails": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "status": {
+            "type": "string",
+            "enum": [
+              "pending",
+              "waiting",
+              "running",
+              "failed",
+              "canceled",
+              "successful"
+            ]
+          },
+          "started": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "finished": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "elapsed": {
+            "type": "number",
+            "format": "double"
+          },
+          "stdout": {
+            "type": "string"
+          }
+        }
+      },
+      "PagedCommandResponse": {
+        "type": "object",
+        "properties": {
+          "totalCount": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "listSize": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "pageNumber": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "limit": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "commands": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/AdHocCommand"
+            }
+          }
+        }
+      },
+      "AwxCommandDetails": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "status": {
+            "type": "string",
+            "enum": [
+              "pending",
+              "waiting",
+              "running",
+              "failed",
+              "canceled",
+              "successful"
+            ]
+          },
+          "started": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "finished": {
+            "type": "string",
+            "format": "date-time"
+          }
+        }
+      },
+      "Announcements": {
+        "type": "object",
+        "properties": {
+          "announcementsText": {
+            "type": "string"
+          }
+        }
+      }
+    },
+    "securitySchemes": {
+      "apiKey": {
+        "type": "apiKey",
+        "name": "CCCE-TOKEN",
+        "in": "header"
+      },
+      "bearerAuth": {
+        "type": "http",
+        "scheme": "bearer",
+        "bearerFormat": "JWT"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
index d9b510d377b7d982320a8e0a426d81b7003ab3b7..3aa1a8534f5a0c65906ac5b43471041262af5e59 100644
--- a/cypress/plugins/index.js
+++ b/cypress/plugins/index.js
@@ -11,7 +11,19 @@
 // This function is called when a project is opened or re-opened (e.g. due to
 // the project's config changing)
 
+// See https://docs.cypress.io/guides/component-testing/framework-configuration#React-Create-React-App
+const injectDevServer = require('@cypress/react/plugins/react-scripts')
 const cucumber = require('cypress-cucumber-preprocessor').default
 module.exports = (on, config) => {
   on('file:preprocessor', cucumber())
+
+  // Configure the dev-server to use the same 
+  // Webpack configuration used by Create React App
+  injectDevServer(on, config)
+  
+  if (config.testingType === 'component') {
+    require('@cypress/react/plugins/react-scripts')(on, config)
+  }
+
+  return config
 }
\ No newline at end of file
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
index 119ab03f7cda1f826e896639924a8612d075d3fc..970728c4ada4ea4641f29458bd0d303f2fa2ec69 100644
--- a/cypress/support/commands.js
+++ b/cypress/support/commands.js
@@ -23,3 +23,4 @@
 //
 // -- This will overwrite an existing command --
 // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+Cypress.Commands.add("login", () => {cy.setCookie("ccce-auth", "DEADBEEF")});
\ No newline at end of file
diff --git a/cypress/support/index.js b/cypress/support/index.js
index d68db96df2697e0835f5c490db0c2cc81673f407..b7f929c0ec8c042ad84be2df868647c2869d30b6 100644
--- a/cypress/support/index.js
+++ b/cypress/support/index.js
@@ -15,6 +15,22 @@
 
 // Import commands.js using ES2015 syntax:
 import './commands'
+import { mockAPI } from './mockAPI'
 
 // Alternatively you can use CommonJS syntax:
 // require('./commands')
+
+// load the configuration variables into the window
+// these are copied from public/config.js
+// but copying is bad
+// maybe we need to rethink how we do config
+window.SERVER_ADDRESS=''
+window.API_BASE_ENDPOINT='/ccce-api'
+window.TOKEN_RENEW_INTERVAL=180000
+window.CCDB_ADDRESS='https://ccdb.esss.lu.se'
+window.ENVIRONMENT_TITLE = ''
+
+// intercept the request and return the API specification fixture
+beforeEach(() => {
+  mockAPI();
+});
diff --git a/cypress/support/mockAPI.js b/cypress/support/mockAPI.js
new file mode 100644
index 0000000000000000000000000000000000000000..26831e044658f0d58933805bacf96ab46a8eb4f5
--- /dev/null
+++ b/cypress/support/mockAPI.js
@@ -0,0 +1,57 @@
+function login(req) {
+  const token = "DEADBEEF";
+  req.reply({
+    headers: {
+      "Set-Cookie": `ccce-auth=${token};`
+    },
+    body: {
+      token,
+    },
+  })
+}
+
+function isLoggedIn(req) {
+  return (req.headers?.cookie ?? "").includes("ccce-auth=");
+}
+
+function auth(routeHandler) {
+  return function(req) {
+    if (isLoggedIn(req)) {
+      routeHandler(req);
+    }
+    else {
+      req.reply({
+        statusCode: 401
+      })
+    }
+  }
+}
+
+function roles(req) {
+  req.reply(["Cowboy", "Gunslinger"]);
+}
+
+function userInfo(req) {
+  req.reply({
+    "fullName": "John Wayne",
+    "loginName": "johnwayne",
+    "avatar": "https://gitlab.esss.lu.se/uploads/-/system/user/avatar/92/avatar.png",
+    "email": null
+  });
+}
+
+function renew(req) {
+  req.reply({token: "FADEDEAD"});
+}
+
+// Mock the CCCE API
+export function mockAPI() {
+  cy.intercept("**/ccce-api", { fixture: "ccce-api.json" }).as("ccceAPI");
+
+  cy.intercept("**/authentication/login", login).as("login");
+  cy.intercept("**/authentication/roles", auth(roles)).as("userRoles");
+  cy.intercept("**/authentication/renew", auth(renew)).as("renew")
+
+  cy.intercept("**/gitHelper/userInfo", auth(userInfo)).as("userInfo");
+
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index a75837f6398615e9d16539ca645b8c03639f186f..6d57dfd890e1257e395f6b6efb59b708014166fe 100644
--- a/package.json
+++ b/package.json
@@ -41,10 +41,12 @@
     "eslint-plugin-react": "7.28.0"
   },
   "scripts": {
-    "preinstall": "npx npm-force-resolutions", 
+    "preinstall": "npx npm-force-resolutions",
+    "postinstall": "npx patch-package",
     "start": "react-scripts start",
     "build": "react-scripts build",
-    "test": "set DEBUG_PRINT_LIMIT=20000&& react-scripts test",
+    "test": "DEBUG_PRINT_LIMIT=20000 react-scripts test",
+    "testComponents": "npx cypress run-ct",
     "coverage": "DEBUG_PRINT_LIMIT=20000 react-scripts test --env=jsdom --watchAll=false --coverage --passWithNoTests",
     "eject": "react-scripts eject",
     "lint": "eslint src --ext .js -o eslint/report.html -f html",
@@ -55,7 +57,8 @@
       "react-app",
       "react-app/jest",
       "eslint:recommended",
-      "plugin:react/recommended"
+      "plugin:react/recommended",
+      "plugin:cypress/recommended"
     ],
     "rules": {
       "react/prop-types": "off",
@@ -76,21 +79,28 @@
     ]
   },
   "devDependencies": {
+    "@cypress/react": "^5.12.4",
+    "@cypress/webpack-dev-server": "^1.8.3",
+    "cypress": "^9.5.2",
     "cypress-cucumber-preprocessor": "^4.1.0",
     "eslint": "^7.27.0",
     "eslint-formatter-gitlab": "^2.2.0",
+    "eslint-plugin-cypress": "^2.12.1",
+    "eslint-plugin-react": "7.28.0",
+    "html-webpack-plugin": "^4.5.2",
     "jest-cucumber": "^3.0.1",
+    "patch-package": "^6.4.7",
+    "react-error-overlay": "6.0.9",
     "react-scripts": "^4.0.3",
     "serve": "^11.3.2",
-    "react-error-overlay": "6.0.9",
-    "eslint-plugin-react": "7.28.0"
+    "webpack-dev-server": "^4.7.4"
   },
   "cypress-cucumber-preprocessor": {
     "nonGlobalStepDefinitions": true
   },
   "jest": {
     "collectCoverageFrom": [
-      "src/**/*.js",
+      "**.test.js",
       "!src/index.js"
     ],
     "coverageReporters": [
@@ -100,6 +110,9 @@
     ],
     "moduleNameMapper": {
       "react-markdown": "<rootDir>/node_modules/react-markdown/react-markdown.min.js"
-    }
+    },
+    "testMatch": [
+      "**.test.js"
+    ]
   }
 }
diff --git a/patches/react-scripts+4.0.3.patch b/patches/react-scripts+4.0.3.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f78081946780803fa9d019daf1c4fda5e4cf65c8
--- /dev/null
+++ b/patches/react-scripts+4.0.3.patch
@@ -0,0 +1,21 @@
+diff --git a/node_modules/react-scripts/config/webpack.config.js b/node_modules/react-scripts/config/webpack.config.js
+index 26c2a65..b26b392 100644
+--- a/node_modules/react-scripts/config/webpack.config.js
++++ b/node_modules/react-scripts/config/webpack.config.js
+@@ -794,5 +794,16 @@ module.exports = function (webpackEnv) {
+     // Turn off performance processing because we utilize
+     // our own hints via the FileSizeReporter
+     performance: false,
++    // PATCH: 
++    // Disable the error overlay for warnings
++    // The error-overlay breaks cypress tests
++    devServer: {
++      client: {
++        overlay: {
++          errors: true,
++          warnings: false,
++        }
++      }
++    },
+   };
+ };
diff --git a/src/CypressComponentTestExample.spec.js b/src/CypressComponentTestExample.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..e9ef42294ab99e67414a28a753575da07e68ce3e
--- /dev/null
+++ b/src/CypressComponentTestExample.spec.js
@@ -0,0 +1,8 @@
+import React from 'react'
+import { mount } from '@cypress/react'
+import { Button } from '@material-ui/core'
+
+it('Button', () => {
+  mount(<Button>Test button</Button>)
+  cy.get('button').contains('Test button')
+})
\ No newline at end of file
diff --git a/src/api/APIProvider.spec.js b/src/api/APIProvider.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..938e452ebed281e7dcbbfdacb2e753a08634015b
--- /dev/null
+++ b/src/api/APIProvider.spec.js
@@ -0,0 +1,54 @@
+import React, { useContext } from 'react'
+import { mount } from '@cypress/react'
+import { apiContext, APIProvider, useAPI } from './SwaggerApi';
+import { SnackbarProvider } from 'notistack';
+
+function AppHarness({ children }) {
+  return (
+    <SnackbarProvider preventDuplicate maxSnack="5">
+      {children}
+    </SnackbarProvider>
+  )
+}
+
+function mountIntoHarness(children) {
+  mount(<AppHarness>{children}</AppHarness>);
+}
+
+function checkAPIDisplayed() {
+  cy.get('#api').contains('CCCE API');
+}
+
+function DisplayAPISpecification({api}) {
+  return <pre id="api">{JSON.stringify(api, null, 2)}</pre>;
+}
+
+context("API", () => {
+
+  describe("useAPI", () => {
+    it('creates the SwaggerClient', () => {
+      const Glue = () => {
+        const [api] = useAPI();
+        return <DisplayAPISpecification api={api} />;
+      }
+      mountIntoHarness(<Glue />)
+      checkAPIDisplayed();
+    })
+  })
+
+  describe("APIProvider", () => {
+    it('makes the API available via context', () => {
+      const Glue = () => {
+        const api = useContext(apiContext);
+        return <DisplayAPISpecification api={api} />
+      }
+      mountIntoHarness(
+        <APIProvider>
+          <Glue />
+        </APIProvider>
+      );
+      checkAPIDisplayed();
+    })
+  })
+
+});
\ No newline at end of file
diff --git a/src/api/UserProvider.spec.js b/src/api/UserProvider.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..e857fed51b0550c7d3a30b7bf2178dfecc7e4644
--- /dev/null
+++ b/src/api/UserProvider.spec.js
@@ -0,0 +1,52 @@
+import React, { useContext } from 'react'
+import { mount } from '@cypress/react'
+import { APIProvider, userContext, UserProvider } from './SwaggerApi';
+import { SnackbarProvider } from 'notistack';
+
+function AppHarness({ children }) {
+  return (
+    <SnackbarProvider preventDuplicate maxSnack="5">
+      <APIProvider>
+        {children}
+      </APIProvider>
+    </SnackbarProvider>
+  )
+}
+
+function mountIntoHarness(children) {
+  mount(<AppHarness>{children}</AppHarness>)
+}
+
+function DisplayUserContextValue() {
+  const contextValue = useContext(userContext);
+
+  return (
+    <pre id="display">
+      {JSON.stringify(contextValue, null, 2)}
+    </pre>
+  )
+}
+
+describe("UserProvider", () => {
+  context("when logged in", () => {
+
+    beforeEach(() => {
+      cy.login();
+    })
+
+    it("provides the user", () => {
+      mountIntoHarness(
+        <UserProvider>
+          <DisplayUserContextValue />
+        </UserProvider>
+      );
+
+      cy.get("#display")
+        .contains("John Wayne")
+        .contains("Gunslinger");
+
+      cy.get("@userInfo.all").should('have.length', 1);
+    })
+
+  })
+})
\ No newline at end of file
diff --git a/src/components/auth/TokenRenew.spec.js b/src/components/auth/TokenRenew.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..d6156e21d1d1ef8abbe246efd5d3036edf24046d
--- /dev/null
+++ b/src/components/auth/TokenRenew.spec.js
@@ -0,0 +1,36 @@
+import { mount } from "@cypress/react";
+import { SnackbarProvider } from "notistack";
+import React from "react";
+import { APIProvider, UserProvider } from "../../api/SwaggerApi";
+import TokenRenew from "./TokenRenew";
+
+function AppHarness({ children }) {
+  return (
+    <SnackbarProvider preventDuplicate maxSnack="5">
+      <APIProvider>
+        <UserProvider>
+          {children}
+        </UserProvider>
+      </APIProvider>
+    </SnackbarProvider>
+  )
+}
+
+function mountIntoHarness(children) {
+  mount(<AppHarness>{children}</AppHarness>)
+}
+
+describe("TokenRenew", () => {
+  context("when logged in", () => {
+    beforeEach(() => {
+      cy.login();
+    })
+
+    it("renews the token periodically", () => {
+      cy.clock();
+      mountIntoHarness(<TokenRenew />);
+      cy.tick(window.TOKEN_RENEW_INTERVAL);
+      cy.wait("@renew", {responseTimeout: 1000})
+    })
+  })
+})
\ No newline at end of file
diff --git a/src/components/common/notification/Notifications.spec.js b/src/components/common/notification/Notifications.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..11c84d8e50767bbd19e60f465b10472dabc5d9f9
--- /dev/null
+++ b/src/components/common/notification/Notifications.spec.js
@@ -0,0 +1,67 @@
+import { mount } from "@cypress/react";
+import { SnackbarProvider } from "notistack";
+import React, { useContext } from "react";
+import { APIProvider, userContext, UserProvider } from "../../../api/SwaggerApi";
+import { useEffectOnMount } from "../../../hooks/MountEffects";
+import { notificationContext, NotificationProvider } from "./Notifications";
+
+function AppHarness({ children }) {
+  return (
+    <SnackbarProvider preventDuplicate maxSnack="5">
+      <APIProvider>
+        <UserProvider>
+          {children}
+        </UserProvider>
+      </APIProvider>
+    </SnackbarProvider>
+  )
+}
+
+function mountIntoHarness(children) {
+  mount(<AppHarness>{children}</AppHarness>)
+}
+
+function DisplayContextValue({context}) {
+  const {login} = useContext(userContext);
+  const contextValue = useContext(context);
+  console.log(contextValue);
+  useEffectOnMount(() => login());
+
+  return (
+    <pre id="display">
+      {JSON.stringify(contextValue, (key, val) => (typeof(val) === "function") ? val.toString() : val, 2)}
+    </pre>
+  )
+}
+
+describe("Notifications", () => {
+  context("when logged in", () => {
+    beforeEach(() => {
+      cy.intercept("**/authentication/login", { token: "DEADBEEF" })
+      cy.intercept("**/authentication/roles", ["Cowboy", "Gunslinger"]).as("userRoles");
+      cy.intercept("**/gitHelper/userInfo", {
+        "fullName": "John Wayne",
+        "loginName": "johnwayne",
+        "avatar": "https://gitlab.esss.lu.se/uploads/-/system/user/avatar/92/avatar.png",
+        "email": null
+      }).as("userInfo");
+    })
+
+    it("Provides the notification context", () => {      
+      mountIntoHarness(
+        <NotificationProvider>
+          <DisplayContextValue context={notificationContext} />
+        </NotificationProvider>
+      )
+      
+      cy.wait("@userInfo");
+      cy.wait("@userRoles")
+
+      cy.get("#display")
+        .contains("notifications")
+        .contains("watchDeployment")
+        .contains("watchCommand")
+        .contains("clearNotifications")
+    })
+  })
+})
\ No newline at end of file