forked from cyberark/secretless-broker
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support AppRole auth method in Vault provider. Connected to cyberark#…
- Loading branch information
1 parent
94dbc9a
commit 99138a8
Showing
4 changed files
with
187 additions
and
7 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
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,73 @@ | ||
package auth | ||
|
||
import ( | ||
"fmt" | ||
vault "github.com/hashicorp/vault/api" | ||
"os" | ||
"strconv" | ||
) | ||
|
||
// DefaultAppRoleLoginPath path to AppRole login in Vault. | ||
const DefaultAppRoleLoginPath = "auth/approle/login" | ||
|
||
// EnvVaultAppRoleRoleID environment variable name of role ID used in AppRole auth method. | ||
const EnvVaultAppRoleRoleID = "VAULT_APPROLE_ROLE_ID" | ||
|
||
// EnvVaultAppRoleSecretID environment variable name of (possibly wrapped) secret ID used in AppRole auth method. | ||
const EnvVaultAppRoleSecretID = "VAULT_APPROLE_SECRET_ID" | ||
|
||
// EnvVaultAppRoleUnwrap environment variable name of unwrapping of secret ID in AppRole auth method. | ||
const EnvVaultAppRoleUnwrap = "VAULT_APPROLE_UNWRAP" | ||
|
||
// AppRoleConfig holds AppRole auth method configuration. | ||
type AppRoleConfig struct { | ||
LoginPath string | ||
RoleID string | ||
SecretID string | ||
Unwrap bool | ||
} | ||
|
||
// AppRoleAuthMethodFactory performs AppRole auth method for given client. | ||
func AppRoleAuthMethodFactory(client *vault.Client) (*vault.Secret, error) { | ||
config := getAppRoleConfigFromEnv() | ||
|
||
var secret *vault.Secret | ||
var err error | ||
if secret, err = getTokenFromAppRoleLogin(client, config); err != nil { | ||
return nil, err | ||
} | ||
|
||
return secret, nil | ||
} | ||
|
||
// getAppRoleConfigFromEnv returns AppRole auth method configuration from environment variables. | ||
func getAppRoleConfigFromEnv() *AppRoleConfig { | ||
config := &AppRoleConfig{} | ||
config.RoleID = os.Getenv(EnvVaultAppRoleRoleID) | ||
config.SecretID = os.Getenv(EnvVaultAppRoleSecretID) | ||
// Ignore error, default unwrap = false | ||
config.Unwrap, _ = strconv.ParseBool(os.Getenv(EnvVaultAppRoleUnwrap)) | ||
config.LoginPath = getLoginPathFromEnv(DefaultAppRoleLoginPath) | ||
return config | ||
} | ||
|
||
// getTokenFromAppRoleLogin performs AppRole login for client using given AppRole auth method configuration. | ||
func getTokenFromAppRoleLogin(client *vault.Client, config *AppRoleConfig) (*vault.Secret, error) { | ||
// Conditionally unwrap secret ID (referred to as pull mode in Vault) | ||
if config.Unwrap { | ||
secret, err := client.Logical().Unwrap(config.SecretID) | ||
if err != nil { | ||
return nil, fmt.Errorf("HashiCorp Vault provider unwrapping failed: %s", err) | ||
} | ||
|
||
// Replace with unwrapped secret ID in config | ||
config.SecretID = secret.Data["secret_id"].(string) | ||
} | ||
|
||
data := map[string]interface{}{ | ||
"role_id": config.RoleID, | ||
"secret_id": config.SecretID, | ||
} | ||
|
||
return client.Logical().Write(config.LoginPath, data) | ||
} |
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,68 @@ | ||
package auth | ||
|
||
import ( | ||
"fmt" | ||
vault "github.com/hashicorp/vault/api" | ||
"os" | ||
) | ||
|
||
// EnvVarVaultAuthMethod environment variable name of Vault auth method to use. | ||
const EnvVarVaultAuthMethod = "VAULT_AUTH_METHOD" | ||
|
||
// EnvVarVaultLoginPath path to auth method's login in Vault. | ||
const EnvVarVaultLoginPath = "VAULT_LOGIN_PATH" | ||
|
||
// VaultAuthMethodFactories mapping of supported Vault auth methods by their IDs. Must have either an auth method | ||
// factory or `nil` to signify no action is required, e.g. for Token auth method. | ||
// NOTE: the "Token" auth methods is added for consistency. Token auth method requires no additional authentication | ||
// steps, unlike other auth methods in Vault. | ||
var VaultAuthMethodFactories = map[string]func(*vault.Client) (*vault.Secret, error) { | ||
"AppRole": AppRoleAuthMethodFactory, | ||
"Token": nil, | ||
} | ||
|
||
// Authenticate a Vault client using any of the supported auth methods. | ||
// NOTE: All auth methods require an initialized Vault API client. | ||
func Authenticate(client *vault.Client) error { | ||
authMethod := getAuthMethodFromEnv() | ||
applyAuthMethod, ok := VaultAuthMethodFactories[authMethod] | ||
if !ok { | ||
return fmt.Errorf("HashiCorp Vault provider unsupported auth method: %s", authMethod) | ||
} | ||
|
||
// No (additional) authentication steps required, hence done | ||
if applyAuthMethod == nil { | ||
return nil | ||
} | ||
|
||
secret, err := applyAuthMethod(client) | ||
if err != nil { | ||
return fmt.Errorf("HashiCorp Vault provider auth method failed: %s", err) | ||
} | ||
if secret == nil || secret.Auth == nil { | ||
return fmt.Errorf("HashiCorp Vault provider login failed (no secret or auth info)") | ||
} | ||
|
||
client.SetToken(secret.Auth.ClientToken) | ||
return nil | ||
} | ||
|
||
// getAuthMethodFromEnv returns the auth method from environment variable. If not set, it defaults to "Token" for | ||
// backwards compatibility. | ||
func getAuthMethodFromEnv() string { | ||
authMethod, ok := os.LookupEnv(EnvVarVaultAuthMethod) | ||
if !ok { | ||
return "Token" | ||
} | ||
return authMethod | ||
} | ||
|
||
// getLoginPathFromEnv returns login path from environment variable or returns given default value otherwise. | ||
func getLoginPathFromEnv(defaultLoginPath string) string { | ||
// Optional path to login, otherwise default path of Vault is used | ||
path := os.Getenv(EnvVarVaultLoginPath) | ||
if path != "" { | ||
return path | ||
} | ||
return defaultLoginPath | ||
} |
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