Coder Social home page Coder Social logo

joemiller / vault-token-helper Goto Github PK

View Code? Open in Web Editor NEW
104.0 2.0 10.0 264 KB

@Hashicorp Vault Token Helper for macOS, Linux and Windows with support for secure token storage and multiple Vault servers ๐Ÿ”

License: MIT License

Makefile 1.93% Go 97.34% Shell 0.73%
vault hashicorp-vault token credentials helper-tool helper windows linux macos keychain

vault-token-helper's Introduction

vault-token-helper

main

A @hashicorp Vault token helper with support for native secret storage on macOS, Linux, and Windows.

Features

Store and retrieve tokens for multiple Vault ($VAULT_ADDR) instances, simplifying operators' workflows when working with multiple Vaults.

Supported backends:

  • macOS Keychain
  • Linux (DBus Secret Service compatible backends, eg: Gnome Keyring)
  • Windows (WinCred)
  • pass (GPG)

Quickstart (macOS)

Install:

brew install joemiller/taps/vault-token-helper

Configure Vault to use the token helper. This will create the ~/.vault config file:

vault-token-helper enable

Authenticate to a Vault instance to encrypt and store a new token locally, for example with the Okta auth backend:

export VAULT_ADDR=https://vault:8200
vault login -method=okta [email protected]

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

Keep reading for further details and installation methods.

Install

One-line install

OS Command
macOS brew install joemiller/taps/vault-token-helper
Linux
(LinuxBrew) untested
brew install joemiller/taps/vault-token-helper

Linux packages

Format Arch
rpm amd64
deb amd64

Pre-built binaries

OS Arch binary
macOS amd64 vault-token-helper
Linux amd64 vault-token-helper
Windows amd64 vault-token-helper

From source

Clone this repo and compile for the current architecture:

make build

Verifying releases

macOS binaries are CodeSign'd with a certificate from Apple.

Additionally all releases are signed using this project's GPG key:

  • 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.

The key can be fetched from most keyservers:

gpg --recv-keys 37F9D1272278CD32

Download and verify the signature on the checksum file:

gpg --verify vault-token-helper_0.2.0_checksums.txt.sig vault-token-helper_0.2.0_checksums.txt

After verifying the checksum file's signature use shasum to verify the checksums of the release artifacts:

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 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:

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:

token_helper = "/install/path/to/vault-token-helper"

Configure vault-token-helper

For most installations the defaults should be sufficient.

An optional configuration file located at $HOME/.vault-token-helper.yaml can be used to override the defaults.

A fully annotated example config file is available in ./vault-token-helper.annotated.yaml

Login to Vault

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:

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.

Support for storing tokens from multiple Vault instances is implemented. Change the VAULT_ADDR environment variable to switch between Vault instances.

The VAULT_NAMESPACE environment variable is also supported.

Additional commands

The standard store, get, and erase commands are implemented according to the vault token helper spec.

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/-e flag to lookup additional details about the stored token by quering the Vault instance's token lookup API.
$ vault-token-helper list --extended

VAULT_ADDR                       display_name      ttl         renewable  policies
----------                       ------------      ---         ---------  --------
https://vault-prod.dom.tld:8200  [email protected]  527h46m18s  true       [admin default]
https://vault-dev.dom.tld:8200   [email protected]  275h13m17s  true       [admin default]
https://localhost                ** ERROR **       Get https://localhost/v1/auth/token/lookup-self: dial tcp 127.0.0.1:443: connect: connection refused

Support

Please open a GitHub issue.

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

Tests

Run tests: make test.

There is test coverage in pkg/store covering all of the supported backends. Additionally, there is an integration test in the cmd package.

Some tests are platform specific and difficult to test outside of a full desktop environment due to interactive elements such as password prompts. To aid in development there are Vagrant VMs with GUIs enabled in the ./vagrant/ directory. See the ./vagrant/README.md for further details.

The most complete way to run all tests would be to run make test under each platform (macOS, Linux, Windows).

CI/CD

Github Actions is used for CI/CD.

Tests are run on pull requests and versioned releases are generated on all successful main 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 main branch builds. This project uses autotag and goreleaser to automate this process.

Semver (vMajor.Minor.Patch) is used for versioning and releases. By default, autotag will bump the patch version on a successful main build, eg: v1.0.0 -> v1.0.1.

To bump the major or minor release instead, include [major] or [minor] in the commit message. Refer to the autotag docs for more details.

Include [skip ci] in the commit message to prevent a new version from being released. Only use this for things like documentation updates.

A local release can be built and signed with a copy of the project GPG key's signing subkey:

$ GPG_KEY="$(cat vault-token-helper.signing-key.gpg | base64)" make release

# or a snapshot build:

$ GPG_KEY="$(cat vault-token-helper.signing-key.gpg | base64)" make snapshot

Apple codesign

In order to avoid macOS keychain from always prompting for passwords the macOS binaries are codesigned with a cert issued by Apple.

TODO

after v0.1.0:

  • The wincred lib used by 99designs/keyring has more configuration options available. Make these available in 99designs/keyring and vault-token-helper.
  • add a flag like --extended to list that will query vault for additional token info, eg: valid/invalid, ttl, policies
  • ci/cd:
    • sign checksum.txt and assets in goreleaser.yaml GPG key
    • apple codesign the macos binaries
    • linux tests, figure out how to test dbus secret-service in headless CI. probably need a stub to connect to Dbus and provide the 'prompt' service

vault-token-helper's People

Contributors

joemiller avatar sgmitchell avatar tianhaopx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

vault-token-helper's Issues

Unable to install (brew + macOS)

Unfortunately running into the following errors when running brew install joemiller/taps/vault-token-helper:

==> Tapping joemiller/taps
Cloning into '/opt/homebrew/Library/Taps/joemiller/homebrew-taps'...
remote: Enumerating objects: 268, done.
remote: Counting objects: 100% (115/115), done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 268 (delta 53), reused 0 (delta 0), pack-reused 153
Receiving objects: 100% (268/268), 41.00 KiB | 4.56 MiB/s, done.
Resolving deltas: 100% (117/117), done.
Error: Invalid formula: /opt/homebrew/Library/Taps/joemiller/homebrew-taps/Formula/certin.rb
formulae require at least a URL
Error: Invalid formula: /opt/homebrew/Library/Taps/joemiller/homebrew-taps/Formula/yk-attest-verify.rb
formulae require at least a URL
Warning: Calling bottle :unneeded is deprecated! There is no replacement.
Please report this issue to the joemiller/taps tap (not Homebrew/brew or Homebrew/core):
  /opt/homebrew/Library/Taps/joemiller/homebrew-taps/Formula/docker-tail.rb:9

Warning: Calling bottle :unneeded is deprecated! There is no replacement.
Please report this issue to the joemiller/taps tap (not Homebrew/brew or Homebrew/core):
  /opt/homebrew/Library/Taps/joemiller/homebrew-taps/Formula/creds.rb:9

Error: Invalid formula: /opt/homebrew/Library/Taps/joemiller/homebrew-taps/Formula/vault-token-helper.rb
formulae require at least a URL
Error: Cannot tap joemiller/taps: invalid syntax in tap!

Any assistance greatly appreciated. Thanks.

refactor support for VAULT_NAMESPACE

Followup from #21, #23

Support for vault namespaces was not considered in the original design and then added later. It was added by cat'ing together VAULT_ADDR + VAULT_NAMESPACE and using the combined value as the primary key when storing in the OS's credential store.

The problem is that you cannot combine these two values to form a valid URL. This resulted in errors when running vault-token-helper list --extended (workaround/fix in #23).

The workaround implemented may not be correct for all possible VAULT_ADDR values. It works by parsing the combined URL and assuming any Path value is the VAULT_NAMESPACE. This is likely to work for the majority of cases but would fail if the VAULT_ADDR contained a legit /path.

I'm not sure if it is even valid for VAULT_ADDR to contain a path. If not, then this is moot.

A more robust solution would involve storing VAULT_ADDR and VAULT_NAMESPACE separately in the credential store. This may cause some issues with some OS's credential stores. During initial development I ran into some strange issues with (IIRC) the gnome keyring where it would duplicate rather than update existing entries depending on the format of the entry's title.

  1. First, determine if VAULT_ADDR containing a path element is valid. If not, then this is likely moot and we can close this.
  2. Update to store VAULT_ADDR and VAULT_NAMESPACE
  3. Ensure backwards compatibility:
  4. When encountering a keychain item of the previous format, upgrade to the new format

Consider add set function to ~/.vault-token

This is OSx/Linux related ofc, but would be nice to have a function to populate the vault-token file without print them.

Linux and MacOSx uses ~/.vault-token to store in use token.

So it would be some thing like:

export VAULT_ADDR="https://vaultserver.local:8200"
vault-token-helper set

In the backend would make the same as https://github.com/joemiller/vault-token-helper/blob/main/cmd/get.go#L37 but write to the correct file in each operating system, or this could be defined at vault-token-helper.yaml

Thanks for this great helper.

Vault namespace support

Have you considered adding namespace support to this tool? Instead of keying off only the VAULT_ADDR each record would need to use VAULT_NAMESPACE in addition.

bottle :unneeded is deprecated! There is no replacement

Please help to resolve

Warning: Calling bottle :unneeded is deprecated! There is no replacement.
Please report this issue to the joemiller/taps tap (not Homebrew/brew or Homebrew/core):
  /usr/local/Homebrew/Library/Taps/joemiller/homebrew-taps/Formula/vault-token-helper.rb:9

Unable to access newly stored token on macOS 10.15+

After completing a vault login the token data is successfully stored in keychain as expected on macOS using the keychain store. However when attempting to access vault using the stored token it will fail. The access control attribute of the secret stored in the keychain is not correct. If you toggle on the "allow all applications to access this item" in the access control tab it works as expected.

This is likely an issue with the keyring dependency. A quick look at that repo didn't show any related issues.

Not able to build on Sonoma macOS 14

It looks like Apple has deprecated the SecAccessCreate API and the build is now failing. We have seen this error for a while but it's a hard failure now. The change proposed in #26 could possibly resolve this.

blake@sonoma-rc ~ % /opt/local/bin/go version
go version go1.21.1 darwin/arm64
blake@sonoma-rc ~ % sudo /opt/local/bin/go install github.com/joemiller/vault-token-helper@latest
# github.com/keybase/go-keychain
cgo-gcc-prolog:55:11: warning: 'SecAccessCreate' is deprecated: first deprecated in macOS 10.10 - SecKeychain is deprecated [-Wdeprecated-declarations]
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Security.framework/Headers/SecAccess.h:132:10: note: 'SecAccessCreate' has been explicitly marked deprecated here
cgo-gcc-prolog:81:11: warning: 'SecKeychainCreate' is deprecated: first deprecated in macOS 10.10 - SecKeychain is deprecated [-Wdeprecated-declarations]
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Security.framework/Headers/SecKeychain.h:309:10: note: 'SecKeychainCreate' has been explicitly marked deprecated here
cgo-gcc-prolog:101:11: warning: 'SecKeychainGetStatus' is deprecated: first deprecated in macOS 10.10 - SecKeychain is deprecated [-Wdeprecated-declarations]
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Security.framework/Headers/SecKeychain.h:462:10: note: 'SecKeychainGetStatus' has been explicitly marked deprecated here
cgo-gcc-prolog:120:11: warning: 'SecKeychainItemDelete' is deprecated: first deprecated in macOS 10.10 - SecKeychain is deprecated [-Wdeprecated-declarations]
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Security.framework/Headers/SecKeychainItem.h:257:10: note: 'SecKeychainItemDelete' has been explicitly marked deprecated here
cgo-gcc-prolog:139:11: warning: 'SecKeychainLock' is deprecated: first deprecated in macOS 10.10 - SecKeychain is deprecated [-Wdeprecated-declarations]
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Security.framework/Headers/SecKeychain.h:365:10: note: 'SecKeychainLock' has been explicitly marked deprecated here
cgo-gcc-prolog:159:11: warning: 'SecKeychainOpen' is deprecated: first deprecated in macOS 10.10 - SecKeychain is deprecated [-Wdeprecated-declarations]
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Security.framework/Headers/SecKeychain.h:294:10: note: 'SecKeychainOpen' has been explicitly marked deprecated here
cgo-gcc-prolog:183:11: warning: 'SecKeychainUnlock' is deprecated: first deprecated in macOS 10.10 - SecKeychain is deprecated [-Wdeprecated-declarations]
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Security.framework/Headers/SecKeychain.h:355:10: note: 'SecKeychainUnlock' has been explicitly marked deprecated here
cgo-gcc-prolog:203:11: warning: 'SecTrustedApplicationCreateFromPath' is deprecated: first deprecated in macOS 10.10 - SecKeychain is deprecated [-Wdeprecated-declarations]
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Security.framework/Headers/SecTrustedApplication.h:61:10: note: 'SecTrustedApplicationCreateFromPath' has been explicitly marked deprecated here
blake@sonoma-rc ~ % sw_vers
ProductName:		macOS
ProductVersion:		14.0
BuildVersion:		23A339

Doesn't seem to work with Gnome Keyring on WSL

I have confirmed other tools can use the GNOME keyring:

secret-tool store --label=foo-label foo bar
Password:

secret-tool search --all foo bar
[/org/freedesktop/secrets/collection/Default_5fkeyring/44]
label = foo-label
secret = fdfd
created = 2024-02-21 12:02:14
modified = 2024-02-21 12:02:50
schema = org.freedesktop.Secret.Generic
attribute.foo = bar

However, vault-token-helper seems to hang and finally gives this error message.

vault-token-helper store
asdfa
Error: Unable to initialize backend 'secret-service': Specified keyring backend not available

pkg/errors is obsoleted

The package has been archived on github and doesn't have a maintainer: pkg/errors#245

As seen in the issues linked to it, different projects took different approaches, from replacing usage with a fork to using only standard library modules (fmt and errors itself).

I'm willing to submit a PR for this.

consider removing the 'renewable' column from list output

Tokens issued by the vault auth/okta backend have the 'renew=true' attribute set but when they're renewed with vault renew the ttl does not actually increase. I believe this is becaues the okta backend doesn't currently allow for creating period tokens that could be renewed and extended before the end of the period's ttl.

Consider removing the renewable column from the output because it's confusing.

Perhaps still available as a -flag for the case where you are storing a period token.

Support serverless use cases (Vault-Zero)

We configure Vault server-less (Vault-Zero).

For use cases such as bootstrapping infrastructure, and personal secret management (keepassxc replacement).

With this setup we encounter:

$ vault-token-helper list --extended
VAULT_ADDR               display_name  ttl  renewable  policies  
----------               ------------  ---  ---------  --------  
http://127.0.0.100:8200  ** ERROR **   error encountered setting up default configuration: open /etc/vault.d/client-certs/client-cert.pem: no such file or directory

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.