# Bank API: A .NET 11 Compliance Reference for Building OWASP, GDPR, and NLGov-Aligned REST APIs

> Bank API is an open-source design reference project in C# that applies OWASP API Security Top 10, NLGov REST API Design Rules, GDPR data redaction, JWS response signing, and CloudEvents to a working ASP.NET Core 11 minimal API. It is intended as a bootstrap template for teams building compliant APIs in the financial or public sector, not as a connection to any live banking institution.

**erwinkramer/bank-api** — The Bank API is a design reference project suitable to bootstrap development for a compliant and modern API.

- Repository: https://github.com/erwinkramer/bank-api
- Website: https://guanchen.nl
- Stars: 843 · Forks: 79
- Language: C#
- License: NOASSERTION
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/erwinkramer-bank-api

## What Bank API Solves: Compliance from the First Commit

Starting a regulated API from scratch typically means deciding which compliance standards apply, finding reference implementations for each, and wiring them together. Bank API does that wiring and documents it. The README describes it as "a design reference project suitable to bootstrap development for a compliant and modern API."

The compliance list is not aspirational: each item has a checkmark and a reference to the specific standard and the tooling that enforces it. OWASP API Security Top 10 (2023 edition) is checked via the Spectral OWASP ruleset. OpenAPI 3.2.0 compliance is checked via Spectral's OAS ruleset. The Dutch public sector NLGov REST API Design Rules 2.2.1 are checked via the Logius ruleset. GDPR and CCPA data protection requirements are implemented via ASP.NET Core Compliance, which redacts sensitive data from logs. Response signing uses RFC 7515 (JWS) with a X-JWS-Signature header, and the corresponding public keys are served at /.well-known/jwks.json per RFC 7517.

The target audience is .NET developers in regulated industries, particularly the Dutch public sector, who want a working starting point rather than a blank project and a checklist.

## Compliance in Detail: Standards, Tools, and the Spectral Linter

Spectral is the primary linting tool. It validates the generated OpenAPI specification against two rulesets: the Spectral OWASP API Security ruleset and the Spectral OAS ruleset. A third ruleset, Specs.Ruleset/ruleset.bank.yml in the repository, adds project-specific naming conventions and structural requirements.

The NLGov ruleset from Logius validates the API against the Dutch public sector design rules, version 2.2.1. This is a narrow specialization: it is relevant to teams building APIs for or interoperating with Dutch government systems, and mostly irrelevant outside that context.

On the event-driven side, the project implements the CloudEvents 1.0.2 specification for defining event data, its HTTP Protocol Binding for transport, and the HTTP Webhooks specification for event delivery. Events follow the outbox pattern. The OpenAPI 3.2.0 webhook field documents the webhook contract in the same specification file as the REST endpoints.

The Model Context Protocol (MCP) server implements version 2025-11-25 of the spec. The README lists a live MCP server endpoint on Azure Container Apps. The MCPify library handles MCP exposure from the C# code.

## Technology Stack: .NET 11 Minimal API, Aspire, and Kiota

The application is built on ASP.NET Core 11.0 using the minimal API approach rather than controllers. The base services wired in are: resilience (for downstream API calls), health checks, service discovery, hybrid cache, rate limiting, CORS, and request validation. Authentication supports API keys, JWT bearer tokens, and OpenID Connect, with token reuse prevention applied specifically to Microsoft Entra ID tokens.

Aspire handles development bootstrapping and client integrations. Kiota generates type-safe API clients for downstream APIs from their OpenAPI specifications. Gridify handles filtering, ordering, and paging on collection endpoints. Scalar generates interactive API documentation from the OpenAPI spec. The .env.sample file shows three Azure-specific variables: ASPNETCORE_ENVIRONMENT, AZURE_TENANT_ID, and AZURE_CLIENT_ID, confirming that the authentication configuration targets Entra ID.

For testing, the project uses TUnit (a .NET test framework) and the REST Client extension for Visual Studio Code with .http files for quick local testing. OpenTelemetry covers observability.

The Dockerfile builds from the .NET 11 SDK Alpine image, publishes the BankApi.Service.Stable project by default, and exposes port 8080. A multi-stage build keeps the final image small. Zscaler certificate support is included via a .certs/ directory at build time.

## Architecture: Core, Service Variants, MCP, and Sidecars

The project's architecture is layered, as documented in the README's Mermaid flowchart. BankApi.Core contains three packages: Defaults (shared configuration), DownstreamClients (Kiota-generated clients), and Implementation (business logic). Two service projects, BankApi.Service.Beta and BankApi.Service.Stable, depend on Core and represent two API lifecycle stages. BankApi.Orchestration wraps both services for development with Aspire.

BankApi.Mcp provides the MCP server. It depends on Specs.Generated, which is built from the API specifications, creating a direct link between the API contract and the AI agent interface.

The sidecar architecture is visible in the top-level directory structure: Sidecar.Dapr, Sidecar.OpenTelemetry, Sidecar.Proxy, and Sidecar.S3Proxy. Each sidecar runs alongside the main service and provides a cross-cutting concern without being compiled into the service binary. Dapr handles event delivery and service-to-service communication. The S3Proxy sidecar likely handles object storage abstraction, though the README does not describe it in detail.

Infrastructure is managed through Infra.Bicep (Azure Bicep templates), Infra.Generated (generated infrastructure code), and Infra.Kro (Kubernetes Resource Objects). The live deployment runs on Azure Container Apps.

## Getting Started: Dev Container, Prerequisites, and Aspire

The README documents a Dev Container option for development. Without it, three prerequisites are needed: the .NET 11 SDK, all recommended VS Code extensions listed in .vscode/extensions.json, and the Aspire CLI. The .devcontainer/devcontainer.json configuration handles the full development environment when used.

The project uses Azure Entra ID for authentication. The .env.sample file shows the required environment variables:

```bash
ASPNETCORE_ENVIRONMENT=Production
AZURE_TENANT_ID=b81eb003-1c5c-45fd-848f-90d9d3f8d016
AZURE_CLIENT_ID=b6997777-3799-4c55-b78a-4ce96e3d959c
AZURE_CLIENT_SECRET=REPLACE_ME
```

Replace the sample tenant and client IDs with your own Entra ID application values, and set AZURE_CLIENT_SECRET to the actual client secret. The README does not document the steps for registering an Entra ID application or what permissions it requires, so some familiarity with Azure app registrations is assumed.

The Dockerfile builds BankApi.Service.Stable by default using the AlpineContainer publish profile, targeting .NET 11 Alpine images. The compiled service listens on port 8080.

The project includes an Arazzo workflow description in .arazzo/ and an APIs.json file (apis.yaml) at the repository root documenting the API according to the APIs.json v0.21 specification. These are machine-readable API catalog files aimed at API discovery tooling.

## Limitations, the CC BY-NC-SA License, and a Comparison with eShopOnContainers

Bank API's compliance focus creates a specific limitation: the sidecar architecture, Aspire orchestration, Azure Bicep infrastructure, and Dapr integration add considerable setup complexity for teams that do not need all of it. There is no documented path to disable individual sidecars or swap Azure infrastructure for a different cloud. The project is a reference, not a modular library.

The README badge shows a CC BY-NC-SA 4.0 license. This license permits non-commercial use and modification with attribution and share-alike conditions, but prohibits commercial use without a separate arrangement. The GitHub license field shows NOASSERTION (GitHub did not auto-detect it). Check the LICENSE file before using this as a commercial project foundation.

A comparable Microsoft reference is eShopOnContainers (now evolved into eShop on Dapr), which demonstrates microservice architecture patterns in .NET with an e-commerce domain. eShop focuses on internal service decomposition using DDD and event sourcing patterns; Bank API focuses on external API compliance standards (OWASP, NLGov, JWS) and a financial domain. Teams that need internal DDD patterns will find eShop more applicable; teams building regulated external APIs targeting the Dutch public sector or similar standards will find Bank API more directly useful.

The last push was on 2026-09-25. The project is not archived and shows regular releases, with the most recent tagged dotnet10-4 on 2026-06-28. The Dockerfile and README reference .NET 11 and ASP.NET Core 11.0, reflecting a recent upgrade beyond the dotnet10 release series.

## Conclusion

Bank API is a useful starting point for .NET developers who need a fully wired compliance baseline covering OWASP, GDPR, NLGov, and JWS signing in a single repository, particularly in the Dutch public sector or any context where those standards apply. It is not a general-purpose API starter template; its compliance scope and sidecar architecture add complexity that is unnecessary outside regulated environments. The CC BY-NC-SA 4.0 license restricts commercial use, so confirm whether your use case qualifies before using it as a project foundation.

## FAQ

### What is Bank API?

Bank API is a C# design reference project built on ASP.NET Core 11 that demonstrates how to build a compliant REST API covering OWASP API Security Top 10, NLGov design rules, GDPR data redaction, JWS response signing, and CloudEvents. It is not a connection to a live banking institution.

### How do you use Bank API as a starting point for a new project?

The README describes it as a bootstrap reference: clone the repository, set up the Dev Container or install the .NET 11 SDK, Aspire CLI, and VS Code extensions, then configure the Azure Entra ID credentials in .env.sample. The compliance rulesets and sidecar configuration are included and can be adapted.

### Is Bank API free to use commercially?

The README shows a CC BY-NC-SA 4.0 license badge, which restricts commercial use. Non-commercial use with attribution and share-alike is permitted. The LICENSE file in the repository contains the full terms.

## Sources

- [erwinkramer/bank-api on GitHub](https://github.com/erwinkramer/bank-api)
- [Issues](https://github.com/erwinkramer/bank-api/issues)
- [Project website](https://guanchen.nl)
- [README](https://github.com/erwinkramer/bank-api/blob/main/README.md)
- [Releases](https://github.com/erwinkramer/bank-api/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/erwinkramer-bank-api
