Skip to content

Commit

Permalink
Merge pull request #27 from Keyfactor/31-main-merge
Browse files Browse the repository at this point in the history
Release 3.1 to main
  • Loading branch information
fiddlermikey committed Apr 18, 2024
2 parents 20a84ef + 6220875 commit 58cee7a
Show file tree
Hide file tree
Showing 23 changed files with 600 additions and 393 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/keyfactor-bootstrap-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Keyfactor Bootstrap Workflow

on:
workflow_dispatch:
pull_request:
types: [opened, closed, synchronize, edited, reopened]
push:
create:
branches:
- 'release-*.*'

jobs:
call-starter-workflow:
uses: keyfactor/actions/.github/workflows/starter.yml@v2
secrets:
token: ${{ secrets.V2BUILDTOKEN}}
APPROVE_README_PUSH: ${{ secrets.APPROVE_README_PUSH}}
gpg_key: ${{ secrets.KF_GPG_PRIVATE_KEY }}
gpg_pass: ${{ secrets.KF_GPG_PASSPHRASE }}
27 changes: 0 additions & 27 deletions .github/workflows/keyfactor-merge-store-types.yml

This file was deleted.

42 changes: 0 additions & 42 deletions .github/workflows/keyfactor-starter-workflow.yml

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
.vs
*.licenseheader
README.md
/README.md
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 3.1.0

* Added support for enterprise namespaces and alternate mount-points during discovery by allowing the value to be entered in the "directories to search" field.
* When error occurs attempting to load a JKS format certificate store, we will now attempt to load it as PKCS12 before failing.

## 3.0.0

* Added support for JKS, PKCS12 and PFX file stores in the Hashicorp Vault Key-Value secrets engine.
Expand Down
59 changes: 51 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

# Orchestrator Extension for Hashicorp Vault

The Hashicorp Vault Orchestrator extension allows you to manage certificates in Hashicorp Vault KeyValue secrets engine and perform inventory on certificates stored in the PKI or Keyfactor secrets engines.

#### Integration status: Production - Ready for use in production environments.


## About the Keyfactor Universal Orchestrator Extension

This repository contains a Universal Orchestrator Extension which is a plugin to the Keyfactor Universal Orchestrator. Within the Keyfactor Platform, Orchestrators are used to manage “certificate stores” — collections of certificates and roots of trust that are found within and used by various applications.
Expand All @@ -13,23 +13,22 @@ The Universal Orchestrator is part of the Keyfactor software distribution and is

The Universal Orchestrator is the successor to the Windows Orchestrator. This Orchestrator Extension plugin only works with the Universal Orchestrator and does not work with the Windows Orchestrator.


## Support for Orchestrator Extension for Hashicorp Vault

Orchestrator Extension for Hashicorp Vault is supported by Keyfactor for Keyfactor customers. If you have a support issue, please open a support ticket with your Keyfactor representative.
Orchestrator Extension for Hashicorp Vault is supported by Keyfactor for Keyfactor customers. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com

###### To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab.


---


---



## Keyfactor Version Supported

The minimum version of the Keyfactor Universal Orchestrator Framework needed to run this version of the extension is 10.1

## Platform Specific Notes

The Keyfactor Universal Orchestrator may be installed on either Windows or Linux based platforms. The certificate operations supported by a capability may vary based what platform the capability is installed on. The table below indicates what capabilities are supported based on which platform the encompassing Universal Orchestrator is running.
Expand Down Expand Up @@ -74,7 +73,6 @@ The following operations are supported by this integration for all of the Key-Va
1. Management (Remove) - Remove a certificate from a defined certificate store.
1. Create - Create a new, empty certificate store at the path defined in Store Path.


Excluding *HCVKVPEM*, the discovery process requires that:
1. The entry for the certificate contain the base64 encoded certificate file.
1. The name (key) for the entry ends with the suffix corresponding to the certificate store type:
Expand All @@ -87,6 +85,43 @@ Excluding *HCVKVPEM*, the discovery process requires that:

**Note**: Key/Value secrets that do not include the expected keys will be ignored during inventory scans.

> :warning: *If your mount point is different than the default "kv-v2" and/or enterprise namespaces are used, you should enter the mount point and namespace into the "Extensions" field in order for discovery to work. Also, if you need to scope discovery to a sub-path rather than the root of the engine mount point, enter that in the "Directories to search" field.*
> *refer to the below image for an example*
![](images/discovery.PNG)



### Important note on PEM (HCVKVPEM) Sub-Folder Inventory
> While HCVKVJKS, HCVKVPFX and HCVKVP12 point to a single file store, the HCVKVPEM is structured differently. Each certificate and private key in a PEM store is in a specific sub-folder under the defined store path.
Consequently you are able to define a single HCVKVPEM store as the root path, and have any number of sub-paths beneath it. These sub-paths could be their own certificate store defined in the platform, or logical containers that don't require a seperate store be set up for each in the Command platform.

> Example:
![](images/PEM-vault-example-1.PNG)

> In the "testpem" path above, there exist both a secret entry (toplevelcert), with a properly formatted and named certificate, and a subpath/ path.
![](images/PEM-vault-example-2.PNG)

> The subpath/ path contains two certificate entries.
![](images/PEM-vault-example-3.PNG)

> - If we define our HCVKVPEM store in the platform to have the path "testpem/", and set "Sub-folder Inventory" to "False", then the inventory job should return the single "toplevelcert" entry.
> - If we define the store with "Sub-Folder Inventory" set to "True", then the inventory job should return 3 entries: "toplevelcert", "cert1", and "testaddexistingcert".
> - If we define another store with the path "testpem/subpath/", then it's inventory will contain "cert1" and "testaddexistingcert".
:warning: _Avoid having the same certificate appearing in multiple stores by setting Sub-Folder inventory to "False" on any HCVKVPEM certificate stores where the path is a parent to another HCVKVPEM store's path that is defined in the platform._

### Base64 encoding

For all of the store types in the Key-Value secrets engine, they should be stored in a base64 encoded format.
One way to encode a binary certificate store is to use the following command in a windows powershell or linux/macOs terminal window:

`c:\> cat <cert store file path> | base64`

### The Hashicorp PKI and Keyfactor Plugin secrets engines

Both the Hashicorp PKI and Keyfactor Secrets Engine plugins are designed to allow managing certifications directly on the Hashicorp Vault instance.
Expand All @@ -107,7 +142,10 @@ This integration was built on the .NET Core 3.1 target framework and are compati

## Security Considerations

1. It is not necessary to use the Vault root token when creating a Certificate Store for HashicorpVault. We recommend creating a token with policies that reflect the minimum permissions necessary to perform the intended operations.
1. It is not necessary to use the Vault root token when creating a Certificate Store for HashicorpVault. We recommend creating a token with policies that reflect the minimum path and permissions necessary to perform the intended operations.
1. The capabilities required to perform all operations on a cert store within vault are `["read", "list", "create", "update", "patch", "delete"]`
1. These capabilities should apply to the parent folder on file stores.
1. The token will also need `"list"` capability on the `<mount point>/metadata` path to perform basic operations.

## Extension Configuration

Expand Down Expand Up @@ -175,7 +213,12 @@ In Keyfactor Command create a new Certificate Store that resembles the one below
- **Mount Point** - This is the mount point name for the instance of the Key Value secrets engine.
- If left blank, will default to "kv-v2".
- If your organization utilizes Vault enterprise namespaces, you should include the namespace here.
- **Subfolder Inventory** - Set to 'True' if it is a requirement to inventory secrets at the subfolder/component level. The default, 'False' will inventory secrets stored at the root of the "Store Path", but will not look at secrets in subfolders. **Note** that there is a limit on the number of certificates that can be in a certificate store. In certain environments enabling Subfolder Inventory may exceed this limit and cause inventory job failure. Inventory job results are currently submitted to the Command platform as a single HTTP POST. There is not a specific limit on the number of certificates in a store, rather the limit is based on the size of the actual certificates and the HTTP POST size limit configured on the Command web server.
- **Subfolder Inventory** - Set to 'True' if all of the certificates . The default, 'False' will inventory secrets stored at the root of the "Store Path", but will not look at secrets in subfolders. **Note** that there is a limit on the number of certificates that can be in a certificate store. In certain environments enabling Subfolder Inventory may exceed this limit and cause inventory job failure. Inventory job results are currently submitted to the Command platform as a single HTTP POST. There is not a specific limit on the number of certificates in a store, rather the limit is based on the size of the actual certificates and the HTTP POST size limit configured on the Command web server.

#### Set the server name and password

- The server name should be the full URL to the instance of Vault that will be accessible by the orchestrator. (example: `http://127.0.0.1:8200`)
- The server password should be the Vault token that will be used for authenticating.

#### Set the server name and password

Expand Down
5 changes: 1 addition & 4 deletions hashicorp-vault-orchestrator/CertUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,7 @@ public static List<CurrentInventoryItem> CurrentInventoryFromPkcs12(Pkcs12Store
string FormatBase64(string ss) =>
ss.Length <= 64 ? ss : ss.Substring(0, 64) + "\n" + FormatBase64(ss.Substring(64));
string header = "-----BEGIN CERTIFICATE-----\n";
string footer = "\n-----END CERTIFICATE-----";
return header + FormatBase64(base64Cert) + footer;
return CertificateHeaders.PEM_HEADER + FormatBase64(base64Cert) + CertificateHeaders.PEM_FOOTER;
};

public static string GenerateRandomString(int length)
Expand Down
26 changes: 24 additions & 2 deletions hashicorp-vault-orchestrator/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,35 @@ static class StoreType
public const string KCVKVJKS = "HCVKVJKS";
public const string HCVKVPKCS12 = "HCVKVP12";
public const string HCVKVPFX = "HCVKVPFX";
public const string HCVPKI = "HCVPKI";
public const string HCVPKI = "HCVPKI";
}

static class StoreFileExtensions {
static class StoreFileExtensions
{
public const string HCVKVJKS = "_jks";
public const string HCVKVPKCS12 = "_p12";
public const string HCVKVPFX = "_pfx";
public const string HCVKVPEM = "certificate";
public static string ForStoreType(string type)
{
switch (type)
{
case StoreType.HCVKVPEM:
return HCVKVPEM;
case StoreType.HCVKVPFX:
return HCVKVPFX;
case StoreType.HCVKVPKCS12:
return HCVKVPKCS12;
case StoreType.KCVKVJKS:
return HCVKVJKS;
default:
return string.Empty;
}
}
}

static class CertificateHeaders {
public const string PEM_HEADER = "-----BEGIN CERTIFICATE-----\n";
public const string PEM_FOOTER = "\n-----END CERTIFICATE-----";
}
}
Loading

0 comments on commit 58cee7a

Please sign in to comment.