-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add keychain provider for reading text/yaml/json secrets
Signed-off-by: Dmitry K. Anisimov <[email protected]>
- Loading branch information
1 parent
5537ae6
commit a14be10
Showing
4 changed files
with
92 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ It supports various backends including: | |
- HCP Vault Secrets | ||
- Bitwarden | ||
- HTTP JSON | ||
- Keychain | ||
|
||
- Use `vals eval -f refs.yaml` to replace all the `ref`s in the file to actual values and secrets. | ||
- Use `vals exec -f env.yaml -- <COMMAND>` to populate envvars and execute the command. | ||
|
@@ -216,6 +217,7 @@ Please see the [relevant unit test cases](https://github.com/helmfile/vals/blob/ | |
- [Google GCS](#google-gcs) | ||
- [SOPS](#sops) powered by [sops](https://github.com/getsops/sops) | ||
- [Terraform (tfstate)](#terraform-tfstate) powered by [tfstate-lookup](https://github.com/fujiwara/tfstate-lookup) | ||
- [Keychain](#keychain) | ||
- [Echo](#echo) | ||
- [File](#file) | ||
- [Azure Key Vault](#azure-key-vault) | ||
|
@@ -592,6 +594,18 @@ Examples: | |
- `ref+sops://path/to/file#/foo/bar` reads `path/to/file` as a `yaml` file and returns the value at `foo.bar`. | ||
- `ref+sops://path/to/file?format=json#/foo/bar` reads `path/to/file` as a `json` file and returns the value at `foo.bar`. | ||
### Keychain | ||
Keychain provider is going to be available on macOS only. It reads a secret from the macOS Keychain. | ||
- `ref+echo://KEY1/[#/path/to/the/value]` | ||
Examples: | ||
- `security add-generic-password -U -a ${USER} -s "secret-name" -D "vals-secret" -w '{"foo":{"bar":"baz"}}'` - will create a secret in the Keychain with the name `secret-name` and the value `{"foo":{"bar":"baz"}}`, `vals-secret` is required to be able to find the secret in the Keychain. | ||
- `echo 'foo: ref+keychain://secret-name' | vals eval -f -` - will read the secret from the Keychain with the name `secret-name` and replace the `foo` with the secret value. | ||
- `echo 'foo: ref+keychain://secret-name#/foo/bar' | vals eval -f -` - will read the secret from the Keychain with the name `secret-name` and replace the `foo` with the value at the path `$.foo.bar`. | ||
### Echo | ||
Echo provider echoes the string for testing purpose. Please read [the original proposal](https://github.com/roboll/helmfile/pull/920#issuecomment-548213738) to get why we might need this. | ||
|
@@ -603,7 +617,6 @@ Examples: | |
- `ref+echo://foo/bar` generates `foo/bar` | ||
- `ref+echo://foo/bar/baz#/foo/bar` generates `baz`. This works by the host and the path part `foo/bar/baz` generating an object `{"foo":{"bar":"baz"}}` and the fragment part `#/foo/bar` results in digging the object to obtain the value at `$.foo.bar`. | ||
### File | ||
File provider reads a local text file, or the value for the specific path in a YAML/JSON file. | ||
|
@@ -834,7 +847,7 @@ Example: | |
### Bitwarden | ||
This provider retrieves the secrets stored in Bitwarden. It uses the [Bitwarden Vault-Management API](https://bitwarden.com/help/vault-management-api/) that is included in the [Bitwarden CLI](https://github.com/bitwarden/clients) by executing `bw serve`. | ||
This provider retrieves the secrets stored in Bitwarden. It uses the [Bitwarden Vault-Management API](https://bitwarden.com/help/vault-management-api/) that is included in the [Bitwarden CLI](https://github.com/bitwarden/clients) by executing `bw serve`. | ||
Environment variables: | ||
|
@@ -857,7 +870,7 @@ Examples: | |
This provider retrieves values stored in JSON hosted by a HTTP frontend. | ||
This provider is built on top of [jsonquery](https://pkg.go.dev/github.com/antchfx/[email protected]) and [xpath](https://pkg.go.dev/github.com/antchfx/[email protected]) packages. | ||
This provider is built on top of [jsonquery](https://pkg.go.dev/github.com/antchfx/[email protected]) and [xpath](https://pkg.go.dev/github.com/antchfx/[email protected]) packages. | ||
Given the diverse array of JSON structures that can be encountered, utilizing jsonquery with XPath presents a more effective approach for handling this variability in data structures. | ||
|
@@ -881,7 +894,7 @@ Let's say you want to fetch the below JSON object from https://api.github.com/us | |
"name": "go-yaml" | ||
} | ||
] | ||
``` | ||
``` | ||
``` | ||
# To get name="chartify" using https protocol you would use: | ||
ref+httpjson://api.github.com/users/helmfile/repos#///*[1]/name | ||
|
@@ -904,7 +917,7 @@ Let's say you want to fetch the below JSON object from https://api.github.com/us | |
"id": 251296379 | ||
} | ||
] | ||
``` | ||
``` | ||
``` | ||
# Running the following will return: 2.51296379e+08 | ||
ref+httpjson://api.github.com/users/helmfile/repos#///*[1]/id | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package keychain | ||
|
||
import ( | ||
"errors" | ||
"strings" | ||
|
||
"gopkg.in/yaml.v3" | ||
|
||
"github.com/helmfile/vals/pkg/api" | ||
"github.com/keybase/go-keychain" | ||
) | ||
|
||
const keychainKind = "vals-secret" | ||
|
||
type provider struct { | ||
} | ||
|
||
func New(cfg api.StaticConfig) *provider { | ||
p := &provider{} | ||
return p | ||
} | ||
|
||
func getKeychainSecret(key string) ([]byte, error) { | ||
query := keychain.NewItem() | ||
query.SetSecClass(keychain.SecClassGenericPassword) | ||
query.SetLabel(key) | ||
query.SetDescription(keychainKind) | ||
query.SetMatchLimit(keychain.MatchLimitOne) | ||
query.SetReturnData(true) | ||
|
||
results, err := keychain.QueryItem(query) | ||
if err != nil { | ||
return nil, err | ||
} else if len(results) == 0 { | ||
return nil, errors.New("not found") | ||
} | ||
|
||
return results[0].Data, nil | ||
} | ||
|
||
func (p *provider) GetString(key string) (string, error) { | ||
key = strings.TrimSuffix(key, "/") | ||
key = strings.TrimSpace(key) | ||
|
||
secret, err := getKeychainSecret(key) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return string(secret), err | ||
} | ||
|
||
func (p *provider) GetStringMap(key string) (map[string]interface{}, error) { | ||
key = strings.TrimSuffix(key, "/") | ||
key = strings.TrimSpace(key) | ||
|
||
secret, err := getKeychainSecret(key) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
m := map[string]interface{}{} | ||
if err := yaml.Unmarshal(secret, &m); err != nil { | ||
return nil, err | ||
} | ||
return m, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters