From aca9e24bf5df3abc311e84ad16ce86ce760dea3f Mon Sep 17 00:00:00 2001 From: joe miller Date: Wed, 2 Jun 2021 18:47:02 -0700 Subject: [PATCH 1/5] docs: add note to vagrant doc about logging in to the gui before running tests --- vagrant/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vagrant/README.md b/vagrant/README.md index 8ab4415..f65e168 100644 --- a/vagrant/README.md +++ b/vagrant/README.md @@ -43,6 +43,9 @@ make test go test -v ./... ``` +> If you run the tests via ssh you need to login to the web UI first in order for +> the gnome keyring service to start first. + ### Windows 10 **Pre-Reqs:** From 68914dbaeef7346c571f4f78bcb6b82b7e371de5 Mon Sep 17 00:00:00 2001 From: joe miller Date: Wed, 2 Jun 2021 18:47:46 -0700 Subject: [PATCH 2/5] update integration tests to pass in the existing environment. necessary for DBUS secret-service in some scenarios --- cmd/integration_test.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/cmd/integration_test.go b/cmd/integration_test.go index 1706975..3f390ae 100644 --- a/cmd/integration_test.go +++ b/cmd/integration_test.go @@ -21,6 +21,22 @@ func TestMain(m *testing.M) { } } +// getEnv returns a copy of the process's current environment with any VAULT_* +// env vars removed. This function exists because we need a copy of the processes +// environment on certain platforms. For example, to run these tests on Linux +// we need a copy of the DBUS_SESSION_BUS_ADDRESS env var in order to access the +// gnome keyring. +func getEnv() []string { + env := os.Environ() + newEnv := []string{} + for _, i := range env { + if !strings.HasPrefix(i, "VAULT_") { + newEnv = append(newEnv, i) + } + } + return newEnv +} + // execCmd executes the vault-token-helper with the provides args and returns // stdout, stderr, and error. // execCommand("list", "--debug") would be similar to executing the compiled program "vault-token-helper list --debug" @@ -47,7 +63,7 @@ func TestGetCmd_MissingVAULT_ADDR(t *testing.T) { } stdin := "" - env := []string{} + env := getEnv() stdout, stderr, err := execCmd(env, stdin, "get") assert.NotNil(t, err) // vault-token-helper should exit non-zero when VAULT_ADDR is not set @@ -62,7 +78,8 @@ func TestGetCmd_NoMatch(t *testing.T) { } stdin := "" - env := []string{"VAULT_ADDR=https://foo.bar:8200"} + env := getEnv() + env = append(env, "VAULT_ADDR=https://foo.bar:8200") stdout, stderr, err := execCmd(env, stdin, "get") assert.Nil(t, err) // vault-token-helper should exit 0 if no token is stored for the $VAULT_ADDR @@ -77,7 +94,8 @@ func TestGetCmd_Match(t *testing.T) { } stdin := "" - env := []string{"VAULT_ADDR=https://foo.bar:8200"} + env := getEnv() + env = append(env, "VAULT_ADDR=https://foo.bar:8200") stdout, stderr, err := execCmd(env, stdin, "get") assert.Nil(t, err) // vault-token-helper should exit 0 if no token is stored for the $VAULT_ADDR assert.Equal(t, "", stdout) From 1099506bb015b657a94a1f25be7ed39fb4d7261a Mon Sep 17 00:00:00 2001 From: joe miller Date: Wed, 2 Jun 2021 18:48:12 -0700 Subject: [PATCH 3/5] explicitly map the default backend selection choice to "automatic" to improve error messages --- cmd/root.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index 624d8b5..39af011 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -106,8 +106,13 @@ func initBackend() error { WinCredPrefix: cfg.WinCred.Prefix, } + // rename the default backendtype to 'automatic' to make potential error messages more useful: + if cfg.BackendType == "" { + cfg.BackendType = "automatic" + } + switch cfg.BackendType { - case "automatic", "": + case "automatic": storeCfg.AllowedBackends = store.SupportedBackends case "keychain": storeCfg.AllowedBackends = []keyring.BackendType{keyring.KeychainBackend} From 59983ba4919e5e7b79a1c7bdc8f11a12a8c14a3d Mon Sep 17 00:00:00 2001 From: joe miller Date: Wed, 2 Jun 2021 18:48:48 -0700 Subject: [PATCH 4/5] enable keyring lib debug logging when KEYRING_DEBUG env var is set --- pkg/store/secret_service_test.go | 3 ++- pkg/store/store.go | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/store/secret_service_test.go b/pkg/store/secret_service_test.go index 7922463..35a8219 100644 --- a/pkg/store/secret_service_test.go +++ b/pkg/store/secret_service_test.go @@ -13,7 +13,8 @@ import ( func TestSecretServiceStore(t *testing.T) { // TODO: get this working in CI. The current blocker is needing to have a dbus prompter service that - // can be driven automatically and headless. + // can be driven automatically and headless: + // https://github.com/99designs/keyring/blob/d9b6b92e219ff56ce753cf84d4956f823d431651/libsecret_test.go#L13-L22 if os.Getenv("CI") != "" { t.Skip("Skipping testing in CI environment") } diff --git a/pkg/store/store.go b/pkg/store/store.go index 5194b25..874cac7 100644 --- a/pkg/store/store.go +++ b/pkg/store/store.go @@ -2,6 +2,7 @@ package store import ( "net/url" + "os" "github.com/99designs/keyring" "github.com/PuerkitoBio/purell" @@ -30,6 +31,10 @@ var SupportedBackends = []keyring.BackendType{ // New creates a new Store from a keyring.Config func New(cfg keyring.Config) (*Store, error) { + if os.Getenv("KEYRING_DEBUG") != "" { + keyring.Debug = true + } + kr, err := keyring.Open(cfg) if err != nil { return nil, err From 0ae3d63707121e3923504fc7f8a49cc5954ef395 Mon Sep 17 00:00:00 2001 From: joe miller Date: Wed, 2 Jun 2021 18:49:06 -0700 Subject: [PATCH 5/5] docs: readability improvements --- README.md | 90 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 6dfe18b..8df64bd 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,14 @@ with the Okta auth backend: export VAULT_ADDR=https://vault:8200 vault login -method=okta username=joe@dom.tld -List stored tokens: +Or to store an existing token: + + export VAULT_ADDR=https://vault:8200 + vault login + + Token (will be hidden): + +List saved tokens with extended status output: vault-token-helper list -e @@ -75,62 +82,60 @@ Install Clone this repo and compile for the current architecture: -```sh -make build -``` + make build -Binaries for all supported platforms are built using the -[dockercore/golang-cross](https://github.com/docker/golang-cross) image. This is the same image used -by the docker cli project for cross-compiling and linking with platform-specific libraries such -as macOS' Keychain and Windows' WinCred. +### Verifying releases -```sh -make snapshot -``` +macOS binaries are CodeSign'd with a certificate from Apple. -### Verifying releases +Additionally all releases are signed using this project's GPG key: -Releases are signed using the project GPG key with key-ID `37F9D1272278CD32` and fingerprint -`5EF2 2550 7053 ACC2 728A A51C 37F9 D127 2278 CD32`. The key can be fetched from most keyservers. +* Subject: `vault-token-helper (github.com/joemiller/vault-token-helper project key) ` +* key-ID `37F9D1272278CD32` +* fingerprint `5EF2 2550 7053 ACC2 728A A51C 37F9 D127 2278 CD32`. -```console -gpg --recv-keys 37F9D1272278CD32 -``` +The key can be fetched from most keyservers: + + gpg --recv-keys 37F9D1272278CD32 [Download](https://github.com/joemiller/vault-token-helper/releases/latest) and verify the signature on the checksum file: -```console -gpg --verify vault-token-helper_0.2.0_checksums.txt.sig vault-token-helper_0.2.0_checksums.txt -``` + gpg --verify vault-token-helper_0.2.0_checksums.txt.sig vault-token-helper_0.2.0_checksums.txt -After verifying the checksum file signature use `shasum` to verify the checksums of the +After verifying the checksum file's signature use `shasum` to verify the checksums of the release artifacts: -```console -shasum --check vault-token-helper_0.2.0_checksums.txt -``` - -macOS binaries are codesign'd. + shasum --check vault-token-helper_0.2.0_checksums.txt Usage ----- +### Pre-Reqs + +`vault-token-helper` will attempt to detect the best available token storage backend. +On macOS this will be the Keychain app, on Windows the native credential store, and +on most Linux distros the DBus Secret-Service API (common packages implementing this are +Gnome Keyring and Seahorse). + +You may need to install a compatible credential storage service on Linux. For example, +on Arch Linux with a vanilla desktop you may need to install `gnome-keyring`. + +Alternatively, the cross-platform, GPG-based [pass](https://www.passwordstore.org/) +utility can also be used. You must initialize `pass` (`pass init`) with a GPG key before +using `vault-token-helper`. + ### Configure Vault Install `vault-token-helper` then run: -```console -vault-token-helper enable -``` + vault-token-helper enable This creates (overwrites) the `$HOME/.vault` config file used by the `vault` CLI. Alternatively, edit the file and specify the full path to the `vault-token-helper` binary: -```toml -token_helper = "/install/path/to/vault-token-helper" -``` + token_helper = "/install/path/to/vault-token-helper" ### Configure vault-token-helper @@ -146,10 +151,12 @@ A fully annotated example config file is available in [./vault-token-helper.anno Set `VAULT_ADDR` to the URL of your Vault instance and run `vault` commands like normal. For example, to login and store a token on a Vault instance with the Okta auth plugin enabled: -```console -export VAULT_ADDR=https://vault:8200 -vault login -method=okta username=joe@dom.tld -``` + VAULT_ADDR=https://vault:8200 vault login -method=okta username=joe@dom.tld + +Or to store an existing token: + + $ VAULT_ADDR=https://vault:8200 vault login + Token (will be hidden): Upon successful authentication the Vault token will be stored securely in the platform's secrets store. @@ -168,7 +175,7 @@ There are a few additional commands: * `enable`: Enable the vault-token-helper by (over)writing the ~/.vault config file. * `backends`: List the available secret storage backends on the current platform. -* `list`: List tokens. Add `--extended` flag to lookup additional details about the stored +* `list`: List tokens. Add `--extended/-e` flag to lookup additional details about the stored token by quering the Vault instance's token lookup API. ```console @@ -186,6 +193,10 @@ Support Please open a GitHub [issue](https://github.com/joemiller/vault-token-helper/issues). +Setting the `KEYRING_DEBUG` environment variable to any value will produce additional output +that may be useful for debugging common issues. Please set this variable and then +run a command such as `vault-token-helper list`. Include the debug output in your issue. + Development ----------- @@ -201,7 +212,7 @@ due to interactive elements such as password prompts. To aid in development ther VMs with GUIs enabled in the `./vagrant/` directory. See the [./vagrant/README.md](./vagrant/README.md) for further details. -The most complete way to run all tests would be to run `make test` under each platform. +The most complete way to run all tests would be to run `make test` under each platform (macOS, Linux, Windows). ### CI/CD @@ -210,6 +221,9 @@ The most complete way to run all tests would be to run `make test` under each pl Tests are run on pull requests and versioned releases are generated on all successful master branch builds. +Some tests are not run in CI/CD due to requiring an interactive desktop such as the Linux +DBus Secret Service backend. + ### Release Management Releases are cut automatically on all successful master branch builds. This project uses