Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
042b8e1
Create skeleton of HC Vault based server keymanager plugin (#5058)
InverseIntegral Sep 18, 2024
d8f7d98
Start implementing signing function for HC vault (#5058)
InverseIntegral Sep 18, 2024
27592b0
Make SignData work with HC Vault keymanager plugin (#5058)
InverseIntegral Sep 18, 2024
5caafd1
Rename transit key type constants (#5058)
InverseIntegral Sep 18, 2024
bd62d68
Make vault client more robust by handling invariant violations (#5058)
InverseIntegral Sep 18, 2024
7ac1a7b
Move logic from plugin to vault client (#5058)
InverseIntegral Sep 18, 2024
ac9d657
Refactor logic to generate vault client (#5058)
InverseIntegral Sep 18, 2024
ff66d99
Use latest key version to sign data (#5058)
InverseIntegral Sep 18, 2024
8380233
Move data encoding to vault client (#5058)
InverseIntegral Sep 18, 2024
e010de9
Add simple vault client auth test (#5058)
InverseIntegral Sep 18, 2024
cc167ab
Remove unused test code (#5058)
InverseIntegral Sep 18, 2024
409e527
Support configuring vault namespace (#5058)
InverseIntegral Sep 18, 2024
f6ce1ac
Support AppRole authentication (#5058)
InverseIntegral Sep 18, 2024
fcbb163
Make transit engine path configurable (#5058)
InverseIntegral Sep 18, 2024
186eb04
Add comments to exported functions (#5058)
InverseIntegral Sep 18, 2024
355cf39
Support certificate authentication (#5058)
InverseIntegral Sep 18, 2024
7cf6e61
Add missing app role auth test case (#5058)
InverseIntegral Sep 18, 2024
f417001
Support K8s auth (#5058)
InverseIntegral Sep 18, 2024
7a8aab3
Support verifying server certificate via CA (#5058)
InverseIntegral Sep 18, 2024
527e342
Test vault client create key function (#5058)
InverseIntegral Sep 18, 2024
5a31f7d
Test vault client get key function (#5058)
InverseIntegral Sep 18, 2024
c2c9d37
Test vault client sign data function (#5058)
InverseIntegral Sep 18, 2024
f615cf8
Test vault key manager configure function (#5058)
InverseIntegral Sep 18, 2024
c7fc59c
Test vault key manager generate key function (#5058)
InverseIntegral Sep 18, 2024
64b0601
Load keys from Vault on configure (#5058)
InverseIntegral Sep 18, 2024
3aa2cea
Test get key entry function (#5058)
InverseIntegral Sep 18, 2024
1c15903
Test get keys function (#5058)
InverseIntegral Sep 18, 2024
ebfc71f
Add simple plugin documentation (#5058)
InverseIntegral Sep 18, 2024
da50cd9
Remove unused hooks (#5058)
InverseIntegral Sep 19, 2024
218c6da
Fix hcl examples in documentation (#5058)
InverseIntegral Oct 20, 2024
9f418a2
Add KeyManager vault integration test (#5058)
InverseIntegral Nov 2, 2024
73e3481
Add warning when skipping TLS verification (#5058)
InverseIntegral Nov 27, 2024
e6ccdca
Prevent shadowing of variable (#5058)
InverseIntegral Nov 27, 2024
babefdb
Improve comment (#5058)
InverseIntegral Nov 27, 2024
987d795
Add type assertion check (#5058)
InverseIntegral Nov 27, 2024
60aa851
Remove TODO (#5058)
InverseIntegral Nov 27, 2024
8d3ed46
Remove TODO (#5058)
InverseIntegral Nov 27, 2024
2fcbe7d
Introduce unique server id for HA setup (#5058)
InverseIntegral Dec 1, 2024
cd8052a
Make key names unique by adding a UUID (#5058)
InverseIntegral Dec 1, 2024
a96511c
Cleanup keys with same SPIRE key id (#5058)
InverseIntegral Dec 1, 2024
269875f
resolve lint issues and implement Validate in plugin
MarcosDY Mar 28, 2025
013696c
Resolve file issue
MarcosDY Mar 28, 2025
79cebc5
Require validate provided key identifier
MarcosDY Mar 28, 2025
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
181 changes: 181 additions & 0 deletions doc/plugin_server_keymanager_hashicorp_vault.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Server plugin: KeyManager "hashicorp_vault"

The `hashicorp_vault` key manager plugin leverages HashiCorp Vault to create, maintain, and rotate key pairs, signing
SVIDs as needed.

## Configuration

The plugin accepts the following configuration options:

| key | type | required | description | default |
|:---------------------|:-------|:--------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------|:---------------------|
| key_identifier_file | string | Required if key_identifier_value is not set | A file path location where information about generated keys will be persisted. See "[Management of keys](#management-of-keys)" for more information. | "" |
| key_identifier_value | string | Required if key_identifier_file is not set | A static identifier for the SPIRE server instance (used instead of `key_identifier_file`). | "" |
| vault_addr | string | | The URL of the Vault server. (e.g., <https://vault.example.com:8443/>) | `${VAULT_ADDR}` |
| namespace | string | | Name of the Vault namespace. This is only available in the Vault Enterprise. | `${VAULT_NAMESPACE}` |
| transit_engine_path | string | | Path of the transit engine that stores the keys. | transit |
| ca_cert_path | string | | Path to a CA certificate file used to verify the Vault server certificate. Only PEM format is supported. | `${VAULT_CACERT}` |
| insecure_skip_verify | bool | | If true, vault client accepts any server certificates. Should only be used for test environments. | false |
| cert_auth | struct | | Configuration for the Client Certificate authentication method | |
| token_auth | struct | | Configuration for the Token authentication method | |
| approle_auth | struct | | Configuration for the AppRole authentication method | |
| k8s_auth | struct | | Configuration for the Kubernetes authentication method | |

The plugin supports **Client Certificate**, **Token** and **AppRole** authentication methods.

- **Client Certificate** method authenticates to Vault using a TLS client certificate.
- **Token** method authenticates to Vault using the token in a HTTP Request header.
- **AppRole** method authenticates to Vault using a RoleID and SecretID that are issued from Vault.

The [`ca_ttl` SPIRE Server configurable](https://github.com/spiffe/spire/blob/main/doc/spire_server.md#server-configuration-file)
should be less than or equal to the Vault's PKI secret engine TTL.
To configure the TTL value, tune the engine.

e.g.

```shell
$ vault secrets tune -max-lease-ttl=8760h pki
```

The configured token needs to be attached to a policy that has at least the following capabilities:

```hcl
path "pki/root/sign-intermediate" {
capabilities = ["update"]
}
```

## Client Certificate Authentication

| key | type | required | description | default |
|:----------------------|:-------|:---------|:---------------------------------------------------------------------------------------------------------------------|:-----------------------|
| cert_auth_mount_point | string | | Name of the mount point where TLS certificate auth method is mounted | cert |
| cert_auth_role_name | string | | Name of the Vault role. If given, the plugin authenticates against only the named role. Default to trying all roles. | |
| client_cert_path | string | | Path to a client certificate file. Only PEM format is supported. | `${VAULT_CLIENT_CERT}` |
| client_key_path | string | | Path to a client private key file. Only PEM format is supported. | `${VAULT_CLIENT_KEY}` |

```hcl
KeyManager "hashicorp_vault" {
plugin_data {
vault_addr = "https://vault.example.org/"
pki_mount_point = "test-pki"
ca_cert_path = "/path/to/ca-cert.pem"
cert_auth {
cert_auth_mount_point = "test-tls-cert-auth"
client_cert_path = "/path/to/client-cert.pem"
client_key_path = "/path/to/client-key.pem"
}
// If specify the role to authenticate with
// cert_auth {
// cert_auth_mount_point = "test-tls-cert-auth"
// cert_auth_role_name = "test"
// client_cert_path = "/path/to/client-cert.pem"
// client_key_path = "/path/to/client-key.pem"
// }

// If specify the key-pair as an environment variable and use the modified mount point
// cert_auth {
// cert_auth_mount_point = "test-tls-cert-auth"
// }

// If specify the key-pair as an environment variable and use the default mount point, set the empty structure.
// cert_auth {}
}
}
```

## Token Authentication

| key | type | required | description | default |
|:------|:-------|:---------|:------------------------------------------------|:-----------------|
| token | string | | Token string to set into "X-Vault-Token" header | `${VAULT_TOKEN}` |

```hcl
KeyManager "hashicorp_vault" {
plugin_data {
vault_addr = "https://vault.example.org/"
pki_mount_point = "test-pki"
ca_cert_path = "/path/to/ca-cert.pem"
token_auth {
token = "<token>"
}
// If specify the token as an environment variable, set the empty structure.
// token_auth {}
}
}
```

## AppRole Authentication

| key | type | required | description | default |
|:-------------------------|:-------|:---------|:-----------------------------------------------------------------|:-----------------------------|
| approle_auth_mount_point | string | | Name of the mount point where the AppRole auth method is mounted | approle |
| approle_id | string | | An identifier of AppRole | `${VAULT_APPROLE_ID}` |
| approle_secret_id | string | | A credential of AppRole | `${VAULT_APPROLE_SECRET_ID}` |

```hcl
KeyManager "hashicorp_vault" {
plugin_data {
vault_addr = "https://vault.example.org/"
pki_mount_point = "test-pki"
ca_cert_path = "/path/to/ca-cert.pem"
approle_auth {
approle_auth_mount_point = "my-approle-auth"
approle_id = "<Role ID>" // or specified by environment variables
approle_secret_id = "<Secret ID>" // or specified by environment variables
}
// If specify the approle_id and approle_secret as an environment variable and use the modified mount point
// approle_auth {
// approle_auth_mount_point = "my-approle-auth"
// }

// If specify the approle_id and approle_secret as an environment variable and use the default mount point, set the empty structure.
// approle_auth {}
}
}
```

## Kubernetes Authentication

| key | type | required | description | default |
|:---------------------|:-------|:---------|:----------------------------------------------------------------------------------|:-----------|
| k8s_auth_mount_point | string | | Name of the mount point where the Kubernetes auth method is mounted | kubernetes |
| k8s_auth_role_name | string | ✔ | Name of the Vault role. The plugin authenticates against the named role | |
| token_path | string | ✔ | Path to the Kubernetes Service Account Token to use authentication with the Vault | |

```hcl
KeyManager "hashicorp_vault" {
plugin_data {
vault_addr = "https://vault.example.org/"
pki_mount_point = "test-pki"
ca_cert_path = "/path/to/ca-cert.pem"
k8s_auth {
k8s_auth_mount_point = "my-k8s-auth"
k8s_auth_role_name = "my-role"
token_path = "/path/to/sa-token"
}

// If specify role name and use the default mount point and token_path
// k8s_auth {
// k8s_auth_role_name = "my-role"
// }
}
}
```

### Management of keys

The plugin needs a way to identify the specific server instance where it's
running. For that, either the `key_identifier_file` or `key_identifier_value`
setting must be used. Setting a _Key Identifier File_ instructs the plugin to
manage the identifier of the server automatically, storing the server ID in the
specified file. This method should be appropriate for most situations.
If a _Key Identifier File_ is configured and the file is not found during server
startup, the file is recreated with a new auto-generated server ID.
Consequently, if the file is lost, the plugin will not be able to identify keys
that it has previously managed and will recreate new keys on demand.

If you need more control over the identifier that's used for the server, the
`key_identifier_value` setting can be used to specify a
static identifier for the server instance. This setting is appropriate in situations
where a key identifier file can't be persisted.
1 change: 1 addition & 0 deletions doc/spire_server.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This document is a configuration reference for SPIRE Server. It includes informa
| DataStore | [sql](/doc/plugin_server_datastore_sql.md) | An SQL database storage for SQLite, PostgreSQL and MySQL databases for the SPIRE datastore |
| KeyManager | [aws_kms](/doc/plugin_server_keymanager_aws_kms.md) | A key manager which manages keys in AWS KMS |
| KeyManager | [disk](/doc/plugin_server_keymanager_disk.md) | A key manager which manages keys persisted on disk |
| KeyManager | [hashicorp_vault](/doc/plugin_server_keymanager_hashicorp_vault.md) | A key manager which manages unpersisted keys in memory |
| KeyManager | [memory](/doc/plugin_server_keymanager_memory.md) | A key manager which manages unpersisted keys in memory |
| CredentialComposer | [uniqueid](/doc/plugin_server_credentialcomposer_uniqueid.md) | Adds the x509UniqueIdentifier attribute to workload X509-SVIDs. |
| NodeAttestor | [aws_iid](/doc/plugin_server_nodeattestor_aws_iid.md) | A node attestor which attests agent identity using an AWS Instance Identity Document |
Expand Down
2 changes: 2 additions & 0 deletions pkg/server/catalog/keymanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package catalog

import (
"github.com/spiffe/spire/pkg/common/catalog"
"github.com/spiffe/spire/pkg/server/plugin/keymanager/hashicorpvault"

"github.com/spiffe/spire/pkg/server/plugin/keymanager"
"github.com/spiffe/spire/pkg/server/plugin/keymanager/awskms"
Expand Down Expand Up @@ -33,6 +34,7 @@ func (repo *keyManagerRepository) BuiltIns() []catalog.BuiltIn {
disk.BuiltIn(),
gcpkms.BuiltIn(),
azurekeyvault.BuiltIn(),
hashicorpvault.BuiltIn(),
memory.BuiltIn(),
}
}
Expand Down
Loading