diff --git a/services/webapp/code/rosetta/core_app/api.py b/services/webapp/code/rosetta/core_app/api.py
index 3add43ad8f650f02c643baeef4341c07e4ed9d77..680042dca6385b75e92fdf4cfbf582495b88f420 100644
--- a/services/webapp/code/rosetta/core_app/api.py
+++ b/services/webapp/code/rosetta/core_app/api.py
@@ -322,7 +322,7 @@ print(port)
             logger.info('Setting task "{}" to ip "{}" and port "{}"'.format(task.uuid, task_ip, task_port))
             task.status = TaskStatuses.running
             task.ip     = task_ip
-            if task.container.supports_dynamic_ports:
+            if task.container.supports_custom_interface_port:
                 task.port = int(task_port)
             task.save()
                     
diff --git a/services/webapp/code/rosetta/core_app/computing_managers.py b/services/webapp/code/rosetta/core_app/computing_managers.py
index a04360124b7481bf86a756fa3a2e9279222b2969..f33bee8dc2b36983bf5cecc97dc5f6439a2c6ac5 100644
--- a/services/webapp/code/rosetta/core_app/computing_managers.py
+++ b/services/webapp/code/rosetta/core_app/computing_managers.py
@@ -41,13 +41,13 @@ class ComputingManager(object):
         task.save()
         
         # Check if the tunnel is active and if so kill it
-        logger.debug('Checking if task "{}" has a running tunnel'.format(task.tid))
-        check_command = 'ps -ef | grep ":'+str(task.tunnel_port)+':'+str(task.ip)+':'+str(task.port)+'" | grep -v grep | awk \'{print $2}\''
+        logger.debug('Checking if task "{}" has a running tunnel'.format(task.uuid))
+        check_command = 'ps -ef | grep ":'+str(task.tcp_tunnel_port)+':'+str(task.interface_ip)+':'+str(task.interface_port)+'" | grep -v grep | awk \'{print $2}\''
         logger.debug(check_command)
         out = os_shell(check_command, capture=True)
         logger.debug(out)
         if out.exit_code == 0:
-            logger.debug('Task "{}" has a running tunnel, killing it'.format(task.tid))
+            logger.debug('Task "{}" has a running tunnel, killing it'.format(task.uuid))
             tunnel_pid = out.stdout
             # Kill Tunnel command
             kill_tunnel_command= 'kill -9 {}'.format(tunnel_pid)
@@ -91,15 +91,12 @@ class InternalSingleNodeComputingManager(SingleNodeComputingManager):
     
     def _start_task(self, task):
 
-        if task.container.type != 'docker':
-            raise ErrorMessage('Sorry, only Docker container are supported on this computing resource.')
-
         # Init run command #--cap-add=NET_ADMIN --cap-add=NET_RAW
-        run_command  = 'sudo docker run  --network=rosetta_default --name rosetta-task-{}'.format( task.id)
+        run_command  = 'sudo docker run  --network=rosetta_default --name {}'.format(task.uuid)
 
         # Pass if any
-        if task.auth_pass:
-            run_command += ' -eAUTH_PASS={} '.format(task.auth_pass)
+        if task.password:
+            run_command += ' -eAUTH_PASS={} '.format(task.password)
 
         # User data volume
         run_command += ' -v {}/user-{}:/data'.format(settings.LOCAL_USER_DATA_DIR, task.user.id)
@@ -108,10 +105,10 @@ class InternalSingleNodeComputingManager(SingleNodeComputingManager):
         if task.container.registry == 'local':
             registry_string = 'localhost:5000/'
         else:
-            registry_string  = ''
+            registry_string  = 'docker.io/'
 
         # Host name, image entry command
-        run_command += ' -h task-{} -d -t {}{}'.format(task.id, registry_string, task.container.image)
+        run_command += ' -h task-{} -d -t {}{}'.format(task.uuid, registry_string, task.container.image)
 
         # Debug
         logger.debug('Running new task with command="{}"'.format(run_command))
@@ -121,20 +118,20 @@ class InternalSingleNodeComputingManager(SingleNodeComputingManager):
         if out.exit_code != 0:
             raise Exception(out.stderr)
         else:
-            task_tid = out.stdout
-            logger.debug('Created task with id: "{}"'.format(task_tid))
+            tid = out.stdout
+            logger.debug('Created task with id: "{}"'.format(tid))
 
             # Get task IP address
-            out = os_shell('sudo docker inspect --format \'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}\' ' + task_tid + ' | tail -n1', capture=True)
+            out = os_shell('sudo docker inspect --format \'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}\' ' + tid + ' | tail -n1', capture=True)
             if out.exit_code != 0:
                 raise Exception('Error: ' + out.stderr)
             task_ip = out.stdout
 
             # Set fields
-            task.tid    = task_tid
+            task.id = tid
             task.status = TaskStatuses.running
-            task.ip     = task_ip
-            task.port   = int(task.container.ports.split(',')[0])
+            task.interface_ip = task_ip
+            task.interface_port = task.container.interface_port
 
             # Save
             task.save()
@@ -145,9 +142,9 @@ class InternalSingleNodeComputingManager(SingleNodeComputingManager):
         # Delete the Docker container
         standby_supported = False
         if standby_supported:
-            stop_command = 'sudo docker stop {}'.format(task.tid)
+            stop_command = 'sudo docker stop {}'.format(task.id)
         else:
-            stop_command = 'sudo docker stop {} && sudo docker rm {}'.format(task.tid,task.tid)
+            stop_command = 'sudo docker stop {} && sudo docker rm {}'.format(task.id,task.id)
     
         out = os_shell(stop_command, capture=True)
         if out.exit_code != 0:
@@ -164,7 +161,7 @@ class InternalSingleNodeComputingManager(SingleNodeComputingManager):
     def _get_task_log(self, task, **kwargs):
 
         # View the Docker container log (attach)
-        view_log_command = 'sudo docker logs {}'.format(task.tid,)
+        view_log_command = 'sudo docker logs {}'.format(task.id,)
         logger.debug(view_log_command)
         out = os_shell(view_log_command, capture=True)
         if out.exit_code != 0:
@@ -200,8 +197,6 @@ class SSHSingleNodeComputingManager(SingleNodeComputingManager, SSHComputingMana
         # Run the container on the host (non blocking)
         if task.container.type == 'singularity':
 
-            task.tid    = task.uuid
-            task.save()
 
             # Set pass if any
             if task.auth_pass:
@@ -260,12 +255,8 @@ class SSHSingleNodeComputingManager(SingleNodeComputingManager, SSHComputingMana
         task = Task.objects.get(uuid=task_uuid)
 
         # Save pid echoed by the command above
-        task_pid = out.stdout
+        task.id = out.stdout
 
-        # Set fields
-        #task.status = TaskStatuses.running
-        task.pid = task_pid
- 
         # Save
         task.save()
 
@@ -359,7 +350,7 @@ class SlurmSSHClusterComputingManager(ClusterComputingManager, SSHComputingManag
         # Submit the job
         if task.container.type == 'singularity':
 
-            #if not task.container.supports_dynamic_ports:
+            #if not task.container.supports_custom_interface_port:
             #     raise Exception('This task does not support dynamic port allocation and is therefore not supported using singularity on Slurm')
 
             # Set pass if any
diff --git a/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py b/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py
index 8cfdeb57366b31c9b3f5c68b9aa05ffc4592a17e..357b3890bdccba30e1eed1641ff6d2c03e5c929c 100644
--- a/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py
+++ b/services/webapp/code/rosetta/core_app/management/commands/core_app_populate.py
@@ -63,116 +63,53 @@ class Command(BaseCommand):
             Text.objects.create(id='home', content=default_home_text_content)
 
 
-        # Public containers
-        public_containers = Container.objects.filter(user=None)
-        if public_containers:
+        # Platform containers
+        platform_containers = Container.objects.filter(user=None)
+        if platform_containers:
             print('Not creating public containers as they already exist')
         else:
-            print('Creating public containers...')
+            print('Creating platform containers...')
             
             # MinimalMetaDesktop Docker (sarusso repo)
             Container.objects.create(user     = None,
-                                     name     = 'MinimalMetaDesktop latest',
+                                     name     = 'MinimalMetaDesktop ',
+                                     description = 'A minimal meta-desktop environment providing basic window management functionalities and a terminal.',
+                                     registry = 'docker.io',
                                      image    = 'sarusso/minimalmetadesktop',
-                                     type     = 'docker',
-                                     registry = 'docker_hub',
-                                     ports    = '8590',
-                                     protocol = 'https',
-                                     supports_dynamic_ports = True,
-                                     supports_user_auth     = False,
-                                     supports_pass_auth     = True)
-
-            # BasicMetaDesktop Docker (sarusso repo)
-            Container.objects.create(user     = None,
-                                     name     = 'BasicMetaDesktop latest',
-                                     image    = 'sarusso/basicmetadesktop',
-                                     type     = 'docker',
-                                     registry = 'docker_hub',
-                                     protocol = 'https',
-                                     ports    = '8590',
-                                     supports_dynamic_ports = True,
-                                     supports_user_auth     = False,
-                                     supports_pass_auth     = True)
-
-
-            # DevMetaDesktop Docker (sarusso repo)
-            Container.objects.create(user     = None,
-                                     name     = 'DevMetaDesktop latest',
-                                     image    = 'sarusso/devmetadesktop',
-                                     type     = 'docker',
-                                     registry = 'docker_hub',
-                                     protocol = 'https',
-                                     ports    = '8590',
-                                     supports_dynamic_ports = True,
-                                     supports_user_auth     = False,
-                                     supports_pass_auth     = True)
-
-
-            # MinimalMetaDesktop Singularity (sarusso repo)
-            Container.objects.create(user     = None,
-                                     name     = 'MinimalMetaDesktop latest',
-                                     image    = 'sarusso/minimalmetadesktop',
-                                     type     = 'singularity',
-                                     registry = 'docker_hub',
-                                     protocol = 'https',
-                                     ports    = '8590',
-                                     supports_dynamic_ports = True,
-                                     supports_user_auth     = False,
-                                     supports_pass_auth     = True)
-            
-
-            # BasicMetaDesktop Singularity (sarusso repo)
-            Container.objects.create(user     = None,
-                                     name     = 'BasicMetaDesktop latest',
-                                     image    = 'sarusso/basicmetadesktop',
-                                     type     = 'singularity',
-                                     registry = 'docker_hub',
-                                     protocol = 'https',
-                                     ports    = '8590',
-                                     supports_dynamic_ports = True,
-                                     supports_user_auth     = False,
-                                     supports_pass_auth     = True)
-
-
-            # DevMetaDesktop Singularity (sarusso repo)
-            Container.objects.create(user     = None,
-                                     name     = 'DevMetaDesktop latest',
-                                     image    = 'sarusso/devmetadesktop',
-                                     type     = 'singularity',
-                                     registry = 'docker_hub',
-                                     protocol = 'https',
-                                     ports    = '8590',
-                                     supports_dynamic_ports = True,
-                                     supports_user_auth     = False,
-                                     supports_pass_auth     = True)
-
-
-            # MetaDesktop Singularity (local)
-            #Container.objects.create(user     = None,
-            #                         name     = 'MetaDesktop latest',
-            #                         image    = 'rosetta/metadesktop',
-            #                         type     = 'singularity',
-            #                         registry = 'docker_local',
-            #                         ports    = '8590',
-            #                         supports_dynamic_ports = True,
-            #                         supports_user_auth     = False,
-            #                         supports_pass_auth     = True)
-
-
-
-            # Astrocook
-            #Container.objects.create(user     = None,
-            #                         name     = 'Astrocook b2b819e',
-            #                         image    = 'sarusso/astrocook:b2b819e',
-            #                         type     = 'docker',
-            #                         registry = 'docker_local',
-            #                         ports    = '8590',
-            #                         supports_dynamic_ports = False,
-            #                         supports_user_auth     = False,
-            #                         supports_pass_auth     = False)
-
-
-        # Private containers
+                                     tag      = 'v0.2.0',
+                                     arch = 'x86_64',
+                                     os = 'linux',
+                                     interface_port     = '8590',
+                                     interface_protocol = 'http',
+                                     interface_transport = 'tcp/ip',
+                                     supports_custom_interface_port = True,
+                                     supports_interface_auth = True)
+
+#             # BasicMetaDesktop Docker (sarusso repo)
+#             Container.objects.create(user     = None,
+#                                      name     = 'BasicMetaDesktop latest',
+#                                      image    = 'sarusso/basicmetadesktop',
+#                                      registry = 'docker_hub',
+#                                      protocol = 'https',
+#                                      ports    = '8590',
+#                                      supports_custom_interface_port = True,
+#                                      supports_user_auth     = False,
+#                                      supports_pass_auth     = True)
+# 
+# 
+#             # DevMetaDesktop Docker (sarusso repo)
+#             Container.objects.create(user     = None,
+#                                      name     = 'DevMetaDesktop latest',
+#                                      image    = 'sarusso/devmetadesktop',
+#                                      type     = 'docker',
+#                                      registry = 'docker_hub',
+#                                      protocol = 'https',
+#                                      ports    = '8590',
+#                                      supports_custom_interface_port = True,
+#                                      supports_user_auth     = False,
+#                                      supports_pass_auth     = True)
+
+        # Testuser containers
         testuser_containers = Container.objects.filter(user=testuser)
         if testuser_containers:
             print('Not creating testuser private containers as they already exist')
@@ -181,25 +118,20 @@ class Command(BaseCommand):
 
             # Jupyter Singularity
             Container.objects.create(user     = testuser,
-                                     name     = 'Jupyter Notebook latest',
-                                     image    = 'jupyter/base-notebook',
-                                     type     = 'singularity',
-                                     registry = 'docker_hub',
-                                     ports    = '8888', 
-                                     supports_dynamic_ports = False,
-                                     supports_user_auth     = False,
-                                     supports_pass_auth     = False)
-            
-            # Jupyter Docker
-            Container.objects.create(user     = testuser,
-                                     name     = 'Jupyter Notebook latest',
+                                     name     = 'Jupyter Notebook',
+                                     description = 'A basic Jupyter notebook environment.',
+                                     registry = 'docker.io',
                                      image    = 'jupyter/base-notebook',
-                                     type     = 'docker',
-                                     registry = 'docker_hub',
-                                     ports    = '8888', 
-                                     supports_dynamic_ports = False,
-                                     supports_user_auth     = False,
-                                     supports_pass_auth     = False)
+                                     tag      = 'latest',
+                                     arch = 'x86_64',
+                                     os = 'linux',
+                                     interface_port     = '8888',
+                                     interface_protocol = 'http',
+                                     interface_transport = 'tcp/ip',
+                                     supports_custom_interface_port = False,
+                                     supports_interface_auth = False)
+
+
 
         # Computing resources
         computing_resources = Computing.objects.all()
@@ -213,27 +145,31 @@ class Command(BaseCommand):
             #==============================
             Computing.objects.create(user = None,
                                      name = 'Demo Internal',
-                                     type = 'singlenode',
-                                     access_method = 'internal',
+                                     description = 'A demo internal computing resource.',
+                                     type = 'standalone',
+                                     access_mode = 'internal',
+                                     auth_mode = 'internal',
+                                     wms = None,
                                      requires_sys_conf  = False,
                                      requires_user_conf = False,
                                      requires_user_keys = False,
-                                     supports_docker = True,
-                                     supports_singularity = False)
+                                     container_runtimes = 'docker')
 
 
             #==============================
             # Demo Single Node computing 
             #==============================    
             demo_singlenode_computing = Computing.objects.create(user = None,
-                                                                 name = 'Demo Single Node',
-                                                                 type = 'singlenode',
-                                                                 access_method = 'ssh',
+                                                                 name = 'Demo Standalone',
+                                                                 description = 'A demo standalone computing resource.',
+                                                                 type = 'standalone',
+                                                                 access_mode = 'ssh+cli',
+                                                                 auth_mode = 'user_keys',
+                                                                 wms = None,
                                                                  requires_sys_conf  = True,
                                                                  requires_user_conf = True,
                                                                  requires_user_keys = True,
-                                                                 supports_docker = True,
-                                                                 supports_singularity = True)
+                                                                 container_runtimes = 'singularity')
     
             ComputingSysConf.objects.create(computing = demo_singlenode_computing,
                                             data      = {'host': 'slurmclusterworker-one',
@@ -249,13 +185,15 @@ class Command(BaseCommand):
             #==============================
             demo_slurm_computing = Computing.objects.create(user = None,
                                                             name = 'Demo Cluster',
+                                                            description = 'A demo cluster computing resource.',
                                                             type = 'cluster',
-                                                            access_method = 'slurm+ssh',
+                                                            access_mode = 'ssh+cli',
+                                                            auth_mode = 'user_keys',
+                                                            wms = 'slurm',
                                                             requires_sys_conf  = True,
                                                             requires_user_conf = True,
                                                             requires_user_keys = True,
-                                                            supports_docker = False,
-                                                            supports_singularity = True)
+                                                            container_runtimes = 'singularity')
     
             # Create demo slurm sys computing conf
             ComputingSysConf.objects.create(computing = demo_slurm_computing,
diff --git a/services/webapp/code/rosetta/core_app/migrations/0005_auto_20211030_2318.py b/services/webapp/code/rosetta/core_app/migrations/0005_auto_20211030_2318.py
new file mode 100644
index 0000000000000000000000000000000000000000..81b294a5e9eb4cece6ff60e4cf5a4de8568950cc
--- /dev/null
+++ b/services/webapp/code/rosetta/core_app/migrations/0005_auto_20211030_2318.py
@@ -0,0 +1,165 @@
+# Generated by Django 2.2.1 on 2021-10-30 23:18
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core_app', '0004_auto_20210408_1041'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='container',
+            old_name='supports_pass_auth',
+            new_name='supports_password_auth',
+        ),
+        migrations.RenameField(
+            model_name='task',
+            old_name='tid',
+            new_name='id',
+        ),
+        migrations.RemoveField(
+            model_name='computing',
+            name='access_method',
+        ),
+        migrations.RemoveField(
+            model_name='computing',
+            name='supports_docker',
+        ),
+        migrations.RemoveField(
+            model_name='computing',
+            name='supports_singularity',
+        ),
+        migrations.RemoveField(
+            model_name='container',
+            name='ports',
+        ),
+        migrations.RemoveField(
+            model_name='container',
+            name='protocol',
+        ),
+        migrations.RemoveField(
+            model_name='container',
+            name='supports_user_auth',
+        ),
+        migrations.RemoveField(
+            model_name='container',
+            name='type',
+        ),
+        migrations.RemoveField(
+            model_name='task',
+            name='access_method',
+        ),
+        migrations.RemoveField(
+            model_name='task',
+            name='auth_pass',
+        ),
+        migrations.RemoveField(
+            model_name='task',
+            name='auth_user',
+        ),
+        migrations.RemoveField(
+            model_name='task',
+            name='ip',
+        ),
+        migrations.RemoveField(
+            model_name='task',
+            name='pid',
+        ),
+        migrations.RemoveField(
+            model_name='task',
+            name='port',
+        ),
+        migrations.AddField(
+            model_name='computing',
+            name='access_mode',
+            field=models.CharField(default='ssh+cli', max_length=36, verbose_name='Computing resource access (control) mode'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='computing',
+            name='auth_mode',
+            field=models.CharField(default='user_keys', max_length=36, verbose_name='Computing resource authentication mode'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='computing',
+            name='container_runtimes',
+            field=models.CharField(default='singularity', max_length=256, verbose_name='Computing resource container runtimes'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='computing',
+            name='description',
+            field=models.TextField(blank=True, null=True, verbose_name='Container description'),
+        ),
+        migrations.AddField(
+            model_name='computing',
+            name='wms',
+            field=models.CharField(blank=True, max_length=36, null=True, verbose_name='Computing resource WMS'),
+        ),
+        migrations.AddField(
+            model_name='container',
+            name='arch',
+            field=models.CharField(default='x86_64', max_length=36, verbose_name='Container architecture'),
+        ),
+        migrations.AddField(
+            model_name='container',
+            name='description',
+            field=models.TextField(blank=True, null=True, verbose_name='Container description'),
+        ),
+        migrations.AddField(
+            model_name='container',
+            name='interface_port',
+            field=models.IntegerField(blank=True, null=True, verbose_name='Container interface default port'),
+        ),
+        migrations.AddField(
+            model_name='container',
+            name='interface_protocol',
+            field=models.CharField(blank=True, max_length=36, null=True, verbose_name='Container interface protocol'),
+        ),
+        migrations.AddField(
+            model_name='container',
+            name='interface_transport',
+            field=models.CharField(blank=True, max_length=36, null=True, verbose_name='Container interface protocol'),
+        ),
+        migrations.AddField(
+            model_name='container',
+            name='os',
+            field=models.CharField(default='linux', max_length=36, verbose_name='Container operating system'),
+        ),
+        migrations.AddField(
+            model_name='container',
+            name='tag',
+            field=models.CharField(default='latest', max_length=255, verbose_name='Container image'),
+        ),
+        migrations.AddField(
+            model_name='task',
+            name='interface_ip',
+            field=models.CharField(blank=True, max_length=36, null=True, verbose_name='Task interface ip address'),
+        ),
+        migrations.AddField(
+            model_name='task',
+            name='interface_port',
+            field=models.IntegerField(blank=True, null=True, verbose_name='Task interface port'),
+        ),
+        migrations.AddField(
+            model_name='task',
+            name='proxy_token',
+            field=models.CharField(blank=True, max_length=36, null=True, verbose_name='Token for proxy auth if any'),
+        ),
+        migrations.AddField(
+            model_name='task',
+            name='requires_proxy',
+            field=models.BooleanField(default=True, verbose_name='Does the task require a proxy?'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='task',
+            name='requires_tunnel',
+            field=models.BooleanField(default=True, verbose_name='Does the task require a tunnel to be opened?'),
+            preserve_default=False,
+        ),
+    ]
diff --git a/services/webapp/code/rosetta/core_app/migrations/0006_auto_20211102_1334.py b/services/webapp/code/rosetta/core_app/migrations/0006_auto_20211102_1334.py
new file mode 100644
index 0000000000000000000000000000000000000000..c2ab07498c533afac5d1aea1f13de23643a216d7
--- /dev/null
+++ b/services/webapp/code/rosetta/core_app/migrations/0006_auto_20211102_1334.py
@@ -0,0 +1,58 @@
+# Generated by Django 2.2.1 on 2021-11-02 13:34
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core_app', '0005_auto_20211030_2318'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='container',
+            old_name='supports_password_auth',
+            new_name='supports_interface_auth',
+        ),
+        migrations.RenameField(
+            model_name='container',
+            old_name='supports_dynamic_ports',
+            new_name='supports_setting_interface_port',
+        ),
+        migrations.RenameField(
+            model_name='task',
+            old_name='tunnel_port',
+            new_name='tcp_tunnel_port',
+        ),
+        migrations.RemoveField(
+            model_name='task',
+            name='proxy_token',
+        ),
+        migrations.RemoveField(
+            model_name='task',
+            name='requires_tunnel',
+        ),
+        migrations.AddField(
+            model_name='task',
+            name='auth_token',
+            field=models.CharField(blank=True, max_length=36, null=True, verbose_name='A one-time token for proxy or task interface auth if any'),
+        ),
+        migrations.AddField(
+            model_name='task',
+            name='requires_proxy_auth',
+            field=models.BooleanField(default=False, verbose_name='Does the task require interface authentication to be enforced at proxy-level?'),
+            preserve_default=False,
+        ),
+        migrations.AddField(
+            model_name='task',
+            name='requires_tcp_tunnel',
+            field=models.BooleanField(default=True, verbose_name='Does the task require a tunnel to be opened for accessing its interface?'),
+            preserve_default=False,
+        ),
+        migrations.AlterField(
+            model_name='task',
+            name='requires_proxy',
+            field=models.BooleanField(verbose_name='Does the task require a proxy for accessing its interface?'),
+        ),
+    ]
diff --git a/services/webapp/code/rosetta/core_app/migrations/0007_auto_20211103_1228.py b/services/webapp/code/rosetta/core_app/migrations/0007_auto_20211103_1228.py
new file mode 100644
index 0000000000000000000000000000000000000000..ad56e41ccfb7a4a48f4cc8e9c8c2c2393be88db8
--- /dev/null
+++ b/services/webapp/code/rosetta/core_app/migrations/0007_auto_20211103_1228.py
@@ -0,0 +1,44 @@
+# Generated by Django 2.2.1 on 2021-11-03 12:28
+
+import django.contrib.postgres.fields.jsonb
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core_app', '0006_auto_20211102_1334'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='container',
+            name='interface_port',
+            field=models.IntegerField(blank=True, null=True, verbose_name='Container interface port'),
+        ),
+        migrations.AlterField(
+            model_name='container',
+            name='supports_interface_auth',
+            field=models.BooleanField(default=False, verbose_name='Does the container interface support authentication?'),
+        ),
+        migrations.AlterField(
+            model_name='container',
+            name='supports_setting_interface_port',
+            field=models.BooleanField(default=False, verbose_name='Does the container support setting a custom interface port?'),
+        ),
+        migrations.AlterField(
+            model_name='task',
+            name='auth_token',
+            field=models.CharField(blank=True, max_length=36, null=True, verbose_name='A one-time token for proxy or interface authentication'),
+        ),
+        migrations.AlterField(
+            model_name='task',
+            name='computing_options',
+            field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True, verbose_name='Task computing options'),
+        ),
+        migrations.AlterField(
+            model_name='task',
+            name='extra_binds',
+            field=models.CharField(blank=True, max_length=4096, null=True, verbose_name='Task container extra binds'),
+        ),
+    ]
diff --git a/services/webapp/code/rosetta/core_app/migrations/0008_auto_20211103_1232.py b/services/webapp/code/rosetta/core_app/migrations/0008_auto_20211103_1232.py
new file mode 100644
index 0000000000000000000000000000000000000000..f5a1f4c16ef017ebf975a5f0da680728d63aafc1
--- /dev/null
+++ b/services/webapp/code/rosetta/core_app/migrations/0008_auto_20211103_1232.py
@@ -0,0 +1,18 @@
+# Generated by Django 2.2.1 on 2021-11-03 12:32
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core_app', '0007_auto_20211103_1228'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='container',
+            old_name='supports_setting_interface_port',
+            new_name='supports_custom_interface_port',
+        ),
+    ]
diff --git a/services/webapp/code/rosetta/core_app/models.py b/services/webapp/code/rosetta/core_app/models.py
index 3ec486ff8a8b6126b04e9ce44e3ba4df6d12baa4..3ed1316a56b1330f3a9b21b4344053f23aa092bb 100644
--- a/services/webapp/code/rosetta/core_app/models.py
+++ b/services/webapp/code/rosetta/core_app/models.py
@@ -27,12 +27,13 @@ logger = logging.getLogger(__name__)
 # Task statuses
 class TaskStatuses(object):
     created = 'created'
-    sumbitted = 'sumbitted'
+    sumbitted = 'sumbitted' # TODO: fix me!
     running = 'running'
     stopped = 'stopped'
     exited = 'exited'
 
-
+# All char model attributes are based on a 36 chars field. This is for making it easy to switch
+# using an UUID pointing to some other model instead of the value in future, should this be necessary.
 
 #=========================
 #  Profile 
@@ -78,54 +79,47 @@ class Container(models.Model):
     user = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE, blank=True, null=True)  
     # If a container has no user, it will be available to anyone. Can be created, edited and deleted only by admins.
 
-    name     = models.CharField('Container Name', max_length=255, blank=False, null=False)    
-    image    = models.CharField('Container image', max_length=255, blank=False, null=False)
-    type     = models.CharField('Container type', max_length=36, blank=False, null=False)
+    # Generic attributes
+    name        = models.CharField('Container Name', max_length=255, blank=False, null=False)
+    description = models.TextField('Container description', blank=True, null=True)
+    
+    # Registry-related attributes
     registry = models.CharField('Container registry', max_length=255, blank=False, null=False)
-    ports    = models.CharField('Container ports', max_length=36, blank=True, null=True)
-    protocol = models.CharField('Container protocol', max_length=36, blank=True, null=True, default='http')
+    image    = models.CharField('Container image', max_length=255, blank=False, null=False)
+    tag      = models.CharField('Container image', max_length=255, blank=False, null=False, default='latest')
 
-    # Capabilities
-    supports_dynamic_ports = models.BooleanField(default=False)
-    supports_user_auth = models.BooleanField(default=False)
-    supports_pass_auth = models.BooleanField(default=False)
+    # Platform-related
+    arch = models.CharField('Container architecture', max_length=36, blank=False, null=False, default='x86_64')
+    os   = models.CharField('Container operating system', max_length=36, blank=False, null=False, default='linux')
+    
+    # TODO: do we want more control with respect to kernel, CPUs, instruction sets? 
+    # requires = i.e. kernel > 3, intel, AVX2
+    
+    # Port, protocol and transport for the container interface
+    interface_port = models.IntegerField('Container interface port', blank=True, null=True) 
+    interface_protocol = models.CharField('Container interface protocol', max_length=36, blank=True, null=True)
+    interface_transport = models.CharField('Container interface protocol', max_length=36, blank=True, null=True)
 
+    # Capabilities
+    supports_custom_interface_port = models.BooleanField('Does the container support setting a custom interface port?', default=False) # BASE_PORT
+    supports_interface_auth = models.BooleanField('Does the container interface support authentication?', default=False) # AUTH_USER / AUTH_PASS
 
     class Meta:
         ordering = ['name']
 
-
     def __str__(self):
-        return str('Container "{}" of type "{}" with image "{}" and  ports "{}" from registry "{}" of user "{}"'.format(self.name, self.type, self.image, self.ports, self.registry, self.user))
+        return str('Container "{}" with image "{}" and tag "{}" of user "{}" on registry "{}" '.format(self.name, self.image, self.tag, self.user, self.registry))
 
-
-    @property
-    def id(self):
-        return str(self.uuid).split('-')[0]
+    #@property
+    #def id(self):
+    #    return str(self.uuid).split('-')[0]
 
     @ property
     def color(self):
-        string_int_hash = hash_string_to_int(self.name + self.type + self.image)
+        string_int_hash = hash_string_to_int(self.registry + self.image + self.tag)
         color_map_index = string_int_hash % len(color_map)
         return color_map[color_map_index]
 
-    @property 
-    def port(self):
-        if not self.ports:
-            return None
-        return(int(self.ports.split(',')[0]))
-
-
-    @property 
-    def image_name(self):
-        return self.image.split(':')[0]
-    
-    def image_tag(self):
-        
-        if ':' in self.image:
-            return self.image.split(':')[1]
-        else:
-            return 'latest'
 
 #=========================
 #  Computing resources
@@ -137,34 +131,23 @@ class Computing(models.Model):
     user = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE, blank=True, null=True)
     # If a compute resource has no user, it will be available to anyone. Can be created, edited and deleted only by admins.
     
-    name = models.CharField('Computing Name', max_length=255, blank=False, null=False)
+    name        = models.CharField('Computing Name', max_length=255, blank=False, null=False)
+    description = models.TextField('Container description', blank=True, null=True)
+
+    # Standalone / sluster
     type = models.CharField('Computing Type', max_length=255, blank=False, null=False)
-    access_method = models.CharField('Computing Access method', max_length=255, blank=False, null=False)
 
     requires_sys_conf  = models.BooleanField(default=False)
     requires_user_conf = models.BooleanField(default=False)
     requires_user_keys = models.BooleanField(default=False)
 
-    supports_docker  = models.BooleanField(default=False)
-    supports_singularity  = models.BooleanField(default=False)
-
-    @property
-    def type_str(self):
-        # TODO: improve me?
-        if self.type == 'cluster':
-            return 'Cluster'
-        elif self.type == 'singlenode':
-            return 'Single Node'
-        else:
-            raise ConsistencyException('Unknown computing resource type "{}"'.format(self.type))
-
-    @property
-    def access_method_str(self):
-        # TODO: improve me?
-        access_method = self.access_method
-        access_method = access_method.replace('ssh', 'SSH')
-        access_method = access_method.replace('slurm', 'Slurm')
-        return access_method
+    # Interfce and interaction definition
+    access_mode = models.CharField('Computing resource access (control) mode', max_length=36, blank=False, null=False)
+    auth_mode   = models.CharField('Computing resource authentication mode', max_length=36, blank=False, null=False)
+    wms         = models.CharField('Computing resource WMS', max_length=36, blank=True, null=True)
+    
+    # Supported container runtimes
+    container_runtimes = models.CharField('Computing resource container runtimes', max_length=256, blank=False, null=False) 
 
     class Meta:
         ordering = ['name']
@@ -198,14 +181,14 @@ class Computing(models.Model):
         try:
             return self._manager
         except AttributeError:
-            if self.type == 'cluster' and self.access_method == 'slurm+ssh':
+            if self.type == 'cluster' and self.access_mode == 'ssh+cli' and self.access_mode == 'user_keys' and self.wms == 'slurm':
                 self._manager = computing_managers.SlurmSSHClusterComputingManager(self)
-            elif self.type == 'singlenode' and self.access_method == 'ssh':
-                self._manager = computing_managers.SSHSingleNodeComputingManager(self)            
-            elif self.type == 'singlenode' and self.access_method == 'internal':
+            elif self.type == 'standalone' and self.access_mode == 'ssh+cli' and self.access_mode == 'user_keys' and self.wms is None:
+                self._manager = computing_managers.SSHSingleNodeComputingManager(self)
+            elif self.type == 'standalone' and self.access_mode == 'internal' and self.access_mode == 'internal' and self.wms is None:
                 self._manager = computing_managers.InternalSingleNodeComputingManager(self)
             else:
-                raise ConsistencyException('Don\'t know how to instantiate a computing manager for computing resource of type "{}" and access mode "{}"'.format(self.type, self.access_method))
+                raise ConsistencyException('Don\'t know how to instantiate a computing manager for computing resource of type "{}", access mode "{}" and WMS "{}"'.format(self.type, self.access_mode, self.wms))
             return self._manager
     
     
@@ -301,29 +284,36 @@ class ComputingUserConf(models.Model):
 
 class Task(models.Model):
 
-    uuid      = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
-    user      = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE)
-    tid       = models.CharField('Task ID', max_length=64, blank=True, null=True)
-    name      = models.CharField('Task name', max_length=36, blank=False, null=False)
+    uuid  = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
+    user  = models.ForeignKey(User, related_name='+', on_delete=models.CASCADE)
+    name  = models.CharField('Task name', max_length=36, blank=False, null=False)
+
+    # Task management
+    id        = models.CharField('Task ID', max_length=64, blank=True, null=True) # i.e. Slurm job id, singularity PID, docker hash
     status    = models.CharField('Task status', max_length=36, blank=True, null=True)
     created   = models.DateTimeField('Created on', default=timezone.now)
-    pid       = models.IntegerField('Task pid', blank=True, null=True)
-    port      = models.IntegerField('Task port', blank=True, null=True)
-    ip        = models.CharField('Task ip address', max_length=36, blank=True, null=True)
-    tunnel_port = models.IntegerField('Task tunnel port', blank=True, null=True)
-    extra_binds = models.CharField('Extra binds', max_length=4096, blank=True, null=True)
+
+    # How to reach the task interface. The IP has to be intended either as the container IP if this is directly
+    # reachable (i.e. using a Docker or Kubernetes network) or as the host IP address, depending on the
+    # computing resource and its computing manager/WMS/container runtime. The port is to be intended
+    # as the port where the task interface is exposed on its IP address.
+    interface_ip   = models.CharField('Task interface ip address', max_length=36, blank=True, null=True)
+    interface_port = models.IntegerField('Task interface port', blank=True, null=True) 
+    
+    # Task access
+    requires_tcp_tunnel = models.BooleanField('Does the task require a tunnel to be opened for accessing its interface?')
+    tcp_tunnel_port     = models.IntegerField('Task tunnel port', blank=True, null=True)
+    requires_proxy      = models.BooleanField('Does the task require a proxy for accessing its interface?')
+    requires_proxy_auth = models.BooleanField('Does the task require interface authentication to be enforced at proxy-level?')
+    auth_token          = models.CharField('A one-time token for proxy or interface authentication', max_length=36, blank=True, null=True)
 
     # Links
     computing = models.ForeignKey(Computing, related_name='+', on_delete=models.CASCADE)
     container = models.ForeignKey('Container', on_delete=models.CASCADE, related_name='+')
 
-    # Auth
-    auth_user     = models.CharField('Task auth user', max_length=36, blank=True, null=True)
-    auth_pass     = models.CharField('Task auth pass', max_length=36, blank=True, null=True)
-    access_method = models.CharField('Task access method', max_length=36, blank=True, null=True)
-
-    # Computing options
-    computing_options = JSONField(blank=True, null=True)
+    # Extra 
+    extra_binds = models.CharField('Task container extra binds', max_length=4096, blank=True, null=True)
+    computing_options = JSONField('Task computing options', blank=True, null=True) # i.e. CPUs, RAM, cluster partition etc. TODO: why here?
 
     class Meta:
         ordering = ['-created']
@@ -360,9 +350,9 @@ class Task(models.Model):
                 
             self.save()                   
 
-    @property
-    def id(self):
-        return str(self.uuid).split('-')[0]
+    #@property
+    #def id(self):
+    #    return str(self.uuid).split('-')[0]
 
 
     def __str__(self):
@@ -375,9 +365,13 @@ class Task(models.Model):
         return color_map[color_map_index]
     
     @property
-    def direct_link(self):
-        return '{}/t/{}'.format(settings.DJANGO_PUBLIC_HTTP_HOST, self.id)
-
+    def sharable_link(self):
+        return '{}/t/{}'.format(settings.DJANGO_PUBLIC_HTTP_HOST, str(self.uuid)[0:8])
+    
+    @property
+    def tcp_tunnel_host(self):
+        # If separate host for tasks is set use that, otherwise:
+        return settings.DJANGO_PUBLIC_HTTP_HOST
 
 
 #=========================
diff --git a/services/webapp/code/rosetta/core_app/static/css/stylish-portfolio.css b/services/webapp/code/rosetta/core_app/static/css/stylish-portfolio.css
index 7662b3b48c2476f37353e331808633dd58e3bf2c..d666a80f52e503a0a415c9610f8de1bca2269234 100644
--- a/services/webapp/code/rosetta/core_app/static/css/stylish-portfolio.css
+++ b/services/webapp/code/rosetta/core_app/static/css/stylish-portfolio.css
@@ -571,6 +571,27 @@ th, td {
 
 
 
+.description-box { 
+  width: 100%; 
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  margin: 5px;
+  line-height:1.3em;
+  font-size:0.9em
+}
+
+
+.image-version-box { 
+  width: 100%; 
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  margin: 5px;
+  font-size:0.9em
+}
 
 
 
diff --git a/services/webapp/code/rosetta/core_app/templates/add_container.html b/services/webapp/code/rosetta/core_app/templates/add_container.html
index 0e342f0fdb71a9fd212144700ce8829e0f82cf4c..2e833ac493ebd3575783bd20a72574ac8f1c9d12 100644
--- a/services/webapp/code/rosetta/core_app/templates/add_container.html
+++ b/services/webapp/code/rosetta/core_app/templates/add_container.html
@@ -13,14 +13,14 @@
 
       {% if not data.added %}
 
-          <h3>Configure the new container.</h3> 
+          <h3>Set up the new container.</h3> 
           
           <br/>
           
           <form action="#" method="POST">
           {% csrf_token %}
 
-          <table class="dashboard" style="max-width:430px">
+          <table class="dashboard" style="width:360px">
 
            <tr>
             <td><b>Name</b></td>
@@ -28,66 +28,94 @@
              <input type="text" name="container_name" value="" placeholder="" size="23" required />
             </td>
            </tr>
-    
+
            <tr>
-            <td><b>Type</b></td><td>
-              <select name="container_type" >
-              <option value="docker" selected>Docker</option>
-              <option value="singularity">Singularity</option>
-              </select>
+            <td><b>Description</b></td>
+            <td>
+             <!-- ><input type="text" name="container_description" value="" placeholder="" size="23" required /> -->
+             ​<textarea name="container_description" rows="3" cols="22"></textarea>
             </td>
            </tr>
+    
+    
 
            <tr>
             <td><b>Registry</b></td><td>
-              <select name="container_registry" >
-              <option value="docker_hub">Docker Hub</option>
-              <option value="singularity_hub">Singularity Hub</option>
-              </select>
+             <input type="text" name="container_registry" value="docker.io" size="23" required />
             </td>
            </tr>
 
            <tr>
-            <td><b>Image:tag</b></td>
+            <td><b>Image</b></td>
             <td>
              <input type="text" name="container_image" value="" placeholder="" size="23" required />
             </td>
            </tr>
 
            <tr>
-            <td><b>Protocol</b></td>
+            <td><b>Tag</b></td>
+            <td>
+             <input type="text" name="container_tag" value="latest" size="23" required />
+            </td>
+           </tr>
+
+           </table>
+
+          <table class="dashboard" style="width:360px">
+
+           <tr>
+            <td><b>Interface port</b></td>
+             <td><input type="text" name="container_interface_port" value="" placeholder="" size="5" /></td>
+           </tr>
+
+           <tr>
+            <td><b>Interface protocol</b></td>
             <td>
-             <select name="container_protocol" id="cars">
-              <option value="http" selected>http</option>
-              <option value="https">https</option>
-             </select>
+             <input type="text" value="http" name="container_interface_protocol" size="5" /> 
             </td>
            </tr>
+           </table>
    
+            <table class="dashboard" style="width:360px">
+
+           <tr><td colspan=2><hr style="margin:5px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Advanced</td></tr>
+
+
+           <tr>
+            <td><b>Architecture</b></td><td>
+              <select name="container_arch" >
+              <option value="x86_64" selected>x86_64</option>
+              </select>
+            </td>
+           </tr>
+
            <tr>
-            <td colspan=2><b>Default port(s)</b>
-             &nbsp; &nbsp;<input type="text" name="container_ports" value="" placeholder="" size="5" />
+            <td><b>OS</b></td><td>
+              <select name="container_os" >
+              <option value="linux" selected>linux</option>
+              </select>
             </td>
            </tr>
 
            <tr>
-            <td colspan=2>
-             <b>Supports dynamic ports</b> &nbsp; 
-             <input type="checkbox" name="container_supports_dynamic_ports" value="True" />
+            <td><b>interface transport</b></td><td>
+              <select name="container_interface_transport" >
+              <option value="tcp/ip" selected>tcp/ip</option>
+              </select>
             </td>
            </tr>
 
            <tr>
             <td colspan=2>
-             <b>Supports user auth</b> &nbsp; 
-             <input type="checkbox" name="container_supports_user_auth" value="True" />
+             <b>Supports custom interface port</b> &nbsp; 
+             <input type="checkbox" name="container_supports_custom_interface_port" value="True" />
             </td>
            </tr>
 
            <tr>
             <td colspan=2>
-             <b>Supports pass auth</b> &nbsp; 
-             <input type="checkbox" name="container_supports_pass_auth" value="True" />
+             <b>Supports interface auth</b> &nbsp; 
+             <input type="checkbox" name="container_supports_interface_auth" value="True" />
             </td>
            </tr>
 
diff --git a/services/webapp/code/rosetta/core_app/templates/components/computing.html b/services/webapp/code/rosetta/core_app/templates/components/computing.html
index a8e5284a4b30cb397ae50e63cb8f51b67e7ed3eb..f6f647a949d692278ac8954f402bfc9606e518cc 100644
--- a/services/webapp/code/rosetta/core_app/templates/components/computing.html
+++ b/services/webapp/code/rosetta/core_app/templates/components/computing.html
@@ -14,6 +14,11 @@
         <td>{{ data.computing.name }}</td>
        </tr>
 
+       <tr>
+        <td><b>Description</b></td>
+        <td>{{ data.computing.description }}</td>
+       </tr>
+
        <tr>
         <td width="110px"><b>ID</b></td>
         <td>{{ data.computing.id }}</a></td>
@@ -25,8 +30,18 @@
        </tr>
 
        <tr>
-        <td><b>Access method</b></td>
-        <td>{{ data.computing.access_method }}</td>
+        <td><b>Access mode</b></td>
+        <td>{{ data.computing.access_mode }}</td>
+       </tr>
+
+       <tr>
+        <td><b>Auth mode</b></td>
+        <td>{{ data.computing.auth_mode }}</td>
+       </tr>
+
+       <tr>
+        <td><b>WMS</b></td>
+        <td>{{ data.computing.wms }}</td>
        </tr>
 
        <tr>
@@ -44,11 +59,8 @@
        </tr>
 
        <tr>
-        <td><b>Supports</b></td>
-        <td>
-          Docker: {{ data.computing.supports_docker }} <br/>
-          Singularity: {{ data.computing.supports_singularity }}
-        </td>
+        <td><b>Container runtimes</b></td>
+        <td>{{ data.computing.container_runtimes }}</td>
        </tr>
 
        <tr>
@@ -77,22 +89,46 @@
         <!-- <div style="background:{{computing.color}}; height:24px"></div> -->
         
         <div style="padding:10px; margin-top:5px; text-align:center; border-bottom: #e0e0e0 solid 1px; ">
-        <a href="?uuid={{ computing.uuid }}&details=True">{{ computing.name }}</a>
+        <a href="/computings/?uuid={{ computing.uuid }}&details=True">{{ computing.name }}</a>
         </div>
         
         <div style="padding:10px;">
-        <b>Type:</b> {{ computing.type_str }}<br/>
-        <b>Access:</b> {{ computing.access_method_str }}<br/>
+
+        {% if computing.description %} 
+        <div class="description-box" title="{{ computing.description }}">
+        {{ computing.description }}
+        </div>
+        {% else %}
+        <br/>  
+        {% endif %}
+        <div class="image-version-box">
+        <b>Type:</b> {{ computing.type }}<br/>
+        {% if computing.auth_mode == 'user_keys' %}
+        <b>Access:</b> restricted
+        {% else %}
+        <b>Access:</b> open
+        {% endif %}
+        </div>
+        <!-- ><b>Access:</b> {{ computing.access_mode }}<br/> --
         <!-- <b>Owner:</b> {% if computing.user %}{{ computing.user }}{% else %}Platform{% endif %}<br/> -->
-        <b>Supports:</b>
-        {% if computing.supports_docker %}Docker <img src="/static/img/docker-logo.svg" style="height:18px; width:18px; margin-bottom:2px" />{% endif %}
-        {% if computing.supports_singularity %}Singularity <img src="/static/img/singularity-logo.svg" style="height:18px; width:18px; margin-bottom:2px" />{% endif %}
+        <!--  <b>Runtimes:</b> {{ computing.container_runtimes }} -->
+        
+        <!-- {% if 'docker' in computing.container_runtimes %}<img src="/static/img/docker-logo.svg" style="height:18px; width:18px; margin-bottom:2px" />{% endif %}
+        {% if 'singularity' in computing.container_runtimes %}<img src="/static/img/singularity-logo.svg" style="height:18px; width:18px; margin-bottom:2px" />{% endif %}-->
+        {% if container %}
+        <div style="margin:0px; margin-top:2px; text-align:center; padding:5px">
+        <form action="/create_task/" method="POST">
+        {% csrf_token %}
+        <input type="hidden" name="step" value="{{ data.next_step }}" />
+        <input type="hidden" name="task_container_uuid" value="{{container.uuid}}">
+        <input type="hidden" name="task_computing_uuid" value="{{computing.uuid}}">
+        <input type="submit" value="Choose" class="btn btn-connect">
+        </form>
         </div>
+        {% endif %}
         
+        </div>  
 
-      
-      
-      
       </div>
       
 
diff --git a/services/webapp/code/rosetta/core_app/templates/components/container.html b/services/webapp/code/rosetta/core_app/templates/components/container.html
index ccdb78f9b903c5d593ade644f80430161f567057..f5da7c50c8c9f9a8bddb3e9c552d225f52408836 100644
--- a/services/webapp/code/rosetta/core_app/templates/components/container.html
+++ b/services/webapp/code/rosetta/core_app/templates/components/container.html
@@ -2,62 +2,81 @@
 
       {% if details %}      
 
-      <table class="dashboard" style="margin:10px">
+      <table class="dashboard" style="margin:10px; max-width:600px">
         
        <tr>
-        <td colspan="2" style="background:{{ container.color }}; height:15px">
-        </td>
+        <td colspan="2" style="background:{{ container.color }}; height:15px"></td>
        </tr>
 
+       <tr><td colspan=2 style="height:5px"></td></tr>
+
+
        <tr>
         <td><b>Name</b></td>
         <td>{{ container.name }}</td>
        </tr>
 
        <tr>
-        <td><b>ID</b></td>
-        <td>{{ container.id }}</td>
+        <td><b>Owner</b></td>
+        <td>{% if container.user %}{{ container.user }}{% else %}platform{% endif %}</td>
+       </tr>
+
+       <tr>
+        <td><b>Description</b></td>
+        <td>{{ container.description }}</td>
+       </tr>
+
+       <tr><td colspan=2><hr style="margin:5px"></td></tr>
+
+       <tr>
+        <td><b>Registry</b></td>
+        <td>{{ container.registry }}</td>
        </tr>
 
        <tr>
         <td><b>Image</b></td>
-        <td>{{ container.image_name }}</td>
+        <td><code>{{ container.image }}</code></td>
        </tr>
 
        <tr>
-        <td><b>V. tag</b></td>
-        <td>{{ container.image_tag }}</td>
+        <td><b>Tag</b></td>
+        <td>{{ container.tag }}</td>
        </tr>
 
+       <tr><td colspan=2><hr style="margin:5px"></td></tr>
+
        <tr>
-        <td><b>Type</b></td>
-        <td>{{ container.type }}</td>
+        <td><b>Protocol</b></td>
+        <td>{{ container.interface_protocol }}</td>
        </tr>
 
        <tr>
-        <td><b>Owner</b></td>
-        <td>{% if container.user %}{{ container.user }}{% else %}platform{% endif %}</td>
+        <td><b>Port</b></td>
+        <td>{{ container.interface_port }}</td>
        </tr>
 
        <tr>
-        <td><b>Registry</b></td>
-        <td>{{ container.registry }}</td>
+        <td><b>Transport</b></td>
+        <td>{{ container.interface_transport }}</td>
        </tr>
 
        <tr>
-        <td><b>Protocol</b></td>
-        <td>{{ container.protocol }}</td>
+        <td><b>Architecture</b></td>
+        <td>{{ container.arch }}</td>
        </tr>
 
+
        <tr>
-        <td colspan=2><b>Default port(s)</b>
-        &nbsp; &nbsp;{{ container.ports }}</td>
+        <td><b>OS</b></td>
+        <td>{{ container.os }}</td>
        </tr>
 
+       <tr><td colspan=2><hr style="margin:5px"></td></tr>
+
        <tr>
         <td colspan=2>
-         <b>Supports dynamic ports</b> &nbsp; 
-         {% if container.supports_dynamic_ports %}
+         <b>Supports custom interface port</b> &nbsp; 
+         {% if container.supports_custom_interface_port %}
            <input type="checkbox" name="container_supports_user_auth" checked disabled/> 
          {% else %}
            <input type="checkbox" name="container_supports_user_auth" disabled/> 
@@ -67,21 +86,11 @@
 
        <tr>
         <td colspan=2>
-         <b>Supports user auth</b> &nbsp; 
-         {% if container.supports_user_auth %}
-           <input type="checkbox" name="supports_user_auth" checked disabled/> 
-         {% else %}
-           <input type="checkbox" name="supports_user_auth" disabled/> 
-         {% endif %}        </td>
-       </tr>
-
-       <tr>
-        <td colspan=2>
-         <b>Supports pass auth</b> &nbsp; 
-         {% if container.supports_pass_auth %}
-           <input type="checkbox" name="supports_pass_auth" checked disabled/> 
+         <b>Supports interface auth</b> &nbsp; 
+         {% if container.supports_interface_auth %}
+           <input type="checkbox" name="supports_interface_auth" checked disabled/> 
          {% else %}
-           <input type="checkbox" name="supports_pass_auth" disabled/> 
+           <input type="checkbox" name="supports_interface_auth" disabled/> 
          {% endif %}        </td>
        </tr>
 
@@ -101,18 +110,31 @@
 
         
         <div style="padding:10px; margin-top:5px; text-align:center; border-bottom: {{container.color}} solid 10px; ">
-        <a href="?uuid={{ container.uuid }}">{{ container.name }}</a>&nbsp; 
-        {% if container.type == 'docker' %}<img src="/static/img/docker-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %}
-        {% if container.type == 'singularity' %}<img src="/static/img/singularity-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %}
+        <a href="/containers/?uuid={{ container.uuid }}">{{ container.name }}</a>&nbsp; 
         </div>
         
-        <div style="padding:10px; height: 64px; vertical-align: middle;">
-        <b>Image:</b> {{ container.image_name }}<br/>
-        <b>Version:</b> {{ container.image_tag }}
+        <div style="padding:10px; height: 110px; vertical-align: middle; ">
+        
+        {% if container.description %} 
+        <div class="description-box" title="{{ container.description }}">
+        {{ container.description }}
+        </div>
+        {% else %}
+        <br/>  
+        {% endif %}
+        
+        <div class="image-version-box">
+        <!-- <font style="font-family:monospace; font-size:1.2em"></font> -->
+        <b>Image:</b> <code>{{ container.image }}</code><br/>
+        <b>Tag:</b> &nbsp;{{ container.tag }}
+        </div> 
+       
         </div>
         
         <div style="margin-bottom:13px; margin-top: 3px; text-align:center">
+        {% if not disable_play_button %}
         <a href="/create_task?task_container_uuid={{ container.uuid }}&step=two" class="btn btn-light" style="border: #c0c0c0 1px solid">&nbsp;<i class="fa fa-play" style="color:green"></i></a>
+        {% endif %}
         </div>    
       
       
diff --git a/services/webapp/code/rosetta/core_app/templates/components/task.html b/services/webapp/code/rosetta/core_app/templates/components/task.html
index 6ea3bf461e4b8b80fdc2551af54f826e77ecfa15..ccf47d3b06588b5fddda504acfaccab64d1b0221 100644
--- a/services/webapp/code/rosetta/core_app/templates/components/task.html
+++ b/services/webapp/code/rosetta/core_app/templates/components/task.html
@@ -59,9 +59,9 @@
             {% endif %}
             
             <!-- Connect -->
-            {% if task.port %}
+            {% if task.interface_port %}
             {% if task.status == "running" %}
-            <a href="?uuid={{task.uuid}}&action=connect" class="btn btn-connect">Connect</a>
+            <a href="/task_connect/?uuid={{task.uuid}}" class="btn btn-connect">Connect</a>
             {% else %}
             <a href="" class="btn btn-disabled">Connect</a>  
             {% endif %}
@@ -140,19 +140,19 @@
            
            <tr>
             <td><b>Tunnel port</b></td>
-            <td>{{ task.tunnel_port }}</td>
+            <td>{{ task.tcp_tunnel_port }}</td>
            </tr>
 
-           {% if task.auth_pass %}
+           {% if task.auth_token %}
            <tr>
-            <td><b>Auth pass</b></td>
-            <td>******</td>
+            <td><b>Auth token</b></td>
+            <td>{{ task.auth_token }}</td>
            </tr>
            {% endif %}
 
-           <tr>
-            <td style="padding-right:0"><b>Direct link</b>
-            <td>{% if task.status == "running" %}<a href="{{ task.direct_link }}">{{ task.direct_link }}</a>{% else %}N.A. (task not running) {% endif %}</td>
+
+            <td style="padding-right:0"><b>Sharable link</b>
+            <td>{% if task.status == "running" %}<a href="{{ task.sharable_link }}">{{ task.sharable_link }}</a>{% else %}N.A. (task not running) {% endif %}</td>
            </tr>
 
 
diff --git a/services/webapp/code/rosetta/core_app/templates/containers.html b/services/webapp/code/rosetta/core_app/templates/containers.html
index 98c78a233ab76320f4ecf1a5ba00724605362671..5623e54bb5177aa6b9dbbae6009aa97fdb1d749e 100644
--- a/services/webapp/code/rosetta/core_app/templates/containers.html
+++ b/services/webapp/code/rosetta/core_app/templates/containers.html
@@ -15,7 +15,7 @@
       {% if data.mode == 'new_task' %}
       <h1>New Task</h1>
       <hr/>
-      <h3>Step 1: choose software container.</h3>
+      <div style="padding-left:10px; padding-top:1px"><h4>Software container</h4></div>
       <br/> 
       {% else %}
       <h1>Software Containers</h1>
@@ -32,24 +32,25 @@
                     
           <input type="text" class="form-control" id="search_text" name="search_text" placeholder="Search..." style="width:200px; margin:0; display:inline" value="{{data.search_text}}" autofocus>
 
-          <select class="form-control" id="search_type" name="search_type" style="width:120px; margin:0; display:inline">
+          <!-- onchange="this.form.submit()"  -->
+          <select class="form-control" id="search_owner" name="search_owner" style="width:120px; margin:0; display:inline">
             
-            {% if data.search_type == 'All' %}
+            {% if data.search_owner == 'All' %}
             <option selected>All</option>
             {% else %}
             <option>All</option>            
             {% endif %}
             
-            {% if data.search_type == 'Docker' %}
-            <option selected>Docker</option>
+            {% if data.search_owner == 'Platform' %}
+            <option selected>Platform</option>
             {% else %}
-            <option>Docker</option>            
+            <option>Platform</option>            
             {% endif %}
             
-            {% if data.search_type == 'Singularity' %}
-            <option selected>Singularity</option>
+            {% if data.search_owner == 'User' %}
+            <option selected>User</option>
             {% else %}
-            <option>Singularity</option>            
+            <option>User</option>            
             {% endif %}
             
           </select>
diff --git a/services/webapp/code/rosetta/core_app/templates/create_task.html b/services/webapp/code/rosetta/core_app/templates/create_task.html
index 49619923584751b63ad4b2be54571456c165762d..1ece6bd59f7579a41b1c9aa861fca594bbb9d067 100644
--- a/services/webapp/code/rosetta/core_app/templates/create_task.html
+++ b/services/webapp/code/rosetta/core_app/templates/create_task.html
@@ -12,80 +12,50 @@
       <hr>
 
 
-      {% if data.step == 'two' %} 
-      <h3>Step 2: set task name and computing.</h3> 
+      <!-- {% if data.step == 'two' %} 
+      <h3>Choose computing resource</h3> 
       {% elif data.step == 'three' %}  
-      <h3>Step 3: add authentication and computing details.</h3>    
+      <h3>Task details and confirm</h3>    
       {% endif %}
 
-      <br/>
+      <br/> -->
 
       {% if data.step != 'created' %}
-      <div style="width:300px; float:left; border: #e0e0e0 solid 1px; margin:10px; background:#f8f8f8; margin-bottom:15px">
-        <div style="padding:10px; margin-top:5px; text-align:center; border-bottom: {{data.task_container.color}} solid 10px; ">
-        <a href="?uuid={{ container.uuid }}">{{ data.task_container.name }}</a>&nbsp; 
-        {% if data.task_container.type == 'docker' %}<img src="/static/img/docker-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %}
-        {% if data.task_container.type == 'singularity' %}<img src="/static/img/singularity-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %}
-        </div>  
-        <div style="padding:10px; height: 64px; vertical-align: middle;">
-        <b>Image:</b> {{ data.task_container.image_name }}<br/>
-        <b>Version:</b> {{ data.task_container.image_tag }}
-        </div>
+      <div style="float:left; background:#ffffff; margin-left:10px; margin-right:10px; margin-top:0px; margin-bottom:20px">
+          <h4>Software container</h4>
+          <div class="row" style="padding:5px">
+          {% include "components/container.html" with container=data.task_container disable_play_button=True %}
+          </div>
       </div>
       {% endif %}
+      
 
       {% if data.step == 'two' %}
 
-          <form action="/create_task/" method="POST">
-          {% csrf_token %}
-          <input type="hidden" name="step" value="{{ data.next_step }}" />
-          <input type="hidden" name="task_container_uuid" value="{{data.task_container.uuid}}">
+      <div style="width:300px; float:left; background:#ffffff; margin-left:10px; margin-right:10px; margin-top:0px; margin-bottom:0px">
+          <h4>Computing resource</h4>
+          <div class="row" style="padding:5px">
+          {% for computing in data.computings %}
+          {% include "components/computing.html" with container=data.task_container %}
+          {% endfor %}
+          </div>
+      </div>
 
-      <div style="width:300px; float:left; border: #e0e0e0 solid 0px; margin:10px; background:#f8f8f8; margin-bottom:15px">
 
-          <table style="max-width:100%; border: #e0e0e0 solid 1px; margin:0">
-          <tr><td colspan="2"></td></tr>
+      {% elif data.step == 'three' %}
 
-           <tr>
-            <td><b>Task name </b></td>
-            <td>
-             <input type="text" name="task_name" value="" placeholder="" size="" required />
-            </td>
-           </tr>
 
-           <tr>
-            <td><b>Computing</b></td><td>
-              <select name="task_computing_uuid" >
-              {% for computing in data.computings %}}
-              <option value="{{ computing.uuid }}">{{ computing.name}}</option>
-              {% endfor %}
-              </select>
-            </td>
-           </tr>
-
-           <tr>
-           <td colspan=2 align=center style="padding:9px">
-           <input type="submit" value="Next">
-           </td>
-           </tr>
-          </table>
+      <div style="width:300px; float:left; background:#ffffff; margin-left:10px; margin-right:10px; margin-top:0px; margin-bottom:0px">
+          <h4>Computing resource</h4>
+          <div class="row" style="padding:5px">
+          {% include "components/computing.html" with computing=data.task_computing %}
           </div>
-          </form>
-
-      {% elif data.step == 'three' %}
+      </div>
           
           
-          <div style="width:300px; float:left; border: #e0e0e0 solid 0px; margin:10px; background:#f8f8f8; margin-bottom:15px">
+          <!-- <div style="width:300px; float:left; border: #e0e0e0 solid 0px; margin:10px; background:#f8f8f8; margin-bottom:15px">
           <table style="width:100%; height:126px;  border: #e0e0e0 solid 1px; margin:0">
 
-           <tr valign="bottom">
-            <td><b>Task name </b></td>
-            <td>
-             <input type="text" name="task_name_RECAP" value="{{ data.task_name }}" placeholder="" size="" disabled />
-            </td>
-           </tr>
-
-           
            <tr valign="top">
             <td><b>Computing</b></td><td>
               <select name="task_computing_uuid_RECAP" >
@@ -95,11 +65,15 @@
            </tr>
 
           </table>
-          </div>
-          
+          </div> -->
+
+      <div style="width:300px;  background:#ffffff; margin-left:10px; margin-right:10px; margin-top:10px; margin-bottom:0px">
+
+          <h4>Options and confirm</h4>
           <div style="width:640px; float:left; border: #e0e0e0 solid 0px; margin:10px; background:#f8f8f8; margin-bottom:15px">
-          
-          {% if data.task_container.type == 'singularity' and not data.task_container.supports_dynamic_ports %}
+              
+
+          {% if data.task_container.type == 'singularity' and not data.task_container.supports_custom_interface_port %}
           <div> <p style="font-size:15px; max-width:700px; margin-bottom:20px; margin-left:5px">
           <i class="fa fa-exclamation-triangle" style="color:orange"></i> This container does not support dynamic ports and you are running it with Singularity, without network insulation. This means that if the container port is already occupied, it will not be able to start.
           </p></div>
@@ -130,7 +104,7 @@
            </tr>
            {% endif %}
 
-           {% if data.task_container.supports_dynamic_ports and data.task_computing.type == 'remotehop' %}
+           {% if data.task_container.supports_custom_interface_port and data.task_computing.type == 'remotehop' %}
            <tr>
             <td valign="top" style="width:180px"><b>Set custom port </b></td>
             <td>
@@ -140,12 +114,36 @@
            </tr>
            {% endif %}
 
-           {% if data.task_container.supports_pass_auth %}
+           {% if data.task_container.supports_interface_auth %}
+           
+           <tr>
+            <td valign="top"><b>Task name</b></td>
+            <td><input type="text" name="task_name" value="" placeholder="" size="" required /></td>
+           </tr>
+           
            <tr>
-            <td valign="top"><b>Set task password</b></td>
+            <td valign="top"><b>Task password</b></td>
             <td>
-             <input type="password" name="auth_password" value="" placeholder="" size="23" /><br>
-             <font size=-1>Use a non-sensitive password as it will be stored in plain text. 6 chars min.</font>
+            
+             <input type="password" name="task_auth_password" placeholder="{{data.task_auth_token}}" size="23" /><br>
+             <input type="hidden" name="task_auth_token" value="{{data.task_auth_token}}">
+
+             <!-- IF NOT USING HTTP PROTOCOL: -->
+             <!-- <font size=-1>Use a non-sensitive password as it will be stored in plain text. 6 chars min.</font> -->
+             <!--  !!!!!!!!!!!
+             
+             Non serve differenziare, lascia che venga generato un token anche dove la pass deve essere immessa nel task (i.e. VNC ma
+             non con la password a soli 6 caratteri, ssh è buon esempio). Metti il mneu advances che si apre.
+             
+             Vedi: https://superuser.com/questions/493583/how-to-connect-to-ssh-with-character-in-username
+             
+             
+             -->
+             <font size=-1>A one-time task password. By default set to a randomly generated token, and automatically handled by Rosetta. Can be also set to a custom one, which in this case will be required to be entered manually when connecting to the task (as it will not be stored by Rosetta). Six characters minimum.</font>
+             
+             <!-- f not set, Rosetta will generate a random token and automatically feed it to the task when you connect. use Use a non-sensitive password as it will be stored in plain text. 6 chars min.</font> -->
+             <!--  TODO: do the /connect with the redirect thing  -->
+             
             </td>
            </tr>
            {% endif %}
@@ -156,7 +154,7 @@
             <td valign="top" style="width:180px"><b>Extra binds</b></td>
             <td>
              <input type="text" name="extra_binds" value="" placeholder="" size="40" /><br>
-             <p style="line-height: 0.95"><font size=-1>Here you can set extra binds on top of the ones already define by the administrator. Format is <i>host_directory:container_directory</i>, comma separated.</font></p>
+<p style="line-height: 0.95"><font size=-1>For this computing resource, you can set extra FS binds on top of the ones already define by the administrators. Format is <i>host_directory:container_directory</i>, comma separated.</font></p>
             </td>
            </tr>
            {% endif %}
@@ -195,19 +193,20 @@
              
            <tr><td colspan=2>
            <table><tr><td  style="border: 1px solid lightgray;" >
-           I understand that files saved or modified in this container, if not explicitly saved to a persistent bind, will be LOST when the task ends.
+           I understand that files saved or modified in this container, if not explicitly saved to a persistent storage, will be LOST when the task ends.
            </td><td  style="border: 1px solid lightgray;" >
            <input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
            </td></table>
            </td></tr>
            <tr>
            <td colspan=2 align=center style="padding:20px">
-           <input type="submit" value="Create">
+           <input type="submit" value="Create task">
            </td>
            </tr>
           </table>
           </form>
           </div>
+      </div>
 
 
       {% else %}
@@ -216,17 +215,17 @@
 
       {% endif %} 
   
+
+      
+    </div>
+  </div>
+</div>
       <br/>
       <br/>
       <br/>
       <br/>
       <br/>
       <br/>
-      
-    </div>
-  </div>
-</div>
-
 {% include "footer.html" %}
 
 
diff --git a/services/webapp/code/rosetta/core_app/templates/header.html b/services/webapp/code/rosetta/core_app/templates/header.html
index 6d82d4959fa0a3ea0b1d71d2065a126181d3097a..46dc332be2c73b1d07c06ede73972f34dba44848 100644
--- a/services/webapp/code/rosetta/core_app/templates/header.html
+++ b/services/webapp/code/rosetta/core_app/templates/header.html
@@ -57,5 +57,5 @@
 
 </head>
 
-<body {{ onload }}>
+<body {{ body_args }}>
   
\ No newline at end of file
diff --git a/services/webapp/code/rosetta/core_app/templates/login.html b/services/webapp/code/rosetta/core_app/templates/login.html
index f61a66a8c6749dc605795b747bd045463a1629d4..6bd98f946014f06b8dd28d3d8e1a66b2ce70393e 100644
--- a/services/webapp/code/rosetta/core_app/templates/login.html
+++ b/services/webapp/code/rosetta/core_app/templates/login.html
@@ -1,5 +1,5 @@
 {% load static %} 
-{% include "header.html" with onload="onload='init()'" use_bg=True  %}
+{% include "header.html" %}
 {% include "navigation.html"%}
 
     <center>
@@ -19,7 +19,7 @@
         
 
         <div style="margin-top:25px; margin-bottom:15px">
-        <font color="#a9a9a9"> — OR —</font>
+        {% if OPENID_ENABLED %}<font color="#a9a9a9"> — OR —</font>{% endif %}
         </div>
         
         {% if OPENID_ENABLED %}
diff --git a/services/webapp/code/rosetta/core_app/templates/main.html b/services/webapp/code/rosetta/core_app/templates/main.html
index ecdc2e396b297d07cbb2dc6213d166e7bf41721b..b134900b8ce969187999b72a9f037206a6abee9b 100644
--- a/services/webapp/code/rosetta/core_app/templates/main.html
+++ b/services/webapp/code/rosetta/core_app/templates/main.html
@@ -1,5 +1,5 @@
 {% load static %} 
-{% include "header.html" with onload="onload=''" use_bg=True  %}
+{% include "header.html" %}
 {% include "navigation.html"%}
 
     <!-- Header -->
diff --git a/services/webapp/code/rosetta/core_app/templates/navigation.html b/services/webapp/code/rosetta/core_app/templates/navigation.html
index cf6829d7b80daf1d704d1ba753ece7b59d0e41b0..f55251056ff62ee8d2a2119ebe919bd5ab4831a1 100644
--- a/services/webapp/code/rosetta/core_app/templates/navigation.html
+++ b/services/webapp/code/rosetta/core_app/templates/navigation.html
@@ -16,9 +16,7 @@
             <hr style="margin-top:10px; margin-bottom:20px; margin-left:10px; margin-right:10px">
 
             {% if user.is_authenticated %}
-            <li>
-                <a href="/account" onclick = $("#menu-close").click(); >Account</a>
-            </li>        
+    
             <li>
                 <a href="/containers" onclick = $("#menu-close").click(); >Software</a>
             </li>
@@ -31,7 +29,9 @@
             <li>
                 <a href="/files" onclick = $("#menu-close").click(); >Files</a>
             </li>
-       
+            <li>
+                <a href="/account" onclick = $("#menu-close").click(); >Account</a>
+            </li>           
             {% else %}
             <li>
               <center>
diff --git a/services/webapp/code/rosetta/core_app/templates/task_connect.html b/services/webapp/code/rosetta/core_app/templates/task_connect.html
new file mode 100644
index 0000000000000000000000000000000000000000..4dc1290d9ab40b0e8f6d3a083a02bba10b66eabc
--- /dev/null
+++ b/services/webapp/code/rosetta/core_app/templates/task_connect.html
@@ -0,0 +1,80 @@
+{% load static %} 
+{% include "header.html" %}
+{% include "navigation.html"%}
+<!-- with body_args="style='background: #202020'" -->
+    <center>
+    <div style="width:300px;">
+      <form class="form-signin" role="form" action='/direct_connect/{{data.task.uuid}}/' method='POST'>
+        {% csrf_token %}
+        <br />
+        <br />
+        <br />
+        <!-- <h1>Rosetta <img src="/static/img/emoji_u1f6f0.png" style="height:84px; width:64px; padding-bottom:20px"></h1> -->
+        <h2> Connecting to task <b>{{ data.task.name }}</b></h2>
+        <p style="font-size: 16px;">
+        <br />
+        User: <input style="margin-bottom:5px;" type="username" class="form-control" value="{{ request.user.email }}"name='username' disabled >
+        
+        
+        {% if data.task.requires_proxy_auth %}
+        
+          {% if data.task.auth_token %}
+          Password: <input type="text" class="form-control" placeholder="" value="{{data.task.auth_token}}" name='password' disabled>
+          {% else %}
+          Password: <input type="password" class="form-control" placeholder="" value="placeholder" name='password' disabled>
+          <p style="margin-left:10px; font-size:0.9em; color:#484848">
+          <i class="fa fa-info-circle" style="color:#337ab7"></i>
+          This task will require manually entering the password set up when creating the task
+          </p> 
+          {% endif %}
+                 
+        {% else %}
+        
+          {% if data.task.auth_token %}
+          Password: <input type="text" class="form-control" placeholder="" value="{{data.task.auth_token}}" name='password' disabled>
+          <p style="margin-left:10px; font-size:0.9em; color:#484848">
+          <i class="fa fa-info-circle" style="color:#337ab7"></i>
+          This task will require manually entering the password token automatically generated when creating the task
+          </p> 
+          {% else %}
+          Password: <input type="password" class="form-control" placeholder="" value="placeholder" name='password' disabled>
+          <p style="margin-left:10px; font-size:0.9em; color:#484848">
+          <i class="fa fa-info-circle" style="color:#337ab7"></i>
+          This task will require manually entering the password set up when creating the task
+          </p> 
+          {% endif %}
+          
+        {% endif %}
+        
+        <br />
+        
+        
+        {% if data.task.container.interface_protocol == 'http' or data.task.container.interface_protocol == 'https' %}       
+        <input type='submit' style="width:110px" class="btn btn-lg btn-success btn-block" value='Log in' />
+        {% else %}
+        To connect, open the program suitable for this task interface protocol ({{data.task.container.interface_protocol}}) with:<br />
+        IP: <code>{{ data.task.tcp_tunnel_host}}</code><br />
+        Port: <code>{{ data.task.tcp_tunnel_port}}</code>
+        {% endif %}
+        
+        
+        </p>
+        
+      </form>      
+    </div>
+    <br /><br />
+    
+    {% if data.task.requires_proxy_auth %}
+    <p style="margin-left:10px; font-size:0.9em; color:rgb(200,200,200); max-width:600px">
+    <i class="fa fa-info-warning" style="color:#337ab7"></i>
+    Some web browsers (i.e. Safari) might require to manually re-enter the above user credentials. You can copy-paste them, or switch
+    to a web browser which supports embedding user credentials in the connection URL (as Chorme, Edge or Firefox). 
+    </p>
+    {% endif %}
+    <br /><br /><br />
+    </center>
+
+
+
+
+{% include "footer.html" %}
diff --git a/services/webapp/code/rosetta/core_app/utils.py b/services/webapp/code/rosetta/core_app/utils.py
index 71931ed9104414a299e09203ad40f49392983082..afba4a7e7d79bd2de781e196e1796578a95638ee 100644
--- a/services/webapp/code/rosetta/core_app/utils.py
+++ b/services/webapp/code/rosetta/core_app/utils.py
@@ -527,30 +527,30 @@ def setup_tunnel(task):
     from .models import Task, KeyPair, TaskStatuses
     
     # If there is no tunnel port allocated yet, find one
-    if not task.tunnel_port:
+    if not task.tcp_tunnel_port:
 
         # Get a free port fot the tunnel:
-        allocated_tunnel_ports = []
+        allocated_tcp_tunnel_ports = []
         for other_task in Task.objects.all():
-            if other_task.tunnel_port and not other_task.status in [TaskStatuses.exited, TaskStatuses.stopped]:
-                allocated_tunnel_ports.append(other_task.tunnel_port)
+            if other_task.tcp_tunnel_port and not other_task.status in [TaskStatuses.exited, TaskStatuses.stopped]:
+                allocated_tcp_tunnel_ports.append(other_task.tcp_tunnel_port)
 
         for port in range(7000, 7021):
-            if not port in allocated_tunnel_ports:
-                tunnel_port = port
+            if not port in allocated_tcp_tunnel_ports:
+                tcp_tunnel_port = port
                 break
-        if not tunnel_port:
+        if not tcp_tunnel_port:
             logger.error('Cannot find a free port for the tunnel for task "{}"'.format(task))
             raise ErrorMessage('Cannot find a free port for the tunnel to the task')
 
-        task.tunnel_port = tunnel_port
+        task.tcp_tunnel_port = tcp_tunnel_port
         task.save()
 
 
     # Check if the tunnel is active and if not create it
     logger.debug('Checking if task "{}" has a running tunnel'.format(task))
 
-    out = os_shell('ps -ef | grep ":{}:{}:{}" | grep -v grep'.format(task.tunnel_port, task.ip, task.port), capture=True)
+    out = os_shell('ps -ef | grep ":{}:{}:{}" | grep -v grep'.format(task.tcp_tunnel_port, task.interface_ip, task.interface_port), capture=True)
 
     if out.exit_code == 0:
         logger.debug('Task "{}" has a running tunnel, using it'.format(task))
@@ -571,10 +571,10 @@ def setup_tunnel(task):
             #setup_command = task.computing.conf.get('setup_command')
             #base_port = task.computing.conf.get('base_port')
                      
-            tunnel_command= 'ssh -4 -i {} -o StrictHostKeyChecking=no -nNT -L 0.0.0.0:{}:{}:{} {}@{} & '.format(user_keys.private_key_file, task.tunnel_port, task.ip, task.port, first_user, first_host)
+            tunnel_command= 'ssh -4 -i {} -o StrictHostKeyChecking=no -nNT -L 0.0.0.0:{}:{}:{} {}@{} & '.format(user_keys.private_key_file, task.tcp_tunnel_port, task.interface_ip, task.interface_port, first_user, first_host)
 
         else:
-            tunnel_command= 'ssh -4 -o StrictHostKeyChecking=no -nNT -L 0.0.0.0:{}:{}:{} localhost & '.format(task.tunnel_port, task.ip, task.port)
+            tunnel_command= 'ssh -4 -o StrictHostKeyChecking=no -nNT -L 0.0.0.0:{}:{}:{} localhost & '.format(task.tcp_tunnel_port, task.interface_ip, task.interface_port)
         
         background_tunnel_command = 'nohup {} >/dev/null 2>&1 &'.format(tunnel_command)
 
diff --git a/services/webapp/code/rosetta/core_app/views.py b/services/webapp/code/rosetta/core_app/views.py
index 067bd8ef88275af7e015c3e8ac77c7c05c1d0e34..360114c5674e5e8591801fc37b2a67b00af0422b 100644
--- a/services/webapp/code/rosetta/core_app/views.py
+++ b/services/webapp/code/rosetta/core_app/views.py
@@ -8,6 +8,7 @@ from django.contrib.auth import authenticate, login, logout
 from django.http import HttpResponse, HttpResponseRedirect
 from django.contrib.auth.models import User
 from django.shortcuts import redirect
+from django.db.models import Q
 from .models import Profile, LoginToken, Task, TaskStatuses, Container, Computing, KeyPair, ComputingSysConf, ComputingUserConf, Text
 from .utils import send_email, format_exception, timezonize, os_shell, booleanize, debug_param, get_tunnel_host, random_username, setup_tunnel, finalize_user_creation
 from .decorators import public_view, private_view
@@ -17,10 +18,6 @@ from .exceptions import ErrorMessage
 import logging
 logger = logging.getLogger(__name__)
 
-# Conf
-SUPPORTED_CONTAINER_TYPES = ['docker', 'singularity']
-SUPPORTED_REGISTRIES = ['docker_hub', 'singularity_hub'] # Registry "docker_local" is also supported but must be set manually
-UNSUPPORTED_TYPES_VS_REGISTRIES = ['docker:singularity_hub']
 
 # Task cache
 _task_cache = {}
@@ -348,7 +345,7 @@ def tasks(request):
 
                 # Then, redirect to the task through the tunnel
                 tunnel_host = get_tunnel_host()
-                return redirect('{}://{}:{}'.format(task.container.protocol, tunnel_host, task.tunnel_port))
+                return redirect('{}://{}:{}'.format(task.container.interface_protocol, tunnel_host, task.tcp_tunnel_port))
 
         except Exception as e:
             data['error'] = 'Error in getting the task or performing the required action'
@@ -467,9 +464,8 @@ def create_task(request):
 
         # Get computing resource
         data['task_computing'] = get_task_computing(request)
-
-        # Get task name
-        data['task_name'] = get_task_name(request)
+        
+        data['task_auth_token'] = str(uuid.uuid4())
 
         # Set current and next step
         data['step'] = 'three'
@@ -499,17 +495,23 @@ def create_task(request):
                     computing = data['task_computing'])
 
         # Add auth
-        task.auth_user     = request.POST.get('auth_user', None)
-        task.auth_pass     = request.POST.get('auth_password', None)
-        task.access_method = request.POST.get('access_method', None)
-        task_base_port     = request.POST.get('task_base_port', None)
-        
-        if task_base_port:
-            task.port = task_base_port
+        task_auth_password = request.POST.get('task_auth_password', None)
+        task_auth_token = request.POST.get('task_auth_token', None)
+        if task_auth_password:
+            if task_auth_password != task_auth_token: # Just an extra check probably not much useful
+                if not task_auth_password:
+                    raise ErrorMessage('No task password set')
+                if len(task_auth_password) < 6:
+                    raise ErrorMessage('Task password must be at least 6 chars')
+                task.password = task_auth_password # Not stored in the ORM model, just a temporary var.
+        else:
+            task.auth_token = task_auth_token # This is saved on the ORM model
+            task.password = task_auth_token # Not stored
         
-        # Checks
-        if task.auth_pass and len(task.auth_pass) < 6:
-            raise ErrorMessage('Task password must be at least 6 chars') 
+        # Hardcoded for now
+        task.requires_tcp_tunnel = True
+        task.requires_proxy      = False
+        task.requires_proxy_auth = False
         
         # Computing options # TODO: This is hardcoded thinking about Slurm and Singularity
         computing_cpus = request.POST.get('computing_cpus', None)
@@ -538,7 +540,7 @@ def create_task(request):
         task.computing.attach_user_conf(task.user)
 
         # Set port if not dynamic ports
-        if not task.container.supports_dynamic_ports:
+        if not task.container.supports_custom_interface_port:
             if task.container.ports:
                 task.port = task.container.port
     
@@ -629,11 +631,11 @@ def containers(request):
 
     # Get filter/search if any
     search_text   = request.POST.get('search_text', '')
-    search_type = request.POST.get('search_type', 'All')
+    search_owner  = request.POST.get('search_owner', 'All')
 
     # Set back to page data
-    data['search_type'] = search_type
-    data['search_text'] = search_text
+    data['search_owner'] = search_owner
+    data['search_text']  = search_text
 
     # Are we using this page as first step of a new task?
     data['mode'] = request.GET.get('mode', None)
@@ -660,6 +662,9 @@ def containers(request):
 
                 # Delete
                 container.delete()
+                
+                # Redirect
+                return HttpResponseRedirect('/containers')
 
         except Exception as e:
             data['error'] = 'Error in getting the container or performing the required action'
@@ -667,24 +672,22 @@ def containers(request):
             return render(request, 'error.html', {'data': data})
 
 
-    # Get containers for list
-    if search_type and search_type != 'All':
-        if search_text:
-            user_containers = Container.objects.filter(user=None, type=search_type.lower(), name__icontains=search_text)
-            platform_containers = Container.objects.filter(user=request.user, type=search_type.lower(), name__icontains=search_text)
-        else:
-            user_containers = Container.objects.filter(user=None, type=search_type.lower())
-            platform_containers = Container.objects.filter(user=request.user, type=search_type.lower())
-                    
+    # Get containers (fitered by search term, or all)
+    if search_text:
+        search_query=(Q(name__icontains=search_text) | Q(description__icontains=search_text) | Q(image__icontains=search_text))
+        user_containers = Container.objects.filter(search_query, user=request.user)
+        platform_containers = Container.objects.filter(search_query, user=None)
     else:
-        if search_text:
-            user_containers = Container.objects.filter(user=None, name__icontains=search_text)
-            platform_containers = Container.objects.filter(user=request.user, name__icontains=search_text)        
-        else:
-            user_containers = Container.objects.filter(user=None)
-            platform_containers = Container.objects.filter(user=request.user)
-                    
+        user_containers = Container.objects.filter(user=request.user)
+        platform_containers = Container.objects.filter(user=None)
     
+    # Filter by owner
+    if search_owner != 'All':
+        if search_owner == 'User':
+            platform_containers =[]
+        if search_owner == 'Platform':
+            user_containers = []
+
     data['containers'] = list(user_containers) + list(platform_containers)
 
     return render(request, 'containers.html', {'data': data})
@@ -704,78 +707,73 @@ def add_container(request):
     data['profile'] = Profile.objects.get(user=request.user)
     data['title']   = 'Add container'
 
-    # Container image if any
-    container_image = request.POST.get('container_image',None)
+    # Container name if setting up a new container
+    container_name = request.POST.get('container_name', None)
 
-    if container_image:
+    if container_name:
 
-        # Container type
-        container_type = request.POST.get('container_type', None)
-        if not container_type:
-            raise ErrorMessage('No container type given')
-        if not container_type in SUPPORTED_CONTAINER_TYPES:
-            raise ErrorMessage('No valid container type, got "{}"'.format(container_type))
+        # Container description
+        container_description = request.POST.get('container_description', None)
 
         # Container registry
         container_registry = request.POST.get('container_registry', None)
-        if not container_registry:
-            raise ErrorMessage('No registry type given')
-        if not container_registry in SUPPORTED_REGISTRIES:
-            raise ErrorMessage('No valid container registry, got "{}"'.format(container_registry))
 
-        # Check container type vs container registry compatibility
-        if container_type+':'+container_registry in UNSUPPORTED_TYPES_VS_REGISTRIES:
-            raise ErrorMessage('Sorry, container type "{}" is not compatible with registry type "{}"'.format(container_type, container_registry))
+        # Container image
+        container_image = request.POST.get('container_image',None)
+        
+        # Container tag
+        container_tag = request.POST.get('container_tag', None)
 
-        # Container name
-        container_name = request.POST.get('container_name', None)
+        # Container architecture
+        container_arch = request.POST.get('container_arch')
 
-        # Container protocol 
-        container_protocol = request.POST.get('container_protocol')
+        # Container operating system
+        container_os = request.POST.get('container_os')
 
-        # Container service ports. TODO: support multiple ports? 
-        container_ports = request.POST.get('container_ports', None)
-        
-        if container_ports:       
+        # Container interface port
+        container_interface_port = request.POST.get('container_interface_port', None) 
+        if container_interface_port:       
             try:
-                for container_service_port in container_ports.split(','):
-                    int(container_service_port)
+                int(container_interface_port)
             except:
-                raise ErrorMessage('Invalid container port(s) in "{}"'.format(container_ports))
-        # Capabilities
-        container_supports_dynamic_ports = request.POST.get('container_supports_dynamic_ports', None)
-        if container_supports_dynamic_ports and container_supports_dynamic_ports == 'True':
-            container_supports_dynamic_ports = True
-        else:
-            container_supports_dynamic_ports = False
+                raise ErrorMessage('Invalid container port "{}"')
 
-        container_supports_user_auth = request.POST.get('container_supports_user_auth', None)
-        if container_supports_user_auth and container_supports_user_auth == 'True':
-            container_supports_user_auth = True
+        # Container interface protocol 
+        container_interface_protocol = request.POST.get('container_interface_protocol')
+
+        # Container interface transport 
+        container_interface_transport = request.POST.get('container_interface_transport')
+        logger.critical('Creating with desc={}, transp={}'.format(container_description, container_interface_transport))
+        # Capabilities
+        container_supports_custom_interface_port = request.POST.get('container_supports_custom_interface_port', None)
+        if container_supports_custom_interface_port and container_supports_custom_interface_port == 'True':
+            container_supports_custom_interface_port = True
         else:
-            container_supports_user_auth = False
+            container_supports_custom_interface_port = False
 
-        container_supports_pass_auth = request.POST.get('container_supports_pass_auth', None)
-        if container_supports_pass_auth and container_supports_pass_auth == 'True':
+        container_supports_interface_auth = request.POST.get('container_supports_interface_auth', None)
+        if container_supports_interface_auth and container_supports_interface_auth == 'True':
             container_supports_pass_auth = True
         else:
             container_supports_pass_auth = False
 
         # Log
-        logger.debug('Creating new container object with image="{}", type="{}", registry="{}", ports="{}"'.format(container_image, container_type, container_registry, container_ports))
+        #logger.debug('Creating new container object with image="{}", type="{}", registry="{}", ports="{}"'.format(container_image, container_type, container_registry, container_ports))
 
         # Create
-        Container.objects.create(user     = request.user,
-                                 image    = container_image,
-                                 name     = container_name,
-                                 type     = container_type,
-                                 registry = container_registry,
-                                 protocol = container_protocol,
-                                 ports    = container_ports,
-                                 supports_dynamic_ports = container_supports_dynamic_ports,
-                                 supports_user_auth     = container_supports_user_auth,
-                                 supports_pass_auth     = container_supports_pass_auth,
-                                 )
+        Container.objects.create(user        = request.user,
+                                 name        = container_name,
+                                 description = container_description,
+                                 registry    = container_registry,
+                                 image       = container_image,
+                                 tag         = container_tag,
+                                 arch        = container_arch,
+                                 os          = container_os,
+                                 interface_port      = container_interface_port,
+                                 interface_protocol  = container_interface_protocol,
+                                 interface_transport = container_interface_transport,
+                                 supports_custom_interface_port = container_supports_custom_interface_port,
+                                 supports_interface_auth = container_supports_pass_auth)
         # Set added switch
         data['added'] = True
 
@@ -938,23 +936,79 @@ def edit_computing_conf(request):
     return render(request, 'edit_computing_conf.html', {'data': data})
 
 
-
 #=========================
-#  Sharable link handler
+#  Task connect
 #=========================
 
-@public_view
-def sharable_link_handler(request, id):
+@private_view
+def task_connect(request):
+
+    task_uuid = request.GET.get('uuid', None)
+    if not task_uuid:
+        raise ErrorMessage('Empty task uuid')
+
+
+    # Get the task     
+    #task = Task.objects.get(uuid__startswith=short_uuid)
+    task = Task.objects.get(uuid=task_uuid)
+    
+    if task.user != request.user:
+        raise ErrorMessage('You do not have access to this task.')
+    
+    data ={}
+    data['task'] = task
+    
+    return render(request, 'task_connect.html', {'data': data})
+
+
+#===========================
+# Direct connection handler
+#===========================
+
+@private_view
+def direct_connection_handler(request, uuid):
 
     # Get the task     
-    task = Task.objects.get(uuid__startswith=id)
+    #task = Task.objects.get(uuid__startswith=short_uuid)
+    task = Task.objects.get(uuid=uuid)
+
+    if task.user != request.user:
+        raise ErrorMessage('You do not have access to this task.')
 
     # First ensure that the tunnel is setu up
     setup_tunnel(task)
 
     # Then, redirect to the task through the tunnel
     tunnel_host = get_tunnel_host()
-    return redirect('{}://{}:{}'.format(task.container.protocol, tunnel_host,task.tunnel_port))
+    if task.requires_proxy_auth and task.auth_token:
+        user = request.user.email
+        password = task.auth_token
+        return redirect('{}://{}:{}@{}:{}'.format(task.container.interface_protocol, user, password, tunnel_host, task.tcp_tunnel_port))
+    else:
+        return redirect('{}://{}:{}'.format(task.container.interface_protocol, tunnel_host,task.tcp_tunnel_port))
+        
+    
+
+#===========================
+#  Sharable link handler
+#===========================
+
+@public_view
+def sharable_link_handler(request, short_uuid):
+
+    # Get the task (if the short uuid is not enough an error wil be raised)
+    task = Task.objects.get(uuid__startswith=short_uuid)
+    
+    if task.user != request.user:
+        raise ErrorMessage('You do not have access to this task.')
+
+    # First ensure that the tunnel is setu up
+    setup_tunnel(task)
+
+    # Then, redirect to the task through the tunnel
+    tunnel_host = get_tunnel_host()
+    return redirect('{}://{}:{}'.format(task.container.interface_protocol, tunnel_host,task.tcp_tunnel_port))
+        
     
 
 
diff --git a/services/webapp/code/rosetta/urls.py b/services/webapp/code/rosetta/urls.py
index cd995c3bf6e072815d0fe8ae348a1b7c50cec1bd..77353f90d592049706ab961d1c0b483604a18626 100644
--- a/services/webapp/code/rosetta/urls.py
+++ b/services/webapp/code/rosetta/urls.py
@@ -49,6 +49,7 @@ urlpatterns = [
     url(r'^tasks/$', core_app_views.tasks),
     url(r'^create_task/$', core_app_views.create_task),
     url(r'^task_log/$', core_app_views.task_log),
+    url(r'^task_connect/$', core_app_views.task_connect),
     url(r'^computings/$', core_app_views.computings),
     url(r'^add_computing/$', core_app_views.add_computing),
     url(r'^edit_computing_conf/$', core_app_views.edit_computing_conf),
@@ -56,8 +57,9 @@ urlpatterns = [
     url(r'^add_container/$', core_app_views.add_container),
     url(r'^files/$', core_app_views.files_view),
 
-    # Sharable link for tasks
-    url(r'^t/(?P<id>\w{0,36})/$', core_app_views.sharable_link_handler),
+    # Sharable and direct connection links for tasks
+    url(r'^direct_connect/(?P<uuid>[0-9a-f-]+)/$', core_app_views.direct_connection_handler),
+    url(r'^t/(?P<short_uuid>\w{0,36})/$', core_app_views.sharable_link_handler),
 
     # Modules
     path('admin/', admin.site.urls),