This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch pqc-examples in repository https://gitbox.apache.org/repos/asf/camel-jbang-examples.git
commit 7b9d005dda5ee2e0951c5bcce8ceac7ba05366b6 Author: Andrea Cosentino <[email protected]> AuthorDate: Mon Oct 13 13:56:58 2025 +0200 Added Java example for PQC Signing with Hashicorp Vault Key Lifecycle Management Signed-off-by: Andrea Cosentino <[email protected]> --- pqc-document-signing/PQCDocumentSigningRoutes.java | 310 ++++++++++++++++++++ pqc-document-signing/README.adoc | 324 +++++++++++++++++++++ pqc-document-signing/application.properties | 40 +++ 3 files changed, 674 insertions(+) diff --git a/pqc-document-signing/PQCDocumentSigningRoutes.java b/pqc-document-signing/PQCDocumentSigningRoutes.java new file mode 100644 index 0000000..6b5c72e --- /dev/null +++ b/pqc-document-signing/PQCDocumentSigningRoutes.java @@ -0,0 +1,310 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.example.pqc; + +import java.security.KeyPair; +import java.security.Security; +import java.util.Base64; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.pqc.lifecycle.HashicorpVaultKeyLifecycleManager; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.springframework.vault.authentication.TokenAuthentication; +import org.springframework.vault.client.VaultEndpoint; +import org.springframework.vault.core.VaultTemplate; + +/** + * RouteBuilder for PQC Document Signing with HashiCorp Vault integration. + * + * This class defines 11 routes: + * 1. Initialize PQC signing key on startup + * 2. REST API - Sign and verify a document + * 4. REST API - Get key metadata + * 5. REST API - List all keys + * 6. REST API - Rotate signing key + * 7. Scheduled job - Check key rotation needs + * 8. Helper - Update key usage metadata + * 9. Helper - Get key metadata + * 10. Helper - Check key expiration and auto-rotate + * 11. Helper - Automatic key rotation on expiration + */ +public class PQCDocumentSigningRoutes extends RouteBuilder { + + @Override + public void configure() throws Exception { + + // Register BouncyCastle providers for PQC algorithms + if (Security.getProvider("BC") == null) { + Security.addProvider(new BouncyCastleProvider()); + } + if (Security.getProvider("BCPQC") == null) { + Security.addProvider(new BouncyCastlePQCProvider()); + } + + // Register beans for HashiCorp Vault integration + registerVaultBeans(); + + // Route 1: Initialize PQC signing key on startup + from("timer:init?repeatCount=1") + .routeId("initialize-signing-key") + .log("Initializing PQC signing key in Vault...") + .bean("keyLifecycleManager", "generateKeyPair('DILITHIUM', 'document-signing-key')") + .log("PQC signing key initialized successfully") + .process(exchange -> { + // Register the KeyPair bean directly for autowiring + HashicorpVaultKeyLifecycleManager keyManager = exchange.getContext().getRegistry() + .lookupByNameAndType("keyLifecycleManager", HashicorpVaultKeyLifecycleManager.class); + KeyPair keyPair = keyManager.getKey("document-signing-key"); + + // Register as KeyPair type so PQC component can autowire it + bindToRegistry("signingKey", keyPair); + }) + .to("direct:get-key-metadata"); + + // Route 2: REST API - Sign a document + from("platform-http:/api/sign") + .routeId("sign-document-api") + .log("Received document signing request: ${body}") + .setHeader("originalBody", simple("${body}")) + // Sign the document using PQC + .toD("pqc:sign?operation=sign&signatureAlgorithm=DILITHIUM&keyPair=#signingKey") + // Convert binary signature to base64 + .process(exchange -> { + byte[] signature = exchange.getMessage().getHeader("CamelPQCSignature", byte[].class); + if (signature != null) { + String base64Signature = Base64.getEncoder().encodeToString(signature); + exchange.getMessage().setHeader("CamelPQCSignature", base64Signature); + } + }) + .log("Document signed with quantum-resistant signature") + // Update key usage metadata + .to("direct:update-key-usage") + // Check if key needs rotation or has expired + .to("direct:check-key-expiration") + // Prepare response with signature and key metadata + .setBody(simple("{\n" + + " \"status\": \"signed\",\n" + + " \"document\": \"${header.originalBody}\",\n" + + " \"signature\": \"${header.CamelPQCSignature}\",\n" + + " \"signatureAlgorithm\": \"DILITHIUM\",\n" + + " \"keyId\": \"document-signing-key\",\n" + + " \"keyMetadata\": ${body}\n" + + "}")) + .setHeader("Content-Type", constant("application/json")) + .log("Response: ${body}") + // Decode base64 signature to binary + .process(exchange -> { + String base64Signature = exchange.getMessage().getHeader("CamelPQCSignature", String.class); + if (base64Signature == null || base64Signature.isEmpty()) { + throw new IllegalArgumentException("CamelPQCSignature header is missing or empty"); + } + byte[] signature = Base64.getDecoder().decode(base64Signature); + exchange.getIn().setHeader("CamelPQCSignature", signature); + exchange.getIn().setHeader("signatureLength", signature.length); + }) + .log("Verifying signature of length: ${header.signatureLength} bytes") + // Verify the document signature using PQC + .doTry() + .toD("pqc:verify?operation=verify&signatureAlgorithm=DILITHIUM&keyPair=#signingKey") + .log("Verification completed. Result: ${header.CamelPQCVerify}") + .doCatch(Exception.class) + .log("ERROR during verification: ${exception.message}") + .setHeader("CamelPQCVerify", constant(false)) + .end() + .choice() + .when(simple("${header.CamelPQCVerify} == true")) + .setBody(simple("{\n" + + " \"status\": \"verified\",\n" + + " \"valid\": true,\n" + + " \"message\": \"Document signature is valid\",\n" + + " \"signatureAlgorithm\": \"DILITHIUM\"\n" + + "}")) + .when(simple("${header.CamelPQCVerify} == false")) + .setBody(simple("{\n" + + " \"status\": \"verified\",\n" + + " \"valid\": false,\n" + + " \"message\": \"Document signature is invalid\",\n" + + " \"signatureAlgorithm\": \"DILITHIUM\"\n" + + "}")) + .end() + .setHeader("Content-Type", constant("application/json")) + .log("Verification result: ${body}");; + + // Route 4: REST API - Get key metadata + from("platform-http:/api/key/metadata") + .routeId("get-key-metadata-api") + .log("Fetching key metadata...") + .to("direct:get-key-metadata"); + + // Route 5: REST API - List all keys + from("platform-http:/api/keys") + .routeId("list-keys-api") + .log("Listing all PQC keys...") + .bean("keyLifecycleManager", "listKeys") + .setBody(simple("{\n" + + " \"keys\": ${body}\n" + + "}")) + .setHeader("Content-Type", constant("application/json")) + .log("Keys listed: ${body}"); + + // Route 6: REST API - Rotate signing key + from("platform-http:/api/key/rotate") + .routeId("rotate-key-api") + .log("Rotating signing key...") + .bean("keyLifecycleManager", "rotateKey('document-signing-key', 'document-signing-key-v2', 'DILITHIUM')") + .log("Key rotated successfully: old key deprecated, new key active") + .setBody(simple("{\n" + + " \"status\": \"rotated\",\n" + + " \"oldKey\": \"document-signing-key\",\n" + + " \"newKey\": \"document-signing-key-v2\",\n" + + " \"message\": \"Key rotation completed successfully\"\n" + + "}")) + .setHeader("Content-Type", constant("application/json")); + + // Route 7: Scheduled job - Check key rotation needs + from("timer:checkRotation?period={{key.rotation.check.period}}") + .routeId("check-rotation-schedule") + .log("Checking if key needs rotation...") + .bean("keyLifecycleManager", "needsRotation('document-signing-key', 'P{{key.max.age.days}}D', {{key.max.usage.count}})") + .choice() + .when(simple("${body} == true")) + .log("WARNING: Key 'document-signing-key' needs rotation!") + .to("direct:get-key-metadata") + .log("Current key metadata: ${body}") + .otherwise() + .log("Key rotation not needed yet") + .end(); + + // Route 8: Helper - Update key usage metadata + from("direct:update-key-usage") + .routeId("update-key-usage") + .bean("keyLifecycleManager", "getKeyMetadata('document-signing-key')") + .setProperty("metadata", simple("${body}")) + .process(exchange -> { + // Update last used timestamp and increment usage count + Object metadata = exchange.getProperty("metadata"); + if (metadata != null) { + // Call updateLastUsed on the metadata object + metadata.getClass().getMethod("updateLastUsed").invoke(metadata); + exchange.getMessage().setBody(metadata); + } + }) + .bean("keyLifecycleManager", "updateKeyMetadata('document-signing-key', ${body})") + .log("Key usage updated. Usage count: ${body.usageCount}"); + + // Route 9: Helper - Get key metadata + from("direct:get-key-metadata") + .routeId("get-key-metadata-helper") + .bean("keyLifecycleManager", "getKeyMetadata('document-signing-key')") + .setBody(simple("{\n" + + " \"keyId\": \"${body.keyId}\",\n" + + " \"algorithm\": \"${body.algorithm}\",\n" + + " \"status\": \"${body.status}\",\n" + + " \"createdAt\": \"${body.createdAt}\",\n" + + " \"lastUsedAt\": \"${body.lastUsedAt}\",\n" + + " \"usageCount\": ${body.usageCount},\n" + + " \"ageInDays\": ${body.ageInDays},\n" + + " \"expiresAt\": \"${body.expiresAt}\",\n" + + " \"nextRotationAt\": \"${body.nextRotationAt}\",\n" + + " \"expired\": ${body.expired},\n" + + " \"needsRotation\": ${body.needsRotation}\n" + + "}")) + .setHeader("Content-Type", constant("application/json")) + .log("Key metadata: ${body}"); + + // Route 10: Helper - Check key expiration and auto-rotate + from("direct:check-key-expiration") + .routeId("check-key-expiration") + .bean("keyLifecycleManager", "getKeyMetadata('document-signing-key')") + .choice() + .when(simple("${body.usageCount} >= {{key.max.usage.count}}")) + .log("WARNING: Key has reached maximum usage count (${body.usageCount} >= {{key.max.usage.count}})") + .setProperty("expirationReason", simple("usage count (${body.usageCount} uses)")) + .to("direct:auto-rotate-key") + .when(simple("${body.ageInDays} >= {{key.max.age.days}}")) + .log("WARNING: Key has reached maximum age (${body.ageInDays} >= {{key.max.age.days}} days)") + .setProperty("expirationReason", simple("age (${body.ageInDays} days)")) + .to("direct:auto-rotate-key") + .otherwise() + .setBody(simple("Key is valid (usage: ${body.usageCount}/{{key.max.usage.count}}, age: ${body.ageInDays}/{{key.max.age.days}} days)")) + .end(); + + // Route 11: Helper - Automatic key rotation on expiration + from("direct:auto-rotate-key") + .routeId("auto-rotate-key") + .log(">>> AUTOMATIC KEY ROTATION TRIGGERED <<<") + .log("Reason: Key expired due to ${exchangeProperty.expirationReason}") + // Generate new key ID with timestamp + .setProperty("timestamp", simple("${date:now:yyyyMMdd-HHmmss}")) + .setProperty("newKeyId", simple("document-signing-key")) + .log("Rotating key from 'document-signing-key' to '${exchangeProperty.newKeyId}'") + // Perform rotation + .bean("keyLifecycleManager", "rotateKey('document-signing-key', '${exchangeProperty.newKeyId}', 'DILITHIUM')") + .log(">>> KEY ROTATION COMPLETED <<<") + .log("Old key 'document-signing-key' status: DEPRECATED") + .log("New key '${exchangeProperty.newKeyId}' status: ACTIVE") + // Update the active key reference for future operations + .setProperty("activeKeyId", simple("${exchangeProperty.newKeyId}")) + // Get metadata of new key + .bean("keyLifecycleManager", "getKeyMetadata('${exchangeProperty.newKeyId}')") + .setBody(simple("{\n" + + " \"rotationTriggered\": true,\n" + + " \"reason\": \"${exchangeProperty.expirationReason}\",\n" + + " \"oldKey\": \"document-signing-key\",\n" + + " \"oldKeyStatus\": \"DEPRECATED\",\n" + + " \"newKey\": \"${exchangeProperty.newKeyId}\",\n" + + " \"newKeyStatus\": \"ACTIVE\",\n" + + " \"newKeyCreatedAt\": \"${body.createdAt}\",\n" + + " \"message\": \"Key automatically rotated due to ${exchangeProperty.expirationReason}\"\n" + + "}")) + .log("Rotation details: ${body}"); + } + + /** + * Register beans for HashiCorp Vault integration + */ + private void registerVaultBeans() throws Exception { + // Get configuration properties + String vaultHost = getContext().resolvePropertyPlaceholders("{{vault.host}}"); + int vaultPort = Integer.parseInt(getContext().resolvePropertyPlaceholders("{{vault.port}}")); + String vaultScheme = getContext().resolvePropertyPlaceholders("{{vault.scheme}}"); + String vaultToken = getContext().resolvePropertyPlaceholders("{{vault.token}}"); + String secretsEngine = getContext().resolvePropertyPlaceholders("{{vault.secrets.engine}}"); + String keyPrefix = getContext().resolvePropertyPlaceholders("{{vault.keys.prefix}}"); + + // Create VaultEndpoint + VaultEndpoint vaultEndpoint = new VaultEndpoint(); + vaultEndpoint.setHost(vaultHost); + vaultEndpoint.setPort(vaultPort); + vaultEndpoint.setScheme(vaultScheme); + bindToRegistry("vaultEndpoint", vaultEndpoint); + + // Create TokenAuthentication + TokenAuthentication tokenAuthentication = new TokenAuthentication(vaultToken); + bindToRegistry("tokenAuthentication", tokenAuthentication); + + // Create VaultTemplate + VaultTemplate vaultTemplate = new VaultTemplate(vaultEndpoint, tokenAuthentication); + bindToRegistry("vaultTemplate", vaultTemplate); + + // Create HashicorpVaultKeyLifecycleManager using constructor with all parameters + HashicorpVaultKeyLifecycleManager keyLifecycleManager = + new HashicorpVaultKeyLifecycleManager(vaultHost, vaultPort, vaultScheme, vaultToken, secretsEngine, keyPrefix); + bindToRegistry("keyLifecycleManager", keyLifecycleManager); + } +} diff --git a/pqc-document-signing/README.adoc b/pqc-document-signing/README.adoc new file mode 100644 index 0000000..d8fe80b --- /dev/null +++ b/pqc-document-signing/README.adoc @@ -0,0 +1,324 @@ += Post-Quantum Cryptography Document Signing with HashiCorp Vault + +This example demonstrates how to build a secure document signing service using Apache Camel with Post-Quantum Cryptography (PQC) and HashiCorp Vault for key lifecycle management. + +== Features + +* **Quantum-Resistant Signatures** - Signs documents using DILITHIUM, a NIST-standardized Post-Quantum Cryptographic algorithm +* **HashiCorp Vault Integration** - Stores and manages PQC keys in HashiCorp Vault for enterprise-grade security +* **Key Lifecycle Management** - Automatic tracking of key usage, age, rotation, and expiration +* **Key Usage Tracking** - Demonstrates key expiration after a predefined number of usages (default: 10 signatures) +* **Automatic Key Rotation** - When a key expires, a new key is **automatically generated and rotated** +* **Key Metadata Tracking** - Real-time visibility into key status, usage count, age, and lifecycle events +* **REST API** - HTTP endpoints for signing, verifying documents, and managing keys +* **Scheduled Monitoring** - Periodic checks for key rotation needs based on age and usage thresholds +* **Multi-Key Support** - Deprecated keys are retained for signature verification of old documents + +== Prerequisites + +* JBang installed (https://www.jbang.dev) +* Docker installed for running HashiCorp Vault + +== Running HashiCorp Vault + +Run HashiCorp Vault using Docker: + +[source,sh] +---- +$ docker run -d \ + --name vault \ + -p 8201:8200 \ + -e VAULT_DEV_ROOT_TOKEN_ID=myroot \ + -e VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200 \ + hashicorp/vault:latest +---- + +This will start HashiCorp Vault configured with: + +* Root token: `myroot` +* Port: `8201` (mapped from container port 8200) +* Secrets engine: `secret` (KV v2) + +Wait a few seconds for Vault to fully start before proceeding. + +== Project Structure + +The example consists of the following files: + +[source,text] +---- +pqc-document-signing/ +├── PQCDocumentSigningRoutes.java # Main RouteBuilder with 11 routes +├── application.properties # Configuration file +└── README.adoc # This file +---- + +== Running the Example + +After Vault is configured and running, start the Camel application: + +[source,sh] +---- +$ jbang -Dcamel.jbang.version=4.16.0-SNAPSHOT camel@apache/camel run PQCDocumentSigningRoutes.java +---- + +Or using Maven: + +[source,sh] +---- +$ mvn compile exec:java +---- + +The application will: + +1. Connect to HashiCorp Vault +2. Generate a DILITHIUM Post-Quantum Cryptographic key pair +3. Store the key securely in Vault at path: `secret/data/pqc/keys/document-signing-key` +4. Start REST API endpoints on port 8080 +5. Begin monitoring key lifecycle (usage count, age, rotation needs) + +== API Endpoints + +The application exposes the following REST endpoints: + +=== 1. Sign a Document + +Signs a document with a quantum-resistant signature. + +[source,sh] +---- +$ curl -X POST http://localhost:8080/api/sign \ + -H "Content-Type: text/plain" \ + -d "This is a confidential document that needs quantum-resistant protection" +---- + +**Response:** +[source,json] +---- +{ + "status": "signed", + "document": "This is a confidential document...", + "signature": "UMyKJt21oIYWNq0jDe6v63Xw8bs7JZ9hg9KEYXdFPIMxXS3AHwOa...", + "signatureAlgorithm": "DILITHIUM", + "keyId": "document-signing-key", + "keyMetadata": { + "keyId": "document-signing-key", + "algorithm": "DILITHIUM", + "status": "ACTIVE", + "usageCount": 1, + "ageInDays": 0 + } +} +---- + +Note: The `signature` field contains a base64-encoded quantum-resistant signature. + +=== 2. Get Key Metadata + +Retrieves detailed metadata about the signing key, including usage count and lifecycle status. + +[source,sh] +---- +$ curl http://localhost:8080/api/key/metadata +---- + +**Response:** +[source,json] +---- +{ + "keyId": "document-signing-key", + "algorithm": "DILITHIUM", + "status": "ACTIVE", + "createdAt": "2024-10-13T10:30:00Z", + "lastUsedAt": "2024-10-13T10:35:00Z", + "usageCount": 5, + "ageInDays": 0, + "expiresAt": null, + "nextRotationAt": null, + "expired": false, + "needsRotation": false +} +---- + +=== 3. List All Keys + +Lists all PQC keys stored in Vault. + +[source,sh] +---- +$ curl http://localhost:8080/api/keys +---- + +**Response:** +[source,json] +---- +{ + "keys": [ + { + "keyId": "document-signing-key", + "algorithm": "DILITHIUM", + "status": "ACTIVE", + "usageCount": 5 + } + ] +} +---- + +=== 4. Rotate Signing Key + +Manually rotates the signing key (creates a new key and deprecates the old one). + +[source,sh] +---- +$ curl -X POST http://localhost:8080/api/key/rotate +---- + +**Response:** +[source,json] +---- +{ + "status": "rotated", + "oldKey": "document-signing-key", + "newKey": "document-signing-key", + "message": "Key rotation completed successfully" +} +---- + +== Automatic Key Rotation + +The example demonstrates automatic key rotation when keys reach expiration criteria: + +* **Usage-based**: After 10 signatures (configurable via `key.max.usage.count`) +* **Age-based**: After 90 days (configurable via `key.max.age.days`) + +When a key expires, the system automatically rotates to a new key, marking the old key as `DEPRECATED` for verification of previously signed documents. + +**Test rotation:** +[source,sh] +---- +# Sign document 10 times to trigger automatic rotation +$ for i in {1..10}; do + curl -X POST http://localhost:8080/api/sign \ + -H "Content-Type: text/plain" \ + -d "Document number $i" +done + +# View both old and new keys +$ curl http://localhost:8080/api/keys +---- + +== Key Storage in HashiCorp Vault + +The PQC keys are stored in Vault's KV v2 secrets engine with the following structure: + +[source,text] +---- +secret/ +└── data/ + └── pqc/ + └── keys/ + └── document-signing-key/ + ├── private/ # PKCS#8 private key + ├── public/ # X.509 public key + └── metadata/ # Key metadata +---- + +This separation enables fine-grained access control where applications can access public keys for verification without having access to private keys for signing. + +== Configuration + +Configuration is managed in `application.properties`: + +[source,properties] +---- +# Vault connection +vault.host=localhost +vault.port=8201 +vault.token=myroot + +# Key rotation policy +key.max.usage.count=10 # Max signatures before rotation +key.max.age.days=90 # Max key age in days +key.rotation.check.period=60000 # Check interval (ms) +---- + +== Troubleshooting + +=== Connection to Vault Failed + +* Ensure Vault is running: `docker ps` +* Verify the port in `application.properties` is set to `8201` +* Check the Vault token is correct (default: `myroot`) + +=== Key Not Found in Vault + +* Check Vault UI at http://localhost:8201 (token: `myroot`) +* Verify the secrets engine is enabled: `vault secrets list` +* Check the key path: `secret/data/pqc/keys/document-signing-key` + +=== Signature Verification Failed + +* Ensure you're using the same document content for both signing and verification +* Include the `CamelPQCSignature` header with the base64-encoded signature from the sign response +* The signature must be passed exactly as received from the sign endpoint (base64 string) +* Verify the key hasn't been rotated or revoked +* Check logs for "ERROR during verification" messages which indicate signature format issues + +== Stopping + +To stop the Camel application, press `Ctrl+C`. + +To stop HashiCorp Vault: + +[source,sh] +---- +$ docker stop vault +$ docker rm vault +---- + +== Architecture + +This example demonstrates: + +1. **Post-Quantum Cryptography (PQC)** - Quantum-resistant digital signatures using DILITHIUM +2. **HashiCorp Vault Integration** - Enterprise secret management for PQC keys +3. **Key Lifecycle Management** - Automated tracking of key usage, rotation, and expiration +4. **RESTful API** - Multiple endpoints for signing, verification, and key management +5. **Platform HTTP Component** - Lightweight HTTP server for REST APIs +6. **Java-based RouteBuilder** - Routes defined using Camel Java DSL +7. **Bean Configuration** - Vault and key manager beans configured programmatically in Java +8. **Scheduled Jobs** - Periodic key rotation checks +9. **Dynamic Routing** - Uses `.toD()` for runtime endpoint creation with autowired KeyPair +10. **Base64 Encoding** - Binary signatures converted to base64 for JSON transport + +=== Implementation Details + +The `PQCDocumentSigningRoutes.java` RouteBuilder: + +- Registers BouncyCastle security providers (BC, BCPQC) +- Creates and binds Vault-related beans to the registry +- Defines 11 Camel routes using Java DSL +- Handles KeyPair registration after key generation +- Converts binary signatures to/from base64 for JSON transport +- Uses dynamic routing (`.toD()`) to create PQC endpoints at runtime +- Implements automatic key rotation based on usage count and age + +== Security Notice + +This example uses **development settings**. For production: + +* Use HTTPS for Vault (`vault.scheme=https`) +* Use AppRole or similar authentication instead of root tokens +* Configure Vault access policies +* Increase `key.max.usage.count` to realistic values (e.g., 100,000) +* Enable Vault audit logging + +== Help and Contributions + +If you hit any problem using Camel or have some feedback, then please +https://camel.apache.org/community/support/[let us know]. + +We also love contributors, so +https://camel.apache.org/community/contributing/[get involved] :-) + +The Camel riders! diff --git a/pqc-document-signing/application.properties b/pqc-document-signing/application.properties new file mode 100644 index 0000000..74b80cc --- /dev/null +++ b/pqc-document-signing/application.properties @@ -0,0 +1,40 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Application Configuration +camel.main.name = PQCDocumentSigningExample + +# HashiCorp Vault Configuration +# Port 8200 is used when running Vault via: camel infra run hashicorp-vault +# Port 8201 is used when running Vault manually via Docker (see README.adoc) +vault.host=localhost +vault.port=8201 +vault.scheme=http +vault.token=myroot +vault.secrets.engine=secret +vault.keys.prefix=pqc/keys + +# PQC Key Lifecycle Configuration +# Maximum number of times a key can be used before expiration +key.max.usage.count=10 + +# Maximum age of a key in days before rotation is needed +key.max.age.days=90 + +# How often to check if key rotation is needed (in milliseconds) +# 60000 = 1 minute (for demo purposes, use longer intervals in production) +key.rotation.check.period=60000
