public Config read() {

    var federationEntityStatementJwksPath = loadJwks(CONFIG_FEDERATION_ENTITY_STATEMENT_JWKS_PATH);

    var baseUri =
        configProvider
            .get(CONFIG_BASE_URI)
            .map(URI::create)
            .orElseThrow(() -> new IllegalArgumentException("no 'base_uri' configured"));

    var idpDiscoveryUri =
        configProvider
            .get(CONFIG_IDP_DISCOVERY_URI)
            .map(URI::create)
            .orElseThrow(
                () ->
                    new IllegalArgumentException(
                        "no '%s' configured".formatted(CONFIG_IDP_DISCOVERY_URI)));

    var host = configProvider.get(CONFIG_HOST).orElse("0.0.0.0");
    var port = getPortConfig(CONFIG_PORT, 1234);
    var managementPort = getPortConfig(CONFIG_MANAGEMENT_PORT, 1235);

    var fedmaster =
        configProvider
            .get(CONFIG_FEDERATION_MASTER)
            .map(URI::create)
            .orElse(URI.create("https://app-test.federationmaster.de"));

    var appName =
        configProvider
            .get(CONFIG_APP_NAME)
            .orElseThrow(() -> new IllegalArgumentException("missing 'app_name' configuration"));

    var entityStatementTtl =
        configProvider.get(CONFIG_ES_TTL).map(Duration::parse).orElse(Duration.ofHours(1));

    var federationConfig =
        FederationConfig.create()
            .sub(baseUri)
            .iss(baseUri)
            .appName(appName)
            .federationMaster(fedmaster)

            // safety, remove the private key as we don't need it here
            .entitySigningKeys(federationEntityStatementJwksPath.toPublicJWKSet())
            .entitySigningKey(federationEntityStatementJwksPath.getKeys().get(0).toECKey())
            .ttl(entityStatementTtl)
            .scopes(getScopes())
            .redirectUris(List.of(baseUri.resolve("/auth/callback").toString()))
            .build();

    var supportedResponseTypes = List.of("code");

    var relyingPartyConfig =
        new RelyingPartyConfig(supportedResponseTypes, loadAllowedRedirectUrls());

    return new Config(
        relyingPartyConfig,
        federationConfig,
        host,
        port,
        managementPort,
        baseUri,
        idpDiscoveryUri,
        sessionStoreConfig(),
        codeStoreConfig());
  }
@Test
  void read_defaults() {
    var provider = mock(ConfigProvider.class);

    var sut = new ConfigReader(provider);

    var baseUri = "https://rp.example.com";
    var idpDiscoveryUri = "https://sso.example.com/.well-known/openid-configuration";
    var appName = "Awesome DiGA";

    when(provider.get(ConfigReader.CONFIG_FEDERATION_ENTITY_STATEMENT_JWKS_PATH))
        .thenReturn(Optional.of("./src/test/resources/fixtures/example_sig_jwks.json"));
    when(provider.get(ConfigReader.CONFIG_BASE_URI)).thenReturn(Optional.of(baseUri));
    when(provider.get(ConfigReader.CONFIG_APP_NAME)).thenReturn(Optional.of(appName));
    when(provider.get(ConfigReader.CONFIG_IDP_DISCOVERY_URI))
        .thenReturn(Optional.of(idpDiscoveryUri));

    // when
    var config = sut.read();

    // then
    assertEquals(baseUri, config.baseUri().toString());
    assertEquals(appName, config.federation().appName());

    assertEquals("0.0.0.0", config.host());
    assertEquals(1234, config.port());

    assertEquals(List.of("code"), config.relyingParty().supportedResponseTypes());
    assertEquals(List.of(), config.relyingParty().validRedirectUris());

    assertEquals(baseUri, config.federation().iss().toString());
    assertEquals(baseUri, config.federation().sub().toString());
    assertEquals(
        List.of(
            "openid",
            "urn:telematik:email",
            "urn:telematik:versicherter",
            "urn:telematik:display_name"),
        config.federation().scopes());

    assertNotNull(config.federation().entitySigningKey());
    assertNotNull(config.federation().entitySigningKeys().getKeyByKeyId("test-sig"));

    // these will be generated
    assertNull(config.federation().relyingPartyKeys());
  }