Skip to content

Commit c3d7422

Browse files
Support non-default SSL truststore for peers communication.
1 parent 17ba308 commit c3d7422

File tree

3 files changed

+67
-26
lines changed

3 files changed

+67
-26
lines changed

docs/CONFIG.md

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Configuration
22

33
TKeeper is configured via environment variables or a YAML/JSON configuration file.
4+
YAML configuration file should be placed at `./config/application.yaml`, relatively to
45

56
## Required
67

@@ -36,6 +37,11 @@ keeper:
3637
jwt:
3738
jwks-location: "https://auth.example.com/.well-known/jwks.json"
3839
refresh: 5m
40+
41+
ssl:
42+
enabled: true
43+
trust-store-path: /secure/truststore.p12
44+
trust-store-password: changeit
3945
```
4046
4147
## Session Expiration
@@ -47,8 +53,8 @@ keeper:
4753

4854
- `peers` define the list of participants (other nodes) in the threshold signing protocol.
4955
- Each peer entry must include:
50-
- `id`: unique index ≥ 1 assigned during key initialization (Shamir share index)
51-
- `public-url`: the HTTP endpoint where this peer is reachable
56+
- `id`: unique index ≥ 1 assigned during key initialization (Shamir share index).
57+
- `public-url`: the HTTP endpoint where this peer is reachable.
5258

5359
> Detailed peer setup is covered in the key generation section.
5460

@@ -60,9 +66,9 @@ The `seal` block defines how the local key share is encrypted and stored on disk
6066

6167
### Available `type` values:
6268

63-
- `shamir`: local sealing using Shamir Secret Sharing
64-
- `aws`: sealing via AWS KMS
65-
- `google`: sealing via Google Cloud KMS
69+
- `shamir`: local sealing using Shamir Secret Sharing.
70+
- `aws`: sealing via AWS KMS.
71+
- `google`: sealing via Google Cloud KMS.
6672

6773
Depending on the selected type, the corresponding sub-section (`shamir`, `aws`, or `google`) must be present.
6874

@@ -78,8 +84,8 @@ seal:
7884
threshold: 2
7985
```
8086

81-
- `total`: number of shares to split the key into
82-
- `threshold`: minimum number of shares required to reconstruct the key
87+
- `total`: number of shares to split the key into.
88+
- `threshold`: minimum number of shares required to reconstruct the key.
8389

8490
> Manual `unseal` is required at application startup.
8591

@@ -96,9 +102,9 @@ seal:
96102
```
97103

98104
- Authentication uses [default AWS Java SDK credential chain](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/credentials.html), including:
99-
- Environment variables
100-
- IAM roles (e.g., EC2, ECS)
101-
- AWS config/profile files
105+
- Environment variables.
106+
- IAM roles (e.g., EC2, ECS).
107+
- AWS config/profile files.
102108

103109
> Unseal is automatic at startup.
104110

@@ -117,13 +123,13 @@ seal:
117123
```
118124

119125
- Authentication uses [Application Default Credentials (ADC)](https://cloud.google.com/docs/authentication/production), supporting:
120-
- Service accounts
121-
- GCE/GKE metadata server
122-
- Local credentials file
126+
- Service accounts.
127+
- GCE/GKE metadata server.
128+
- Local credentials file.
123129

124130
> Unseal is automatic at startup.
125131

126-
See [seal.md](seal.md) for more details on sealing and unsealing.
132+
See [SEAL.md](SEAL.md) for more details on sealing and unsealing.
127133

128134
---
129135

@@ -142,8 +148,25 @@ keeper:
142148
```
143149

144150
- `type`: authentication provider type. Currently, only `jwt` is supported.
145-
- `allowAnonymous`: whether unauthenticated requests are allowed
146-
- `jwt.jwks-location`: URL of the JWKS endpoint for public key retrieval
147-
- `jwt.refresh`: optional refresh interval for reloading the JWKS
148-
-
149-
See [auth.md](auth.md) for authentication options and JWT integration.
151+
- `allowAnonymous`: whether unauthenticated requests are allowed.
152+
- `jwt.jwks-location`: URL of the JWKS endpoint for public key retrieval.
153+
- `jwt.refresh`: optional refresh interval for reloading the JWKS.
154+
155+
See [SEAL.md](AUTH.md) for authentication options and JWT integration.
156+
157+
---
158+
159+
## SSL
160+
Outgoing SSL settings are defined under the `keeper.ssl` block:
161+
162+
```yaml
163+
keeper:
164+
ssl:
165+
enabled: true
166+
trust-store-path: /secure/truststore.p12
167+
trust-store-password: changeit
168+
```
169+
170+
- `enabled`: whether non-default SSL truststore should be enabled.
171+
- `trust-store-path`: path to PKCS12\JKS truststore file.
172+
- `trust-store-password`: password to truststore file, previously specified in `trust-store-path`.

src/main/kotlin/org/exploit/keeper/config/KeeperConfig.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.exploit.keeper.config;
1+
package org.exploit.keeper.config
22

33
import io.quarkus.runtime.annotations.StaticInitSafe
44
import io.smallrye.config.ConfigMapping
@@ -19,6 +19,8 @@ interface KeeperConfig {
1919

2020
fun peers(): List<PeerConfig>
2121

22+
fun ssl(): SslConfig
23+
2224
interface SessionConfig {
2325
fun gg20(): SessionDetail
2426

@@ -33,5 +35,11 @@ interface KeeperConfig {
3335
fun id(): Int
3436
fun publicUrl(): String
3537
}
38+
39+
interface SslConfig {
40+
fun enabled(): Boolean
41+
fun trustStorePath(): String?
42+
fun trustStorePassword(): String?
43+
}
3644
}
3745

src/main/kotlin/org/exploit/keeper/producer/JettyxProducer.kt

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.exploit.keeper.producer
33
import com.fasterxml.jackson.databind.ObjectMapper
44
import jakarta.enterprise.inject.Produces
55
import jakarta.inject.Singleton
6+
import org.eclipse.jetty.util.ssl.SslContextFactory
67
import org.exploit.jettyx.Jettyx
78
import org.exploit.jettyx.http2.Http2Version
89
import org.exploit.jettyx.jackson.JacksonHttpMapper
@@ -19,11 +20,20 @@ class JettyxProducer(
1920
) {
2021
@Produces
2122
@Singleton
22-
fun jettyx(): Jettyx = Jettyx.newBuilder()
23-
.enableVersion(Http2Version())
24-
.addHttpMapper(JacksonHttpMapper.create(objectMapper))
25-
.executor(Executors.newWorkStealingPool(config.parallelism()))
26-
.build()
23+
fun jettyx(): Jettyx {
24+
val builder = Jettyx.newBuilder()
25+
.enableVersion(Http2Version())
26+
.addHttpMapper(JacksonHttpMapper.create(objectMapper))
27+
.executor(Executors.newWorkStealingPool(config.parallelism()))
28+
29+
if (config.ssl().enabled()) {
30+
val sslContext = SslContextFactory.Client()
31+
sslContext.trustStorePath = config.ssl().trustStorePath() ?: throw IllegalArgumentException("keeper.ssl.trust-store-path must be set while keeper.ssl.enabled is set to true")
32+
sslContext.setTrustStorePassword(config.ssl().trustStorePassword() ?: throw IllegalArgumentException("keeper.ssl.trust-store-password must be set while keeper.ssl.enabled is set to true"))
33+
}
34+
35+
return builder.build()
36+
}
2737

2838
@Produces
2939
@Singleton
@@ -39,7 +49,7 @@ class JettyxProducer(
3949
peerId = peer.id(),
4050
auth = authenticator,
4151
url = peer.publicUrl(),
42-
jettyx =jettyx
52+
jettyx = jettyx
4353
)
4454
}
4555
}

0 commit comments

Comments
 (0)