mirror of
https://github.com/Infisical/infisical.git
synced 2025-08-05 07:30:33 +00:00
Compare commits
18 Commits
doc/add-do
...
daniel/key
Author | SHA1 | Date | |
---|---|---|---|
|
c8b93e4467 | ||
|
891cb06de0 | ||
|
02e8f20cbf | ||
|
d5f4ce4376 | ||
|
85653a90d5 | ||
|
879ef2c178 | ||
|
8777cfe680 | ||
|
2b630f75aa | ||
|
91cee20cc8 | ||
|
4249ec6030 | ||
|
e7a95e6af2 | ||
|
a9f04a3c1f | ||
|
3d380710ee | ||
|
2177ec6bcc | ||
|
070eb2aacd | ||
|
e619cfa313 | ||
|
c3038e3ca1 | ||
|
ff0e7feeee |
@@ -4,6 +4,7 @@ Copyright (c) 2023 Infisical Inc.
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -13,53 +14,56 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var AvailableVaultsAndDescriptions = []string{"auto (automatically select native vault on system)", "file (encrypted file vault)"}
|
||||
var AvailableVaults = []string{"auto", "file"}
|
||||
type VaultBackendType struct {
|
||||
Name string
|
||||
Description string
|
||||
}
|
||||
|
||||
var AvailableVaults = []VaultBackendType{
|
||||
{
|
||||
Name: "auto",
|
||||
Description: "automatically select the system keyring",
|
||||
},
|
||||
{
|
||||
Name: "file",
|
||||
Description: "encrypted file vault",
|
||||
},
|
||||
}
|
||||
|
||||
var vaultSetCmd = &cobra.Command{
|
||||
Example: `infisical vault set pass`,
|
||||
Use: "set [vault-name]",
|
||||
Short: "Used to set the vault backend to store your login details securely at rest",
|
||||
Example: `infisical vault set file --passphrase <your-passphrase>`,
|
||||
Use: "set [file|auto] [flags]",
|
||||
Short: "Used to configure the vault backends",
|
||||
DisableFlagsInUseLine: true,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
wantedVaultTypeName := args[0]
|
||||
currentVaultBackend, err := util.GetCurrentVaultBackend()
|
||||
|
||||
vaultType := args[0]
|
||||
|
||||
passphrase, err := cmd.Flags().GetString("passphrase")
|
||||
if err != nil {
|
||||
log.Error().Msgf("Unable to set vault to [%s] because of [err=%s]", wantedVaultTypeName, err)
|
||||
util.HandleError(err, "Unable to get passphrase flag")
|
||||
}
|
||||
|
||||
if vaultType == util.VAULT_BACKEND_FILE_MODE && passphrase != "" {
|
||||
setFileVaultPassphrase(passphrase)
|
||||
return
|
||||
}
|
||||
|
||||
if wantedVaultTypeName == string(currentVaultBackend) {
|
||||
log.Error().Msgf("You are already on vault backend [%s]", currentVaultBackend)
|
||||
return
|
||||
}
|
||||
|
||||
if wantedVaultTypeName == "auto" || wantedVaultTypeName == "file" {
|
||||
configFile, err := util.GetConfigFile()
|
||||
if err != nil {
|
||||
log.Error().Msgf("Unable to set vault to [%s] because of [err=%s]", wantedVaultTypeName, err)
|
||||
return
|
||||
}
|
||||
|
||||
configFile.VaultBackendType = wantedVaultTypeName // save selected vault
|
||||
configFile.LoggedInUserEmail = "" // reset the logged in user to prompt them to re login
|
||||
|
||||
err = util.WriteConfigFile(&configFile)
|
||||
if err != nil {
|
||||
log.Error().Msgf("Unable to set vault to [%s] because an error occurred when saving the config file [err=%s]", wantedVaultTypeName, err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("\nSuccessfully, switched vault backend from [%s] to [%s]. Please login in again to store your login details in the new vault with [infisical login]\n", currentVaultBackend, wantedVaultTypeName)
|
||||
|
||||
Telemetry.CaptureEvent("cli-command:vault set", posthog.NewProperties().Set("currentVault", currentVaultBackend).Set("wantedVault", wantedVaultTypeName).Set("version", util.CLI_VERSION))
|
||||
} else {
|
||||
log.Error().Msgf("The requested vault type [%s] is not available on this system. Only the following vault backends are available for you system: %s", wantedVaultTypeName, strings.Join(AvailableVaults, ", "))
|
||||
}
|
||||
util.PrintWarning("This command has been deprecated. Please use 'infisical vault use [file|auto]' to select which vault to use.\n")
|
||||
selectVaultTypeCmd(cmd, args)
|
||||
},
|
||||
}
|
||||
|
||||
var vaultUseCmd = &cobra.Command{
|
||||
Example: `infisical vault use [file|auto]`,
|
||||
Use: "use [file|auto]",
|
||||
Short: "Used to select the the type of vault backend to store sensitive data securely at rest",
|
||||
DisableFlagsInUseLine: true,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: selectVaultTypeCmd,
|
||||
}
|
||||
|
||||
// runCmd represents the run command
|
||||
var vaultCmd = &cobra.Command{
|
||||
Use: "vault",
|
||||
@@ -71,10 +75,30 @@ var vaultCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func setFileVaultPassphrase(passphrase string) {
|
||||
configFile, err := util.GetConfigFile()
|
||||
if err != nil {
|
||||
log.Error().Msgf("Unable to set passphrase for file vault because of [err=%s]", err)
|
||||
return
|
||||
}
|
||||
|
||||
// encode with base64
|
||||
encodedPassphrase := base64.StdEncoding.EncodeToString([]byte(passphrase))
|
||||
configFile.VaultBackendPassphrase = encodedPassphrase
|
||||
|
||||
err = util.WriteConfigFile(&configFile)
|
||||
if err != nil {
|
||||
log.Error().Msgf("Unable to set passphrase for file vault because of [err=%s]", err)
|
||||
return
|
||||
}
|
||||
|
||||
util.PrintSuccessMessage("\nSuccessfully, set passphrase for file vault.\n")
|
||||
}
|
||||
|
||||
func printAvailableVaultBackends() {
|
||||
fmt.Printf("Vaults are used to securely store your login details locally. Available vaults:")
|
||||
for _, backend := range AvailableVaultsAndDescriptions {
|
||||
fmt.Printf("\n- %s", backend)
|
||||
for _, vaultType := range AvailableVaults {
|
||||
fmt.Printf("\n- %s (%s)", vaultType.Name, vaultType.Description)
|
||||
}
|
||||
|
||||
currentVaultBackend, err := util.GetCurrentVaultBackend()
|
||||
@@ -87,7 +111,53 @@ func printAvailableVaultBackends() {
|
||||
fmt.Printf("\n\nYou are currently using [%s] vault to store your login credentials\n", string(currentVaultBackend))
|
||||
}
|
||||
|
||||
func selectVaultTypeCmd(cmd *cobra.Command, args []string) {
|
||||
wantedVaultTypeName := args[0]
|
||||
currentVaultBackend, err := util.GetCurrentVaultBackend()
|
||||
if err != nil {
|
||||
log.Error().Msgf("Unable to set vault to [%s] because of [err=%s]", wantedVaultTypeName, err)
|
||||
return
|
||||
}
|
||||
|
||||
if wantedVaultTypeName == string(currentVaultBackend) {
|
||||
log.Error().Msgf("You are already on vault backend [%s]", currentVaultBackend)
|
||||
return
|
||||
}
|
||||
|
||||
if wantedVaultTypeName == util.VAULT_BACKEND_AUTO_MODE || wantedVaultTypeName == util.VAULT_BACKEND_FILE_MODE {
|
||||
configFile, err := util.GetConfigFile()
|
||||
if err != nil {
|
||||
log.Error().Msgf("Unable to set vault to [%s] because of [err=%s]", wantedVaultTypeName, err)
|
||||
return
|
||||
}
|
||||
|
||||
configFile.VaultBackendType = wantedVaultTypeName // save selected vault
|
||||
configFile.LoggedInUserEmail = "" // reset the logged in user to prompt them to re login
|
||||
|
||||
err = util.WriteConfigFile(&configFile)
|
||||
if err != nil {
|
||||
log.Error().Msgf("Unable to set vault to [%s] because an error occurred when saving the config file [err=%s]", wantedVaultTypeName, err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("\nSuccessfully, switched vault backend from [%s] to [%s]. Please login in again to store your login details in the new vault with [infisical login]\n", currentVaultBackend, wantedVaultTypeName)
|
||||
|
||||
Telemetry.CaptureEvent("cli-command:vault set", posthog.NewProperties().Set("currentVault", currentVaultBackend).Set("wantedVault", wantedVaultTypeName).Set("version", util.CLI_VERSION))
|
||||
} else {
|
||||
var availableVaultsNames []string
|
||||
for _, vault := range AvailableVaults {
|
||||
availableVaultsNames = append(availableVaultsNames, vault.Name)
|
||||
}
|
||||
log.Error().Msgf("The requested vault type [%s] is not available on this system. Only the following vault backends are available for you system: %s", wantedVaultTypeName, strings.Join(availableVaultsNames, ", "))
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
vaultSetCmd.Flags().StringP("passphrase", "p", "", "Set the passphrase for the file vault")
|
||||
|
||||
vaultCmd.AddCommand(vaultSetCmd)
|
||||
vaultCmd.AddCommand(vaultUseCmd)
|
||||
|
||||
rootCmd.AddCommand(vaultCmd)
|
||||
}
|
||||
|
@@ -11,10 +11,11 @@ type UserCredentials struct {
|
||||
|
||||
// The file struct for Infisical config file
|
||||
type ConfigFile struct {
|
||||
LoggedInUserEmail string `json:"loggedInUserEmail"`
|
||||
LoggedInUserDomain string `json:"LoggedInUserDomain,omitempty"`
|
||||
LoggedInUsers []LoggedInUser `json:"loggedInUsers,omitempty"`
|
||||
VaultBackendType string `json:"vaultBackendType,omitempty"`
|
||||
LoggedInUserEmail string `json:"loggedInUserEmail"`
|
||||
LoggedInUserDomain string `json:"LoggedInUserDomain,omitempty"`
|
||||
LoggedInUsers []LoggedInUser `json:"loggedInUsers,omitempty"`
|
||||
VaultBackendType string `json:"vaultBackendType,omitempty"`
|
||||
VaultBackendPassphrase string `json:"vaultBackendPassphrase,omitempty"`
|
||||
}
|
||||
|
||||
type LoggedInUser struct {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -50,10 +51,11 @@ func WriteInitalConfig(userCredentials *models.UserCredentials) error {
|
||||
}
|
||||
|
||||
configFile := models.ConfigFile{
|
||||
LoggedInUserEmail: userCredentials.Email,
|
||||
LoggedInUserDomain: config.INFISICAL_URL,
|
||||
LoggedInUsers: existingConfigFile.LoggedInUsers,
|
||||
VaultBackendType: existingConfigFile.VaultBackendType,
|
||||
LoggedInUserEmail: userCredentials.Email,
|
||||
LoggedInUserDomain: config.INFISICAL_URL,
|
||||
LoggedInUsers: existingConfigFile.LoggedInUsers,
|
||||
VaultBackendType: existingConfigFile.VaultBackendType,
|
||||
VaultBackendPassphrase: existingConfigFile.VaultBackendPassphrase,
|
||||
}
|
||||
|
||||
configFileMarshalled, err := json.Marshal(configFile)
|
||||
@@ -215,6 +217,14 @@ func GetConfigFile() (models.ConfigFile, error) {
|
||||
return models.ConfigFile{}, err
|
||||
}
|
||||
|
||||
if configFile.VaultBackendPassphrase != "" {
|
||||
decodedPassphrase, err := base64.StdEncoding.DecodeString(configFile.VaultBackendPassphrase)
|
||||
if err != nil {
|
||||
return models.ConfigFile{}, fmt.Errorf("GetConfigFile: Unable to decode base64 passphrase [err=%s]", err)
|
||||
}
|
||||
os.Setenv("INFISICAL_VAULT_FILE_PASSPHRASE", string(decodedPassphrase))
|
||||
}
|
||||
|
||||
return configFile, nil
|
||||
}
|
||||
|
||||
|
@@ -8,6 +8,10 @@ const (
|
||||
INFISICAL_WORKSPACE_CONFIG_FILE_NAME = ".infisical.json"
|
||||
INFISICAL_TOKEN_NAME = "INFISICAL_TOKEN"
|
||||
INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN_NAME = "INFISICAL_UNIVERSAL_AUTH_ACCESS_TOKEN"
|
||||
INFISICAL_VAULT_FILE_PASSPHRASE_ENV_NAME = "INFISICAL_VAULT_FILE_PASSPHRASE" // This works because we've forked the keyring package and added support for this env variable. This explains why you won't find any occurrences of it in the CLI codebase.
|
||||
|
||||
VAULT_BACKEND_AUTO_MODE = "auto"
|
||||
VAULT_BACKEND_FILE_MODE = "file"
|
||||
|
||||
// Universal Auth
|
||||
INFISICAL_UNIVERSAL_AUTH_CLIENT_ID_NAME = "INFISICAL_UNIVERSAL_AUTH_CLIENT_ID"
|
||||
|
@@ -1,6 +1,9 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/manifoldco/promptui"
|
||||
"github.com/zalando/go-keyring"
|
||||
)
|
||||
|
||||
@@ -20,16 +23,51 @@ func SetValueInKeyring(key, value string) error {
|
||||
PrintErrorAndExit(1, err, "Unable to get current vault. Tip: run [infisical rest] then try again")
|
||||
}
|
||||
|
||||
return keyring.Set(currentVaultBackend, MAIN_KEYRING_SERVICE, key, value)
|
||||
err = keyring.Set(currentVaultBackend, MAIN_KEYRING_SERVICE, key, value)
|
||||
|
||||
if err != nil {
|
||||
configFile, _ := GetConfigFile()
|
||||
|
||||
if configFile.VaultBackendPassphrase == "" {
|
||||
PrintWarning("System keyring could not be used, falling back to `file` vault for sensitive data storage.")
|
||||
passphrasePrompt := promptui.Prompt{
|
||||
Label: "Enter the passphrase to use for keyring encryption",
|
||||
}
|
||||
passphrase, err := passphrasePrompt.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encodedPassphrase := base64.StdEncoding.EncodeToString([]byte(passphrase))
|
||||
configFile.VaultBackendPassphrase = encodedPassphrase
|
||||
err = WriteConfigFile(&configFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// We call this function at last to trigger the environment variable to be set
|
||||
GetConfigFile()
|
||||
}
|
||||
|
||||
err = keyring.Set(VAULT_BACKEND_FILE_MODE, MAIN_KEYRING_SERVICE, key, value)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func GetValueInKeyring(key string) (string, error) {
|
||||
currentVaultBackend, err := GetCurrentVaultBackend()
|
||||
if err != nil {
|
||||
PrintErrorAndExit(1, err, "Unable to get current vault. Tip: run [infisical rest] then try again")
|
||||
PrintErrorAndExit(1, err, "Unable to get current vault. Tip: run [infisical reset] then try again")
|
||||
}
|
||||
|
||||
return keyring.Get(currentVaultBackend, MAIN_KEYRING_SERVICE, key)
|
||||
value, err := keyring.Get(currentVaultBackend, MAIN_KEYRING_SERVICE, key)
|
||||
|
||||
if err != nil {
|
||||
value, err = keyring.Get(VAULT_BACKEND_FILE_MODE, MAIN_KEYRING_SERVICE, key)
|
||||
}
|
||||
return value, err
|
||||
|
||||
}
|
||||
|
||||
func DeleteValueInKeyring(key string) error {
|
||||
@@ -38,5 +76,11 @@ func DeleteValueInKeyring(key string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
return keyring.Delete(currentVaultBackend, MAIN_KEYRING_SERVICE, key)
|
||||
err = keyring.Delete(currentVaultBackend, MAIN_KEYRING_SERVICE, key)
|
||||
|
||||
if err != nil {
|
||||
err = keyring.Delete(VAULT_BACKEND_FILE_MODE, MAIN_KEYRING_SERVICE, key)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
@@ -11,11 +11,11 @@ func GetCurrentVaultBackend() (string, error) {
|
||||
}
|
||||
|
||||
if configFile.VaultBackendType == "" {
|
||||
return "auto", nil
|
||||
return VAULT_BACKEND_AUTO_MODE, nil
|
||||
}
|
||||
|
||||
if configFile.VaultBackendType != "auto" && configFile.VaultBackendType != "file" {
|
||||
return "auto", nil
|
||||
if configFile.VaultBackendType != VAULT_BACKEND_AUTO_MODE && configFile.VaultBackendType != VAULT_BACKEND_FILE_MODE {
|
||||
return VAULT_BACKEND_AUTO_MODE, nil
|
||||
}
|
||||
|
||||
return configFile.VaultBackendType, nil
|
||||
|
@@ -32,6 +32,6 @@ description: "Change the vault type in Infisical"
|
||||
|
||||
To safeguard your login details when using the CLI, Infisical places them in a system vault or an encrypted text file, protected by a passphrase that only the user knows.
|
||||
|
||||
<Tip>To avoid constantly entering your passphrase when using the `file` vault type, set the `INFISICAL_VAULT_FILE_PASSPHRASE` environment variable with your password in your shell</Tip>
|
||||
<Tip>To avoid constantly entering your passphrase when using the `file` vault type, use the `infisical vault set file --passphrase <your-passphrase>` CLI command to specify your password once.</Tip>
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user