Skip to content

Commit

Permalink
feat: consolidate tractus-x HashiCorp Vault impl (#3266)
Browse files Browse the repository at this point in the history
* feat: consolidate tractus-x HashiCorp Vault impl

* updated README

* custom tostring for healthresponsepayload

* checkstyle
  • Loading branch information
paullatzelsperger authored Jul 6, 2023
1 parent c3b245f commit eba6ca1
Show file tree
Hide file tree
Showing 32 changed files with 1,791 additions and 272 deletions.
22 changes: 0 additions & 22 deletions .github/workflows/verify.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,27 +105,6 @@ jobs:
command: ./gradlew test -DincludeTags="PostgresqlIntegrationTest"


Hashicorp-Vault-Integration-Tests:
runs-on: ubuntu-latest

services:
vault:
image: vault:1.9.7
ports:
- 8200:8200
env:
VAULT_DEV_ROOT_TOKEN_ID: test-token
VAULT_TOKEN: test-token

steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup-build

- name: Hashicorp Vault Integration Tests
uses: ./.github/actions/run-tests
with:
command: ./gradlew -p extensions test -DincludeTags="HashicorpVaultIntegrationTest"

End-To-End-Tests:
runs-on: ubuntu-latest
steps:
Expand Down Expand Up @@ -189,7 +168,6 @@ jobs:
- Component-Tests
- Daps-Integration-Tests
- End-To-End-Tests
- Hashicorp-Vault-Integration-Tests
- Postgresql-Integration-Tests
- Kafka-Integration-Tests
- Unit-Tests
Expand Down
83 changes: 74 additions & 9 deletions extensions/common/vault/vault-hashicorp/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,81 @@
# [HashiCorp Vault](https://www.vaultproject.io/) Extension

---

**Please note:**
Using the HashiCorp vault it is possible to define multiple data entries per secret. Other vaults might allow only one
entry per secret (e.g. Azure Key Vault).

Therefore, the HashiCorp vault extension **only** checks the '**content**' data entry! Please use this knowledge when
creating secrets the EDC should consume.

---

## Configuration

| Key | Description | Mandatory |
|:---|:---|---|
| edc.vault.hashicorp.url | URL to connect to the HashiCorp Vault | X |
| edc.vault.hashicorp.token | Value for [Token Authentication](https://www.vaultproject.io/docs/auth/token) with the vault | X |
| edc.vault.hashicorp.timeout.seconds | Request timeout in seconds when contacting the vault (default: 30) | |
| Key | Description | Mandatory | Default |
|:--------------------------------------------|:-----------------------------------------------------------------------------------------------------------------|-----------|------------------|
| edc.vault.hashicorp.url | URL to connect to the HashiCorp Vault | X | | |
| edc.vault.hashicorp.token | Value for [Token Authentication](https://www.vaultproject.io/docs/auth/token) with the vault | X | | |
| edc.vault.hashicorp.timeout.seconds | Request timeout in seconds when contacting the vault | | `30` |
| edc.vault.hashicorp.health.check.enabled | Enable health checks to ensure vault is initialized, unsealed and active | | `true` |
| edc.vault.hashicorp.health.check.standby.ok | Specifies if a vault in standby is healthy. This is useful when Vault is behind a non-configurable load balancer | | `false` |
| edc.vault.hashicorp.api.secret.path | Path to the [secret api](https://www.vaultproject.io/api-docs/secret/kv/kv-v1) | | `/v1/secret` |
| edc.vault.hashicorp.api.health.check.path | Path to the [health api](https://www.vaultproject.io/api-docs/system/health) | | `/v1/sys/health` |

## Health Check

The HashiCorp Vault Extension is able to run health checks. A health check is successful when the vault is
_initialized_, _active_ and _unsealed_. Successful health checks are logged with level _FINE_. Unsuccessful health
checks will be logged
with level _WARNING_.

---

### Health Checks

If your project uses the Tractus-X HashiCorp Vault please set `edc.vault.hashicorp.health.check.standby.ok` to _true_.
Otherwise, the health check would fail if the Vault is in standby.

```plain
# Logs of successful check with standby vault
[2022-08-01 14:48:37] [FINE ] HashiCorp Vault HealthCheck successful. HashicorpVaultHealthResponsePayload(isInitialized=true, isSealed=false, isStandby=true, isPerformanceStandby=false, replicationPerformanceMode=disabled,replicationDrMode=disabled, serverTimeUtc=1659365317, version=1.9.2, clusterName=vault-cluster-4b193c26, clusterId=83fabd45-685d-7f8d-9495-18fab6f50d5e)
```

---

## Example: Create & Configure an OAuth2 private key

### Insert private key into HashiCorp Vault

```bash
cat << EOF | /bin/vault kv put secret/my-private-key content=-
-----BEGIN PRIVATE KEY-----
<PRIVATE KEY CONTENT>
EOF
```
### Configure key in the EDC
```bash
EDC_OAUTH_PRIVATE_KEY_ALIAS: my-private-key
```
or
## Setup vault for integration tests
```bash
edc.oauth.private.key.alias=my-privatekey
```
The integration tests rely on a vault running locally.
This can be achieved by starting a docker container with the following configuration.
## Example
`docker run -e 'VAULT_DEV_ROOT_TOKEN_ID=test-token' -p "8200:8200" vault:1.9.7`
```properties
#########
# Vault #
#########
edc.vault.hashicorp.url=https://vault.demo.tractus-x.net
# or even better configure token as k8 secret
edc.vault.hashicorp.token=<token>
edc.vault.hashicorp.api.secret.path=/v1/<tenant>/
edc.vault.hashicorp.health.check.standby.ok=true
```
4 changes: 4 additions & 0 deletions extensions/common/vault/vault-hashicorp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ dependencies {
implementation(project(":core:common:util"))

testImplementation(project(":core:common:junit"))
testImplementation(libs.testcontainers.junit)
testImplementation(libs.testcontainers.vault)
implementation(libs.bouncyCastle.bcpkixJdk18on)

}


Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2022 Mercedes-Benz Tech Innovation GmbH
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Mercedes-Benz Tech Innovation GmbH - Initial API and Implementation
*
*/

package org.eclipse.edc.vault.hashicorp;

import org.eclipse.edc.spi.EdcException;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.security.CertificateResolver;
import org.eclipse.edc.spi.security.Vault;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;

/**
* Resolves an X.509 certificate in Hashicorp vault.
*/
public class HashicorpCertificateResolver implements CertificateResolver {
private final Vault vault;
private final Monitor monitor;

public HashicorpCertificateResolver(Vault vault, Monitor monitor) {
this.vault = vault;
this.monitor = monitor;
}

@Override
public X509Certificate resolveCertificate(String id) {
String certificateRepresentation = vault.resolveSecret(id);
if (certificateRepresentation == null) {
return null;
}
try (InputStream inputStream =
new ByteArrayInputStream(certificateRepresentation.getBytes(StandardCharsets.UTF_8))) {
X509Certificate x509Certificate = PemUtil.readX509Certificate(inputStream);
if (x509Certificate == null) {
monitor.warning(
String.format("Expected PEM certificate on key %s, but value not PEM.", id));
}
return x509Certificate;
} catch (IOException e) {
throw new EdcException(e.getMessage(), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
/**
* Implements a vault backed by Hashicorp Vault.
*/
class HashicorpVault implements Vault {
public class HashicorpVault implements Vault {

@NotNull
private final HashicorpVaultClient hashicorpVaultClient;
@NotNull
private final Monitor monitor;

HashicorpVault(@NotNull HashicorpVaultClient hashicorpVaultClient, @NotNull Monitor monitor) {
public HashicorpVault(@NotNull HashicorpVaultClient hashicorpVaultClient, @NotNull Monitor monitor) {
this.hashicorpVaultClient = hashicorpVaultClient;
this.monitor = monitor;
}
Expand Down
Loading

0 comments on commit eba6ca1

Please sign in to comment.