diff --git a/polkadot/.gitlab-ci.yml b/polkadot/.gitlab-ci.yml
index ff60e5bdcc0b60416d7550eb470b597191d5abf5..0b6e75134abe55564efea2d5c8e514cc8fe0e968 100644
--- a/polkadot/.gitlab-ci.yml
+++ b/polkadot/.gitlab-ci.yml
@@ -104,6 +104,12 @@ default:
 #### Vault secrets
 .vault-secrets:                    &vault-secrets
   secrets:
+    AWS_ACCESS_KEY_ID:
+      vault:                       cicd/gitlab/$CI_PROJECT_PATH/AWS_ACCESS_KEY_ID@kv
+      file:                        false
+    AWS_SECRET_ACCESS_KEY:
+      vault:                       cicd/gitlab/$CI_PROJECT_PATH/AWS_SECRET_ACCESS_KEY@kv
+      file:                        false
     GITHUB_PR_TOKEN:
       vault:                       cicd/gitlab/parity/GITHUB_PR_TOKEN@kv
       file:                        false
@@ -497,6 +503,47 @@ update_westend_weights:
 
 #### stage:                        publish
 
+publish-s3-release:                &publish-s3
+  stage:                           publish
+  needs:
+    - job:                         test-build-linux-stable
+      artifacts:                   true
+  <<:                              *kubernetes-env
+  <<:                              *vault-secrets
+  image:                           paritytech/awscli:latest
+  variables:
+    GIT_STRATEGY:                  none
+    PREFIX:                        "builds/polkadot/${ARCH}-${DOCKER_OS}"
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "pipeline"
+      when: never
+    # publishing binaries nightly
+    - if: $CI_PIPELINE_SOURCE == "schedule"
+  before_script:
+    - *check-versions
+  script:
+    - echo "uploading objects to https://releases.parity.io/${PREFIX}/${VERSION}"
+    - aws s3 sync --acl public-read ./artifacts/ s3://${AWS_BUCKET}/${PREFIX}/${VERSION}/
+    - echo "update objects at https://releases.parity.io/${PREFIX}/${EXTRATAG}"
+    - find ./artifacts -type f | while read file; do
+        name="${file#./artifacts/}";
+        aws s3api copy-object
+          --copy-source ${AWS_BUCKET}/${PREFIX}/${VERSION}/${name}
+          --bucket ${AWS_BUCKET} --key ${PREFIX}/${EXTRATAG}/${name};
+      done
+    - |
+      cat <<-EOM
+      |
+      |  polkadot binary paths:
+      |
+      |  - https://releases.parity.io/${PREFIX}/${EXTRATAG}/polkadot
+      |  - https://releases.parity.io/${PREFIX}/${VERSION}/polkadot
+      |
+      EOM
+  after_script:
+    - aws s3 ls s3://${AWS_BUCKET}/${PREFIX}/${EXTRATAG}/
+        --recursive --human-readable --summarize
+
 publish-rustdoc:
   stage:                           publish
   <<:                              *kubernetes-env