Skip to content

Commit

Permalink
Make kms path generic to read from a file path instead of `KMS_AUTH_T…
Browse files Browse the repository at this point in the history
…OKEN`

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 <[email protected]>
  • Loading branch information
PuneetPunamiya committed Jul 30, 2024
1 parent a4633b0 commit b62c8dd
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 41 deletions.
20 changes: 4 additions & 16 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,28 +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.

## Namespaces Restrictions in Chains Controller
This feature allows you to specify a list of namespaces for the controller to monitor, providing granular control over its operation. If no namespaces are specified, the controller defaults to monitoring all namespaces.

### Usage
To restrict the Chains Controller to specific namespaces, pass a comma-separated list of namespaces as an argument to the controller using the --namespace flag.

### Example
To restrict the controller to the dev and test namespaces, you would start the controller with the following argument:
```shell
--namespace=dev,test
```
In this example, the controller will only monitor resources (pipelinesruns and taskruns) within the dev and test namespaces.
2 changes: 1 addition & 1 deletion docs/signing.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
16 changes: 5 additions & 11 deletions pkg/chains/signing/kms/kms.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"net"
"net/url"
"os"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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.
Expand Down
12 changes: 6 additions & 6 deletions pkg/chains/signing/kms/kms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -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)
}

Expand All @@ -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"
}
14 changes: 7 additions & 7 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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),
Expand Down

0 comments on commit b62c8dd

Please sign in to comment.