SAP Event Mesh supports mTLS – “cool … ehmm… and what is mTLS ?”

Since october 2021, SAP Event Mesh supports mTLS.

Cool… ehmm… and what is “mTLS”???
“Mutual TLS”.

What is “mutual”?
It refers to both communicating parties.
Means, not only the server, but also the client.

What is “TLS”?
“Transport Layer Security”.
Successor of the old “SSL” (“Secure Sockets Layer”).
“TLS” is about encryption.
“TLS” is used by HTTPS.

What is “HTTPS”?
It is the same like HTTP but with trailing S.

What is “HTTP”?
“Hypertext Transfer Protocol”

What is “S”?
S ecure.

What is “encryption”?
To encrypt a text means to make it unreadable for others.
To encrypt a text, a key is used.
Example for a key:
“key” = “use 😉 instead of a”
Now let’s encrypt my name using that key:
-> C😉rlos
Yes, looks cryptic.

What is “symmetric encryption”?
I send a message to Hanna:
Hi H😉nn😉, greetings from C😉rlos
Looks cryptic, she cannot understand.
I give the key to Hanna.
So she can decrypt the message.
“Symmetric” = both parties use the same secret key.

What is “asymmetric encryption”?
In this case, there are 2 keys: “public key” and “private key”.
I encrypt my message with my private key (and I keep the private key private)
I send the message to Hanna and give her the public key,
So she can decrypt/read my silly text.
“Asymmetric” = not symmetric
In any case, it is more secure.

What is “secure”?
A browser opens a secure website (server).
The website identifies itself with a certificate which is sent to the browser (client).
The certificate contains e.g. the public key.
The browser will check the certificate, to verify if the website is safe.
The communication between browser and server is done via HTTPS, which itself uses TLS.
So we can be sure that the website is secure.

What is a “certificate”?
It is a very small document which proves that the website is real, not faked.

How does it prove??
The certificate itself is certified by a second certificate.
The second (intermediate) certificate is certified by a really really true and trustworthy authority.
The third (root) certificate is self-issued by the CA.
There can be of course more than 3 certificates in that so-called “chain” or “path”.
To prove, the certificates are signed with public keys.

What is the “CA”?
“Certification Authority”

How does a certificate look like?

What is the content?
The screenshot shows the certificate of my mtlsapp which is a server app deployed to SAP BTP.

Is that nice???

Can it lie to me?
If a cert has been caught while lying, then it is added to a CRL.

What is CRL?
“Certificate Revocation List”

Where do I find it?
It is a property in the certificate:

What is TLS handshake?
A secure communication between website (server) and browser (client) starts with handshake (HTTPS).
The server sends its certificate which contains public key (see asymmetric encryption).
Some more details (e.g. encryption) are discussed between website and browser before the secure data transfer can start.
No worries, it takes only few milliseconds.

What have I learned?
When talking about HTTPS or TLS or even SSL, etc, then we talk about making sure that a server is trustworthy.
If not, then we should not trust what we read and we should not send data to that website.
The server shows a certificate which has been issued and signed by a trustworthy authority and the browser checks that.

What have I not learned?

Why do we need this blog post?
Philosophic questions are not allowed.

What is mTLS?
In this case, both sides, server and client, show certificates to prove that they are trustworthy.

How does that work?
Client does the same ceremony like server, as explained above.
Means, the client as well sends its (client) certificate and key which is then checked by the server.
Thus we talk about mutual mTLS.

What is client certificate?
The client is a client which calls a server app.
Instead of authenticating with user/password, it sends a certificate and key.

Why mTLS?
It is more safe.

What else?
For instance, a certificate can be configured to expire after 1 day.
As a consequence, credentials need to be renewed on regular basis.

Isn’t that tedious?
No. It’s safe. That’s credential rotation.

What is credential rotation?
See below exercise.

What does it have to do with Event Mesh?
Event Mesh supports mTLS.

How does it support mTLS?
Event Mesh provides API for programmatically sending messages or viewing/creating queues, etc
As usual, such an API is protected and requires authentication.
Typically, OAuth 2.0 is used for protection.
So if we want to use that API, we create an Event Mesh service instance and bind it to our app.
Like this, we get the credentials which we need to call the Event Mesh API.
These credentials are used to fetch a JWT token, which we then can use to call the API.
Usually, the JWT token is fetched by authenticating via user/password, represented by clientid/clientsecret.
That is still supported, and in addition Event Mesh supports mTLS.

How does it work?
We, as a client, get the certificate and key in binding (instead of clientid/secret).
Alternatively, we can create a service key to get the credentials.
We then use the certificate to fetch a JWT token.

How to fetch token with certificate?
See next blogs for usage programmatically in app or with Postman.

How to tell Event Mesh to use mTLS?
See next blogs.
In brief: it can be specified in the credential-types param in the config of the service instance, and if desired, in the config of the binding.

What is a credential type?
During binding, Event Mesh gives us the credentials which we need to call the REST API.
Several types of credentials are supported: basically it is “basic authentication” or “client certificate”.
More precise:
instance-secret, binding-secret or x509.
In order to specify which one we want, we can use the credential-type property (in the config params for instance creation).
See next blog for details.

Why mTLS?
Already asked above.

What else?
The credential-type x509 supports credentials rotation.

What is credential rotation?
This means that credentials can be changed.
With other words, a password can be invalidated and replaced by a new one.
Or a certificate can be set to expire soon (short lived) and it needs to be regenerated regularly.
For example, a provider application is deployed every week to the cloud to provide updates and features.
During this process, credentials can be rotated.

How does credential rotation work?
To see it working in detail, I encourage you to go through the optional exercise below.
Together, we will be rotating.

Will it make fun?

Can I skip it?

Where can I get more information?
Here are some links:
SAP Event Mesh landing page.
SAP Event Mesh: Syntax for Service Descriptor.
SAP Event Mesh: Create an instance using the command line.
Specification RFC about PEM and representation format in single lines.

Where is a summary?
As a client, we authenticate using certificate and key.
Instead of basic authentication with user/pwd.

Optional Exercise: Credential Rotation

In this exercise we want to try how the different credential types behave wrt credential rotation.
We’re going to create an instance of Event Mesh and we’re going to check how the credentials are provided and changed.
We’re going to do the exercise for all 3 credential types.
The description is based on the command line client, but the same can be done in the cockpit as well.
The configuration parameters for the Event Mesh instance can be copied from the samples in the Appendix.

1. Instance Secrect

In the past, there was no option to specify credential types.
Background: XSUAA didn’t support multiple secrets per instance.
Back of Background: each instance of xsuaa represents one OAuth client, and naturally each OAuth client was created with one secret.
As such, instance-secret was kind of default.
Foreground: in the meantime, instance-secret is legacy, so in order to create an instance of Event Mesh with this credential type, we need to explicitly specify it in the configuration params of the Event Mesh instance:

 "xs-security": { "oauth2-configuration": { "credential-types": [ "instance-secret"

The content of the config file can be found in the Appendix 1.

We create an instance of Event Mesh and provide the configuration in a file called

The creation command:
cf cs enterprise-messaging default instMsg -c config-messaging-instsec.json
To get the credentials, we just create a service key
cf csk instMsg sk1
To view the credentials
cf service-key instMsg sk1

We take a note of the credentials in the uaa section:

“uaa”: {
“clientid”: “sb-default-1a2b3c-…-clone!b12345|xbem-service-broker-!b1234”,
“clientsecret”: “abcd1234…”

Now we create a second service key
cf csk instMsg sk2
And check the credentials
cf service-key instMsg sk2
. . .
We compare the credentials:
The value of client secret property is the same.

We can do another check:
We delete both service keys:
cf dsk instMsg sk1 -f
cf dsk instMsg sk2 -f
Then re create one of them:
cf csk instMsg sk1
And check the service key
cf service-key instMsg sk1

The secret is again the same.

This means :
When creating a service with credential type instance-secret, then the secret is always the same for this instance.

And we can do one more check:
Update the service instance:
cf update-service instMsg -c config-messaging-instsec.json
However, we’ll see that we don’t get a new secret.

And the very last check:
Delete the service instance
cf ds instMsg -f
And create new instance.

Of course, after creating a new instance (with same name and config), we get new credentials.

All service keys or bindings have the same secret, as it is based on the instance.
The secret is always the same, for all service keys or bindings.
If we want a new secret, we need to delete and re-create the whole instance (but see the note).
Deleting just the credentials (service key) is not enough.

Of course, deleting a service instance in productive scenario is not desirable.
Instead, we can update the instance, with configuration that supports the credential type binding-secret, or x509 (or both).
Afterwards, we can activate the new credential type by moving it to the first place (and update again the instance)

2. Binding Secret

Now we check the behavior with credential type binding-secret
We use below config, which differs only wrt the credential type and is named

"oauth2-configuration": { "credential-types": [ "binding-secret"

The full content can be found in the Appendix 2.

We repeat the steps described above.
The instance:
cf cs enterprise-messaging default bindMsg -c config-messaging-bindsec.json
The service key:
cf csk bindMsg sk1
The credentials:
cf service-key bindMsg sk1
Take a note:
“clientsecret”: “aaaaa11111-…$…-xxx-xxxA1=”
And note:
We notice that the secret is much longer, as it contains the binding GUID before the $

Now create the second:
cf csk bindMsg sk2
cf service-key bindMsg sk2
“clientsecret”: “abcd1234-…$…-xyz-xyzA0=”
We just need to throw a quick glance at the 2 secrets to notice that they are different

Want to do the deletion check as well?
cf dsk bindMsg sk1 -f
cf dsk bindMsg sk2 -f
cf csk bindMsg sk1
cf service-key bindMsg sk1

Result: Again, the secret is new

Each new service key or new binding will show up with a new secret.
So that’s why it is called binding-secret.
We only need to create the instance once and if we need a new secret, then we just need to re-bind the service to our application (or re-create a service key)

So now we’ve learned what it means: “credential rotation”.

3. x509

Now that we know the meaning of credential rotation, we’re curious to see how the service behaves in case of x509 certificate.


"oauth2-configuration": { "credential-types": [ "x509"

The content of the config file can be found in the Appendix 3.

Again, we do all the commands:

cf cs enterprise-messaging default mtlsMsg -c config-messaging-mtls.json
cf csk mtlsMsg sk1
cf service-key mtlsMsg sk1

Now we need to take a note of the certificate
“certificate”: “—–BEGIN CERTIFICATE—–\nMIIFuzCCA6OgAwIBAgIRAPrc3a

cf csk mtlsMsg sk2
cf service-key mtlsMsg sk2


The certificates are always different

In case of mTLS, the credential rotation is supported as well-
Even more: it is enforced, because any certificate is designed to expire after certain (configurable) period. To obtain a new certificate, we just need to re-bind.

Appendix 1: Sample Config for instance-secret


{ "emname": "instxsappname", "namespace": "my/inst/sec", "version": "1.1.0", "options": { "management": true, "messagingrest": true, "messaging": true }, "rules": { "queueRules": { "publishFilter": [ "${namespace}/*" ], "subscribeFilter": [ "${namespace}/*" ] }, "topicRules": { "publishFilter": [ "${namespace}/*" ], "subscribeFilter": [ "${namespace}/*" ] } }, "xs-security": { "oauth2-configuration": { "credential-types": [ "instance-secret" ] } }

Appendix 2: Sample Config for binding-secret


{ "emname": "bindxsappname", "namespace": "my/bind/sec", "version": "1.1.0", "options": { "management": true, "messagingrest": true, "messaging": true }, "rules": { "queueRules": { "publishFilter": [ "${namespace}/*" ], "subscribeFilter": [ "${namespace}/*" ] }, "topicRules": { "publishFilter": [ "${namespace}/*" ], "subscribeFilter": [ "${namespace}/*" ] } }, "xs-security": { "oauth2-configuration": { "credential-types": [ "binding-secret" ] } }

Appendix 3: Sample Config for x509


{ "emname": "x509xsappname", "namespace": "my/x5/09", "version": "1.1.0", "options": { "management": true, "messagingrest": true, "messaging": true }, "rules": { "queueRules": { "publishFilter": [ "${namespace}/*" ], "subscribeFilter": [ "${namespace}/*" ] }, "topicRules": { "publishFilter": [ "${namespace}/*" ], "subscribeFilter": [ "${namespace}/*" ] } }, "xs-security": { "oauth2-configuration": { "credential-types": [ "x509" ] } }