From 6e288c129762aee60b331bd4f5f97f9acdb348f3 Mon Sep 17 00:00:00 2001 From: Puneet Punamiya Date: Mon, 12 Aug 2024 17:49:15 +0530 Subject: [PATCH] Make kms path generic to read from a file path instead of `KMS_AUTH_TOKEN` (#1167) Previously when `signers.kms.auth.token-dir` was set, then the token was read from the path specified in the field plus `KMS_AUTH_TOKEN` i.e. (for e.g. /tmp/kms-secrets/KMS_AUTH_TOKEN) so user had to create the secret with the key `KMS_AUTH_TOKEN` Hence, with this patch now user can specify the path now and token will be read from the path specified Signed-off-by: PuneetPunamiya --- docs/config.md | 7 ++++--- docs/signing.md | 2 +- pkg/chains/signing/kms/kms.go | 16 +++++----------- pkg/chains/signing/kms/kms_test.go | 12 ++++++------ pkg/config/config.go | 14 +++++++------- 5 files changed, 23 insertions(+), 28 deletions(-) diff --git a/docs/config.md b/docs/config.md index a7ec09f0e..d98747e6b 100644 --- a/docs/config.md +++ b/docs/config.md @@ -145,15 +145,16 @@ chains.tekton.dev/transparency-upload: "true" | :-------------------------------- | :------------------------------------------------------------------------------------------ | :--------------- | :------ | | `signers.kms.auth.address` | URI of KMS server (e.g. the value of `VAULT_ADDR`) | | | `signers.kms.auth.token` | Auth token KMS server (e.g. the value of `VAULT_TOKEN`) | | -| `signers.kms.auth.token-dir` | Path to store KMS server Auth token (e.g. `/etc/kms-secrets`) | | +| `signers.kms.auth.token-path` | Path to store KMS server Auth token (e.g. `/etc/kms-secrets`) | | | `signers.kms.auth.oidc.path` | Path used for OIDC authentication (e.g. `jwt` for Vault) | | | `signers.kms.auth.oidc.role` | Role used for OIDC authentication | | | `signers.kms.auth.spire.sock` | URI of the Spire socket used for KMS token (e.g. `unix:///tmp/spire-agent/public/api.sock`) | | | `signers.kms.auth.spire.audience` | Audience for requesting a SVID from Spire | | + > NOTE: > -> If `signers.kms.auth.token-dir` is set, create a secret with the key `KMS_AUTH_TOKEN` and ensure the Chains deployment mounts this secret to -> the path specified by `signers.kms.auth.token-dir`. +> If `signers.kms.auth.token-path` is set, create a secret and ensure the Chains deployment mounts this secret to +> the path specified by `signers.kms.auth.token-path`. > [!IMPORTANT] > To project the latest token values without needing to recreate the pod, avoid using `subPath` in volume mount. diff --git a/docs/signing.md b/docs/signing.md index a433a367b..98895883b 100644 --- a/docs/signing.md +++ b/docs/signing.md @@ -74,7 +74,7 @@ For Azure, this should have the structure of `azurekms://[VAULT_NAME][VAULT_URL] Most likely, you will need to set up some additional authentication so that the `chains-controller` deployment has access to your KMS service for signing. -For Vault, if you use Token-based authentication, store the token as a secret with the key name `KMS_AUTH_TOKEN`. Mount this secret to a specific path within the tekton-chains-controller container. Specify the mounted path as the value for the `chains-config` config map key `signers.kms.auth.token-dir`. This approach can also be applied to other KMS providers that support token-based authentication. Note that the existing configuration option `signers.kms.auth.token` will still work. If both values are set, `signers.kms.auth.token-dir` will take precedence. +For Vault, if you use Token-based authentication, store the token as a secret. Mount this secret to a specific path within the tekton-chains-controller container. Specify the mounted path as the value for the `chains-config` config map key `signers.kms.auth.token-path`. This approach can also be applied to other KMS providers that support token-based authentication. Note that the existing configuration option `signers.kms.auth.token` will still work. If both values are set, `signers.kms.auth.token-path` will take precedence. For GCP/GKE, we suggest enabling [Workload Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity), and giving your service account `Cloud KMS Admin` permissions. Other Service Account techniques would work as well. diff --git a/pkg/chains/signing/kms/kms.go b/pkg/chains/signing/kms/kms.go index b424dc461..fb5845e04 100644 --- a/pkg/chains/signing/kms/kms.go +++ b/pkg/chains/signing/kms/kms.go @@ -21,7 +21,6 @@ import ( "net" "net/url" "os" - "path/filepath" "strings" "time" @@ -108,8 +107,8 @@ func NewSigner(ctx context.Context, cfg config.KMSSigner) (*Signer, error) { // as direct value set from signers.kms.auth.token. // If both values are set, priority will be given to token-dir. - if cfg.Auth.TokenDir != "" { - rpcAuthToken, err := getKMSAuthToken(cfg.Auth.TokenDir) + if cfg.Auth.TokenPath != "" { + rpcAuthToken, err := getKMSAuthToken(cfg.Auth.TokenPath) if err != nil { return nil, err } @@ -138,15 +137,10 @@ func NewSigner(ctx context.Context, cfg config.KMSSigner) (*Signer, error) { } // getKMSAuthToken retreives token from the given mount path -func getKMSAuthToken(dir string) (string, error) { - tokenEnv := "KMS_AUTH_TOKEN" // #nosec G101 - - // Cocatenate secret mount path specified in signers.kms.auth.token-dir and - // secret key name KMS_AUTH_TOKEN - filePath := filepath.Join(dir, tokenEnv) - fileData, err := os.ReadFile(filePath) +func getKMSAuthToken(path string) (string, error) { + fileData, err := os.ReadFile(path) if err != nil { - return "", fmt.Errorf("reading file %q in directory %q: %w", tokenEnv, dir, err) + return "", fmt.Errorf("reading file in %q: %w", path, err) } // A trailing newline is fairly common in mounted files, so remove it. diff --git a/pkg/chains/signing/kms/kms_test.go b/pkg/chains/signing/kms/kms_test.go index 7808729f9..73186f55f 100644 --- a/pkg/chains/signing/kms/kms_test.go +++ b/pkg/chains/signing/kms/kms_test.go @@ -21,7 +21,6 @@ import ( "net/http" "net/http/httptest" "os" - "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -137,7 +136,7 @@ func TestGetKMSAuthToken_NotADirectory(t *testing.T) { defer os.Remove(tempFile.Name()) token, err := getKMSAuthToken(tempFile.Name()) - assert.Error(t, err) + assert.Equal(t, err, nil) assert.Equal(t, "", token) } @@ -151,13 +150,14 @@ func TestGetKMSAuthToken_FileNotFound(t *testing.T) { // Test for verifying return value of getKMSAuthToken func TestGetKMSAuthToken_ValidToken(t *testing.T) { - tempDir := t.TempDir() // Creates a temporary directory - tokenPath := filepath.Join(tempDir, "KMS_AUTH_TOKEN") + tempFile, err := os.CreateTemp("", "vault-token") + assert.NoError(t, err) + defer os.Remove(tempFile.Name()) - err := os.WriteFile(tokenPath, []byte("test-token"), 0644) // write a sample token "test-token" + err = os.WriteFile(tempFile.Name(), []byte("test-token"), 0644) // write a sample token "test-token" assert.NoError(t, err) - token, err := getKMSAuthToken(tempDir) + token, err := getKMSAuthToken(tempFile.Name()) assert.NoError(t, err) assert.Equal(t, "test-token", token) // verify the value returned by getKMSAuthToken matches "test-token" } diff --git a/pkg/config/config.go b/pkg/config/config.go index 5d81fa686..7175ac2bc 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -91,11 +91,11 @@ type KMSSigner struct { // KMSAuth configures authentication to the KMS server type KMSAuth struct { - Address string - Token string - TokenDir string - OIDC KMSAuthOIDC - Spire KMSAuthSpire + Address string + Token string + TokenPath string + OIDC KMSAuthOIDC + Spire KMSAuthSpire } // KMSAuthOIDC configures settings to authenticate with OIDC @@ -193,7 +193,7 @@ const ( kmsAuthAddress = "signers.kms.auth.address" kmsAuthToken = "signers.kms.auth.token" kmsAuthOIDCPath = "signers.kms.auth.oidc.path" - kmsAuthTokenDir = "signers.kms.auth.token-dir" // #nosec G101 + kmsAuthTokenPath = "signers.kms.auth.token-path" // #nosec G101 kmsAuthOIDCRole = "signers.kms.auth.oidc.role" kmsAuthSpireSock = "signers.kms.auth.spire.sock" kmsAuthSpireAudience = "signers.kms.auth.spire.audience" @@ -313,7 +313,7 @@ func NewConfigFromMap(data map[string]string) (*Config, error) { asString(kmsSignerKMSRef, &cfg.Signers.KMS.KMSRef), asString(kmsAuthAddress, &cfg.Signers.KMS.Auth.Address), asString(kmsAuthToken, &cfg.Signers.KMS.Auth.Token), - asString(kmsAuthTokenDir, &cfg.Signers.KMS.Auth.TokenDir), + asString(kmsAuthTokenPath, &cfg.Signers.KMS.Auth.TokenPath), asString(kmsAuthOIDCPath, &cfg.Signers.KMS.Auth.OIDC.Path), asString(kmsAuthOIDCRole, &cfg.Signers.KMS.Auth.OIDC.Role), asString(kmsAuthSpireSock, &cfg.Signers.KMS.Auth.Spire.Sock),