Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EDGNCIP-27] - Enhance HTTP Endpoint Security with TLS and FIPS-140-2… #42

Merged
merged 10 commits into from
May 27, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
74 changes: 62 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ Version 2.0. See the file "[LICENSE](LICENSE)" for more information.
Edge API for mod-ncip

## Overview
The purpose of this module is to expose mod-ncip to external applications/3rd party software. It simply passes requests through to the NCIP module (after the API key is authenticated). It does not contain any other functionality

The purpose of this module is to expose mod-ncip to external applications/3rd party software. It simply passes requests
through to the NCIP module (after the API key is authenticated). It does not contain any other functionality

## Permissions
Institutional users should be granted the following permissions in order to use this edge API (because these are required for the NCIP module itself):

Institutional users should be granted the following permissions in order to use this edge API (because these are
required for the NCIP module itself):

```
ncip.all
inventory-storage.items.collection.get
Expand All @@ -24,23 +29,69 @@ Institutional users should be granted the following permissions in order to use
manualblocks.collection.get

```
### IMPORTANT NOTE ABOUT INSTITUTIONAL USER - It has to be assigned a patron group. There is an issue with create item which requires the user to be assigned a patron group.

## Security & Configuration
The edge-ncip module is secured via the functionality provided by the edge-common project (via API key).
### IMPORTANT NOTE ABOUT INSTITUTIONAL USER - It has to be assigned a patron group. There is an issue with create item which requires the user to be assigned a patron group.

The configuration for this module conforms to the edge-common project.
## Security Configuration

Configuration information is specified in two forms:

https://github.com/folio-org/edge-common
1. System Properties - General configuration
2. Properties File - Configuration specific to the desired secure store

## endpoints (you can use either)
### System Properties

.../ncip/yourapikeygoeshere <br>
.../ncip?apikey=yourapikeygoeshere
| Property | Default | Description |
|---------------------------|---------------------|---------------------------------------------------------------------|
| `port` | `8081` | Server port to listen on |
| `okapi_url` | *required* | Where to find Okapi (URL) |
| `secure_store` | `Ephemeral` | Type of secure store to use. Valid: `Ephemeral`, `AwsSsm`, `Vault` |
| `secure_store_props` | `NA` | Path to a properties file specifying secure store configuration |
| `token_cache_ttl_ms` | `3600000` | How long to cache JWTs, in milliseconds (ms) |
| `null_token_cache_ttl_ms` | `30000` | How long to cache login failure (null JWTs), in milliseconds (ms) |
| `token_cache_capacity` | `100` | Max token cache size |
| `log_level` | `INFO` | Log4j Log Level |
| `request_timeout_ms` | `30000` | Request Timeout |
| `api_key_sources` | `PARAM,HEADER,PATH` | Defines the sources (order of precedence) of the API key. |

### Env variables for TLS configuration for Http server

To configure Transport Layer Security (TLS) for the HTTP server in an edge module, the following configuration
parameters should be used.
Parameters marked as Required are required only in case when ssl_enabled is set to true.

| Property | Default | Description |
|-----------------------------------------|-------------------|----------------------------------------------------------------------------------|
| `FOLIO_CLIENT_TLS_ENABLED` | `false` | Set whether SSL/TLS is enabled for Vertx Http Server |
| `FOLIO_CLIENT_TLS_TRUSTSTORETYPE` | `NA` | Set the type of the keystore. Common types include `JKS`, `PKCS12`, and `BCFKS` |
| `FOLIO_CLIENT_TLS_TRUSTSTOREPATH` | `NA` | Set the location of the keystore file in the local file system |
| `FOLIO_CLIENT_TLS_TRUSTSTOREPASSWORD` | `NA` | Set the password for the keystore |

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here should be server related properties


### Env variables for TLS configuration for Web Client

To configure Transport Layer Security (TLS) for Web clients in the edge module, you can use the following configuration
parameters.
Truststore parameters for configuring Web clients are optional even when ssl_enabled = true.
If truststore parameters need to be populated, truststore_type, truststore_path and truststore_password are required.

| Property | Default | Description |
|-----------------------------------------|-------------------|----------------------------------------------------------------------------------|
| `FOLIO_CLIENT_TLS_ENABLED` | `false` | Set whether SSL/TLS is enabled for Vertx Http Server |
| `FOLIO_CLIENT_TLS_TRUSTSTORETYPE` | `NA` | Set the type of the keystore. Common types include `JKS`, `PKCS12`, and `BCFKS` |
| `FOLIO_CLIENT_TLS_TRUSTSTOREPATH` | `NA` | Set the location of the keystore file in the local file system |
| `FOLIO_CLIENT_TLS_TRUSTSTOREPASSWORD` | `NA` | Set the password for the keystore |

## Additional information

There will be a single instance of okapi client per OkapiClientFactory and per tenant,
which means that this client should never be closed or else there will be runtime errors.
To enforce this behaviour, method close() has been removed from OkapiClient class.

## Endpoints (you can use either)

.../ncip/yourapikeygoeshere <br>
.../ncip?apikey=yourapikeygoeshere

### Issue tracker

See project [EDGNCIP](https://issues.folio.org/browse/EDGNCIP)
Expand All @@ -64,5 +115,4 @@ and the [Docker image](https://hub.docker.com/r/folioorg/edge-ncip/).
### Other documentation

Other [modules](https://dev.folio.org/source-code/#server-side) are described,
with further FOLIO Developer documentation at [dev.folio.org](https://dev.folio.org/)

with further FOLIO Developer documentation at [dev.folio.org](https://dev.folio.org/)
10 changes: 9 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
<dependency>
<groupId>org.folio</groupId>
<artifactId>edge-common</artifactId>
<version>4.5.1</version>
<version>4.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>args4j</groupId>
Expand Down Expand Up @@ -220,6 +220,14 @@
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>**/Log4j2Plugins.dat</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
Expand Down
21 changes: 3 additions & 18 deletions src/main/java/org/folio/edge/ncip/MainVerticle.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,17 @@
package org.folio.edge.ncip;

import org.folio.edge.core.EdgeVerticleHttp;
import org.folio.edge.ncip.utils.NcipOkapiClientFactory;
import io.vertx.ext.web.Router;
import io.vertx.core.http.HttpMethod;
import io.vertx.ext.web.handler.BodyHandler;
import static org.folio.edge.core.Constants.SYS_OKAPI_URL;
import static org.folio.edge.core.Constants.SYS_REQUEST_TIMEOUT_MS;

import org.folio.edge.core.utils.OkapiClientFactory;
import org.folio.edge.core.utils.OkapiClientFactoryInitializer;

public class MainVerticle extends EdgeVerticleHttp {

final private String okapiUrl = System.getProperty(SYS_OKAPI_URL);
private int reqTimeoutMs;


public MainVerticle() {
super();
if (System.getProperty(SYS_REQUEST_TIMEOUT_MS) != null) {
reqTimeoutMs = Integer.parseInt(System.getProperty(SYS_REQUEST_TIMEOUT_MS));
} else {
reqTimeoutMs = 35000;
}
}

@Override
public Router defineRoutes() {
NcipOkapiClientFactory ocf = new NcipOkapiClientFactory(vertx, okapiUrl, reqTimeoutMs);
OkapiClientFactory ocf = OkapiClientFactoryInitializer.createInstance(vertx, config());
NcipHandler ncipHandler = new NcipHandler(secureStore, ocf);
Router router = Router.router(vertx);
router.route().handler(BodyHandler.create());
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/folio/edge/ncip/NcipHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
import org.apache.logging.log4j.Logger;
import org.folio.edge.core.Handler;
import org.folio.edge.core.security.SecureStore;
import org.folio.edge.core.utils.OkapiClientFactory;
import org.folio.edge.ncip.utils.NcipOkapiClient;
import org.folio.edge.ncip.utils.NcipOkapiClientFactory;
import org.folio.edge.core.utils.OkapiClient;

import com.fasterxml.jackson.core.JsonProcessingException;
Expand All @@ -30,7 +30,7 @@ public class NcipHandler extends Handler {
private static final Logger logger = LogManager.getLogger(NcipHandler.class);


public NcipHandler(SecureStore secureStore, NcipOkapiClientFactory ocf) {
public NcipHandler(SecureStore secureStore, OkapiClientFactory ocf) {
super(secureStore, ocf);
}

Expand Down
5 changes: 0 additions & 5 deletions src/main/java/org/folio/edge/ncip/utils/NcipOkapiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,13 @@
import org.folio.edge.core.utils.OkapiClient;
import io.vertx.core.Handler;
import io.vertx.core.MultiMap;
import io.vertx.core.Vertx;




public class NcipOkapiClient extends OkapiClient {


protected NcipOkapiClient(Vertx vertx, String okapiURL, String tenant, int timeout) {
super(vertx, okapiURL, tenant, timeout);
}

public NcipOkapiClient(OkapiClient client) {
super(client);
}
Expand Down

This file was deleted.