SuperAPI AI Directory

btp-service-bindings

Testing & quality

View repository

Updated 10-16 09:47

About this skill

BTP Service Bindings — Best Practices

Primary reference: https://cap.cloud.sap/docs/node.js/cds-connect Hybrid testing: https://cap.cloud.sap/docs/advanced/hybrid-testing Kyma bindings: https://cap.cloud.sap/docs/guides/deployment/to-kyma


How CAP resolves service bindings

CAP supports servicebinding.io service bindings and SAP BTP service bindings created by the SAP BTP Service Operator. On Cloud Foundry, service bindings are provided in the VCAP_SERVICES environment variable. CAP matches them to cds.requires entries in this order: service name → binding_name → tags array → kind vs label property → kind vs type property.

// VCAP_SERVICES structure (Cloud Foundry)
{
  "xsuaa": [{
    "name": "my-app-auth",
    "label": "xsuaa",
    "tags": ["xsuaa"],
    "credentials": {
      "clientid": "...",
      "clientsecret": "...",
      "url": "https://..."
    }
  }],
  "hana": [{
    "name": "my-app-db",
    "label": "hana",
    "tags": ["hana", "database"],
    "credentials": { ... }
  }]
}

Local development — cds bind (recommended)

Use cds bind to bind BTP services locally. It constructs a VCAP_SERVICES environment variable from real BTP service instances without committing credentials.

# Bind a single service instance
cds bind -2 my-app-auth

# Bind using a specific service key
cds bind -2 my-app-destination:my-destination-key

# Bind multiple services at once
cds bind -2 my-app-auth,my-app-destination,my-app-db

# Run your app with the bound services (hybrid mode)
cds watch --profile hybrid

This creates .cdsrc-private.json — add to .gitignore immediately:

echo ".cdsrc-private.json" >> .gitignore

Use cds bind --exec to run any command with the VCAP_SERVICES variable filled from your bound services — useful for running the App Router locally with real XSUAA credentials.

# Run App Router locally with real XSUAA binding
cds bind --exec -- npm start --prefix app/router

Local development — default-env.json (legacy, less secure)

Only use if cds bind is not available. Never commit this file.

{
  "VCAP_SERVICES": {
    "xsuaa": [{
      "name": "my-app-auth",
      "credentials": { ... }
    }]
  }
}

Add to .gitignore:

echo "default-env.json" >> .gitignore

Kyma / Kubernetes bindings

Use the ServiceBinding custom resource of the SAP BTP Service Operator to create bindings in Kyma. Specify a root directory for all service bindings using the SERVICE_BINDING_ROOT environment variable.

# servicebinding.yaml
apiVersion: services.cloud.sap.com/v1
kind: ServiceBinding
metadata:
  name: my-app-xsuaa-binding
spec:
  serviceInstanceName: my-app-auth
  secretName: my-app-xsuaa-secret
# deployment.yaml — mount the secret as a volume
env:
  - name: SERVICE_BINDING_ROOT
    value: /bindings
volumeMounts:
  - name: xsuaa-binding
    mountPath: /bindings/auth
volumes:
  - name: xsuaa-binding
    secret:
      secretName: my-app-xsuaa-secret

Resolving ambiguous bindings

If multiple instances of the same kind are bound, CAP warns it can't auto-resolve. Fix with vcap.name:

{
  "cds": {
    "requires": {
      "db": {
        "kind": "hana",
        "vcap": { "name": "my-app-db-production" }
      }
    }
  }
}

Accessing credentials in code

// Never hardcode credentials — always read from binding
const { credentials } = cds.requires['my-remote-service']
const { url, clientid, clientsecret } = credentials

// Or use @sap/xsenv for direct access
const xsenv = require('@sap/xsenv')
const services = xsenv.getServices({ myService: { tag: 'my-tag' } })

Common mistakes to avoid

  • ❌ Committing .cdsrc-private.json or default-env.json — contains real credentials

  • ✅ Both files must be in .gitignore before running cds bind

  • ❌ Using default-env.json in CI/CD pipelines — credentials in repo history

  • ✅ Use environment variables or secret management in pipelines

  • ❌ Hardcoding VCAP_SERVICES JSON in code

  • ✅ Always read credentials via cds.requires[...].credentials or xsenv

  • ❌ Binding to a service instance shared with production for local testing

  • ✅ Use dedicated dev/test service instances

  • ❌ Forgetting SERVICE_BINDING_ROOT in Kyma deployments

  • ✅ CAP won't find the credentials without the env variable pointing to the mount path