Self-hosted service
SteeltoeOSS/Steeltoe avatar
SteeltoeOSS/Steeltoe

Steeltoe: the .NET client libraries for Spring, Cloud Foundry and Kubernetes

.NET Components for Externalized Configuration, Database Connectors, Service Discovery, Logging and Distributed Tracing, Application Management, Security, and more.

1,096 stars172 forksC#Apache-2.0

At a glance

What is it?
Steeltoe is a set of .NET components for building applications that talk to Spring and Spring Boot environments, Cloud Foundry and Kubernetes, covering externalised configuration, service discovery, management endpoints, database connectivity and single sign-on. It is Apache-2.0 licensed, and its branch table makes the trade explicit: main is unstable and 4.x is the stable line.
Who is it for?
Steeltoe fits a .NET team that has to run on Spring Cloud or Cloud Foundry infrastructure and needs the platform integration to exist on the .NET side, including configuration servers, Eureka or Consul discovery, actuator style management endpoints and the platform's own authentication. It does not fit a .NET team running only on plain Kubernetes with no Spring components, and it does not fit a team that wants the newest features and expects them to be supported.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap Steeltoe fills is platform integration on the .NET side

Steeltoe provides building blocks for the development of .NET applications that integrate with Spring and Spring Boot environments, as well as Cloud Foundry and Kubernetes with first-party support for Tanzu.

That sentence names the problem precisely. These platforms have client libraries for the JVM, and a .NET application running on Cloud Foundry or beside a Spring Cloud Config Server or an Eureka server needs the equivalent client in C#. Writing one per application is the alternative, and Steeltoe is the shared answer.

The key features list is organised by platform capability rather than by .NET concept. External, optionally encrypted, configuration using Spring Cloud Config Server. Service discovery with Netflix Eureka and HashiCorp Consul. Management endpoints that are compatible with actuators, providing system info such as versions, configuration, service container contents, mapped routes and HTTP traffic, plus heap and thread dumps, health checks, exporting metrics to Prometheus, and changing log levels at runtime.

Then database connectivity, which names SQL Server and Azure SQL, Cosmos DB, MongoDB, Redis, RabbitMQ, PostgreSQL and MySQL, including support for Entity Framework Core. And single sign-on, JWT and certificate auth with Cloud Foundry.

Two details in that list deserve attention. The management endpoints are the actuator model, and Spring Boot's actuator has become the de facto standard for how a microservice exposes its operational surface, so implementing them means an existing operations tool works against a .NET service. And the encrypted configuration is the one that matters most in practice, because a config server usually holds credentials, and the docker-compose file in this repository shows exactly what that involves, a keystore passed in as a volume with the key store location, password and alias configured, and an RSA OAEP algorithm setting with a salt.

That compose file is also the most revealing artefact in the repository, and it is what the next section is about.

The docker-compose file, which is the test harness in plain sight

The repository root carries a docker-compose.yml, and its header comment states its purpose: it starts Eureka Server and Spring Cloud Config Server for running Configuration integration tests locally.

The usage block gives the sequence.

bash
docker compose up -d

Then a wait, because the config server needs the eureka server to be up before it is useful.

bash
Start-Sleep -Seconds 15   # wait for servers to be ready

And then the tests themselves, filtered to the integration category.

bash
dotnet test src/Configuration --filter "Category=Integration"

Two services are defined. The eureka-server uses the image steeltoe.azurecr.io/eureka-server with a pull policy of always, publishes port 8761, and the config-server uses steeltoe.azurecr.io/config-server, depends on eureka-server, publishes port 8888, and mounts a keystore from the test tree.

The environment block on the config server is the interesting part. It enables the eureka client, points the service URL at the eureka container, sets the instance hostname and instance id, and then configures the encryption: the key store location pointing at the mounted file, the key store password, the alias, the RSA algorithm set to OAEP, a salt, and a strong flag set to false.

That is a complete, working description of the encrypted configuration feature, in a file that is checked in. It shows the exact key names the library expects, the algorithm it uses, and the fact that a salt is part of the contract. For anyone implementing encrypted config against a Spring Cloud Config Server, this file is a specification.

The last block of the file is a recipe for regenerating a test vector, using Invoke-RestMethod to post plaintext to an encrypt endpoint on the config server, which tells you that the server exposes an encryption API the tests use to produce ciphertext.

The branch table, which tells you where to point your build

The prerequisites table is the most operationally useful thing in the README, and it is worth reading carefully because the labels are not decorative.

| Steeltoe Branch | .NET Version | Status | | --- | --- | --- | | main | .NET 8 - 10 | Unstable | | 4.x | .NET 8 - 10 | Stable | | 3.x | .NET 8 | Stable | | 2.x | .NET Framework 4.6.1+ | Out of Support |

So there is a stable line that targets .NET 8 through 10, a stable line for .NET 8 only, an unstable main branch that targets .NET 8 through 10, and a .NET Framework line that is finished. The project points at a wiki page on supported versions for more detail.

Two things follow from this. First, the main branch is where the next major version is being built, and the release list confirms the shape, with 4.3.0 in September 2026, 4.2.0 in May 2026 and 3.4.0 in the same month.

Second, and this is the operational trap, the stable 4.x line and the unstable main branch both target .NET 8 to 10, so the .NET version alone does not tell you which line you are on. If your pipeline resolves the latest package, you may end up on a different line than the one your team tested, and the only way to know is to pin the major version.

The 2.x entry is the other signal. A .NET Framework 4.6.1 or later branch marked out of support means the framework specific components are no longer maintained, so an application still on .NET Framework has to either stay on 2.x or migrate.

Pre release packages come from a development feed, not from NuGet

If you want to try the latest bits from the main branch, the README tells you to use the Steeltoe development feed by adding a reference to your nuget.config file.

xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="Steeltoe-ci" value="https://pkgs.dev.azure.com/dotnet/Steeltoe/_packaging/ci/nuget/v3/index.json" />
    <add key="NuGet" value="https://api.nuget.org/v3/index.json" />
  </packageSources>
</configuration>

The structure is worth noting, because it is a pattern you will meet again. The development feed is added alongside the normal NuGet source rather than replacing it, and the two entries have distinct keys, Steeltoe-ci and NuGet, so a project can pull a prerelease from one source and a stable dependency from the other.

The practical caveat is that the same key ordering and version resolution apply as for any multi feed setup, and with a prerelease feed in the list, an unpinned restore can pick up an unexpected build. The mitigation is the same as always, a lock file and explicit version pinning, and the README does not spell that out.

The broader point is that Steeltoe publishes its own packages. The NuGet badge in the README points at the SteeltoeOSS profile on nuget.org, and the packages are per component, with Steeltoe.Common named in the badge. The components are separate NuGet packages, so adopting one of them, say just the configuration client, does not drag in the whole set.

The repository layout reflects the same structure at source level. The src/ directory holds the implementation, there are shared build props files for packages, projects and tests, a versions.props file, a nuget.config, rulesets for debug and release, stylecop.json, and a set of public API scripts, public-api-mark-shipped.ps1 and public-api-verify-shipped.ps1, which is how the project tracks what has been published as public API surface.

Where Steeltoe is the wrong component to reach for

Three boundaries, and the middle one is the practical question most teams face.

The first is that this is a set of clients for platforms that have specific .NET integration stories. If you are running a .NET service on plain Kubernetes with no Spring components, no Cloud Foundry, no Eureka and no config server, most of what Steeltoe provides has nothing to attach to. You would be adding a dependency to talk to something you do not have.

The second is the version line, and it comes back to the branch table. A team that wants the 4.x line gets stability and a slower feature cadence. A team that wants the newest features takes the main branch, which the project labels unstable. There is no third option, and the choice has to be made deliberately rather than by letting the package resolver decide.

The third is that Steeltoe is infrastructure glue, not an application framework. It does not give you configuration management, dependency injection, or an application model. It gives you the client side of a handful of platform contracts, and the value of each one is proportional to how much of that platform you actually use.

The alternative worth naming is writing the client yourself, which for a single endpoint can be a small job, since the protocol on the wire is usually HTTP and JSON. The reason to use Steeltoe instead is that the interesting part is rarely the request, it is the lifecycle. The config client has to watch for changes and refresh, the discovery client has to maintain the service registry relationship and fail over, the management endpoints have to expose the right shapes, and the encryption has to agree with the server's keystore and algorithm. That is the part Steeltoe provides, and it is the part a hand written client gets wrong.

So the sizing question is whether you need one of those lifecycles or just a request. If it is just a request, the framework is overhead. If it is a lifecycle, the framework is the reason you are reading this.

Editorial conclusion

Steeltoe fits a .NET team that has to run on Spring Cloud or Cloud Foundry infrastructure and needs the platform integration to exist on the .NET side, including configuration servers, Eureka or Consul discovery, actuator style management endpoints and the platform's own authentication. It does not fit a .NET team running only on plain Kubernetes with no Spring components, and it does not fit a team that wants the newest features and expects them to be supported. Check three things before you commit. Check which branch and .NET version you need, because the table states main targets .NET 8 to 10 and is unstable, 4.x targets .NET 8 to 10 and is stable, 3.x targets .NET 8 and is stable, and 2.x is .NET Framework 4.6.1 or later and is out of support. Check which feature you actually need, since the components are separate and each one is a dependency with its own lifecycle. And check the packaging feed, because the pre release packages come from a Steeltoe development feed that you add to your nuget.config rather than from NuGet proper. The last push was on 2026-10-14, the newest release listed is 4.3.0 from 2026-09-09, and the license is Apache-2.0.

Frequently asked questions

What is Steeltoe and what does it provide?

Steeltoe provides building blocks for .NET applications that integrate with Spring and Spring Boot environments, Cloud Foundry and Kubernetes with first-party support for Tanzu, including externalised optionally encrypted configuration, service discovery with Eureka and Consul, actuator compatible management endpoints, database connectivity and single sign-on.

Which .NET versions and branches does Steeltoe support?

The README table lists main targeting .NET 8 to 10 as unstable, 4.x targeting .NET 8 to 10 as stable, 3.x targeting .NET 8 as stable, and 2.x targeting .NET Framework 4.6.1 or later as out of support.

How do I get pre release Steeltoe packages?

Add a reference to the Steeltoe development feed in your nuget.config file, pointing a package source with key Steeltoe-ci at the Azure DevOps nuget v3 index, alongside the normal NuGet source.

How does Steeltoe handle encrypted configuration?

It uses Spring Cloud Config Server with external configuration that can be encrypted. The repository's docker-compose file shows the settings the library expects, including a key store location, password and alias, the RSA OAEP algorithm, a salt, and a strong flag.

What management endpoints does Steeltoe expose?

Endpoints compatible with Spring Boot actuators, providing system info such as versions, configuration, service container contents, mapped routes and HTTP traffic, plus heap and thread dumps, health checks, exporting metrics to Prometheus, and changing log levels at runtime.

What license is Steeltoe released under?

Apache-2.0, with a LICENSE file at the root of the repository. The newest listed release is 4.3.0 from 2026-09-09, and the last push was on 2026-10-14.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. SteeltoeOSS/Steeltoe on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/steeltoeoss-steeltoe.svg)](https://hysenlabs.com/projects/steeltoeoss-steeltoe)

Was this useful?