Skip to content

Commit

Permalink
Feature/oidf 54 (#26)
Browse files Browse the repository at this point in the history
* chore: Removed redundant HTTPCache

* chore: Uncommented ios targets back

* refactor: refactored serializeNullable()

* refactor: refactored deserialize()

* refactor: refactored OutgoingEntityStatementContent.bytes()

* refactor: refactored the tests to use assertEquals()

* refactor: Changed the response body to jwt string

* refactor: Removed unnecessary converter

* feat: implement jwk persistence

* fix: remove unused statement

* fix: github CI

* feat/OIDF-51 - Implement Persistence Module (#21)

* merge oidf-7

* fix: models package

* fix: openapi TrustMarkOwner property

* fix: create account method return type

* fix: rename file for consistency

* feat: implement migration

* fix: repository dependency

* fix: add missing trailing new line

* feat: implement services module

* fix: package path

* fix: remove unused file

* fix: add missing entity to openapi spec

* feat: persist generated keys

* fix: typo

* fix: missing deps

* fix: ci docker command

* fix: dependency

* fix: remove unnecessary statement

* feat: abstract jwk to its own module

* feat: encrypt private keys when saving to database

* feat: add note to README regarding usage of Local KMS in prod envs

* fix: adapt key encryption test cases for when APP_KEY is null

* fix: adjust function name

* fix: add kotlin-js-store to gitignore

* fix: clean common gradle file

* fix: disable android build

* fix: remove js implementation from services

* feat: implement Subordinate repository (#29)

* feat: implement federation server structure (#28)

* feat: implement federation server structure

* feat: implement Subordinate repository

* fix: remove unused files

* feat: implement federation list endpoint

---------

Co-authored-by: Zoe Maas <[email protected]>
  • Loading branch information
jcmelati and Zoe Maas authored Aug 16, 2024
1 parent 4848ba3 commit e6e8527
Show file tree
Hide file tree
Showing 65 changed files with 3,947 additions and 484 deletions.
9 changes: 5 additions & 4 deletions .env
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
DATASOURCE_URL=jdbc:postgresql://localhost:5432/openid-federation-db
DATASOURCE_USER=openid-federation-db-user
DATASOURCE_PASSWORD=openid-federation-db-password
DATASOURCE_DB=openid-federation-db
DATASOURCE_URL=jdbc:postgresql://localhost:5432/openid-federation-db
DATASOURCE_USER=openid-federation-db-user
DATASOURCE_PASSWORD=openid-federation-db-password
DATASOURCE_DB=openid-federation-db
APP_KEY=Nit5tWts42QeCynT1Q476LyStDeSd4xb
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ captures
/.temp/
/docker/.env
/.run/*
kotlin-js-store/
165 changes: 94 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,71 +1,94 @@
<h1 align="center">
<br>
<a href="https://www.sphereon.com"><img src="https://sphereon.com/content/themes/sphereon/assets/img/logo.svg" alt="Sphereon" width="400"></a>
<br>OpenID Federation Monorepo
<br>
</h1>

# Background

OpenID Federation is a framework designed to facilitate the secure and interoperable interaction of entities within a federation. This involves the use of JSON Web Tokens (JWTs) to represent and convey necessary information for entities to participate in federations, ensuring trust and security across different organizations and systems.

In the context of OpenID Federation, Entity Statements play a crucial role. These are signed JWTs that contain details about the entity, such as its public keys and metadata. This framework allows entities to assert their identity and capabilities in a standardized manner, enabling seamless integration and interoperability within federations.

## Key Concepts

- **Federation**: A group of organizations that agree to interoperate under a set of common rules defined in a federation policy.
- **Entity Statements**: JSON objects that contain metadata about entities (IdPs, RPs) and their federation relationships.
- **Trust Chains**: Mechanisms by which parties in a federation verify each other’s trustworthiness through a chain of entity statements, leading back to a trusted authority.
- **Federation API**: Interfaces defined for entities to exchange information and perform operations necessary for federation management.

## Core Components

- **Federation Operator**: The central authority in a federation that manages policy and trust chain verification.
- **Identity Providers (IdPs)**: Entities that authenticate users and provide identity assertions to relying parties.
- **Relying Parties (RPs)**: Entities that rely on identity assertions provided by IdPs to offer services to users.

## Technical Features

- **JSON Web Tokens (JWT)**: Used for creating verifiable entity statements and security assertions.
- **JSON Object Signing and Encryption (JOSE)**: Standards for signing and encrypting JSON-based objects to ensure their integrity and confidentiality.

## Operational Model

- **Dynamic Federation**: Allows entities to join or adjust their federation relationships dynamically, based on real-time verification of entity statements.
- **Trust Model**: Establishes a model where trust is derived from known and verifiable sources and can be dynamically adjusted according to real-time interactions and policy evaluations.
- **Conflict Resolution**: Defines how disputes or mismatches in federation policies among entities are resolved.

# Data Structure

## Entity Statement Overview

### 1. Definition
- An Entity Statement is a signed JWT containing information necessary for the Entity to participate in federations.
- **Entity Configuration**: An Entity Statement about itself.
- **Subordinate Statement**: An Entity Statement about an Immediate Subordinate Entity by a Superior Entity.

### 2. Requirements and Structure
- **Type**: JWT must be explicitly typed as `entity-statement+jwt`.
- **Signature**: Signed using the issuer’s private key, preferably using ECDSA with P-256 and SHA-256 (ES256).
- **Key ID (kid)**: The header must include the Key ID of the signing key.

### 3. Claims in an Entity Statement
- **iss (Issuer)**: Entity Identifier of the issuer.
- **sub (Subject)**: Entity Identifier of the subject.
- **iat (Issued At)**: Time the statement was issued.
- **exp (Expiration Time)**: Time after which the statement is no longer valid.
- **jwks (JSON Web Key Set)**: Public keys for verifying signatures. Required except in specific cases like Explicit Registration.
- **authority_hints** (Optional): Identifiers of Intermediate Entities or Trust Anchors that may issue Subordinate Statements.
- **metadata** (Optional): Represents the Entity’s Types and metadata.
- **metadata_policy** (Optional): Defines a metadata policy, applicable to the subject and its Subordinates.
- **constraints** (Optional): Defines Trust Chain constraints.
- **crit** (Optional): Specifies critical claims that must be understood and processed.
- **metadata_policy_crit** (Optional): Specifies critical metadata policy operators that must be understood and processed.
- **trust_marks** (Optional): Array of JSON objects, each representing a Trust Mark.
- **trust_mark_issuers** (Optional): Specifies trusted issuers of Trust Marks.
- **trust_mark_owners** (Optional): Specifies ownership of Trust Marks by different Entities.
- **source_endpoint** (Optional): URL to fetch the Entity Statement from the issuer.

### 4. Usage and Flexibility
- Entity Statements can include additional claims as required by applications and protocols.
- Metadata in Subordinate Statements overrides that in the Entity’s own configuration.
<h1 align="center">
<br>
<a href="https://www.sphereon.com"><img src="https://sphereon.com/content/themes/sphereon/assets/img/logo.svg" alt="Sphereon" width="400"></a>
<br>OpenID Federation Monorepo
<br>
</h1>

# Background

OpenID Federation is a framework designed to facilitate the secure and interoperable interaction of entities within a
federation. This involves the use of JSON Web Tokens (JWTs) to represent and convey necessary information for entities
to participate in federations, ensuring trust and security across different organizations and systems.

In the context of OpenID Federation, Entity Statements play a crucial role. These are signed JWTs that contain details
about the entity, such as its public keys and metadata. This framework allows entities to assert their identity and
capabilities in a standardized manner, enabling seamless integration and interoperability within federations.

## Key Concepts

- **Federation**: A group of organizations that agree to interoperate under a set of common rules defined in a
federation policy.
- **Entity Statements**: JSON objects that contain metadata about entities (IdPs, RPs) and their federation
relationships.
- **Trust Chains**: Mechanisms by which parties in a federation verify each other’s trustworthiness through a chain of
entity statements, leading back to a trusted authority.
- **Federation API**: Interfaces defined for entities to exchange information and perform operations necessary for
federation management.

## Core Components

- **Federation Operator**: The central authority in a federation that manages policy and trust chain verification.
- **Identity Providers (IdPs)**: Entities that authenticate users and provide identity assertions to relying parties.
- **Relying Parties (RPs)**: Entities that rely on identity assertions provided by IdPs to offer services to users.

## Technical Features

- **JSON Web Tokens (JWT)**: Used for creating verifiable entity statements and security assertions.
- **JSON Object Signing and Encryption (JOSE)**: Standards for signing and encrypting JSON-based objects to ensure their
integrity and confidentiality.

## Operational Model

- **Dynamic Federation**: Allows entities to join or adjust their federation relationships dynamically, based on
real-time verification of entity statements.
- **Trust Model**: Establishes a model where trust is derived from known and verifiable sources and can be dynamically
adjusted according to real-time interactions and policy evaluations.
- **Conflict Resolution**: Defines how disputes or mismatches in federation policies among entities are resolved.

# Local Key Management System - Important Notice

Local Key Management Service is designed primarily for testing, development, and local experimentation
purposes. **It is not intended for use in production environments** due to significant security and compliance risks.

# Data Structure

## Entity Statement Overview

### 1. Definition

- An Entity Statement is a signed JWT containing information necessary for the Entity to participate in federations.
- **Entity Configuration**: An Entity Statement about itself.
- **Subordinate Statement**: An Entity Statement about an Immediate Subordinate Entity by a Superior Entity.

### 2. Requirements and Structure

- **Type**: JWT must be explicitly typed as `entity-statement+jwt`.
- **Signature**: Signed using the issuer’s private key, preferably using ECDSA with P-256 and SHA-256 (ES256).
- **Key ID (kid)**: The header must include the Key ID of the signing key.

### 3. Claims in an Entity Statement

- **iss (Issuer)**: Entity Identifier of the issuer.
- **sub (Subject)**: Entity Identifier of the subject.
- **iat (Issued At)**: Time the statement was issued.
- **exp (Expiration Time)**: Time after which the statement is no longer valid.
- **jwks (JSON Web Key Set)**: Public keys for verifying signatures. Required except in specific cases like Explicit
Registration.
- **authority_hints** (Optional): Identifiers of Intermediate Entities or Trust Anchors that may issue Subordinate
Statements.
- **metadata** (Optional): Represents the Entity’s Types and metadata.
- **metadata_policy** (Optional): Defines a metadata policy, applicable to the subject and its Subordinates.
- **constraints** (Optional): Defines Trust Chain constraints.
- **crit** (Optional): Specifies critical claims that must be understood and processed.
- **metadata_policy_crit** (Optional): Specifies critical metadata policy operators that must be understood and
processed.
- **trust_marks** (Optional): Array of JSON objects, each representing a Trust Mark.
- **trust_mark_issuers** (Optional): Specifies trusted issuers of Trust Marks.
- **trust_mark_owners** (Optional): Specifies ownership of Trust Marks by different Entities.
- **source_endpoint** (Optional): URL to fetch the Entity Statement from the issuer.

### 4. Usage and Flexibility

- Entity Statements can include additional claims as required by applications and protocols.
- Metadata in Subordinate Statements overrides that in the Entity’s own configuration.
2 changes: 0 additions & 2 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '3.9'

services:
db:
image: postgres:latest
Expand Down
5 changes: 4 additions & 1 deletion modules/admin-server/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ java {
}

dependencies {
api(projects.modules.openapi)
api(projects.modules.openidFederationCommon)
api(projects.modules.persistence)
api(projects.modules.services)
implementation(libs.springboot.actuator)
implementation(libs.springboot.web)
implementation(libs.springboot.data.jdbc)
Expand All @@ -42,4 +45,4 @@ tasks.withType<Test> {
events("started", "skipped", "passed", "failed")
showStandardStreams = true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ import org.springframework.boot.runApplication
class Application

fun main(args: Array<String>) {
runApplication<Application>(*args)
}
runApplication<Application>(*args)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.sphereon.oid.fed.server.admin.controllers

import com.sphereon.oid.fed.openapi.models.AccountDTO
import com.sphereon.oid.fed.openapi.models.CreateAccountDTO
import com.sphereon.oid.fed.services.AccountService
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/accounts")
class AccountController {
private val accountService = AccountService()

@GetMapping
fun getAccounts(): List<AccountDTO> {
return accountService.findAll()
}

@PostMapping
fun createAccount(@RequestBody account: CreateAccountDTO): AccountDTO {
return accountService.create(account)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.sphereon.oid.fed.server.admin.controllers

import com.sphereon.oid.fed.openapi.models.JwkAdminDTO
import com.sphereon.oid.fed.services.KeyService
import com.sphereon.oid.fed.services.extensions.toJwkAdminDTO
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/accounts/{accountUsername}/keys")
class KeyController {
private val keyService = KeyService()

@PostMapping
fun create(@PathVariable accountUsername: String): JwkAdminDTO {
val key = keyService.create(accountUsername)
return key.toJwkAdminDTO()
}

@GetMapping
fun getKeys(@PathVariable accountUsername: String): List<JwkAdminDTO> {
val keys = keyService.getKeys(accountUsername)
return keys
}

@DeleteMapping("/{keyId}")
fun revokeKey(
@PathVariable accountUsername: String,
@PathVariable keyId: Int,
@RequestParam reason: String?
): JwkAdminDTO {
return keyService.revokeKey(accountUsername, keyId, reason)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.sphereon.oid.fed.server.admin.controllers

import com.sphereon.oid.fed.persistence.models.Subordinate
import com.sphereon.oid.fed.services.SubordinateService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/accounts/{accountUsername}/subordinates")
class SubordinateController {
private val subordinateService = SubordinateService()

@GetMapping
fun getSubordinates(@PathVariable accountUsername: String): List<Subordinate> {
return subordinateService.findSubordinatesByAccount(accountUsername)
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
spring.config.import=optional:file:../../.env[.properties]

spring.application.name=OpenID Federation

spring.datasource.url=${DATASOURCE_URL}
spring.datasource.username=${DATASOURCE_USER}
spring.datasource.password=${DATASOURCE_PASSWORD}
spring.datasource.driver-class-name=org.postgresql.Driver

# Mapping /actuator/health to /status
management.endpoints.web.base-path=/
management.endpoints.web.path-mapping.health=status
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import org.springframework.boot.test.context.SpringBootTest
@SpringBootTest
class ApplicationTests {

@Test
fun contextLoads() {
}
@Test
fun contextLoads() {
}

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.sphereon.oid.fed.server.admin

import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.web.servlet.MockMvc
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.*
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
Expand Down
27 changes: 27 additions & 0 deletions modules/federation-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Federation Server

API
<br>
```/status``` - To check health status

<br>

Add environment file (.env) with following properties

```
DATASOURCE_USER=<USER>
DATASOURCE_PASSWORD=<PASSWORD>
DATASOURCE_URL=<URL>
```

To build
<br>
```./gradlew :modules:federation-server:build```

To run
<br>
```./gradlew :modules:federation-server:bootRun```

To run tests
<br>
```./gradlew :modules:federation-server:test```
Loading

0 comments on commit e6e8527

Please sign in to comment.