Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nonce support #202

Merged
merged 2 commits into from
Sep 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/content/functions/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,11 @@ to wait for AWS to respond before skipping the attempt.
If set, the `VAULT_AUTH_AWS_ROLE` environment variable will be used to specify the role to authenticate
using. If not set the AMI ID of the EC2 instance will be used by Vault.

If you want to allow multiple authentications using AWS EC2 auth (i.e. run gomplate multiple times) you
will need to pass the same nonce each time. This can be sent using `VAULT_AUTH_AWS_NONCE`. If not set once
will automatically be generated by AWS. The nonce used can be stored by setting `VAULT_AUTH_AWS_NONCE_OUTPUT`
to a filename. If the file doesn't exist it is created with 0600 permission.

## `datasourceExists`

Tests whether or not a given datasource was defined on the commandline (with the
Expand Down
24 changes: 24 additions & 0 deletions vault/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,19 @@ func (v *Vault) UserPassLogin() string {
func (v *Vault) EC2Login() string {
role := env.Getenv("VAULT_AUTH_AWS_ROLE")
mount := env.Getenv("VAULT_AUTH_AWS_MOUNT", "aws")
nonce := env.Getenv("VAULT_AUTH_AWS_NONCE")
output := env.Getenv("VAULT_AUTH_AWS_NONCE_OUTPUT")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if maybe naming this VAULT_AUTH_AWS_NONCE_FILE would be better, and making it possible to provide a nonce via a file (the case where the file exists already), or save it to that path if it's nonexistant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should already work as it should be using the env lookup with _FILE support

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! Good point. 🤔

In that case maybe _OUTPUT is not so bad an idea... let's just leave this as-is for now.


vars := map[string]interface{}{}

if role != "" {
vars["role"] = role
}

if nonce != "" {
vars["nonce"] = nonce
}

opts := aws.ClientOptions{
Timeout: time.Duration(conv.MustAtoi(os.Getenv("AWS_TIMEOUT"))) * time.Millisecond,
}
Expand All @@ -187,6 +193,24 @@ func (v *Vault) EC2Login() string {
logFatal("Empty response from AWS EC2 logon")
}

if output != "" {
if val, ok := secret.Auth.Metadata["nonce"]; ok {
nonce = val
}
fs := vfs.OS()
f, err := fs.OpenFile(output, os.O_WRONLY, os.FileMode(0600))
if err != nil {
logFatal("Error opening nonce output file")
}
n, err := f.Write([]byte(nonce + "\n"))
if err != nil {
logFatal("Error writing nonce output file")
}
if n == 0 {
logFatal("No bytes written to nonce output file")
}
}

return secret.Auth.ClientToken
}

Expand Down