Skip to content

Commit

Permalink
feat: add file path for each secret
Browse files Browse the repository at this point in the history
* feat: add a warning explaining why the plugin won't work

* feat: increment version

* feat: add optional path for each secret

* feat: return client error if file retrieval fails

* feat: use source enum in tests

* feat: test source logic

* feat: update git ignore

* feat: fix test

* feat: update docs
  • Loading branch information
Ruddickmg authored Oct 3, 2024
1 parent 008a5d6 commit 076b8f3
Show file tree
Hide file tree
Showing 28 changed files with 435 additions and 180 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@
.idea
sockets
node_modules
documentation/dist
documentation/dist
test_files/role_id
test_files/secret_id
test_files/source_test
test_files/jwt
39 changes: 38 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[package]
name = "vault_kms_provider"
version = "0.7.0"
version = "0.8.0"
edition = "2021"

[dependencies]
base64 = "0.22.1"
bytes = "1.7.2"
http = "1.1.0"
http-body-util = "0.1.2"
hyper-util = { version = "0.1.9", features = ["tokio"] }
hyper-util = { version = "0.1.9", features = ["tokio"] }
hyper = { version = "1.4.1", features = ["http1", "server"] }
notify = "6.1.1"
prost = "0.13.3"
Expand All @@ -21,6 +21,9 @@ tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["json", "ansi", "env-filter"] }
vaultrs = "0.7.2"
futures = "0.3.30"
convert_case = "0.6.0"
strum = "0.26.3"
strum_macros = "0.26.4"

[dev-dependencies]
pretty_assertions = "1.4.1"
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ See usage [documentation here](https://vault-kms-provider.io/)

### RoadMap:
- [ ] Set up Authentication
- [ ] Make optional file path or value for each secret
- [x] Make optional file path or value for each secret
- [x] Kubernetes
- [x] Token
- [x] User & Password
- [x] App Role
- [ ] JWT
- [ ] Tls certs
- [ ] JWT/OIDC
- [ ] OIDC

## Kubernetes authentication

Expand Down
3 changes: 3 additions & 0 deletions documentation/src/_includes/home.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ layout: nav.njk
---

<div class="content-header">
{% for alert in collections.alert %}
{{ alert.content }}
{% endfor %}
<h1>{{ header | default: 'Documentation' }}</h1>
</div>
<div class="content-body">
Expand Down
3 changes: 3 additions & 0 deletions documentation/src/alerts/alerts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"tags": ["alert"]
}
3 changes: 3 additions & 0 deletions documentation/src/alerts/kubernetes_fix_required.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
> [!WARNING]
> This plugin is currently awaiting [a fix](https://github.com/kubernetes/kubernetes/pull/126930) to be released in [Kubernetes version 1.32](https://github.com/kubernetes/kubernetes/milestone/65). Until [the fix](https://github.com/kubernetes/kubernetes/pull/126930) is released by the Kubernetes team, this plugin will not work.
12 changes: 10 additions & 2 deletions documentation/src/configuration/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,29 @@ Configuration of auth methods is done using the environment variables listed bel
```hcl
# Path defined for the authentication route, ex: auth/custom-auth-path/...
# if not set, will default to the associated auth method, ex: auth/userpass/.. or auth/kubernetes/..
VAULT_AUTH_PATH = "custom-auth-path"
VAULT_AUTH_MOUNT = "custom-auth-path"
# Vault token for vault access
VAULT_TOKEN = "SiQOECxwSDCeQt1r0n5kqQCr"
# path to file containing vault token
VAULT_TOKEN_PATH = "/path/to/vault/token"
# user and password for userpass authentication
VAULT_USER = "vault-kms-provider"
VAULT_PASSWORD = "some-password"
# path to file containing vault password
VAULT_PASSWORD_PATH = "/path/to/vault/password"
# path to mounted JWT for kubernetes auth
VAULT_JWT_PATH = "/path/to/vault.jwt"
VAULT_KUBERNETES_JWT_PATH = "/path/to/vault.jwt"
# jwt for kubernetes auth
VAULT_KUBERNETES_JWT = "jwt"
# role_id and secret_id for approle authentication
VAULT_ROLE_ID = "role"
VAULT_SECRET_ID = "secret"
# path to file containing secret id
VAULT_SECRET_ID_PATH = "/path/to/secret/id"
```

Environment variables can be configured using the `env` property in the values.yaml, ex:
Expand Down
28 changes: 5 additions & 23 deletions documentation/src/configuration/provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ helm install vault-kms-provider --set "serviceAccount.create=false"

### Environment variables

Below are all the environment variables and their defaults for configuration of the KMS provider
Below are some general environment variables and their defaults for configuration of the KMS provider

```hcl
# Url of the vault service
VAULT_ADDRESS = "https://vault.vault.svc.cluster.local:8200"
# The endpoint that the health checks will listen on
HEALTH_ENDPOINT = "0.0.0.0:8080"
# Path to the socket used for communication with the Kubernetes API server
SOCKET_PATH = "./sockets/vault-kms-provider.sock"
Expand All @@ -42,26 +45,5 @@ SOCKET_PERMISSIONS = "any"
VAULT_TRANSIT_KEY = "vault-kms-provider"
# path defined for the transit gateway, ex: auth/transit/... or auth/transit-path/...
VAULT_TRANSIT_PATH = "transit"
# The endpoint that the health checks will listen on
HEALTH_ENDPOINT = "0.0.0.0:8080"
# Path defined for the authentication route, ex: auth/custom-auth-path/...
# if not set, will default to the associated auth method, ex: auth/userpass/.. or auth/kubernetes/..
VAULT_AUTH_PATH = null
# Vault token for vault access
VAULT_TOKEN = null
# user and password for userpass authentication
VAULT_USER = "vault-kms-provider"
VAULT_PASSWORD = null
# path to mounted JWT for kubernetes auth
VAULT_JWT_PATH = null
# role_id and secret_id for approle authentication
VAULT_ROLE_ID = null
VAULT_SECRET_ID = null
VAULT_TRANSIT_MOUNT = "transit"
```
4 changes: 2 additions & 2 deletions helm/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.7.0
version: 0.8.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "0.7.0"
appVersion: "0.8.0"
4 changes: 2 additions & 2 deletions helm/templates/configurations/config-map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ data:
VAULT_TRANSIT_KEY: "{{ .Values.vault.transit.key }}"
VAULT_TRANSIT_PATH: "{{ .Values.vault.transit.path }}"
{{- if .Values.vault.authentication.path }}
VAULT_AUTH_PATH: "{{ .Values.vault.authentication.path }}"
VAULT_AUTH_MOUNT: {{ .Values.vault.authentication.path }}
{{- end }}
{{- if and .Values.serviceAccount.token.path .Values.serviceAccount.token.name }}
VAULT_JWT_PATH: "{{ .Values.serviceAccount.token.path }}/{{ .Values.serviceAccount.token.name }}"
VAULT_KUBERNETES_JWT_PATH: "{{ .Values.serviceAccount.token.path }}/{{ .Values.serviceAccount.token.name }}"
{{- end }}
{{- if .Values.vault.ca.file }}
VAULT_CA_CERT: {{ .Values.vault.ca.file }}
Expand Down
6 changes: 4 additions & 2 deletions src/configuration/authentication/app_role.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use crate::utilities::source::Source;

const DEFAULT_MOUNT_PATH: &str = "approle";

#[derive(Clone, Debug)]
pub struct AppRole {
pub role_id: String,
pub secret_id: String,
pub secret_id: Source,
pub mount_path: String,
}

impl AppRole {
pub fn new(role_id: String, secret_id: String, mount_path: Option<String>) -> Self {
pub fn new(role_id: String, secret_id: Source, mount_path: Option<String>) -> Self {
Self {
role_id,
secret_id,
Expand Down
8 changes: 5 additions & 3 deletions src/configuration/authentication/kubernetes.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
use crate::utilities::source::Source;

const DEFAULT_KUBERNETES_AUTH_PATH: &str = "kubernetes";

#[derive(Clone, Debug)]
pub struct Kubernetes {
pub file_path: String,
pub jwt: Source,
pub mount_path: String,
}

impl Kubernetes {
pub fn new(file_path: String, mount_path: Option<String>) -> Self {
pub fn new(source: Source, mount_path: Option<String>) -> Self {
Self {
file_path,
jwt: source,
mount_path: mount_path.unwrap_or(DEFAULT_KUBERNETES_AUTH_PATH.to_string()),
}
}
Expand Down
25 changes: 13 additions & 12 deletions src/configuration/authentication/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use app_role::AppRole;
pub use kubernetes::Kubernetes;
pub use user_pass::UserPass;

use crate::utilities::env::{get_env, get_env_option};
use crate::utilities::{environment::Environment, source::Source};

const DEFAULT_USER: &str = "vault-kms-provider";

Expand All @@ -15,27 +15,28 @@ pub enum Credentials {
AppRole(AppRole),
UserPass(UserPass),
Kubernetes(Kubernetes),
Token(String),
Token(Source),
None,
}

impl Credentials {
pub fn from_env() -> Self {
let auth_path = get_env_option("VAULT_AUTH_PATH");
if let Some(token) = get_env_option("VAULT_TOKEN") {
let auth_mount = Environment::VaultAuthMount.get();
if let Some(token) = Environment::VaultToken.source() {
Self::Token(token)
} else if let Some(file_path) = get_env_option("VAULT_JWT_PATH") {
Self::Kubernetes(Kubernetes::new(file_path, auth_path))
} else if let Some(password) = get_env_option("VAULT_PASSWORD") {
} else if let Some(jwt) = Environment::VaultKubernetesJwt.source() {
Self::Kubernetes(Kubernetes::new(jwt, auth_mount))
} else if let Some(password) = Environment::VaultPassword.source() {
Self::UserPass(UserPass::new(
get_env("VAULT_USER", DEFAULT_USER),
Environment::VaultUser.or(DEFAULT_USER),
password,
auth_path,
auth_mount,
))
} else if let Some((role_id, secret_id)) =
get_env_option("VAULT_ROLE_ID").zip(get_env_option("VAULT_SECRET_ID"))
} else if let Some((role_id, secret_id)) = Environment::VaultRoleId
.get()
.zip(Environment::VaultSecretId.source())
{
Self::AppRole(AppRole::new(role_id, secret_id, auth_path))
Self::AppRole(AppRole::new(role_id, secret_id, auth_mount))
} else {
Self::None
}
Expand Down
6 changes: 4 additions & 2 deletions src/configuration/authentication/user_pass.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use crate::utilities::source::Source;

const DEFAULT_USER_PASS_AUTH_PATH: &str = "userpass";

#[derive(Clone, Debug)]
pub struct UserPass {
pub username: String,
pub password: String,
pub password: Source,
pub mount_path: String,
}

impl UserPass {
pub fn new(username: String, password: String, mount_path: Option<String>) -> Self {
pub fn new(username: String, password: Source, mount_path: Option<String>) -> Self {
Self {
username,
password,
Expand Down
4 changes: 2 additions & 2 deletions src/configuration/health.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::utilities::env::get_env;
use crate::utilities::environment::Environment;

const DEFAULT_HEALTH_ENDPOINT: &str = "0.0.0.0:8080";

Expand All @@ -9,7 +9,7 @@ pub struct HealthCheckConfiguration {
impl HealthCheckConfiguration {
pub fn new() -> Self {
Self {
endpoint: get_env("HTTP_ADDRESS", DEFAULT_HEALTH_ENDPOINT),
endpoint: Environment::HttpAddress.or(DEFAULT_HEALTH_ENDPOINT),
}
}
}
6 changes: 3 additions & 3 deletions src/configuration/logging.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::utilities::env::get_env;
use crate::utilities::environment::Environment;
use tracing::Level;

const DEFAULT_LOG_LEVEL: &str = "info";
Expand All @@ -22,8 +22,8 @@ impl LoggingConfiguration {

pub fn new() -> Self {
Self {
level: Self::str_to_log_level(get_env("LOG_LEVEL", DEFAULT_LOG_LEVEL).as_str()),
format: get_env("LOG_FORMAT", DEFAULT_LOG_FORMAT),
level: Self::str_to_log_level(Environment::LogLevel.or(DEFAULT_LOG_LEVEL).as_str()),
format: Environment::LogFormat.or(DEFAULT_LOG_FORMAT),
}
}
}
Loading

0 comments on commit 076b8f3

Please sign in to comment.