Amish Kushwaha - May 10, 2026
The Go toolkit SAP BTP was missing: announcing btp-go
Part 1 of a 5-part series introducing btp-go, a stdlib-only Go toolkit for SAP BTP, released under Apache-2.0.
The setup
If you’ve built anything on SAP BTP, you know the language story: Java and JavaScript/TypeScript are first-class citizens. The SAP Cloud SDK ships in both, with deep integrations for the Destination Service, XSUAA, Cloud Connector, OData generation, the works. CAP โ the SAP Cloud Application Programming Model โ assumes one of those two runtimes.
Pick anything else, and you’re on your own.
That’s not a hypothetical complaint. We’ve been building Go services on BTP for our own products at BlueFunda โ event-driven workers, OData proxies, on-prem bridges โ and every time we needed to talk to a re-use service, we hit the same wall: there’s no equivalent toolkit for Go.
So we wrote one. btp-go is a small monorepo of stdlib-only Go libraries for consuming SAP BTP services, released under Apache-2.0. This post explains what’s in the box and why we made the architectural choices we did. The next four posts walk through each subsystem with working code.
What’s actually in the Go ecosystem today
Before we built btp-go, we did the obvious thing โ we checked whether someone else had already solved this. Here’s the survey, current as of late 2025:
SAP/cloud-security-client-goโ Officially maintained. Solves one problem: validating OIDC tokens issued by SAP Identity Authentication Service (IAS), as middleware on the server side of an incoming request. It does not fetch XSUAA tokens, does not look up destinations, does not open Cloud Connector tunnels, and does not parse service bindings beyond IAS itself.SAP-archive/cloud-security-client-golang-xsuaaโ XSUAA token validation in Go. The README opens with “This is not an official library (ITS A SAMPLE!!) and therefore is not been maintained in the future.” It’s in theSAP-archiveorg. That’s the polite way SAP says don’t ship this. And again, validation only โ no client-credentials fetching.SAP/cloud-identity-authorizations-golang-libraryโ Client for the newer Cloud Identity Authorization Management Service. Useful if that’s your auth model, irrelevant if you’re integrating XSUAA, the Destination Service, or Cloud Connector.SAP/sap-btp-service-operatorโ Kubernetes operator for provisioning BTP service instances from a K8s cluster. Operator, not consumer library โ entirely different layer.- SAP Cloud SDK โ Java and JavaScript only. There is no Go port and, as far as anyone has communicated publicly, no plans for one.
Add it up: every Go application that needs to talk to BTP has been writing the same scaffolding from scratch. SOCKS5 dialer with the SAP-specific authentication byte. JWT fetch loop with caching against XSUAA. Destination Service REST client. VCAP_SERVICES parsing. Then the same again for Kyma’s file-mounted bindings, which work nothing like Cloud Foundry’s environment variable.
That scaffolding is what btp-go is.
What’s in the box
btp-go is a Go workspace monorepo with six independently versioned modules:
| Module | What it does |
|---|---|
binding |
Parses service bindings from VCAP_SERVICES (Cloud Foundry), Kyma’s servicebinding.io file mounts, or auto-detects the runtime |
xsuaa |
Fetches and caches client-credentials access tokens from XSUAA |
connectivity |
Opens TCP tunnels through SAP Cloud Connector via the SOCKS5 proxy (with SAP’s custom 0x80 auth method) |
destination |
Looks up named destinations through the SAP Destination Service REST API |
sshclient |
High-level SSH/SFTP client over the Cloud Connector tunnel โ wraps connectivity + destination |
httpclient |
HTTP/REST/OData client wired for a Destination’s auth + Cloud Connector tunnel; includes OData v2 CSRF token helper |
The whole thing is stdlib-only. No viper, no zap, no third-party HTTP clients. The one exception is sshclient, which uses golang.org/x/crypto/ssh for SSH โ there’s no SSH implementation in the Go standard library, so that’s unavoidable. Everything else is net/http, encoding/json, crypto/tls.
Three design choices worth explaining
1. A monorepo of independent modules
Each subdirectory is its own Go module with its own go.mod and its own semver tag. If your application only needs to fetch XSUAA tokens, you go get github.com/bluefunda/btp-go/xsuaa@latest and nothing else lands in your dependency tree. You don’t pay for SSH if you only need HTTP.
The modules are tied together by a Go workspace (go.work) for local development, so contributors can edit two modules in one IDE session, but consumers see them as six separate libraries.
2. Zero cross-module imports
Look at the dependency graph:
consumer app
โโโ binding/auto
โโโ connectivity (local TokenSource interface)
โโโ destination (local TokenSource interface)
โโโ sshclient (local Dialer interface)
โโโ httpclient (local Dialer + TokenSource interfaces)
โโโ xsuaaNotice what’s not there: connectivity does not import xsuaa. sshclient does not import connectivity. Each module declares the interfaces it needs locally โ a TokenSource here, a Dialer there โ and any concrete implementation that satisfies the interface plugs in.
This means you can swap xsuaa for your own token source. You can swap connectivity for a direct net.Dialer in tests, or for a different proxy implementation entirely. The modules compose, but they don’t entangle. Each one is independently auditable, independently testable, and independently versionable.
3. Cloud Foundry and Kyma, one binding API
binding/auto detects at runtime whether the app is running on Cloud Foundry (read VCAP_SERVICES from the environment) or on Kyma (read mounted secret files at /bindings/<name>/). The Kyma reader handles all three layouts the servicebinding.io spec allows โ per-key files, JSON-blob fallback, Kubernetes atomic-update sentinel directories โ so application code never branches on runtime.
That mattered a lot to us. We don’t want to maintain two integration paths just because BTP exposes credentials differently in two of its own runtimes.
What’s coming in this series
This was the introduction. The next four posts each take one slice of btp-go and walk through it with working code:
- Part 2 โ Foundations: service bindings and XSUAA. What
VCAP_SERVICESactually contains, what Kyma puts on disk, howbinding/autopicks between them, and howxsuaacaches tokens correctly across concurrent goroutines. - Part 3 โ Reaching on-prem: Connectivity and Destination. The SAP-specific 0x80 auth byte that no off-the-shelf SOCKS5 client speaks. How destination lookups thread the JWT correctly. Why the two compose.
- Part 4 โ Worked example: counting files in AL11. A complete Cloud Foundry app that uses
sshclientto connect through Cloud Connector to an on-prem ABAP system and count files in an AL11 directory. End-to-end: bindings โ xsuaa โ connectivity โ destination โ SFTP. - Part 5 โ Worked example: HTTP destinations end-to-end. Create a destination programmatically through the Destination Service API. Use it to fetch a public weather feed. Then use it to call an on-prem
/sap/opu/odata/iwfnd/CATALOGSERVICE/Gateway service, with CSRF token handling for the writes.
If you build Go services that need to talk to BTP โ or to ABAP systems behind Cloud Connector โ clone the repo, browse the examples/ directory, and let us know in GitHub issues what you’d want to see next. M2 (Oracle over connectivity.Dial using go-ora) and M5 (principal propagation in xsuaa) are on the roadmap; we’re prioritizing by what real users hit first.
The repo is at github.com/bluefunda/btp-go. Apache-2.0. Issues and PRs welcome.
Next up โ Part 2: Foundations: service bindings and XSUAA.
Ready to transform your SAP experience?
Join thousands of developers using BlueFunda AI tools.