diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0711f200..c880663b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -34,6 +34,36 @@ variables:
     when: always
     expire_in: 1 week
 
+.rootless-build: &rootless-build
+  stage: build
+  variables:
+    RUNNER_AFTER_SCRIPT_TIMEOUT: 15m
+  before_script:
+    - export http_proxy=$HTTP_PROXY
+    - export https_proxy=$HTTPS_PROXY
+    - export ftp_proxy=$FTP_PROXY
+    - export no_proxy=$NO_PROXY
+    - export DISTRO_APT_PREMIRRORS=$DISTRO_APT_PREMIRRORS
+  after_script:
+    - |
+      if [[ -n "${SSTATE_LOCATION}" ]] && [[ -d "sstate-cache" ]]; then
+        echo "=== Upload sstate artifacts to ${SSTATE_LOCATION} ==="
+        ./scripts/isar-sstate --filter '^(?!isar-image-)' upload "sstate-cache" "${SSTATE_LOCATION}"
+        ./scripts/isar-sstate info -v "${SSTATE_LOCATION}"
+      fi
+
+  artifacts:
+    name: "logs-$CI_JOB_ID"
+    paths:
+      - build/testsuite/tmp*/work/*/*/*/temp
+      - build/testsuite/job-results
+      - build/testsuite/vm_start
+    reports:
+      junit:
+        - build/testsuite/job-results/job*/results.xml
+    when: always
+    expire_in: 1 week
+
 
 .test-container: &test-container
   image: ghcr.io/ilbers/isar/test-container:1
@@ -113,6 +143,17 @@ full-ci-isar:
   script:
     - scripts/ci_build.sh --sstate 1 -T full
 
+
+dev-rootless-ci:
+  tags:
+    - shell-rootless
+  <<: *rootless-build
+  rules:
+    - if: $TESTSUITE == 'dev-rootless' || $CI_PIPELINE_SOURCE != 'schedule'
+  script:
+    - scripts/run-tests.sh --debug --clean-rootless-files testsuite/citest.py:test_dev$ -p rootless=1
+
+
 sstate-cache-info:
   stage: build
   when: manual
