diff --git a/mc_openapi/__main__.py b/mc_openapi/__main__.py
index 4d3ee38f3bff491c7e22204dba811f486db3e3b6..439bf1998070276470a45651a3486f3d113bdfd4 100644
--- a/mc_openapi/__main__.py
+++ b/mc_openapi/__main__.py
@@ -10,7 +10,7 @@ from doml_synthesis.types import State
 
 from mc_openapi.app_config import app
 from mc_openapi.doml_mc import DOMLVersion
-from mc_openapi.doml_mc.csp_compatibility.cspcomp import check_csp_compatibility
+from mc_openapi.doml_mc.csp_compatibility._iec_check import check_csp_compatibility
 from mc_openapi.doml_mc.domlr_parser.exceptions import RequirementException
 from mc_openapi.doml_mc.domlr_parser.parser import (DOMLRTransformer, Parser,
                                                     SynthesisDOMLRTransformer)
@@ -76,10 +76,9 @@ else:
 
     # Check CSP Compatibility
     if args.csp:
-        # from mc_openapi.doml_mc.csp_compatibility import CSPCompatibilityValidator
-        # cspc = CSPCompatibilityValidator
-        # cspc.check(dmc.intermediate_model, doml_ver)
-        check_csp_compatibility(dmc.intermediate_model, doml_ver)
+        from mc_openapi.doml_mc.csp_compatibility import CSPCompatibilityValidator as csp_comp
+        csp_comp.check(dmc.intermediate_model, doml_ver)
+        # check_csp_compatibility(dmc.intermediate_model, doml_ver)
         exit(0)
 
     # Store of Requirements and unique string constants
diff --git a/mc_openapi/assets/csp/architectures.yml b/mc_openapi/assets/csp/arch.yml
similarity index 100%
rename from mc_openapi/assets/csp/architectures.yml
rename to mc_openapi/assets/csp/arch.yml
diff --git a/mc_openapi/assets/csp/keypair.yml b/mc_openapi/assets/csp/keypair.yml
new file mode 100644
index 0000000000000000000000000000000000000000..151293ed41ddff6e51f5cee3fa8c9d2b698d868c
--- /dev/null
+++ b/mc_openapi/assets/csp/keypair.yml
@@ -0,0 +1,16 @@
+# CSP Name
+aws:
+  - RSA
+  - ED25519
+  - ECDSA
+
+
+azure:
+  - RSA
+
+gcp: 
+  - Elliptic Curve
+  - RSA
+
+bad_csp:
+  - OLD_ALGO
diff --git a/mc_openapi/assets/csp/keypairs.yml b/mc_openapi/assets/csp/keypairs.yml
deleted file mode 100644
index c73365c06b8b1d4ba6302b83c05cd3e05eb71bad..0000000000000000000000000000000000000000
--- a/mc_openapi/assets/csp/keypairs.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-# CSP Name
-aws:
-  - algorithm: "RSA"
-    bits: "2048"
-  - algorithm: "ED25519"
-
-azure:
-  - algorithm: "RSA"
-    bits: "2048-*"
-
-bad_csp:
-  - algorithm: "OLD_ALGO"
-    bits: "*-1024"
\ No newline at end of file
diff --git a/mc_openapi/assets/csp/minimum_setup.yml b/mc_openapi/assets/csp/minimum_setup.yml
new file mode 100644
index 0000000000000000000000000000000000000000..64e591c690ab151807cb54f5301241363159b632
--- /dev/null
+++ b/mc_openapi/assets/csp/minimum_setup.yml
@@ -0,0 +1,15 @@
+aws:
+  - infrastructure_ComputingNode::os # AMI
+  # - an Instance Type
+  - [infrastructure_ComputingNode::ifaces, infrastructure_NetworkInterface::associated] # NetworkInterface
+  - infrastructure_ComputingNode::credentials # KeyPair
+
+azure:
+  - infrastructure_ComputingNode::os # OS Image
+  - [infrastructure_ComputingNode::ifaces, infrastructure_NetworkInterface::belongsTo] # NetworkInterface
+  - infrastructure_ComputingNode::storage # Storage/VMSize
+
+gcp:
+  - infrastructure_ComputingNode::location
+  - infrastructure_ComputingNode::os # OS Image
+  - infrastructure_ComputingNode::architecture
\ No newline at end of file
diff --git a/mc_openapi/assets/csp/os.yml b/mc_openapi/assets/csp/os.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9a5060edfbe201a900bab603f44ba74a1f5a52bf
--- /dev/null
+++ b/mc_openapi/assets/csp/os.yml
@@ -0,0 +1,41 @@
+aws:
+  Linux:
+    - Amazon Linux
+    - Amazon Linux 2
+    - Bottlerocket
+    - CentOS
+    - Debian Server
+    - Oracle Linux
+    - Red Hat Enterprise Linux (RHEL)
+    - Rocky Linux
+    - SUSE Linux Enterprise Server (SLES)
+    - Ubuntu Server
+  macOS:
+    - macOS
+  Windows Server:
+    - Windows Server
+    
+azure:
+  Linux:
+    - Red Hat Enterprise Linux
+    - CentOS
+    - CoreOS
+    - Debian
+    - Oracle Linux
+    - SUSE Linux Enterprise
+    - openSUSE
+    - Ubuntu
+  Windows Server:
+    - Windows Server
+
+gcp:
+  Linux:
+    - Amazon Linux
+    - Amazon Linux 2
+    - CentOS
+    - Debian
+    - Red Hat Enterprise Linux (RHEL)
+    - SUSE Linux Enterprise
+    - Ubuntu
+  Windows Server:
+    - Windows Server
\ No newline at end of file
diff --git a/mc_openapi/assets/csp/regions.yml b/mc_openapi/assets/csp/region.yml
similarity index 100%
rename from mc_openapi/assets/csp/regions.yml
rename to mc_openapi/assets/csp/region.yml
diff --git a/mc_openapi/doml_mc/csp_compatibility/__init__.py b/mc_openapi/doml_mc/csp_compatibility/__init__.py
index 6040fe698e0a93bc9bbc38dee9ab62483a81b86c..27620127f693445ba8ab6f9846b1f25d7a511d14 100644
--- a/mc_openapi/doml_mc/csp_compatibility/__init__.py
+++ b/mc_openapi/doml_mc/csp_compatibility/__init__.py
@@ -1,22 +1,22 @@
-from .validator import CSPCompatibilityValidator
+from .allowlist_check_v1 import CSPCompatibilityValidator
 import importlib.resources as ilres
 from ... import assets
 import yaml
 
 FILE = lambda filename: ilres.files(assets).joinpath(f"csp/{filename}")
 
-with open(FILE('keypairs.yml')) as kp:
-    KEYPAIRS = yaml.safe_load(kp)
+SOURCES = [
+    'keypair',
+    'arch',
+    'os',
+    'minimum_setup'
+]
 
-with open(FILE('architectures.yml')) as kp:
-    ARCHS = yaml.safe_load(kp)
+DATA = {}
 
-with open(FILE('regions.yml')) as kp:
-    REGIONS = yaml.safe_load(kp)
+for src in SOURCES:
+    with open(FILE(f'{src}.yml')) as data:
+        DATA[src] = yaml.safe_load(data)
 
-CSPCompatibilityValidator = CSPCompatibilityValidator(
-    keypairs=KEYPAIRS,
-    architectures=ARCHS,
-    regions=REGIONS
-)
+CSPCompatibilityValidator = CSPCompatibilityValidator(DATA)
 
diff --git a/mc_openapi/doml_mc/csp_compatibility/cspcomp.py b/mc_openapi/doml_mc/csp_compatibility/_iec_check.py
similarity index 97%
rename from mc_openapi/doml_mc/csp_compatibility/cspcomp.py
rename to mc_openapi/doml_mc/csp_compatibility/_iec_check.py
index 690f7db410f9724c461db6c9c6aec9f4b67fde73..809c26b31ba10e39e0d125c62b817bf8068ae343 100644
--- a/mc_openapi/doml_mc/csp_compatibility/cspcomp.py
+++ b/mc_openapi/doml_mc/csp_compatibility/_iec_check.py
@@ -4,6 +4,9 @@ import requests
 from mc_openapi.doml_mc.imc import IntermediateModelChecker
 from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion
 
+# DEPRECATED
+# Doing this would overlap with IOP tool, therefore checks will be performed using the other tool
+
 
 IEC_API = 'https://iec.ci.piacere.digital.tecnalia.dev/services/iecbackend/api/root-services/catalogue'
 
diff --git a/mc_openapi/doml_mc/csp_compatibility/allowlist_check_v1.py b/mc_openapi/doml_mc/csp_compatibility/allowlist_check_v1.py
new file mode 100644
index 0000000000000000000000000000000000000000..7f641c04e64b7518dadda730ec83325935e4c4ae
--- /dev/null
+++ b/mc_openapi/doml_mc/csp_compatibility/allowlist_check_v1.py
@@ -0,0 +1,124 @@
+
+
+from mc_openapi.doml_mc.intermediate_model.doml_element import DOMLElement, IntermediateModel
+from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion
+from difflib import SequenceMatcher
+from tabulate import tabulate
+
+import re
+
+class CSPCompatibilityValidator:
+    def __init__(self, data: dict) -> None:
+        self.data = data
+
+    def check(self, model: IntermediateModel, doml_version: DOMLVersion) -> list[str]:
+        """Returns a list of CSP supported by the model"""
+
+        # Check KeyPair
+        keypairs = self.check_keypair(model)
+        if len(keypairs) > 1:
+            print(tabulate(keypairs, headers='firstrow', tablefmt='fancy_grid'))
+
+        # ComputingNode and inheritors
+        arch, os, minreq = self.check_computing_nodes(model)
+        if len(arch) > 1:
+            print(tabulate(arch, headers='firstrow', tablefmt='fancy_grid'))
+        if len(os) > 1:
+            print(tabulate(os, headers='firstrow', tablefmt='fancy_grid'))
+        if len(minreq) > 1:
+            print(tabulate(minreq, headers='firstrow', tablefmt='fancy_grid'))
+
+    def check_keypair(self, model: IntermediateModel):
+        elems = model.values()
+        keypairs = [kp for kp in elems if kp.class_ == 'commons_KeyPair']
+        TABLE = [['KeyPair', 'Algorithm', *self.data['keypair'].keys()]]
+        for kp in keypairs:
+            name = kp.user_friendly_name
+            algorithm = kp.attributes.get('commons_KeyPair::algorithm')
+            bits = kp.attributes.get('commons_KeyPair::bits')
+            # For each vendor, check if there's at least one supported configuration
+            if algorithm is not None and len(algorithm) > 0:
+                algorithm = algorithm[0].upper()
+                ROW = [name, algorithm]
+                for _, valid_algos in self.data['keypair'].items():
+                    value = '✅' if algorithm in valid_algos else '❌'
+                    ROW.append(value)
+                TABLE.append(ROW)
+        return TABLE
+    
+    def check_computing_nodes(self, model: IntermediateModel):
+        elems = model.values()
+        compnodes = [cn for cn in elems if re.match(r"infrastructure_(ComputingNode|Container|PhysicalComputingNode|VirtualMachine)", cn.class_)]
+        ARCH_TABLE = [['Node', 'Arch', *self.data['arch'].keys()]]
+        OS_TABLE = [['Node', 'OS', *self.data['os'].keys()]]
+        MINREQ_TABLE = [['Node', *self.data['minimum_setup'].keys()]]
+
+        VALID_OS_MATCH_PERCENT = 0.33
+
+        for el in compnodes:
+            name = el.user_friendly_name or el.attributes.get('commons_DOMLElement::name') or f'[{el.class_}]'
+            arch = el.attributes.get('infrastructure_ComputingNode::architecture')
+            os = el.attributes.get('infrastructure_ComputingNode::os')
+            # cpu_count = el.attributes.get('infrastructure_ComputingNode::cpu_count')
+            # memory_mb = el.attributes.get('infrastructure_ComputingNode::memory_mb')
+
+            # CHECK ARCH
+            if arch and len(arch) > 0:
+                arch = arch[0].upper()
+                ROW = [name, arch]
+                for _, valid_archs in self.data['arch'].items():
+                    valid_archs = [v.upper() for v in valid_archs]
+                    value = '✅' if arch in valid_archs else '❌'
+                    ROW.append(value)
+                ARCH_TABLE.append(ROW)
+
+            # CHECK OS
+            if os and len(os) > 0:
+                os = os[0].upper()
+                ROW = [name, os]
+                for _, valid_os in self.data['os'].items():
+                    valid_os = [distro.upper() for os_family in valid_os for distro in valid_os[os_family]]
+                    compatible_os = [v for v in valid_os if v in os or os in v]
+                    alt_compatible_os = [(v, SequenceMatcher(None, v, os).ratio()) for v in valid_os if SequenceMatcher(None, v, os).ratio() > VALID_OS_MATCH_PERCENT]
+                    alt_compatible_os = sorted(alt_compatible_os, key=lambda x: x[1])
+                    value = any(compatible_os)
+                    value = '✅' if value else '❌' if len(alt_compatible_os) == 0 else '❓' 
+                    if len(compatible_os) > 0:
+                        value += f' ({compatible_os[0].lower()})'
+                    if value == '❓':
+                        alt_os_name, alt_os_ratio = alt_compatible_os[0]
+                        value += f' ({alt_os_name.lower()}, {alt_os_ratio*100:.{1}f}%)'
+                    ROW.append(value)
+                OS_TABLE.append(ROW)
+               
+            # CHECK MINIMUM REQUIREMENTS FOR CSP
+            ROW = [name]
+            for vendor, reqs in self.data['minimum_setup'].items():
+                CHECKS = {}
+                for req in reqs:
+                    if isinstance(req, list):
+                        try:
+                            dep = list(el.associations.get(req[0]))[0]
+                            dep = model[dep]
+                            CHECKS[str(req)] = dep.associations.get(req[1]) is not None or el.attributes.get(req[1]) is not None
+                        except:
+                            CHECKS[str(req)] = False
+                    if isinstance(req, str):
+                        CHECKS[req] = el.associations.get(req) is not None or el.attributes.get(req) is not None
+                
+                all_req_valid = all([v for v in CHECKS.values()])
+                value = '✅' if all_req_valid else '❌'
+                if not all_req_valid:
+                    value += " Missing:\n" + "\n".join([
+                        k.replace("_", ".", 1).replace("::", ".")
+                        for k, v in CHECKS.items() 
+                        if v is False
+                    ])
+                ROW.append(value)
+            MINREQ_TABLE.append(ROW)
+
+        return ARCH_TABLE, OS_TABLE, MINREQ_TABLE
+    
+       
+
+    
diff --git a/mc_openapi/doml_mc/csp_compatibility/validator.py b/mc_openapi/doml_mc/csp_compatibility/validator.py
deleted file mode 100644
index 584e610f4b58f053361634e6f5e69d356a25021b..0000000000000000000000000000000000000000
--- a/mc_openapi/doml_mc/csp_compatibility/validator.py
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
-from mc_openapi.doml_mc.intermediate_model.doml_element import DOMLElement, IntermediateModel
-from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion
-
-import re
-
-class CSPCompatibilityValidator:
-    def __init__(self, keypairs, architectures, regions) -> None:
-        self.valid_keypairs = keypairs
-        self.valid_architectures = architectures
-        self.valid_regions = regions
-        pass
-
-    def check(self, model: IntermediateModel, doml_version: DOMLVersion) -> list[str]:
-        """Returns a list of CSP supported by the model"""
-        if doml_version == DOMLVersion.V2_2:
-            elems = model.values()
-            
-            print('=====================================')
-            print('========= CSP Compatibility =========')
-            print('=====================================')
-
-            # Check KeyPair
-            keypairs = [kp for kp in elems if kp.class_ == 'commons_KeyPair']
-            print("\n--- Keypairs ---")
-            self.check_keypair(keypairs)
-
-            # ComputingNode and inheritors
-            print("\n--- Architectures ---")
-            compnodes = [cn for cn in elems if re.match(r"infrastructure_(ComputingNode|Container|PhysicalComputingNode|VirtualMachine)", cn.class_)]
-            self.check_computing_nodes(compnodes)
-
-            # Locations
-            print("\n--- Locations ---")
-            locations = [lc for lc in elems if lc.class_ == 'infrastructure_Location']
-            self.check_locations(locations)
-        else:
-            raise "Unsupported DOML version (<2.2) for CSP Compatibility check"
-
-    def check_keypair(self, keypairs: list[DOMLElement]):
-        for kp in keypairs:
-                algorithm = kp.attributes.get('commons_KeyPair::algorithm')
-                bits = kp.attributes.get('commons_KeyPair::bits')
-                # For each vendor, check if there's at least one supported configuration
-                for vendor, vkps in self.valid_keypairs.items():
-                    valid_algorithms = []
-                    valid_bits = []
-
-                    if algorithm:
-                        valid_algorithms = [vkp.get('algorithm').lower() == algorithm[0].lower() for vkp in vkps]
-                    if bits:
-                        def comp_bits(b, bits):
-                            if b is None:
-                                return True
-                            b =  b.split('-')
-                            if len(b) > 1:
-                                lb = b[0]
-                                ub = b[1]
-                                return (int(lb) <= bits if lb != '*' else True) and (bits <= int(ub) if ub != '*' else True)
-                            else:
-                                return b[0] == bits
-                        valid_bits = [comp_bits(vkp.get('bits'), bits[0]) for vkp in vkps]
-                
-                    if not any(valid_algorithms):
-                        print(f"{kp.user_friendly_name} 'algorithm' not compatible with: {vendor}")
-                    if not any(valid_bits):
-                        print(f"{kp.user_friendly_name} 'bits' not compatible with: {vendor}")
-    
-    def check_computing_nodes(self, elems: list[DOMLElement]):
-        for el in elems:
-            arch = el.attributes.get('infrastructure_ComputingNode::architecture')
-            # os = el.attributes.get('infrastructure_ComputingNode::os')
-            # cpu_count = el.attributes.get('infrastructure_ComputingNode::cpu_count')
-            # memory_mb = el.attributes.get('infrastructure_ComputingNode::memory_mb')
-
-            if arch:
-                for vendor, varchs in self.valid_architectures.items():
-                    valid_archs = [arch[0] == varch for varch in varchs]
-                    if not any(valid_archs):
-                        print(f"{el.user_friendly_name} 'architecture' not compatible with: {vendor}")
-
-            # OS requires probably a fine-handling of <os>, <flavor/version>
-    
-    def check_locations(self, locations: list[DOMLElement]):
-        for loc in locations:
-            reg = loc.attributes.get('infrastructure_Location::region')
-            
-            if reg:
-                for vendor, vregs in self.valid_regions.items():
-                    valid_regs = [reg[0] == vreg for vreg in vregs]
-                    if not any(valid_regs):
-                        print(f"{loc.user_friendly_name or 'A'} 'region' (value: {reg[0]}) not compatible with: {vendor}")
-                    
-
diff --git a/mc_openapi/doml_mc/domlr_parser/exceptions.py b/mc_openapi/doml_mc/domlr_parser/exceptions.py
index a37ed1f8d1f9c41ebe72a6d86359e16aa18eef0d..630ce72e3c0ec7285c42d5bbc255b1d65fd42d26 100644
--- a/mc_openapi/doml_mc/domlr_parser/exceptions.py
+++ b/mc_openapi/doml_mc/domlr_parser/exceptions.py
@@ -6,7 +6,7 @@ class RequirementException(Exception):
 class RequirementMissingKeyException(RequirementException):
     def __init__(self, key_type: str, key: str, close_matches: list[str], *args: object) -> None:
         super().__init__(*args)
-        fix_syntax = lambda x: x.replace("_", ".", 1).replace("::", "->")
+        fix_syntax = lambda x: x.replace("_", ".", 1).replace("::", ".")
         key = fix_syntax(key)
         close_matches = list(map(fix_syntax, close_matches))
         self.message = f"Error: no {key_type} found named '{key}'.\n"