Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion completed_developments.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
## Completed developments (most recent first)

(a non exhaustive summary!)
This is a curated log of major engineering milestones, deliberately **not** a complete history. The authoritative record of shipped API functionality is the Resource Docs / API Explorer, the glossary and the README — this file exists for the work those structurally cannot show: re-platforms, dependency removals, performance and architecture changes that alter no API signature.

### Lift Web → http4s re-platform (2026)

The entire OBP-API HTTP surface — every API version from v1.2.1 to v7.0.0, plus Berlin Group and UK Open Banking — now runs on [http4s](https://http4s.org/) and Cats IO. Lift Web and Jetty have been removed entirely.

Key points:

* Done **in place**, endpoint by endpoint, with zero API version bumps and zero signature changes — API versioning at OBP is tech-agnostic, so a framework migration is invisible to API consumers. (This is also why this milestone appears here and not in the API catalogs: it changed no API contract.)
* Purely functional Scala (Cats Effect), non-blocking I/O.
* Fewer dependencies; unblocks the Scala 2.13 / 3.x upgrade (see [roadmap.md](roadmap.md), Theme 3 — Lift Mapper persistence is the remaining Lift dependency).


* New / Enhanced support for Berlin Group, STET, UK Open Banking, Polish and Australia CDR APIs e.g.
Expand Down
14 changes: 0 additions & 14 deletions dependency-check-suppressions.xml
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd">

<suppress>
<notes><![CDATA[
CPE collision. CVE-2026-33504 is a SQL injection in the Ory Hydra server
(the Go service, fixed in Hydra v26.2.0). The Java client SDK
sh.ory.hydra:hydra-client is a generated HTTP client with no SQL code,
so it cannot be affected.

Tracking the dep itself for eventual removal — integrate_with_hydra
defaults to false and TESOBE does not deploy with Hydra enabled.
]]></notes>
<packageUrl regex="true">^pkg:maven/sh\.ory\.hydra/hydra-client@.*$</packageUrl>
<cve>CVE-2026-33504</cve>
</suppress>

<suppress>
<notes><![CDATA[
CPE collision. CVE-2023-37475 is a DoS in Hamba Avro
Expand Down
20 changes: 15 additions & 5 deletions docs/IdP/OAUTH2_IDENTITY_PROVIDERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,27 @@ rejects foreign client IDs — and it is instance-global (no per-tenant
scoping) and needs a restart to change. The natural end-state — validation
asking "does an *enabled, registered* Consumer with this client ID exist?" —
would make the allowlist manageable at runtime via API Manager and express
per-tenant scoping (the Hydra introspection path already resolves consumers
by client ID this way). Until then, the recommended combination is policy 3
per-tenant scoping. Until then, the recommended combination is policy 3
above for rejection plus pre-registered Consumers for per-app control.

## Operator-controlled IdPs (Keycloak, OBP-OIDC, Hydra)
## Operator-controlled IdPs (Keycloak, OBP-OIDC)

These run under the API operator's control: only applications the operator
registers can obtain tokens at all, so the "any stranger's app gets valid
tokens" problem does not exist. They are exempt from audience-allowlist and
enablement enforcement (Hydra additionally uses token introspection rather
than JWT validation).
enablement enforcement. Both can be enabled simultaneously (e.g. OBP-OIDC for
development, Keycloak for production) — tokens are dispatched per request by
their `iss` claim.

## Consent-bound flows (consent_id claim)

Flows that bind an access token to a Consent (e.g. UK Open Banking AIS)
require the IdP to include a `consent_id` claim in the access tokens it
issues during the consent authorisation flow. OBP-API reads the claim and
validates the consent (status, consumer match, revocation) against its own
database on every request — the IdP never stores consent state. OBP-OIDC
supports this natively; in Keycloak use a protocol mapper that copies the
consent id from the auth session into the access token.

## Client requirement (all providers)

Expand Down
9 changes: 0 additions & 9 deletions obp-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -492,15 +492,6 @@
<artifactId>java-scriptengine</artifactId>
<version>2.0.0</version>
</dependency>
<!--
Java Client for ORY Hydra
https://github.com/ory/hydra-client-java
-->
<dependency>
<groupId>sh.ory.hydra</groupId>
<artifactId>hydra-client</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
Expand Down
141 changes: 13 additions & 128 deletions obp-api/src/main/resources/docs/introductory_system_documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,11 @@ For more detailed information or the sources of truths, please refer to the indi
- 3.4 [Opey II (AI Agent)](#34-opey-ii-ai-agent)
- 3.5 [OBP-OIDC (Development Provider)](#35-obp-oidc-development-provider)
- 3.6 [Keycloak Integration (Production Provider)](#36-keycloak-integration-production-provider)
- 3.7 [Ory Hydra (Production Provider)](#37-ory-hydra-production-provider)
- 3.8 [OBP-Hola](#38-obp-hola)
- 3.9 [OBP-SEPA-Adapter](#39-obp-sepa-adapter)
- 3.10 [OBP-Rabbit-Cats-Adapter](#310-obp-rabbit-cats-adapter)
- 3.11 [Connectors](#311-connectors)
- 3.12 [Adapters](#312-adapters)
- 3.7 [OBP-Hola](#37-obp-hola)
- 3.8 [OBP-SEPA-Adapter](#38-obp-sepa-adapter)
- 3.9 [OBP-Rabbit-Cats-Adapter](#39-obp-rabbit-cats-adapter)
- 3.10 [Connectors](#310-connectors)
- 3.11 [Adapters](#311-adapters)
- 3.13 [Message Docs](#313-message-docs)
- 3.14 [OBP-MCP (Model Context Protocol Server)](#314-obp-mcp-model-context-protocol-server)
4. [Standards Compliance](#standards-compliance)
Expand Down Expand Up @@ -395,7 +394,7 @@ The Open Bank Project (OBP) is an open-source RESTful API platform for banks tha

**OIDC Providers:**

- Production: Keycloak, Hydra, Google, Yahoo, Auth0, Azure AD
- Production: Keycloak, Google, Yahoo, Auth0, Azure AD
- Development/Testing: OBP-OIDC

---
Expand Down Expand Up @@ -739,120 +738,7 @@ docker pull openbankproject/obp-keycloak:main-themed

---

### 3.7 Ory Hydra (Production Provider)

**Purpose:** Cloud-native OAuth2 and OpenID Connect server for production deployments

**Overview:**

Ory Hydra is a hardened, open-source OAuth 2.0 and OpenID Connect server optimized for low-latency, high-throughput, and low resource consumption. It integrates with OBP-API to provide enterprise-grade authentication and authorization.

**Key Features:**

- **OAuth2 & OIDC Compliance:** Full implementation of OAuth 2.0 and OpenID Connect specifications
- **Cloud Native:** Designed for containerized deployments (Docker, Kubernetes)
- **Performance:** Low latency and high throughput
- **Separation of Concerns:** Hydra handles OAuth/OIDC flow; identity management delegated to custom Identity Provider
- **Security Hardened:** Regular security audits and compliance certifications
- **Storage Backend:** PostgreSQL, MySQL, CockroachDB support

**Architecture:**

```
Client → Hydra (OAuth2 Server) → OBP Hydra Identity Provider → OBP-API
Database (PostgreSQL)
```

**Components:**

- **Ory Hydra:** OAuth2/OIDC server
- **OBP Hydra Identity Provider:** Custom login/consent UI and user management
- **OBP-API:** Banking API with Hydra integration

**OBP-API Configuration:**

```properties
# Enable Hydra login
login_with_hydra=true

# Hydra server URLs
hydra_public_url=http://127.0.0.1:4444
hydra_admin_url=http://127.0.0.1:4445

# Consent scopes
hydra_consents=ReadAccountsBasic,ReadAccountsDetail,ReadBalances,ReadTransactionsBasic,ReadTransactionsDebits,ReadTransactionsDetail

# JWKS validation
oauth2.jwk_set.url=http://127.0.0.1:4444/.well-known/jwks.json

# Mirror consumers to Hydra clients
mirror_consumer_in_hydra=true
```

**Hydra Identity Provider Configuration:**

```properties
# Server port
server.port=8086

# OBP-API URL
obp.base_url=http://localhost:8080
endpoint.path.prefix=${obp.base_url}/obp/v4.0.0

# Hydra admin URL
oauth2.admin_url=http://127.0.0.1:4445

# Service account credentials
identity_provider.user.username=serviceuser
identity_provider.user.password=password
consumer_key=your-consumer-key

# mTLS configuration (optional)
mtls.keyStore.path=file:///path/to/keystore.jks
mtls.keyStore.password=keystore-password
mtls.trustStore.path=file:///path/to/truststore.jks
mtls.trustStore.password=truststore-password
```

**Docker Deployment:**

```bash
# Start Hydra with docker-compose
docker-compose -f quickstart.yml \
-f quickstart-postgres.yml \
up --build

# Verify Hydra is running
curl http://127.0.0.1:4444/.well-known/openid-configuration
```

**Hydra quickstart.yml environment:**

```yaml
environment:
- URLS_CONSENT=http://localhost:8086/consent
- URLS_LOGIN=http://localhost:8086/login
- URLS_LOGOUT=http://localhost:8086/logout
```

**Use Cases:**

- High-performance OAuth2/OIDC deployments
- Microservices architectures requiring centralized authentication
- Multi-tenant banking platforms
- Open Banking TPP integrations
- Cloud-native banking solutions

**Repositories:**

- Ory Hydra: https://github.com/ory/hydra
- OBP Hydra Identity Provider: https://github.com/OpenBankProject/OBP-Hydra-Identity-Provider
- Demo OAuth2 Client: https://github.com/OpenBankProject/OBP-Hydra-OAuth2

---

### 3.8 OBP-Hola
### 3.7 OBP-Hola

**Purpose:** Reference implementation for OAuth2 authentication and consent flow testing

Expand All @@ -878,8 +764,7 @@ OBP-Hola is a Java/Spring Boot application that demonstrates and tests OBP authe
**Dependencies:**

- **OBP-API:** Core banking API
- **Ory Hydra:** OAuth2 server
- **OBP Hydra Identity Provider:** Identity management
- **An OIDC provider:** OBP-OIDC (development) or Keycloak (production)

**Use Cases:**

Expand Down Expand Up @@ -934,7 +819,7 @@ docker run -p 48123:48123 \

---

### 3.9 OBP-SEPA-Adapter
### 3.8 OBP-SEPA-Adapter

**Purpose:** Reference implementation for SEPA payment processing with OBP-API

Expand Down Expand Up @@ -1092,7 +977,7 @@ sbt "runMain sepa.scheduler.ProcessIncomingFilesActorSystem"

---

### 3.10 OBP-Rabbit-Cats-Adapter
### 3.9 OBP-Rabbit-Cats-Adapter

**Purpose:** OBP-Rabbit-Cats-Adapter is a functional, type-safe adapter that bridges OBP-API with Core Banking Systems (CBS) using RabbitMQ messaging and/or gRPC. It is built on a modern Scala stack using Cats Effect and http4s.

Expand Down Expand Up @@ -1188,7 +1073,7 @@ When gRPC is enabled, the adapter starts a gRPC server alongside the RabbitMQ co

---

### 3.11 Connectors
### 3.10 Connectors

**Purpose:** Connectors provide the integration layer between OBP-API and backend banking systems or data sources.

Expand Down Expand Up @@ -1257,7 +1142,7 @@ When gRPC is enabled, the adapter starts a gRPC server alongside the RabbitMQ co

---

### 3.12 Adapters
### 3.11 Adapters

**Purpose:** Adapters are backend services that receive messages from OBP-API connectors and respond according to Message Doc definitions.

Expand Down Expand Up @@ -2677,7 +2562,7 @@ Authorization: Bearer ACCESS_TOKEN

**Providers:**

- **Production:** Keycloak, Hydra, Google, Yahoo, Auth0, Azure AD
- **Production:** Keycloak, Google, Yahoo, Auth0, Azure AD
- **Development:** OBP-OIDC

**Configuration Example (Keycloak):**
Expand Down
24 changes: 6 additions & 18 deletions obp-api/src/main/resources/props/sample.props.template
Original file line number Diff line number Diff line change
Expand Up @@ -1330,27 +1330,15 @@ outboundAdapterCallContext.generalContext
#connector.name.export.as.endpoints=stored_procedure_vDec2019
# ------------------------------------------------------------------------------------------

# ------------------------------ Hydra oauth2 props ------------------------------
## if integrate_with_hydra set to true, all other props must not be empty
#integrate_with_hydra=true
#hydra_public_url=http://127.0.0.1:4444
#hydra_admin_url=http://127.0.0.1:4445
#hydra_consents=ReadAccountsBasic,ReadAccountsDetail,ReadBalances,ReadTransactionsBasic,ReadTransactionsDebits,ReadTransactionsDetail
## check the oauth2.jwk_set.url props, it must contains jwks.json that locate in ${hydra_public_url}/.well-known/jwks.json
##oauth2.jwk_set.url=http://localhost:4444/.well-known/jwks.json,https://www.googleapis.com/oauth2/v3/certs
## whether create hydra client when create consumer, default is false
#mirror_consumer_in_hydra=true
# There are 2 ways of authenticating OAuth 2.0 Clients at the /oauth2/token we support: private_key_jwt and client_secret_post
# hydra_token_endpoint_auth_method=private_key_jwt
# hydra_supported_token_endpoint_auth_methods=client_secret_basic,client_secret_post,private_key_jwt
## ORY Hydra login url is "obp-api-hostname/user_mgt/login" implies "true" in order to avoid creation of a new user during OIDC flow
# hydra_uses_obp_user_credentials=true
# ------------------------------ Hydra oauth2 props end ------------------------------

# ------------------------------ OBP-OIDC oauth2 props ------------------------------
## OBP-OIDC Provider Configuration
## Choose which OIDC provider to use: 'keycloak' or 'obp-oidc'
## OIDC provider(s) to advertise via the /well-known endpoint: 'keycloak', 'obp-oidc',
## or a comma-separated list to run several in parallel (tokens are dispatched per
## request by their iss claim, so e.g. OBP-OIDC and Keycloak can serve side by side).
#oauth2.oidc_provider=obp-oidc
## Consent-bound flows (e.g. UK Open Banking AIS) additionally require the provider to
## include a consent_id claim in the access tokens it issues during the consent
## authorisation flow — OBP-API resolves and validates the consent from its own database.

## OBP-OIDC OAuth2 Provider Settings
#oauth2.obp_oidc.host=http://localhost:9000
Expand Down
31 changes: 0 additions & 31 deletions obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ import code.customerlinks.CustomerLink
import code.userlocks.UserLocks
import code.users._
import code.util.Helper.MdcLoggable
import code.util.HydraUtil
import code.validation.JsonSchemaValidation
import code.views.Views
import code.views.system.{AccountAccess, ViewDefinition, ViewPermission}
Expand All @@ -160,7 +159,6 @@ import net.liftweb.util._
import org.apache.commons.io.FileUtils

import java.io.{File, FileInputStream}
import java.util.stream.Collectors
import java.util.{Locale, TimeZone}
import scala.util.control.NonFatal

Expand Down Expand Up @@ -582,35 +580,6 @@ class Boot extends MdcLoggable {

// ConnectorEndpoints (connector.name.export.as.endpoints) registered via Lift statelessDispatch
// which is no longer reachable (Lift bridge removed in Phase B). Disabled until migrated to http4s.
if(HydraUtil.integrateWithHydra && HydraUtil.mirrorConsumerInHydra) {
createHydraClients()
}

}

// create Hydra client if exists active consumer but missing Hydra client
def createHydraClients() = {
try {
import scala.concurrent.ExecutionContext.Implicits.global
// exists hydra clients id
val oAuth2ClientIds = HydraUtil.hydraAdmin.listOAuth2Clients(Long.MaxValue, 0L).stream()
.map[String](_.getClientId)
.collect(Collectors.toSet())

Consumers.consumers.vend.getConsumersFuture(Nil, None).foreach{ consumers =>
consumers.filter(consumer => consumer.isActive.get && !oAuth2ClientIds.contains(consumer.key.get))
.foreach(HydraUtil.createHydraClient(_))
}
} catch {
case e: Exception =>
if(HydraUtil.integrateWithHydra) {
logger.error("------------------------------ Mirror consumer in hydra issue ------------------------------")
e.printStackTrace()
} else {
logger.warn("------------------------------ Mirror consumer in hydra issue ------------------------------")
logger.warn(e)
}
}
}

def schemifyAll() = {
Expand Down
Loading
Loading