diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0e359c8b315319e33616616c84b2b98f6a808088..cfd8c3bcf453685a5a85d561feb3d2e1902393d2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,5 +1,6 @@
 stages:
   - test
+  - make_public
 
 tests:
   stage: test
@@ -9,16 +10,38 @@ tests:
     paths:
       - _opam
   script:
-  - if [ ! -d _opam ]; then echo "no local switch in the CI cache, we setup a new switch"; opam switch create --yes --no-install . ocaml-base-compiler.4.13.1; fi
-  - opam switch 4.13
-  - eval $(opam env --switch=4.13 --set-switch)
-  - opam switch
-  - sudo apt-get update
-  - sudo apt install -y protobuf-compiler
-  - opam repository add remote https://opam.ocaml.org
-  - opam depext --yes ocplib-endian base fmt alt-ergo.2.4.0
-  - opam install . --deps-only --with-test --yes
-  - make
-  - make test
+    - if [ ! -d _opam ]; then echo "no local switch in the CI cache, we setup a new switch"; opam switch create --yes --no-install . ocaml-base-compiler.4.13.1; fi
+    - opam switch 4.13
+    - eval $(opam env --switch=4.13 --set-switch)
+    - opam switch
+    - sudo apt-get update
+    - sudo apt install -y protobuf-compiler
+    - opam repository add remote https://opam.ocaml.org
+    - opam depext --yes ocplib-endian base fmt alt-ergo.2.4.0
+    - opam install . --deps-only --with-test --yes
+    - make
+    - make test
   tags:
     - docker
+
+
+################################################################################
+### PUBLIC
+
+# make_public stage is used to push the current master branch of CAISAR to the
+# public pub group at git.frama-c.com/pub/caisar.
+# For that, it uses the 'caisar to caisar-public' deploy key stored in the
+# public repository. This is the public key of the private one stored in the
+# variable $CAISAR_PUBLIC_SSH_PRIVATE_KEY of private repository.
+
+make_public:
+  stage: make_public
+  image: ocaml/opam@sha256:013a26ccbaa8344b63274e335e2492c432cec1c3526b9ba888ab151abb2b4c25
+  script:
+    - echo "$CAISAR_PUBLIC_SSH_PRIVATE_KEY" | base64 -d > ci/caisar-public/id_ed25519
+    - chmod 400 ci/caisar-public/id_ed25519
+    - GIT_SSH=$PWD/ci/caisar-public/ssh.sh git push git@git.frama-c.com:pub/caisar.git origin/master:refs/heads/master
+  tags:
+    - docker
+  only:
+    - schedules
diff --git a/ci/caisar-public/known_hosts b/ci/caisar-public/known_hosts
new file mode 100644
index 0000000000000000000000000000000000000000..9d81a10a357ba18eec5f4ef0aee7e46752dfca5d
--- /dev/null
+++ b/ci/caisar-public/known_hosts
@@ -0,0 +1,6 @@
+git.frama-c.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICr2Qt3FnYcg6IxAdSJ2jHjrYUZPeYOSsPNs4r9hy5w3
+git.frama-c.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuywpGMKnFOqiZn32w7X1k2UbP09NLpwQkqj2dDmm9hn+Yh5MyG9qCMpPplDQW3ywyW1tvyyUDEop0modY+JL1C+CmGPPLiA3PvLQTwJZ/sKT0bGjYFlrKK6f7B6wbwvWB9KkyIdt/3VQOA+HY3ILn0nRvYSNpVFBCeQ3pJcbFeDAXLKQodQZzfLrQZ3lmccCWxvTMzhAiiaj9ybOFLptzWzpB3fmtid/XjRECfhJDreRdirntmnuuvscKOEl2jvDIxfnH9l2xPjHtVkp+xAE6u0PT4jJkFSN45ZaUhXx5+mN7XlGMGQTpXV0thtzbW1ty3cQgQk7pXrx4Q4Z23Gex
+git.frama-c.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKqxcbMBcJwt9R6Kb1d4bZwRqqPJJt478Vp52ocA2GpNSfw57MMdd/uV0X1CeFkcDUbu9R6viUN03+XIU3ArDBQ=
+54.38.94.65 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuywpGMKnFOqiZn32w7X1k2UbP09NLpwQkqj2dDmm9hn+Yh5MyG9qCMpPplDQW3ywyW1tvyyUDEop0modY+JL1C+CmGPPLiA3PvLQTwJZ/sKT0bGjYFlrKK6f7B6wbwvWB9KkyIdt/3VQOA+HY3ILn0nRvYSNpVFBCeQ3pJcbFeDAXLKQodQZzfLrQZ3lmccCWxvTMzhAiiaj9ybOFLptzWzpB3fmtid/XjRECfhJDreRdirntmnuuvscKOEl2jvDIxfnH9l2xPjHtVkp+xAE6u0PT4jJkFSN45ZaUhXx5+mN7XlGMGQTpXV0thtzbW1ty3cQgQk7pXrx4Q4Z23Gex
+54.38.94.65 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKqxcbMBcJwt9R6Kb1d4bZwRqqPJJt478Vp52ocA2GpNSfw57MMdd/uV0X1CeFkcDUbu9R6viUN03+XIU3ArDBQ=
+54.38.94.65 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICr2Qt3FnYcg6IxAdSJ2jHjrYUZPeYOSsPNs4r9hy5w3
diff --git a/ci/caisar-public/ssh.sh b/ci/caisar-public/ssh.sh
new file mode 100755
index 0000000000000000000000000000000000000000..2415c7817ab86d42b1d3897a56479005162c243c
--- /dev/null
+++ b/ci/caisar-public/ssh.sh
@@ -0,0 +1,5 @@
+#!/bin/sh -eux
+
+PWD=$(dirname $0)
+
+exec ssh -o "UserKnownHostsFile ${PWD}/known_hosts" -i "${PWD}/id_ed25519" "$@"