diff --git a/esd/configuration/GpgConfig.py b/esd/configuration/GpgConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..a8f0c2d3bc0f39db8c5b251d9ffc6f6fa3a577ec
--- /dev/null
+++ b/esd/configuration/GpgConfig.py
@@ -0,0 +1,7 @@
+class GpgConfig:
+    """
+    Configuration for gpg key used by spack
+    """
+    def __init__(self, gpg_name='example', gpg_mail='example@example.com'):
+        self.name = gpg_name
+        self.mail = gpg_mail
diff --git a/esd/configuration/SpackConfig.py b/esd/configuration/SpackConfig.py
index 93a2e87423b871b0b9b4f583efec79e328739edf..b6178760ae724b8ecc5fd8c7ad576343c0624922 100644
--- a/esd/configuration/SpackConfig.py
+++ b/esd/configuration/SpackConfig.py
@@ -1,22 +1,31 @@
 import os
 from pathlib import Path
+
+from esd.configuration.GpgConfig import GpgConfig
 from esd.model import SpackDescriptor
 
 
 class SpackConfig:
     def __init__(self, env: SpackDescriptor = None, repos: list[SpackDescriptor] = None,
                  install_dir=Path(os.getcwd()).resolve(), upstream_instance=None, system_name=None,
-                 concretization_dir: Path = None, buildcache_dir: Path = None):
+                 concretization_dir: Path = None, buildcache_dir: Path = None, gpg: GpgConfig = None):
         self.env = env
         if repos is None:
             self.repos = []
         else:
             self.repos = repos
         self.install_dir = install_dir
+        if self.install_dir:
+            os.makedirs(self.install_dir, exist_ok=True)
         self.upstream_instance = upstream_instance
         self.system_name = system_name
         self.concretization_dir = concretization_dir
+        if self.concretization_dir:
+            os.makedirs(self.concretization_dir, exist_ok=True)
         self.buildcache_dir = buildcache_dir
+        if self.buildcache_dir:
+            os.makedirs(self.buildcache_dir, exist_ok=True)
+        self.gpg = gpg
 
     def add_repo(self, repo: SpackDescriptor):
         if self.repos is None:
diff --git a/esd/error_handling/exceptions.py b/esd/error_handling/exceptions.py
index 9d11b5fa46e1d87c80e258753dcfa425ea367d34..0256f886ab0cf4b958ac12d59d6fcea2d5f568ec 100644
--- a/esd/error_handling/exceptions.py
+++ b/esd/error_handling/exceptions.py
@@ -29,3 +29,13 @@ class SpackInstallPackagesException(BashCommandException):
     """
     To be thrown when the spack fails to install spack packages
     """
+
+class SpackMirrorException(BashCommandException):
+    """
+    To be thrown when the spack add mirror command fails
+    """
+
+class SpackGpgException(BashCommandException):
+    """
+    To be thrown when the spack fails to create gpg keys
+    """
diff --git a/esd/spack_factory/SpackOperation.py b/esd/spack_factory/SpackOperation.py
index 29f44f4904ac8b112bd3ca5eb27748e8b525e32c..a0b21a1c8934ac604388be139b5e9b9ec2f0b5b4 100644
--- a/esd/spack_factory/SpackOperation.py
+++ b/esd/spack_factory/SpackOperation.py
@@ -1,10 +1,9 @@
 import os
 import re
 import subprocess
-from abc import ABC, abstractmethod
 from pathlib import Path
 from esd.error_handling.exceptions import BashCommandException, NoSpackEnvironmentException, \
-    SpackInstallPackagesException, SpackConcertizeException
+    SpackInstallPackagesException, SpackConcertizeException, SpackMirrorException, SpackGpgException
 from esd.logger.logger_builder import get_logger
 from esd.configuration.SpackConfig import SpackConfig
 from esd.tests.testing_variables import SPACK_VERSION
@@ -12,7 +11,7 @@ from esd.wrapper.spack_wrapper import check_spack_env
 from esd.utils.utils import run_command, git_clone_repo, log_command, set_bashrc_variable
 
 
-class SpackOperation(ABC):
+class SpackOperation:
     """
     This class should implement the methods necessary for installing spack, set up an environment, concretize and install packages.
     Factory design pattern is used because there are 2 cases: creating an environment from scratch or creating an environment from the buildcache.
@@ -38,10 +37,6 @@ class SpackOperation(ABC):
             self.env_path = spack_config.env.path / spack_config.env.env_name
             self.spack_command_on_env = f'source {self.spack_setup_script} && spack env activate -p {self.env_path}'
 
-    @abstractmethod
-    def concretize_spack_env(self, force=True):
-        pass
-
     def create_fetch_spack_environment(self):
         if self.spack_config.env.git_path:
             git_clone_repo(self.spack_config.env.env_name, self.spack_config.env.path / self.spack_config.env.env_name,
@@ -65,8 +60,10 @@ class SpackOperation(ABC):
             set_bashrc_variable('SYSTEMNAME', self.spack_config.system_name, bashrc_path, logger=self.logger)
             os.environ['SYSTEMNAME'] = self.spack_config.system_name
         if self.spack_dir.exists() and self.spack_dir.is_dir():
-            set_bashrc_variable('SPACK_USER_CACHE_PATH', str(self.spack_dir / ".spack"), bashrc_path, logger=self.logger)
-            set_bashrc_variable('SPACK_USER_CONFIG_PATH', str(self.spack_dir / ".spack"), bashrc_path, logger=self.logger)
+            set_bashrc_variable('SPACK_USER_CACHE_PATH', str(self.spack_dir / ".spack"), bashrc_path,
+                                logger=self.logger)
+            set_bashrc_variable('SPACK_USER_CONFIG_PATH', str(self.spack_dir / ".spack"), bashrc_path,
+                                logger=self.logger)
             self.logger.debug('Added env variables SPACK_USER_CACHE_PATH and SPACK_USER_CONFIG_PATH')
         else:
             self.logger.error(f'Invalid installation path: {self.spack_dir}')
@@ -160,13 +157,55 @@ class SpackOperation(ABC):
     def concretize_spack_env(self, force=True):
         force = '--force' if force else ''
         run_command("bash", "-c",
-                    f'source {self.spack_setup_script} && spack env activate -p {self.env_path} && spack concretize {force}',
+                    f'{self.spack_command_on_env} && spack concretize {force}',
                     check=True,
-                    capture_output=True, text=True, logger=self.logger,
+                     logger=self.logger,
                     info_msg=f'Concertization step for {self.spack_config.env.env_name}',
                     exception_msg=f'Failed the concertization step for {self.spack_config.env.env_name}',
                     exception=SpackConcertizeException)
 
+    def create_gpg_keys(self):
+        if self.spack_config.gpg:
+            run_command("bash", "-c",
+                        f'source {self.spack_setup_script} && spack gpg init && spack gpg create {self.spack_config.gpg.name} {self.spack_config.gpg.mail}',
+                        check=True,
+                        logger=self.logger,
+                        info_msg=f'Created pgp keys for {self.spack_config.env.env_name}',
+                        exception_msg=f'Failed to create pgp keys mirror {self.spack_config.env.env_name}',
+                        exception=SpackGpgException)
+        else:
+            raise SpackGpgException('No GPG configuration was defined is spack configuration')
+
+    def add_mirror(self, mirror_name: str, mirror_path: Path, signed=False, autopush=False, global_mirror=False):
+        autopush = '--autopush' if autopush else ''
+        signed = '--signed' if signed else ''
+        if global_mirror:
+            run_command("bash", "-c",
+                        f'source {self.spack_setup_script} && spack mirror add {autopush} {signed} {mirror_name} {mirror_path}',
+                        check=True,
+                        logger=self.logger,
+                        info_msg=f'Added mirror {mirror_name}',
+                        exception_msg=f'Failed to add mirror {mirror_name}',
+                        exception=SpackMirrorException)
+        else:
+            check_spack_env(
+                run_command("bash", "-c",
+                            f'{self.spack_command_on_env} && spack mirror add {autopush} {signed} {mirror_name} {mirror_path}',
+                            check=True,
+                            logger=self.logger,
+                            info_msg=f'Added mirror {mirror_name}',
+                            exception_msg=f'Failed to add mirror {mirror_name}',
+                            exception=SpackMirrorException))
+
+    def remove_mirror(self, mirror_name: str):
+        run_command("bash", "-c",
+                    f'source {self.spack_setup_script} && spack mirror rm {mirror_name}',
+                    check=True,
+                    logger=self.logger,
+                    info_msg=f'Removing mirror {mirror_name}',
+                    exception_msg=f'Failed to remove mirror {mirror_name}',
+                    exception=SpackMirrorException)
+
     @check_spack_env
     def install_packages(self, jobs: int, signed=True, fresh=False, debug=False):
         signed = '' if signed else '--no-check-signature'
diff --git a/esd/spack_factory/SpackOperationUseCache.py b/esd/spack_factory/SpackOperationUseCache.py
index 15a3822fc982788b3df997b6dfb15e1efa5100b1..313522d235515955124ba44536976d995e17ff77 100644
--- a/esd/spack_factory/SpackOperationUseCache.py
+++ b/esd/spack_factory/SpackOperationUseCache.py
@@ -1,3 +1,5 @@
+import os
+from esd.build_cache.BuildCacheManager import BuildCacheManager
 from esd.logger.logger_builder import get_logger
 from esd.spack_factory.SpackOperation import SpackOperation
 from esd.configuration.SpackConfig import SpackConfig
@@ -8,8 +10,19 @@ class SpackOperationUseCache(SpackOperation):
     This class uses caching for the concretization step and for the installation step.
     """
 
-    def __init__(self, spack_config: SpackConfig = SpackConfig()):
+    def __init__(self, spack_config: SpackConfig = SpackConfig(), cache_version_concretize='cache',
+                 cache_version_build='cache'):
         super().__init__(spack_config, logger=get_logger(__name__))
+        self.cache_dependency = BuildCacheManager(os.environ.get('CONCRETIZE_OCI_HOST'),
+                                                  os.environ.get('CONCRETIZE_OCI_PROJECT'),
+                                                  os.environ.get('CONCRETIZE_OCI_USERNAME'),
+                                                  os.environ.get('CONCRETIZE_OCI_PASSWORD'),
+                                                  cache_version=cache_version_concretize)
+        self.build_cache = BuildCacheManager(os.environ.get('BUILDCACHE_OCI_HOST'),
+                                             os.environ.get('BUILDCACHE_OCI_PROJECT'),
+                                             os.environ.get('BUILDCACHE_OCI_USERNAME'),
+                                             os.environ.get('BUILDCACHE_OCI_PASSWORD'),
+                                             cache_version=cache_version_build)
 
     def setup_spack_env(self):
         super().setup_spack_env()