forked from hashicorp/vault
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cli.go
129 lines (109 loc) · 3.93 KB
/
cli.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package awsauth
import (
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/sts"
"github.com/hashicorp/vault/api"
"github.com/hashicorp/vault/helper/awsutil"
)
type CLIHandler struct{}
func (h *CLIHandler) Auth(c *api.Client, m map[string]string) (string, error) {
mount, ok := m["mount"]
if !ok {
mount = "aws"
}
role, ok := m["role"]
if !ok {
role = ""
}
headerValue, ok := m["header_value"]
if !ok {
headerValue = ""
}
// Grab any supplied credentials off the command line
// Ensure we're able to fall back to the SDK default credential providers
credConfig := &awsutil.CredentialsConfig{
AccessKey: m["aws_access_key_id"],
SecretKey: m["aws_secret_access_key"],
SessionToken: m["aws_security_token"],
}
creds, err := credConfig.GenerateCredentialChain()
if err != nil {
return "", err
}
if creds == nil {
return "", fmt.Errorf("could not compile valid credential providers from static config, environemnt, shared, or instance metadata")
}
// Use the credentials we've found to construct an STS session
stsSession, err := session.NewSessionWithOptions(session.Options{
Config: aws.Config{Credentials: creds},
})
if err != nil {
return "", err
}
var params *sts.GetCallerIdentityInput
svc := sts.New(stsSession)
stsRequest, _ := svc.GetCallerIdentityRequest(params)
// Inject the required auth header value, if suplied, and then sign the request including that header
if headerValue != "" {
stsRequest.HTTPRequest.Header.Add(iamServerIdHeader, headerValue)
}
stsRequest.Sign()
// Now extract out the relevant parts of the request
headersJson, err := json.Marshal(stsRequest.HTTPRequest.Header)
if err != nil {
return "", err
}
requestBody, err := ioutil.ReadAll(stsRequest.HTTPRequest.Body)
if err != nil {
return "", err
}
method := stsRequest.HTTPRequest.Method
targetUrl := base64.StdEncoding.EncodeToString([]byte(stsRequest.HTTPRequest.URL.String()))
headers := base64.StdEncoding.EncodeToString(headersJson)
body := base64.StdEncoding.EncodeToString(requestBody)
// And pass them on to the Vault server
path := fmt.Sprintf("auth/%s/login", mount)
secret, err := c.Logical().Write(path, map[string]interface{}{
"iam_http_request_method": method,
"iam_request_url": targetUrl,
"iam_request_headers": headers,
"iam_request_body": body,
"role": role,
})
if err != nil {
return "", err
}
if secret == nil {
return "", fmt.Errorf("empty response from credential provider")
}
return secret.Auth.ClientToken, nil
}
func (h *CLIHandler) Help() string {
help := `
The AWS credential provider allows you to authenticate with
AWS IAM credentials. To use it, you specify valid AWS IAM credentials
in one of a number of ways. They can be specified explicitly on the
command line (which in general you should not do), via the standard AWS
environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and
AWS_SECURITY_TOKEN), via the ~/.aws/credentials file, or via an EC2
instance profile (in that order).
Example: vault auth -method=aws
If you need to explicitly pass in credentials, you would do it like this:
Example: vault auth -method=aws aws_access_key_id=<access key> aws_secret_access_key=<secret key> aws_security_token=<token>
Key/Value Pairs:
mount=aws The mountpoint for the AWS credential provider.
Defaults to "aws"
aws_access_key_id=<access key> Explicitly specified AWS access key
aws_secret_access_key=<secret key> Explicitly specified AWS secret key
aws_security_token=<token> Security token for temporary credentials
header_value The Value of the X-Vault-AWS-IAM-Server-ID header.
role The name of the role you're requesting a token for
`
return strings.TrimSpace(help)
}