diff --git a/README.md b/README.md
index b60803e0791e506358e8ad9894c8cdcdb912a3b8..7df5f4cd0e9fcc64a4dc22f4408962eb24fa2e74 100644
--- a/README.md
+++ b/README.md
@@ -75,6 +75,16 @@ It is possible to horizontally scale the UI Middleware, as more clients are fetc
 | `compressFileSize`    | Larger files will be gzipped    | `600`    |
 | `compressFileTypes`   | Set of compression mime types   |see values|
 
+**config map**
+
+```yaml
+# List of urls where to find ui containers
+baseUrls:
+  - http://service.namespace.svc.cluster.local/
+# optional, when this number is changed, the changes on clients will be invalidated and will reload the ui-sources
+salt: '1234'
+```
+
 ## Ingress
 
 When using Ingress to make the service available to the public, the service is intended to be
diff --git a/spec/salt_test.js b/spec/salt_test.js
new file mode 100644
index 0000000000000000000000000000000000000000..a3b36325d4a8577e87da43e7272860d85dff92c9
--- /dev/null
+++ b/spec/salt_test.js
@@ -0,0 +1,46 @@
+import request from 'supertest'
+import { brotliParser, generateSimpleViteManifest, mockApp, mockConfig, mockFetch, mockRedis } from './util.js'
+import { expect } from 'chai'
+import * as td from 'testdouble'
+import RedisMock from 'ioredis-mock'
+
+describe('Salt', function () {
+  let app
+  let config
+
+  beforeEach(async function () {
+    mockConfig(config = { baseUrls: ['http://ui-server/'] })
+    mockRedis()
+    mockFetch({
+      'http://ui-server': {
+        '/manifest.json': generateSimpleViteManifest({ 'example.js': 'test' }),
+        '/example.js': ''
+      }
+    })
+    app = await mockApp()
+  })
+
+  afterEach(async function () {
+    td.reset()
+    await new RedisMock().flushdb()
+  })
+
+  it('change version when salt changes', async function () {
+    const response = await request(app.server).get('/manifests').parse(brotliParser)
+    expect(response.statusCode).to.equal(200)
+    expect(response.headers.version).to.equal('1916675216')
+
+    // update salt
+    config.salt = '1'
+
+    await import('../src/version.js').then(async ({ updateVersionProcessor }) => {
+      // need to process two times to actually trigger the update
+      await updateVersionProcessor()
+      await updateVersionProcessor()
+    })
+
+    const responseAfterUpdate = await request(app.server).get('/manifests').parse(brotliParser)
+    expect(responseAfterUpdate.statusCode).to.equal(200)
+    expect(responseAfterUpdate.headers.version).to.equal('1916675216-1')
+  })
+})
diff --git a/src/configMap.js b/src/configMap.js
index 095ff3a69aa18aba1bc8596b13f7ea59efcf0840..d3ba89c2825cdf2f685447c38b08126f7c3bba43 100644
--- a/src/configMap.js
+++ b/src/configMap.js
@@ -7,12 +7,18 @@ class Config {
     const doc = yaml.load(await fs.readFile('./config/config.yaml', 'utf8'))
     // @ts-ignore
     this._urls = doc.baseUrls
+    // @ts-ignore
+    this._salt = doc.salt
     logger.debug('[Config] Config has been loaded')
   }
 
   get urls () {
     return this._urls || []
   }
+
+  get salt () {
+    return this._salt
+  }
 }
 
 export const configMap = new Config()
diff --git a/src/version.js b/src/version.js
index c0828ebad6e47837d34d27d15ccf744a22d9881c..de716432b15babf2499878a287f608fbb7de8511 100644
--- a/src/version.js
+++ b/src/version.js
@@ -45,7 +45,7 @@ export const fetchLatestVersion = async () => {
       logger.error(`[Version] Cannot fetch manifest from ${baseUrl}. Version info will not be correct.`)
     }
   }))
-  return hash(infos)
+  return `${hash(infos)}${configMap.salt ? `-${configMap.salt}` : ''}`
 }
 
 export async function getLatestVersion () {