BTP Security
BTP & Integrationintermediate

Securing Application-to-Application Communication with OAuth2 Client Credentials and X.509 Certificates

Learn how BTP applications authenticate to each other and to backend systems using OAuth2 client credentials flow and X.509 certificate-based mutual TLS, including how to configure service instances, rotate credentials, and troubleshoot token failures.

Explanation

In SAP BTP, service-to-service and application-to-backend communication rarely relies on end-user credentials. Instead, technical communication uses OAuth2 client credentials grants issued by XSUAA (Cloud Foundry) or by the SAP Authorization and Trust Management service equivalents in Kyma, and increasingly, X.509 certificate-based mutual TLS for higher assurance scenarios such as Integration Suite calling SAP S/4HANA Cloud APIs or a custom application invoking a protected microservice. Why this matters: password-based technical users are a long-standing audit finding because they do not expire predictably, are often shared across environments, and provide no strong binding to a specific workload identity. OAuth2 client credentials and certificates solve this by binding trust to a cryptographic secret or key pair scoped to a specific service instance, with expiry and rotation built into the platform. Design and configuration: when you create a service instance of xsuaa (or a destination with OAuth2ClientCredentials authentication type), the platform generates a clientid and either a clientsecret or, in certificate-based setups, a client certificate and private key pair bound to the instance. The consuming application stores these credentials in its bound VCAP_SERVICES environment (Cloud Foundry) or in a Kubernetes secret (Kyma), never hard-coded. At runtime, the application calls the token endpoint of the XSUAA tenant with grant_type=client_credentials, presenting either the secret or a signed JWT assertion (in certificate flows) to obtain an access token scoped to specific OAuth scopes defined in the app's xs-security.json. Runtime flow: (1) calling application reads bound credentials, (2) requests a token from the /oauth/token endpoint, (3) XSUAA validates the client identity and issues a signed JWT with scopes and expiry (commonly short-lived, minutes to an hour), (4) calling application attaches the token as a Bearer header to the downstream API call, (5) the receiving service validates the token signature against XSUAA's public key (JWKS) and checks required scopes before processing the request. For certificate-based auth, the flow differs: instead of a shared secret, the application signs a client assertion JWT using its private key, and the receiving XSUAA validates it against the public certificate registered on the service instance. This avoids ever transmitting a shared secret and is the preferred pattern for high-security integrations, such as Integration Suite iFlows calling sensitive backend systems. Troubleshooting: token failures typically surface as HTTP 401 or 403 responses. Common causes include an expired or rotated secret not yet updated in the consuming app's configuration, scope mismatches (the token was issued but lacks the scope the resource server expects), or clock skew between the token issuer and validator affecting expiry checks. Checking the decoded JWT (without exposing it insecurely) for issuer, audience, scope, and expiry claims is the first diagnostic step. In Kyma, missing or misconfigured Kubernetes secrets referenced by a Function or Deployment is a frequent cause of silent authentication failures. Deployment differences: Cloud Foundry environments rely heavily on VCAP_SERVICES injection and the SAP-provided XSUAA broker, while Kyma requires explicit ServiceBinding/ServiceInstance CRDs or SAP BTP Operator resources to achieve the equivalent binding. S/4HANA Cloud Public Edition APIs typically expect OAuth2SAMLBearerAssertion or client credentials flows depending on the communication scenario configured in the SAP Fiori-based communication management app, whereas on-premise S/4HANA often still supports basic authentication for legacy compatibility, though this is increasingly discouraged. Production considerations include credential rotation policies (avoid manual, undocumented rotation), monitoring token issuance failure rates, and ensuring destinations in BTP cockpit are configured with the correct authentication type rather than defaulting to NoAuthentication during rapid prototyping and forgetting to harden before go-live.

Code example

ABAP Code
# Example: requesting an OAuth2 client credentials token from XSUAA (Cloud Foundry)curl -X POST https://myaccount.authentication.eu10.hana.ondemand.com/oauth/token \  -d 'grant_type=client_credentials' \  -d 'client_id=sb-myapp!t12345' \  -d 'client_secret=REPLACE_WITH_BOUND_SECRET' \  -H 'Content-Type: application/x-www-form-urlencoded' # Example xs-security.json fragment defining a scope consumed by another app{  "xsappname": "myapp",  "tenant-mode": "shared",  "scopes": [    { "name": "$XSAPPNAME.OrderRead", "description": "Read access to Orders API" }  ],  "oauth2-configuration": {    "credential-types": ["binding-secret", "x509"]  }} # Kyma: referencing a bound secret in a Deployment env var# env:#   - name: CLIENT_ID#     valueFrom:#       secretKeyRef:#         name: myapp-xsuaa-binding#         key: clientid

Real project scenario

A consulting team built a custom Cloud Foundry application that needed to call an Integration Suite exposed API to trigger a downstream IDoc-based order creation in S/4HANA. Initially the team used a NoAuthentication destination during development for speed. Before go-live, the security review flagged this as a critical finding. The team reconfigured the destination to OAuth2ClientCredentials, created a dedicated xsuaa service instance scoped to only the OrderCreate scope, and set up automated secret rotation via the platform's credential-type rotation feature. During cutover testing, they discovered a scope naming mismatch between the xs-security.json definition and the destination configuration, which was resolved by aligning scope names exactly, including the XSAPPNAME prefix.

Common mistakes

• Leaving destinations configured with NoAuthentication in production because it was convenient during development. • Hard-coding client secrets in application code or repository config files instead of relying on bound service credentials. • Requesting overly broad OAuth scopes for a technical user instead of scoping tightly to the specific operation needed. • Not handling token expiry gracefully, causing intermittent failures under load when tokens expire mid-batch. • Mixing up client credentials flow scopes with user-propagated token scopes, leading to authorization confusion during debugging. • Assuming certificate-based auth setup in Cloud Foundry works identically in Kyma without adjusting for Kubernetes secret and CRD requirements.

Best practices

• Always scope OAuth2 clients to the minimum set of required scopes following least privilege. • Prefer certificate-based (x509) client credentials over shared secrets for sensitive or high-volume integrations where the platform supports it. • Automate credential and certificate rotation and monitor token issuance failures as an early warning signal. • Never store client secrets in source control; rely on bound service credentials or a secure vault. • Explicitly configure destination authentication types before promoting to production; never rely on default NoAuthentication. • Validate JWT claims (issuer, audience, expiry, scope) as part of standard troubleshooting playbooks. • Document scope naming conventions across teams to avoid XSAPPNAME prefix mismatches in multi-app landscapes.

Interview angle

Interviewers commonly probe whether a candidate understands the difference between user-context tokens (authorization code / SAML bearer flows) and technical client credentials tokens, and why the latter is preferred for service-to-service calls. Be ready to explain the token request flow step by step, describe how scopes are validated on the resource server, and articulate why certificate-based authentication is considered stronger than shared-secret based authentication in a client credentials grant. Expect scenario questions about diagnosing 401/403 errors and about secret rotation without downtime.