Skip to content

Commit

Permalink
Merge pull request #27 from joemiller/keyring-debug-and-readme-refact…
Browse files Browse the repository at this point in the history
…oring
  • Loading branch information
joemiller authored Jun 3, 2021
2 parents 5f538bc + 0ae3d63 commit 7a288ac
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 43 deletions.
90 changes: 52 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ with the Okta auth backend:
export VAULT_ADDR=https://vault:8200
vault login -method=okta [email protected]

List stored tokens:
Or to store an existing token:

export VAULT_ADDR=https://vault:8200
vault login

Token (will be hidden): <paste token>

List saved tokens with extended status output:

vault-token-helper list -e

Expand Down Expand Up @@ -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) <[email protected]>`
* 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

Expand All @@ -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 [email protected]
```
VAULT_ADDR=https://vault:8200 vault login -method=okta [email protected]

Or to store an existing token:

$ VAULT_ADDR=https://vault:8200 vault login
Token (will be hidden): <paste token>

Upon successful authentication the Vault token will be stored securely in the platform's
secrets store.
Expand All @@ -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
Expand All @@ -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
-----------

Expand All @@ -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

Expand All @@ -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
Expand Down
24 changes: 21 additions & 3 deletions cmd/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand Down
7 changes: 6 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
3 changes: 2 additions & 1 deletion pkg/store/secret_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package store

import (
"net/url"
"os"

"github.com/99designs/keyring"
"github.com/PuerkitoBio/purell"
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions vagrant/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:**
Expand Down

0 comments on commit 7a288ac

Please sign in to comment.