aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/minio/minio-go/v7/pkg/credentials
diff options
context:
space:
mode:
authorLibravatar Rutger Broekhoff2023-12-29 21:31:53 +0100
committerLibravatar Rutger Broekhoff2023-12-29 21:31:53 +0100
commit404aeae4545d2426c089a5f8d5e82dae56f5212b (patch)
tree2d84e00af272b39fc04f3795ae06bc48970e57b5 /vendor/github.com/minio/minio-go/v7/pkg/credentials
parent209d8b0187ed025dec9ac149ebcced3462877bff (diff)
downloadgitolfs3-404aeae4545d2426c089a5f8d5e82dae56f5212b.tar.gz
gitolfs3-404aeae4545d2426c089a5f8d5e82dae56f5212b.zip
Make Nix builds work
Diffstat (limited to 'vendor/github.com/minio/minio-go/v7/pkg/credentials')
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go242
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/chain.go88
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/config.json.sample17
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.go193
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.json7
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.sample15
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/doc.go60
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/env_aws.go71
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/env_minio.go68
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/error_response.go95
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/file_aws_credentials.go157
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/file_minio_client.go139
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/iam_aws.go433
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/signature_type.go77
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/static.go67
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_client_grants.go182
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_custom_identity.go146
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_ldap_identity.go189
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_tls_identity.go211
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_web_identity.go205
20 files changed, 2662 insertions, 0 deletions
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go
new file mode 100644
index 0000000..800c4a2
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/assume_role.go
@@ -0,0 +1,242 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2020 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import (
21 "bytes"
22 "crypto/sha256"
23 "encoding/hex"
24 "encoding/xml"
25 "errors"
26 "io"
27 "net/http"
28 "net/url"
29 "strconv"
30 "strings"
31 "time"
32
33 "github.com/minio/minio-go/v7/pkg/signer"
34)
35
36// AssumeRoleResponse contains the result of successful AssumeRole request.
37type AssumeRoleResponse struct {
38 XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleResponse" json:"-"`
39
40 Result AssumeRoleResult `xml:"AssumeRoleResult"`
41 ResponseMetadata struct {
42 RequestID string `xml:"RequestId,omitempty"`
43 } `xml:"ResponseMetadata,omitempty"`
44}
45
46// AssumeRoleResult - Contains the response to a successful AssumeRole
47// request, including temporary credentials that can be used to make
48// MinIO API requests.
49type AssumeRoleResult struct {
50 // The identifiers for the temporary security credentials that the operation
51 // returns.
52 AssumedRoleUser AssumedRoleUser `xml:",omitempty"`
53
54 // The temporary security credentials, which include an access key ID, a secret
55 // access key, and a security (or session) token.
56 //
57 // Note: The size of the security token that STS APIs return is not fixed. We
58 // strongly recommend that you make no assumptions about the maximum size. As
59 // of this writing, the typical size is less than 4096 bytes, but that can vary.
60 // Also, future updates to AWS might require larger sizes.
61 Credentials struct {
62 AccessKey string `xml:"AccessKeyId" json:"accessKey,omitempty"`
63 SecretKey string `xml:"SecretAccessKey" json:"secretKey,omitempty"`
64 Expiration time.Time `xml:"Expiration" json:"expiration,omitempty"`
65 SessionToken string `xml:"SessionToken" json:"sessionToken,omitempty"`
66 } `xml:",omitempty"`
67
68 // A percentage value that indicates the size of the policy in packed form.
69 // The service rejects any policy with a packed size greater than 100 percent,
70 // which means the policy exceeded the allowed space.
71 PackedPolicySize int `xml:",omitempty"`
72}
73
74// A STSAssumeRole retrieves credentials from MinIO service, and keeps track if
75// those credentials are expired.
76type STSAssumeRole struct {
77 Expiry
78
79 // Required http Client to use when connecting to MinIO STS service.
80 Client *http.Client
81
82 // STS endpoint to fetch STS credentials.
83 STSEndpoint string
84
85 // various options for this request.
86 Options STSAssumeRoleOptions
87}
88
89// STSAssumeRoleOptions collection of various input options
90// to obtain AssumeRole credentials.
91type STSAssumeRoleOptions struct {
92 // Mandatory inputs.
93 AccessKey string
94 SecretKey string
95
96 SessionToken string // Optional if the first request is made with temporary credentials.
97 Policy string // Optional to assign a policy to the assumed role
98
99 Location string // Optional commonly needed with AWS STS.
100 DurationSeconds int // Optional defaults to 1 hour.
101
102 // Optional only valid if using with AWS STS
103 RoleARN string
104 RoleSessionName string
105 ExternalID string
106}
107
108// NewSTSAssumeRole returns a pointer to a new
109// Credentials object wrapping the STSAssumeRole.
110func NewSTSAssumeRole(stsEndpoint string, opts STSAssumeRoleOptions) (*Credentials, error) {
111 if stsEndpoint == "" {
112 return nil, errors.New("STS endpoint cannot be empty")
113 }
114 if opts.AccessKey == "" || opts.SecretKey == "" {
115 return nil, errors.New("AssumeRole credentials access/secretkey is mandatory")
116 }
117 return New(&STSAssumeRole{
118 Client: &http.Client{
119 Transport: http.DefaultTransport,
120 },
121 STSEndpoint: stsEndpoint,
122 Options: opts,
123 }), nil
124}
125
126const defaultDurationSeconds = 3600
127
128// closeResponse close non nil response with any response Body.
129// convenient wrapper to drain any remaining data on response body.
130//
131// Subsequently this allows golang http RoundTripper
132// to re-use the same connection for future requests.
133func closeResponse(resp *http.Response) {
134 // Callers should close resp.Body when done reading from it.
135 // If resp.Body is not closed, the Client's underlying RoundTripper
136 // (typically Transport) may not be able to re-use a persistent TCP
137 // connection to the server for a subsequent "keep-alive" request.
138 if resp != nil && resp.Body != nil {
139 // Drain any remaining Body and then close the connection.
140 // Without this closing connection would disallow re-using
141 // the same connection for future uses.
142 // - http://stackoverflow.com/a/17961593/4465767
143 io.Copy(io.Discard, resp.Body)
144 resp.Body.Close()
145 }
146}
147
148func getAssumeRoleCredentials(clnt *http.Client, endpoint string, opts STSAssumeRoleOptions) (AssumeRoleResponse, error) {
149 v := url.Values{}
150 v.Set("Action", "AssumeRole")
151 v.Set("Version", STSVersion)
152 if opts.RoleARN != "" {
153 v.Set("RoleArn", opts.RoleARN)
154 }
155 if opts.RoleSessionName != "" {
156 v.Set("RoleSessionName", opts.RoleSessionName)
157 }
158 if opts.DurationSeconds > defaultDurationSeconds {
159 v.Set("DurationSeconds", strconv.Itoa(opts.DurationSeconds))
160 } else {
161 v.Set("DurationSeconds", strconv.Itoa(defaultDurationSeconds))
162 }
163 if opts.Policy != "" {
164 v.Set("Policy", opts.Policy)
165 }
166 if opts.ExternalID != "" {
167 v.Set("ExternalId", opts.ExternalID)
168 }
169
170 u, err := url.Parse(endpoint)
171 if err != nil {
172 return AssumeRoleResponse{}, err
173 }
174 u.Path = "/"
175
176 postBody := strings.NewReader(v.Encode())
177 hash := sha256.New()
178 if _, err = io.Copy(hash, postBody); err != nil {
179 return AssumeRoleResponse{}, err
180 }
181 postBody.Seek(0, 0)
182
183 req, err := http.NewRequest(http.MethodPost, u.String(), postBody)
184 if err != nil {
185 return AssumeRoleResponse{}, err
186 }
187 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
188 req.Header.Set("X-Amz-Content-Sha256", hex.EncodeToString(hash.Sum(nil)))
189 if opts.SessionToken != "" {
190 req.Header.Set("X-Amz-Security-Token", opts.SessionToken)
191 }
192 req = signer.SignV4STS(*req, opts.AccessKey, opts.SecretKey, opts.Location)
193
194 resp, err := clnt.Do(req)
195 if err != nil {
196 return AssumeRoleResponse{}, err
197 }
198 defer closeResponse(resp)
199 if resp.StatusCode != http.StatusOK {
200 var errResp ErrorResponse
201 buf, err := io.ReadAll(resp.Body)
202 if err != nil {
203 return AssumeRoleResponse{}, err
204 }
205 _, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
206 if err != nil {
207 var s3Err Error
208 if _, err = xmlDecodeAndBody(bytes.NewReader(buf), &s3Err); err != nil {
209 return AssumeRoleResponse{}, err
210 }
211 errResp.RequestID = s3Err.RequestID
212 errResp.STSError.Code = s3Err.Code
213 errResp.STSError.Message = s3Err.Message
214 }
215 return AssumeRoleResponse{}, errResp
216 }
217
218 a := AssumeRoleResponse{}
219 if _, err = xmlDecodeAndBody(resp.Body, &a); err != nil {
220 return AssumeRoleResponse{}, err
221 }
222 return a, nil
223}
224
225// Retrieve retrieves credentials from the MinIO service.
226// Error will be returned if the request fails.
227func (m *STSAssumeRole) Retrieve() (Value, error) {
228 a, err := getAssumeRoleCredentials(m.Client, m.STSEndpoint, m.Options)
229 if err != nil {
230 return Value{}, err
231 }
232
233 // Expiry window is set to 10secs.
234 m.SetExpiration(a.Result.Credentials.Expiration, DefaultExpiryWindow)
235
236 return Value{
237 AccessKeyID: a.Result.Credentials.AccessKey,
238 SecretAccessKey: a.Result.Credentials.SecretKey,
239 SessionToken: a.Result.Credentials.SessionToken,
240 SignerType: SignatureV4,
241 }, nil
242}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/chain.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/chain.go
new file mode 100644
index 0000000..ddccfb1
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/chain.go
@@ -0,0 +1,88 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2017 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20// A Chain will search for a provider which returns credentials
21// and cache that provider until Retrieve is called again.
22//
23// The Chain provides a way of chaining multiple providers together
24// which will pick the first available using priority order of the
25// Providers in the list.
26//
27// If none of the Providers retrieve valid credentials Value, ChainProvider's
28// Retrieve() will return the no credentials value.
29//
30// If a Provider is found which returns valid credentials Value ChainProvider
31// will cache that Provider for all calls to IsExpired(), until Retrieve is
32// called again after IsExpired() is true.
33//
34// creds := credentials.NewChainCredentials(
35// []credentials.Provider{
36// &credentials.EnvAWSS3{},
37// &credentials.EnvMinio{},
38// })
39//
40// // Usage of ChainCredentials.
41// mc, err := minio.NewWithCredentials(endpoint, creds, secure, "us-east-1")
42// if err != nil {
43// log.Fatalln(err)
44// }
45type Chain struct {
46 Providers []Provider
47 curr Provider
48}
49
50// NewChainCredentials returns a pointer to a new Credentials object
51// wrapping a chain of providers.
52func NewChainCredentials(providers []Provider) *Credentials {
53 return New(&Chain{
54 Providers: append([]Provider{}, providers...),
55 })
56}
57
58// Retrieve returns the credentials value, returns no credentials(anonymous)
59// if no credentials provider returned any value.
60//
61// If a provider is found with credentials, it will be cached and any calls
62// to IsExpired() will return the expired state of the cached provider.
63func (c *Chain) Retrieve() (Value, error) {
64 for _, p := range c.Providers {
65 creds, _ := p.Retrieve()
66 // Always prioritize non-anonymous providers, if any.
67 if creds.AccessKeyID == "" && creds.SecretAccessKey == "" {
68 continue
69 }
70 c.curr = p
71 return creds, nil
72 }
73 // At this point we have exhausted all the providers and
74 // are left without any credentials return anonymous.
75 return Value{
76 SignerType: SignatureAnonymous,
77 }, nil
78}
79
80// IsExpired will returned the expired state of the currently cached provider
81// if there is one. If there is no current provider, true will be returned.
82func (c *Chain) IsExpired() bool {
83 if c.curr != nil {
84 return c.curr.IsExpired()
85 }
86
87 return true
88}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/config.json.sample b/vendor/github.com/minio/minio-go/v7/pkg/credentials/config.json.sample
new file mode 100644
index 0000000..d793c9e
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/config.json.sample
@@ -0,0 +1,17 @@
1{
2 "version": "8",
3 "hosts": {
4 "play": {
5 "url": "https://play.min.io",
6 "accessKey": "Q3AM3UQ867SPQQA43P2F",
7 "secretKey": "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG",
8 "api": "S3v2"
9 },
10 "s3": {
11 "url": "https://s3.amazonaws.com",
12 "accessKey": "accessKey",
13 "secretKey": "secret",
14 "api": "S3v4"
15 }
16 }
17} \ No newline at end of file
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.go
new file mode 100644
index 0000000..af61049
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.go
@@ -0,0 +1,193 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2017 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import (
21 "sync"
22 "time"
23)
24
25const (
26 // STSVersion sts version string
27 STSVersion = "2011-06-15"
28
29 // How much duration to slash from the given expiration duration
30 defaultExpiryWindow = 0.8
31)
32
33// A Value is the AWS credentials value for individual credential fields.
34type Value struct {
35 // AWS Access key ID
36 AccessKeyID string
37
38 // AWS Secret Access Key
39 SecretAccessKey string
40
41 // AWS Session Token
42 SessionToken string
43
44 // Signature Type.
45 SignerType SignatureType
46}
47
48// A Provider is the interface for any component which will provide credentials
49// Value. A provider is required to manage its own Expired state, and what to
50// be expired means.
51type Provider interface {
52 // Retrieve returns nil if it successfully retrieved the value.
53 // Error is returned if the value were not obtainable, or empty.
54 Retrieve() (Value, error)
55
56 // IsExpired returns if the credentials are no longer valid, and need
57 // to be retrieved.
58 IsExpired() bool
59}
60
61// A Expiry provides shared expiration logic to be used by credentials
62// providers to implement expiry functionality.
63//
64// The best method to use this struct is as an anonymous field within the
65// provider's struct.
66//
67// Example:
68//
69// type IAMCredentialProvider struct {
70// Expiry
71// ...
72// }
73type Expiry struct {
74 // The date/time when to expire on
75 expiration time.Time
76
77 // If set will be used by IsExpired to determine the current time.
78 // Defaults to time.Now if CurrentTime is not set.
79 CurrentTime func() time.Time
80}
81
82// SetExpiration sets the expiration IsExpired will check when called.
83//
84// If window is greater than 0 the expiration time will be reduced by the
85// window value.
86//
87// Using a window is helpful to trigger credentials to expire sooner than
88// the expiration time given to ensure no requests are made with expired
89// tokens.
90func (e *Expiry) SetExpiration(expiration time.Time, window time.Duration) {
91 if e.CurrentTime == nil {
92 e.CurrentTime = time.Now
93 }
94 cut := window
95 if cut < 0 {
96 expireIn := expiration.Sub(e.CurrentTime())
97 cut = time.Duration(float64(expireIn) * (1 - defaultExpiryWindow))
98 }
99 e.expiration = expiration.Add(-cut)
100}
101
102// IsExpired returns if the credentials are expired.
103func (e *Expiry) IsExpired() bool {
104 if e.CurrentTime == nil {
105 e.CurrentTime = time.Now
106 }
107 return e.expiration.Before(e.CurrentTime())
108}
109
110// Credentials - A container for synchronous safe retrieval of credentials Value.
111// Credentials will cache the credentials value until they expire. Once the value
112// expires the next Get will attempt to retrieve valid credentials.
113//
114// Credentials is safe to use across multiple goroutines and will manage the
115// synchronous state so the Providers do not need to implement their own
116// synchronization.
117//
118// The first Credentials.Get() will always call Provider.Retrieve() to get the
119// first instance of the credentials Value. All calls to Get() after that
120// will return the cached credentials Value until IsExpired() returns true.
121type Credentials struct {
122 sync.Mutex
123
124 creds Value
125 forceRefresh bool
126 provider Provider
127}
128
129// New returns a pointer to a new Credentials with the provider set.
130func New(provider Provider) *Credentials {
131 return &Credentials{
132 provider: provider,
133 forceRefresh: true,
134 }
135}
136
137// Get returns the credentials value, or error if the credentials Value failed
138// to be retrieved.
139//
140// Will return the cached credentials Value if it has not expired. If the
141// credentials Value has expired the Provider's Retrieve() will be called
142// to refresh the credentials.
143//
144// If Credentials.Expire() was called the credentials Value will be force
145// expired, and the next call to Get() will cause them to be refreshed.
146func (c *Credentials) Get() (Value, error) {
147 if c == nil {
148 return Value{}, nil
149 }
150
151 c.Lock()
152 defer c.Unlock()
153
154 if c.isExpired() {
155 creds, err := c.provider.Retrieve()
156 if err != nil {
157 return Value{}, err
158 }
159 c.creds = creds
160 c.forceRefresh = false
161 }
162
163 return c.creds, nil
164}
165
166// Expire expires the credentials and forces them to be retrieved on the
167// next call to Get().
168//
169// This will override the Provider's expired state, and force Credentials
170// to call the Provider's Retrieve().
171func (c *Credentials) Expire() {
172 c.Lock()
173 defer c.Unlock()
174
175 c.forceRefresh = true
176}
177
178// IsExpired returns if the credentials are no longer valid, and need
179// to be refreshed.
180//
181// If the Credentials were forced to be expired with Expire() this will
182// reflect that override.
183func (c *Credentials) IsExpired() bool {
184 c.Lock()
185 defer c.Unlock()
186
187 return c.isExpired()
188}
189
190// isExpired helper method wrapping the definition of expired credentials.
191func (c *Credentials) isExpired() bool {
192 return c.forceRefresh || c.provider.IsExpired()
193}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.json b/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.json
new file mode 100644
index 0000000..afbfad5
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.json
@@ -0,0 +1,7 @@
1{
2 "Version": 1,
3 "SessionToken": "token",
4 "AccessKeyId": "accessKey",
5 "SecretAccessKey": "secret",
6 "Expiration": "9999-04-27T16:02:25.000Z"
7}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.sample b/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.sample
new file mode 100644
index 0000000..e2dc1bf
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/credentials.sample
@@ -0,0 +1,15 @@
1[default]
2aws_access_key_id = accessKey
3aws_secret_access_key = secret
4aws_session_token = token
5
6[no_token]
7aws_access_key_id = accessKey
8aws_secret_access_key = secret
9
10[with_colon]
11aws_access_key_id: accessKey
12aws_secret_access_key: secret
13
14[with_process]
15credential_process = /bin/cat credentials.json
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/doc.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/doc.go
new file mode 100644
index 0000000..fbfb105
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/doc.go
@@ -0,0 +1,60 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2017 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18// Package credentials provides credential retrieval and management
19// for S3 compatible object storage.
20//
21// By default the Credentials.Get() will cache the successful result of a
22// Provider's Retrieve() until Provider.IsExpired() returns true. At which
23// point Credentials will call Provider's Retrieve() to get new credential Value.
24//
25// The Provider is responsible for determining when credentials have expired.
26// It is also important to note that Credentials will always call Retrieve the
27// first time Credentials.Get() is called.
28//
29// Example of using the environment variable credentials.
30//
31// creds := NewFromEnv()
32// // Retrieve the credentials value
33// credValue, err := creds.Get()
34// if err != nil {
35// // handle error
36// }
37//
38// Example of forcing credentials to expire and be refreshed on the next Get().
39// This may be helpful to proactively expire credentials and refresh them sooner
40// than they would naturally expire on their own.
41//
42// creds := NewFromIAM("")
43// creds.Expire()
44// credsValue, err := creds.Get()
45// // New credentials will be retrieved instead of from cache.
46//
47// # Custom Provider
48//
49// Each Provider built into this package also provides a helper method to generate
50// a Credentials pointer setup with the provider. To use a custom Provider just
51// create a type which satisfies the Provider interface and pass it to the
52// NewCredentials method.
53//
54// type MyProvider struct{}
55// func (m *MyProvider) Retrieve() (Value, error) {...}
56// func (m *MyProvider) IsExpired() bool {...}
57//
58// creds := NewCredentials(&MyProvider{})
59// credValue, err := creds.Get()
60package credentials
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/env_aws.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/env_aws.go
new file mode 100644
index 0000000..b6e60d0
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/env_aws.go
@@ -0,0 +1,71 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2017 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import "os"
21
22// A EnvAWS retrieves credentials from the environment variables of the
23// running process. EnvAWSironment credentials never expire.
24//
25// EnvAWSironment variables used:
26//
27// * Access Key ID: AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY.
28// * Secret Access Key: AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY.
29// * Secret Token: AWS_SESSION_TOKEN.
30type EnvAWS struct {
31 retrieved bool
32}
33
34// NewEnvAWS returns a pointer to a new Credentials object
35// wrapping the environment variable provider.
36func NewEnvAWS() *Credentials {
37 return New(&EnvAWS{})
38}
39
40// Retrieve retrieves the keys from the environment.
41func (e *EnvAWS) Retrieve() (Value, error) {
42 e.retrieved = false
43
44 id := os.Getenv("AWS_ACCESS_KEY_ID")
45 if id == "" {
46 id = os.Getenv("AWS_ACCESS_KEY")
47 }
48
49 secret := os.Getenv("AWS_SECRET_ACCESS_KEY")
50 if secret == "" {
51 secret = os.Getenv("AWS_SECRET_KEY")
52 }
53
54 signerType := SignatureV4
55 if id == "" || secret == "" {
56 signerType = SignatureAnonymous
57 }
58
59 e.retrieved = true
60 return Value{
61 AccessKeyID: id,
62 SecretAccessKey: secret,
63 SessionToken: os.Getenv("AWS_SESSION_TOKEN"),
64 SignerType: signerType,
65 }, nil
66}
67
68// IsExpired returns if the credentials have been retrieved.
69func (e *EnvAWS) IsExpired() bool {
70 return !e.retrieved
71}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/env_minio.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/env_minio.go
new file mode 100644
index 0000000..5bfeab1
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/env_minio.go
@@ -0,0 +1,68 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2017 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import "os"
21
22// A EnvMinio retrieves credentials from the environment variables of the
23// running process. EnvMinioironment credentials never expire.
24//
25// Environment variables used:
26//
27// * Access Key ID: MINIO_ACCESS_KEY.
28// * Secret Access Key: MINIO_SECRET_KEY.
29// * Access Key ID: MINIO_ROOT_USER.
30// * Secret Access Key: MINIO_ROOT_PASSWORD.
31type EnvMinio struct {
32 retrieved bool
33}
34
35// NewEnvMinio returns a pointer to a new Credentials object
36// wrapping the environment variable provider.
37func NewEnvMinio() *Credentials {
38 return New(&EnvMinio{})
39}
40
41// Retrieve retrieves the keys from the environment.
42func (e *EnvMinio) Retrieve() (Value, error) {
43 e.retrieved = false
44
45 id := os.Getenv("MINIO_ROOT_USER")
46 secret := os.Getenv("MINIO_ROOT_PASSWORD")
47
48 signerType := SignatureV4
49 if id == "" || secret == "" {
50 id = os.Getenv("MINIO_ACCESS_KEY")
51 secret = os.Getenv("MINIO_SECRET_KEY")
52 if id == "" || secret == "" {
53 signerType = SignatureAnonymous
54 }
55 }
56
57 e.retrieved = true
58 return Value{
59 AccessKeyID: id,
60 SecretAccessKey: secret,
61 SignerType: signerType,
62 }, nil
63}
64
65// IsExpired returns if the credentials have been retrieved.
66func (e *EnvMinio) IsExpired() bool {
67 return !e.retrieved
68}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/error_response.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/error_response.go
new file mode 100644
index 0000000..07a9c2f
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/error_response.go
@@ -0,0 +1,95 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2021 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import (
21 "bytes"
22 "encoding/xml"
23 "fmt"
24 "io"
25)
26
27// ErrorResponse - Is the typed error returned.
28// ErrorResponse struct should be comparable since it is compared inside
29// golang http API (https://github.com/golang/go/issues/29768)
30type ErrorResponse struct {
31 XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ ErrorResponse" json:"-"`
32 STSError struct {
33 Type string `xml:"Type"`
34 Code string `xml:"Code"`
35 Message string `xml:"Message"`
36 } `xml:"Error"`
37 RequestID string `xml:"RequestId"`
38}
39
40// Error - Is the typed error returned by all API operations.
41type Error struct {
42 XMLName xml.Name `xml:"Error" json:"-"`
43 Code string
44 Message string
45 BucketName string
46 Key string
47 Resource string
48 RequestID string `xml:"RequestId"`
49 HostID string `xml:"HostId"`
50
51 // Region where the bucket is located. This header is returned
52 // only in HEAD bucket and ListObjects response.
53 Region string
54
55 // Captures the server string returned in response header.
56 Server string
57
58 // Underlying HTTP status code for the returned error
59 StatusCode int `xml:"-" json:"-"`
60}
61
62// Error - Returns S3 error string.
63func (e Error) Error() string {
64 if e.Message == "" {
65 return fmt.Sprintf("Error response code %s.", e.Code)
66 }
67 return e.Message
68}
69
70// Error - Returns STS error string.
71func (e ErrorResponse) Error() string {
72 if e.STSError.Message == "" {
73 return fmt.Sprintf("Error response code %s.", e.STSError.Code)
74 }
75 return e.STSError.Message
76}
77
78// xmlDecoder provide decoded value in xml.
79func xmlDecoder(body io.Reader, v interface{}) error {
80 d := xml.NewDecoder(body)
81 return d.Decode(v)
82}
83
84// xmlDecodeAndBody reads the whole body up to 1MB and
85// tries to XML decode it into v.
86// The body that was read and any error from reading or decoding is returned.
87func xmlDecodeAndBody(bodyReader io.Reader, v interface{}) ([]byte, error) {
88 // read the whole body (up to 1MB)
89 const maxBodyLength = 1 << 20
90 body, err := io.ReadAll(io.LimitReader(bodyReader, maxBodyLength))
91 if err != nil {
92 return nil, err
93 }
94 return bytes.TrimSpace(body), xmlDecoder(bytes.NewReader(body), v)
95}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/file_aws_credentials.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/file_aws_credentials.go
new file mode 100644
index 0000000..5b07376
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/file_aws_credentials.go
@@ -0,0 +1,157 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2017 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import (
21 "encoding/json"
22 "errors"
23 "os"
24 "os/exec"
25 "path/filepath"
26 "strings"
27 "time"
28
29 ini "gopkg.in/ini.v1"
30)
31
32// A externalProcessCredentials stores the output of a credential_process
33type externalProcessCredentials struct {
34 Version int
35 SessionToken string
36 AccessKeyID string `json:"AccessKeyId"`
37 SecretAccessKey string
38 Expiration time.Time
39}
40
41// A FileAWSCredentials retrieves credentials from the current user's home
42// directory, and keeps track if those credentials are expired.
43//
44// Profile ini file example: $HOME/.aws/credentials
45type FileAWSCredentials struct {
46 Expiry
47
48 // Path to the shared credentials file.
49 //
50 // If empty will look for "AWS_SHARED_CREDENTIALS_FILE" env variable. If the
51 // env value is empty will default to current user's home directory.
52 // Linux/OSX: "$HOME/.aws/credentials"
53 // Windows: "%USERPROFILE%\.aws\credentials"
54 Filename string
55
56 // AWS Profile to extract credentials from the shared credentials file. If empty
57 // will default to environment variable "AWS_PROFILE" or "default" if
58 // environment variable is also not set.
59 Profile string
60
61 // retrieved states if the credentials have been successfully retrieved.
62 retrieved bool
63}
64
65// NewFileAWSCredentials returns a pointer to a new Credentials object
66// wrapping the Profile file provider.
67func NewFileAWSCredentials(filename, profile string) *Credentials {
68 return New(&FileAWSCredentials{
69 Filename: filename,
70 Profile: profile,
71 })
72}
73
74// Retrieve reads and extracts the shared credentials from the current
75// users home directory.
76func (p *FileAWSCredentials) Retrieve() (Value, error) {
77 if p.Filename == "" {
78 p.Filename = os.Getenv("AWS_SHARED_CREDENTIALS_FILE")
79 if p.Filename == "" {
80 homeDir, err := os.UserHomeDir()
81 if err != nil {
82 return Value{}, err
83 }
84 p.Filename = filepath.Join(homeDir, ".aws", "credentials")
85 }
86 }
87 if p.Profile == "" {
88 p.Profile = os.Getenv("AWS_PROFILE")
89 if p.Profile == "" {
90 p.Profile = "default"
91 }
92 }
93
94 p.retrieved = false
95
96 iniProfile, err := loadProfile(p.Filename, p.Profile)
97 if err != nil {
98 return Value{}, err
99 }
100
101 // Default to empty string if not found.
102 id := iniProfile.Key("aws_access_key_id")
103 // Default to empty string if not found.
104 secret := iniProfile.Key("aws_secret_access_key")
105 // Default to empty string if not found.
106 token := iniProfile.Key("aws_session_token")
107
108 // If credential_process is defined, obtain credentials by executing
109 // the external process
110 credentialProcess := strings.TrimSpace(iniProfile.Key("credential_process").String())
111 if credentialProcess != "" {
112 args := strings.Fields(credentialProcess)
113 if len(args) <= 1 {
114 return Value{}, errors.New("invalid credential process args")
115 }
116 cmd := exec.Command(args[0], args[1:]...)
117 out, err := cmd.Output()
118 if err != nil {
119 return Value{}, err
120 }
121 var externalProcessCredentials externalProcessCredentials
122 err = json.Unmarshal([]byte(out), &externalProcessCredentials)
123 if err != nil {
124 return Value{}, err
125 }
126 p.retrieved = true
127 p.SetExpiration(externalProcessCredentials.Expiration, DefaultExpiryWindow)
128 return Value{
129 AccessKeyID: externalProcessCredentials.AccessKeyID,
130 SecretAccessKey: externalProcessCredentials.SecretAccessKey,
131 SessionToken: externalProcessCredentials.SessionToken,
132 SignerType: SignatureV4,
133 }, nil
134 }
135 p.retrieved = true
136 return Value{
137 AccessKeyID: id.String(),
138 SecretAccessKey: secret.String(),
139 SessionToken: token.String(),
140 SignerType: SignatureV4,
141 }, nil
142}
143
144// loadProfiles loads from the file pointed to by shared credentials filename for profile.
145// The credentials retrieved from the profile will be returned or error. Error will be
146// returned if it fails to read from the file, or the data is invalid.
147func loadProfile(filename, profile string) (*ini.Section, error) {
148 config, err := ini.Load(filename)
149 if err != nil {
150 return nil, err
151 }
152 iniProfile, err := config.GetSection(profile)
153 if err != nil {
154 return nil, err
155 }
156 return iniProfile, nil
157}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/file_minio_client.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/file_minio_client.go
new file mode 100644
index 0000000..eb77767
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/file_minio_client.go
@@ -0,0 +1,139 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2017 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import (
21 "os"
22 "path/filepath"
23 "runtime"
24
25 jsoniter "github.com/json-iterator/go"
26)
27
28// A FileMinioClient retrieves credentials from the current user's home
29// directory, and keeps track if those credentials are expired.
30//
31// Configuration file example: $HOME/.mc/config.json
32type FileMinioClient struct {
33 // Path to the shared credentials file.
34 //
35 // If empty will look for "MINIO_SHARED_CREDENTIALS_FILE" env variable. If the
36 // env value is empty will default to current user's home directory.
37 // Linux/OSX: "$HOME/.mc/config.json"
38 // Windows: "%USERALIAS%\mc\config.json"
39 Filename string
40
41 // MinIO Alias to extract credentials from the shared credentials file. If empty
42 // will default to environment variable "MINIO_ALIAS" or "default" if
43 // environment variable is also not set.
44 Alias string
45
46 // retrieved states if the credentials have been successfully retrieved.
47 retrieved bool
48}
49
50// NewFileMinioClient returns a pointer to a new Credentials object
51// wrapping the Alias file provider.
52func NewFileMinioClient(filename, alias string) *Credentials {
53 return New(&FileMinioClient{
54 Filename: filename,
55 Alias: alias,
56 })
57}
58
59// Retrieve reads and extracts the shared credentials from the current
60// users home directory.
61func (p *FileMinioClient) Retrieve() (Value, error) {
62 if p.Filename == "" {
63 if value, ok := os.LookupEnv("MINIO_SHARED_CREDENTIALS_FILE"); ok {
64 p.Filename = value
65 } else {
66 homeDir, err := os.UserHomeDir()
67 if err != nil {
68 return Value{}, err
69 }
70 p.Filename = filepath.Join(homeDir, ".mc", "config.json")
71 if runtime.GOOS == "windows" {
72 p.Filename = filepath.Join(homeDir, "mc", "config.json")
73 }
74 }
75 }
76
77 if p.Alias == "" {
78 p.Alias = os.Getenv("MINIO_ALIAS")
79 if p.Alias == "" {
80 p.Alias = "s3"
81 }
82 }
83
84 p.retrieved = false
85
86 hostCfg, err := loadAlias(p.Filename, p.Alias)
87 if err != nil {
88 return Value{}, err
89 }
90
91 p.retrieved = true
92 return Value{
93 AccessKeyID: hostCfg.AccessKey,
94 SecretAccessKey: hostCfg.SecretKey,
95 SignerType: parseSignatureType(hostCfg.API),
96 }, nil
97}
98
99// IsExpired returns if the shared credentials have expired.
100func (p *FileMinioClient) IsExpired() bool {
101 return !p.retrieved
102}
103
104// hostConfig configuration of a host.
105type hostConfig struct {
106 URL string `json:"url"`
107 AccessKey string `json:"accessKey"`
108 SecretKey string `json:"secretKey"`
109 API string `json:"api"`
110}
111
112// config config version.
113type config struct {
114 Version string `json:"version"`
115 Hosts map[string]hostConfig `json:"hosts"`
116 Aliases map[string]hostConfig `json:"aliases"`
117}
118
119// loadAliass loads from the file pointed to by shared credentials filename for alias.
120// The credentials retrieved from the alias will be returned or error. Error will be
121// returned if it fails to read from the file.
122func loadAlias(filename, alias string) (hostConfig, error) {
123 cfg := &config{}
124 json := jsoniter.ConfigCompatibleWithStandardLibrary
125
126 configBytes, err := os.ReadFile(filename)
127 if err != nil {
128 return hostConfig{}, err
129 }
130 if err = json.Unmarshal(configBytes, cfg); err != nil {
131 return hostConfig{}, err
132 }
133
134 if cfg.Version == "10" {
135 return cfg.Aliases[alias], nil
136 }
137
138 return cfg.Hosts[alias], nil
139}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/iam_aws.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/iam_aws.go
new file mode 100644
index 0000000..c5153c4
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/iam_aws.go
@@ -0,0 +1,433 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2017 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import (
21 "bufio"
22 "context"
23 "errors"
24 "fmt"
25 "io"
26 "net"
27 "net/http"
28 "net/url"
29 "os"
30 "path"
31 "strings"
32 "time"
33
34 jsoniter "github.com/json-iterator/go"
35)
36
37// DefaultExpiryWindow - Default expiry window.
38// ExpiryWindow will allow the credentials to trigger refreshing
39// prior to the credentials actually expiring. This is beneficial
40// so race conditions with expiring credentials do not cause
41// request to fail unexpectedly due to ExpiredTokenException exceptions.
42// DefaultExpiryWindow can be used as parameter to (*Expiry).SetExpiration.
43// When used the tokens refresh will be triggered when 80% of the elapsed
44// time until the actual expiration time is passed.
45const DefaultExpiryWindow = -1
46
47// A IAM retrieves credentials from the EC2 service, and keeps track if
48// those credentials are expired.
49type IAM struct {
50 Expiry
51
52 // Required http Client to use when connecting to IAM metadata service.
53 Client *http.Client
54
55 // Custom endpoint to fetch IAM role credentials.
56 Endpoint string
57
58 // Region configurable custom region for STS
59 Region string
60
61 // Support for container authorization token https://docs.aws.amazon.com/sdkref/latest/guide/feature-container-credentials.html
62 Container struct {
63 AuthorizationToken string
64 CredentialsFullURI string
65 CredentialsRelativeURI string
66 }
67
68 // EKS based k8s RBAC authorization - https://docs.aws.amazon.com/eks/latest/userguide/pod-configuration.html
69 EKSIdentity struct {
70 TokenFile string
71 RoleARN string
72 RoleSessionName string
73 }
74}
75
76// IAM Roles for Amazon EC2
77// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
78const (
79 DefaultIAMRoleEndpoint = "http://169.254.169.254"
80 DefaultECSRoleEndpoint = "http://169.254.170.2"
81 DefaultSTSRoleEndpoint = "https://sts.amazonaws.com"
82 DefaultIAMSecurityCredsPath = "/latest/meta-data/iam/security-credentials/"
83 TokenRequestTTLHeader = "X-aws-ec2-metadata-token-ttl-seconds"
84 TokenPath = "/latest/api/token"
85 TokenTTL = "21600"
86 TokenRequestHeader = "X-aws-ec2-metadata-token"
87)
88
89// NewIAM returns a pointer to a new Credentials object wrapping the IAM.
90func NewIAM(endpoint string) *Credentials {
91 return New(&IAM{
92 Client: &http.Client{
93 Transport: http.DefaultTransport,
94 },
95 Endpoint: endpoint,
96 })
97}
98
99// Retrieve retrieves credentials from the EC2 service.
100// Error will be returned if the request fails, or unable to extract
101// the desired
102func (m *IAM) Retrieve() (Value, error) {
103 token := os.Getenv("AWS_CONTAINER_AUTHORIZATION_TOKEN")
104 if token == "" {
105 token = m.Container.AuthorizationToken
106 }
107
108 relativeURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI")
109 if relativeURI == "" {
110 relativeURI = m.Container.CredentialsRelativeURI
111 }
112
113 fullURI := os.Getenv("AWS_CONTAINER_CREDENTIALS_FULL_URI")
114 if fullURI == "" {
115 fullURI = m.Container.CredentialsFullURI
116 }
117
118 identityFile := os.Getenv("AWS_WEB_IDENTITY_TOKEN_FILE")
119 if identityFile == "" {
120 identityFile = m.EKSIdentity.TokenFile
121 }
122
123 roleArn := os.Getenv("AWS_ROLE_ARN")
124 if roleArn == "" {
125 roleArn = m.EKSIdentity.RoleARN
126 }
127
128 roleSessionName := os.Getenv("AWS_ROLE_SESSION_NAME")
129 if roleSessionName == "" {
130 roleSessionName = m.EKSIdentity.RoleSessionName
131 }
132
133 region := os.Getenv("AWS_REGION")
134 if region == "" {
135 region = m.Region
136 }
137
138 var roleCreds ec2RoleCredRespBody
139 var err error
140
141 endpoint := m.Endpoint
142 switch {
143 case identityFile != "":
144 if len(endpoint) == 0 {
145 if region != "" {
146 if strings.HasPrefix(region, "cn-") {
147 endpoint = "https://sts." + region + ".amazonaws.com.cn"
148 } else {
149 endpoint = "https://sts." + region + ".amazonaws.com"
150 }
151 } else {
152 endpoint = DefaultSTSRoleEndpoint
153 }
154 }
155
156 creds := &STSWebIdentity{
157 Client: m.Client,
158 STSEndpoint: endpoint,
159 GetWebIDTokenExpiry: func() (*WebIdentityToken, error) {
160 token, err := os.ReadFile(identityFile)
161 if err != nil {
162 return nil, err
163 }
164
165 return &WebIdentityToken{Token: string(token)}, nil
166 },
167 RoleARN: roleArn,
168 roleSessionName: roleSessionName,
169 }
170
171 stsWebIdentityCreds, err := creds.Retrieve()
172 if err == nil {
173 m.SetExpiration(creds.Expiration(), DefaultExpiryWindow)
174 }
175 return stsWebIdentityCreds, err
176
177 case relativeURI != "":
178 if len(endpoint) == 0 {
179 endpoint = fmt.Sprintf("%s%s", DefaultECSRoleEndpoint, relativeURI)
180 }
181
182 roleCreds, err = getEcsTaskCredentials(m.Client, endpoint, token)
183
184 case fullURI != "":
185 if len(endpoint) == 0 {
186 endpoint = fullURI
187 var ok bool
188 if ok, err = isLoopback(endpoint); !ok {
189 if err == nil {
190 err = fmt.Errorf("uri host is not a loopback address: %s", endpoint)
191 }
192 break
193 }
194 }
195
196 roleCreds, err = getEcsTaskCredentials(m.Client, endpoint, token)
197
198 default:
199 roleCreds, err = getCredentials(m.Client, endpoint)
200 }
201
202 if err != nil {
203 return Value{}, err
204 }
205 // Expiry window is set to 10secs.
206 m.SetExpiration(roleCreds.Expiration, DefaultExpiryWindow)
207
208 return Value{
209 AccessKeyID: roleCreds.AccessKeyID,
210 SecretAccessKey: roleCreds.SecretAccessKey,
211 SessionToken: roleCreds.Token,
212 SignerType: SignatureV4,
213 }, nil
214}
215
216// A ec2RoleCredRespBody provides the shape for unmarshaling credential
217// request responses.
218type ec2RoleCredRespBody struct {
219 // Success State
220 Expiration time.Time
221 AccessKeyID string
222 SecretAccessKey string
223 Token string
224
225 // Error state
226 Code string
227 Message string
228
229 // Unused params.
230 LastUpdated time.Time
231 Type string
232}
233
234// Get the final IAM role URL where the request will
235// be sent to fetch the rolling access credentials.
236// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
237func getIAMRoleURL(endpoint string) (*url.URL, error) {
238 u, err := url.Parse(endpoint)
239 if err != nil {
240 return nil, err
241 }
242 u.Path = DefaultIAMSecurityCredsPath
243 return u, nil
244}
245
246// listRoleNames lists of credential role names associated
247// with the current EC2 service. If there are no credentials,
248// or there is an error making or receiving the request.
249// http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
250func listRoleNames(client *http.Client, u *url.URL, token string) ([]string, error) {
251 req, err := http.NewRequest(http.MethodGet, u.String(), nil)
252 if err != nil {
253 return nil, err
254 }
255 if token != "" {
256 req.Header.Add(TokenRequestHeader, token)
257 }
258 resp, err := client.Do(req)
259 if err != nil {
260 return nil, err
261 }
262 defer resp.Body.Close()
263 if resp.StatusCode != http.StatusOK {
264 return nil, errors.New(resp.Status)
265 }
266
267 credsList := []string{}
268 s := bufio.NewScanner(resp.Body)
269 for s.Scan() {
270 credsList = append(credsList, s.Text())
271 }
272
273 if err := s.Err(); err != nil {
274 return nil, err
275 }
276
277 return credsList, nil
278}
279
280func getEcsTaskCredentials(client *http.Client, endpoint, token string) (ec2RoleCredRespBody, error) {
281 req, err := http.NewRequest(http.MethodGet, endpoint, nil)
282 if err != nil {
283 return ec2RoleCredRespBody{}, err
284 }
285
286 if token != "" {
287 req.Header.Set("Authorization", token)
288 }
289
290 resp, err := client.Do(req)
291 if err != nil {
292 return ec2RoleCredRespBody{}, err
293 }
294 defer resp.Body.Close()
295 if resp.StatusCode != http.StatusOK {
296 return ec2RoleCredRespBody{}, errors.New(resp.Status)
297 }
298
299 respCreds := ec2RoleCredRespBody{}
300 if err := jsoniter.NewDecoder(resp.Body).Decode(&respCreds); err != nil {
301 return ec2RoleCredRespBody{}, err
302 }
303
304 return respCreds, nil
305}
306
307func fetchIMDSToken(client *http.Client, endpoint string) (string, error) {
308 ctx, cancel := context.WithTimeout(context.Background(), time.Second)
309 defer cancel()
310
311 req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint+TokenPath, nil)
312 if err != nil {
313 return "", err
314 }
315 req.Header.Add(TokenRequestTTLHeader, TokenTTL)
316 resp, err := client.Do(req)
317 if err != nil {
318 return "", err
319 }
320 defer resp.Body.Close()
321 data, err := io.ReadAll(resp.Body)
322 if err != nil {
323 return "", err
324 }
325 if resp.StatusCode != http.StatusOK {
326 return "", errors.New(resp.Status)
327 }
328 return string(data), nil
329}
330
331// getCredentials - obtains the credentials from the IAM role name associated with
332// the current EC2 service.
333//
334// If the credentials cannot be found, or there is an error
335// reading the response an error will be returned.
336func getCredentials(client *http.Client, endpoint string) (ec2RoleCredRespBody, error) {
337 if endpoint == "" {
338 endpoint = DefaultIAMRoleEndpoint
339 }
340
341 // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html
342 token, err := fetchIMDSToken(client, endpoint)
343 if err != nil {
344 // Return only errors for valid situations, if the IMDSv2 is not enabled
345 // we will not be able to get the token, in such a situation we have
346 // to rely on IMDSv1 behavior as a fallback, this check ensures that.
347 // Refer https://github.com/minio/minio-go/issues/1866
348 if !errors.Is(err, context.DeadlineExceeded) && !errors.Is(err, context.Canceled) {
349 return ec2RoleCredRespBody{}, err
350 }
351 }
352
353 // http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
354 u, err := getIAMRoleURL(endpoint)
355 if err != nil {
356 return ec2RoleCredRespBody{}, err
357 }
358
359 // http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
360 roleNames, err := listRoleNames(client, u, token)
361 if err != nil {
362 return ec2RoleCredRespBody{}, err
363 }
364
365 if len(roleNames) == 0 {
366 return ec2RoleCredRespBody{}, errors.New("No IAM roles attached to this EC2 service")
367 }
368
369 // http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
370 // - An instance profile can contain only one IAM role. This limit cannot be increased.
371 roleName := roleNames[0]
372
373 // http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
374 // The following command retrieves the security credentials for an
375 // IAM role named `s3access`.
376 //
377 // $ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/s3access
378 //
379 u.Path = path.Join(u.Path, roleName)
380 req, err := http.NewRequest(http.MethodGet, u.String(), nil)
381 if err != nil {
382 return ec2RoleCredRespBody{}, err
383 }
384 if token != "" {
385 req.Header.Add(TokenRequestHeader, token)
386 }
387
388 resp, err := client.Do(req)
389 if err != nil {
390 return ec2RoleCredRespBody{}, err
391 }
392 defer resp.Body.Close()
393 if resp.StatusCode != http.StatusOK {
394 return ec2RoleCredRespBody{}, errors.New(resp.Status)
395 }
396
397 respCreds := ec2RoleCredRespBody{}
398 if err := jsoniter.NewDecoder(resp.Body).Decode(&respCreds); err != nil {
399 return ec2RoleCredRespBody{}, err
400 }
401
402 if respCreds.Code != "Success" {
403 // If an error code was returned something failed requesting the role.
404 return ec2RoleCredRespBody{}, errors.New(respCreds.Message)
405 }
406
407 return respCreds, nil
408}
409
410// isLoopback identifies if a uri's host is on a loopback address
411func isLoopback(uri string) (bool, error) {
412 u, err := url.Parse(uri)
413 if err != nil {
414 return false, err
415 }
416
417 host := u.Hostname()
418 if len(host) == 0 {
419 return false, fmt.Errorf("can't parse host from uri: %s", uri)
420 }
421
422 ips, err := net.LookupHost(host)
423 if err != nil {
424 return false, err
425 }
426 for _, ip := range ips {
427 if !net.ParseIP(ip).IsLoopback() {
428 return false, nil
429 }
430 }
431
432 return true, nil
433}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/signature_type.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/signature_type.go
new file mode 100644
index 0000000..b794333
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/signature_type.go
@@ -0,0 +1,77 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2017 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import "strings"
21
22// SignatureType is type of Authorization requested for a given HTTP request.
23type SignatureType int
24
25// Different types of supported signatures - default is SignatureV4 or SignatureDefault.
26const (
27 // SignatureDefault is always set to v4.
28 SignatureDefault SignatureType = iota
29 SignatureV4
30 SignatureV2
31 SignatureV4Streaming
32 SignatureAnonymous // Anonymous signature signifies, no signature.
33)
34
35// IsV2 - is signature SignatureV2?
36func (s SignatureType) IsV2() bool {
37 return s == SignatureV2
38}
39
40// IsV4 - is signature SignatureV4?
41func (s SignatureType) IsV4() bool {
42 return s == SignatureV4 || s == SignatureDefault
43}
44
45// IsStreamingV4 - is signature SignatureV4Streaming?
46func (s SignatureType) IsStreamingV4() bool {
47 return s == SignatureV4Streaming
48}
49
50// IsAnonymous - is signature empty?
51func (s SignatureType) IsAnonymous() bool {
52 return s == SignatureAnonymous
53}
54
55// Stringer humanized version of signature type,
56// strings returned here are case insensitive.
57func (s SignatureType) String() string {
58 if s.IsV2() {
59 return "S3v2"
60 } else if s.IsV4() {
61 return "S3v4"
62 } else if s.IsStreamingV4() {
63 return "S3v4Streaming"
64 }
65 return "Anonymous"
66}
67
68func parseSignatureType(str string) SignatureType {
69 if strings.EqualFold(str, "S3v4") {
70 return SignatureV4
71 } else if strings.EqualFold(str, "S3v2") {
72 return SignatureV2
73 } else if strings.EqualFold(str, "S3v4Streaming") {
74 return SignatureV4Streaming
75 }
76 return SignatureAnonymous
77}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/static.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/static.go
new file mode 100644
index 0000000..7dde00b
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/static.go
@@ -0,0 +1,67 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2017 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20// A Static is a set of credentials which are set programmatically,
21// and will never expire.
22type Static struct {
23 Value
24}
25
26// NewStaticV2 returns a pointer to a new Credentials object
27// wrapping a static credentials value provider, signature is
28// set to v2. If access and secret are not specified then
29// regardless of signature type set it Value will return
30// as anonymous.
31func NewStaticV2(id, secret, token string) *Credentials {
32 return NewStatic(id, secret, token, SignatureV2)
33}
34
35// NewStaticV4 is similar to NewStaticV2 with similar considerations.
36func NewStaticV4(id, secret, token string) *Credentials {
37 return NewStatic(id, secret, token, SignatureV4)
38}
39
40// NewStatic returns a pointer to a new Credentials object
41// wrapping a static credentials value provider.
42func NewStatic(id, secret, token string, signerType SignatureType) *Credentials {
43 return New(&Static{
44 Value: Value{
45 AccessKeyID: id,
46 SecretAccessKey: secret,
47 SessionToken: token,
48 SignerType: signerType,
49 },
50 })
51}
52
53// Retrieve returns the static credentials.
54func (s *Static) Retrieve() (Value, error) {
55 if s.AccessKeyID == "" || s.SecretAccessKey == "" {
56 // Anonymous is not an error
57 return Value{SignerType: SignatureAnonymous}, nil
58 }
59 return s.Value, nil
60}
61
62// IsExpired returns if the credentials are expired.
63//
64// For Static, the credentials never expired.
65func (s *Static) IsExpired() bool {
66 return false
67}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_client_grants.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_client_grants.go
new file mode 100644
index 0000000..9e92c1e
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_client_grants.go
@@ -0,0 +1,182 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2019-2022 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import (
21 "bytes"
22 "encoding/xml"
23 "errors"
24 "fmt"
25 "io"
26 "net/http"
27 "net/url"
28 "strings"
29 "time"
30)
31
32// AssumedRoleUser - The identifiers for the temporary security credentials that
33// the operation returns. Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser
34type AssumedRoleUser struct {
35 Arn string
36 AssumedRoleID string `xml:"AssumeRoleId"`
37}
38
39// AssumeRoleWithClientGrantsResponse contains the result of successful AssumeRoleWithClientGrants request.
40type AssumeRoleWithClientGrantsResponse struct {
41 XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleWithClientGrantsResponse" json:"-"`
42 Result ClientGrantsResult `xml:"AssumeRoleWithClientGrantsResult"`
43 ResponseMetadata struct {
44 RequestID string `xml:"RequestId,omitempty"`
45 } `xml:"ResponseMetadata,omitempty"`
46}
47
48// ClientGrantsResult - Contains the response to a successful AssumeRoleWithClientGrants
49// request, including temporary credentials that can be used to make MinIO API requests.
50type ClientGrantsResult struct {
51 AssumedRoleUser AssumedRoleUser `xml:",omitempty"`
52 Audience string `xml:",omitempty"`
53 Credentials struct {
54 AccessKey string `xml:"AccessKeyId" json:"accessKey,omitempty"`
55 SecretKey string `xml:"SecretAccessKey" json:"secretKey,omitempty"`
56 Expiration time.Time `xml:"Expiration" json:"expiration,omitempty"`
57 SessionToken string `xml:"SessionToken" json:"sessionToken,omitempty"`
58 } `xml:",omitempty"`
59 PackedPolicySize int `xml:",omitempty"`
60 Provider string `xml:",omitempty"`
61 SubjectFromClientGrantsToken string `xml:",omitempty"`
62}
63
64// ClientGrantsToken - client grants token with expiry.
65type ClientGrantsToken struct {
66 Token string
67 Expiry int
68}
69
70// A STSClientGrants retrieves credentials from MinIO service, and keeps track if
71// those credentials are expired.
72type STSClientGrants struct {
73 Expiry
74
75 // Required http Client to use when connecting to MinIO STS service.
76 Client *http.Client
77
78 // MinIO endpoint to fetch STS credentials.
79 STSEndpoint string
80
81 // getClientGrantsTokenExpiry function to retrieve tokens
82 // from IDP This function should return two values one is
83 // accessToken which is a self contained access token (JWT)
84 // and second return value is the expiry associated with
85 // this token. This is a customer provided function and
86 // is mandatory.
87 GetClientGrantsTokenExpiry func() (*ClientGrantsToken, error)
88}
89
90// NewSTSClientGrants returns a pointer to a new
91// Credentials object wrapping the STSClientGrants.
92func NewSTSClientGrants(stsEndpoint string, getClientGrantsTokenExpiry func() (*ClientGrantsToken, error)) (*Credentials, error) {
93 if stsEndpoint == "" {
94 return nil, errors.New("STS endpoint cannot be empty")
95 }
96 if getClientGrantsTokenExpiry == nil {
97 return nil, errors.New("Client grants access token and expiry retrieval function should be defined")
98 }
99 return New(&STSClientGrants{
100 Client: &http.Client{
101 Transport: http.DefaultTransport,
102 },
103 STSEndpoint: stsEndpoint,
104 GetClientGrantsTokenExpiry: getClientGrantsTokenExpiry,
105 }), nil
106}
107
108func getClientGrantsCredentials(clnt *http.Client, endpoint string,
109 getClientGrantsTokenExpiry func() (*ClientGrantsToken, error),
110) (AssumeRoleWithClientGrantsResponse, error) {
111 accessToken, err := getClientGrantsTokenExpiry()
112 if err != nil {
113 return AssumeRoleWithClientGrantsResponse{}, err
114 }
115
116 v := url.Values{}
117 v.Set("Action", "AssumeRoleWithClientGrants")
118 v.Set("Token", accessToken.Token)
119 v.Set("DurationSeconds", fmt.Sprintf("%d", accessToken.Expiry))
120 v.Set("Version", STSVersion)
121
122 u, err := url.Parse(endpoint)
123 if err != nil {
124 return AssumeRoleWithClientGrantsResponse{}, err
125 }
126
127 req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(v.Encode()))
128 if err != nil {
129 return AssumeRoleWithClientGrantsResponse{}, err
130 }
131
132 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
133
134 resp, err := clnt.Do(req)
135 if err != nil {
136 return AssumeRoleWithClientGrantsResponse{}, err
137 }
138 defer resp.Body.Close()
139 if resp.StatusCode != http.StatusOK {
140 var errResp ErrorResponse
141 buf, err := io.ReadAll(resp.Body)
142 if err != nil {
143 return AssumeRoleWithClientGrantsResponse{}, err
144 }
145 _, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
146 if err != nil {
147 var s3Err Error
148 if _, err = xmlDecodeAndBody(bytes.NewReader(buf), &s3Err); err != nil {
149 return AssumeRoleWithClientGrantsResponse{}, err
150 }
151 errResp.RequestID = s3Err.RequestID
152 errResp.STSError.Code = s3Err.Code
153 errResp.STSError.Message = s3Err.Message
154 }
155 return AssumeRoleWithClientGrantsResponse{}, errResp
156 }
157
158 a := AssumeRoleWithClientGrantsResponse{}
159 if err = xml.NewDecoder(resp.Body).Decode(&a); err != nil {
160 return AssumeRoleWithClientGrantsResponse{}, err
161 }
162 return a, nil
163}
164
165// Retrieve retrieves credentials from the MinIO service.
166// Error will be returned if the request fails.
167func (m *STSClientGrants) Retrieve() (Value, error) {
168 a, err := getClientGrantsCredentials(m.Client, m.STSEndpoint, m.GetClientGrantsTokenExpiry)
169 if err != nil {
170 return Value{}, err
171 }
172
173 // Expiry window is set to 10secs.
174 m.SetExpiration(a.Result.Credentials.Expiration, DefaultExpiryWindow)
175
176 return Value{
177 AccessKeyID: a.Result.Credentials.AccessKey,
178 SecretAccessKey: a.Result.Credentials.SecretKey,
179 SessionToken: a.Result.Credentials.SessionToken,
180 SignerType: SignatureV4,
181 }, nil
182}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_custom_identity.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_custom_identity.go
new file mode 100644
index 0000000..e1f9ce4
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_custom_identity.go
@@ -0,0 +1,146 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2015-2022 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import (
21 "encoding/xml"
22 "errors"
23 "fmt"
24 "net/http"
25 "net/url"
26 "time"
27)
28
29// CustomTokenResult - Contains temporary creds and user metadata.
30type CustomTokenResult struct {
31 Credentials struct {
32 AccessKey string `xml:"AccessKeyId"`
33 SecretKey string `xml:"SecretAccessKey"`
34 Expiration time.Time `xml:"Expiration"`
35 SessionToken string `xml:"SessionToken"`
36 } `xml:",omitempty"`
37
38 AssumedUser string `xml:",omitempty"`
39}
40
41// AssumeRoleWithCustomTokenResponse contains the result of a successful
42// AssumeRoleWithCustomToken request.
43type AssumeRoleWithCustomTokenResponse struct {
44 XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleWithCustomTokenResponse" json:"-"`
45 Result CustomTokenResult `xml:"AssumeRoleWithCustomTokenResult"`
46 Metadata struct {
47 RequestID string `xml:"RequestId,omitempty"`
48 } `xml:"ResponseMetadata,omitempty"`
49}
50
51// CustomTokenIdentity - satisfies the Provider interface, and retrieves
52// credentials from MinIO using the AssumeRoleWithCustomToken STS API.
53type CustomTokenIdentity struct {
54 Expiry
55
56 Client *http.Client
57
58 // MinIO server STS endpoint to fetch STS credentials.
59 STSEndpoint string
60
61 // The custom token to use with the request.
62 Token string
63
64 // RoleArn associated with the identity
65 RoleArn string
66
67 // RequestedExpiry is to set the validity of the generated credentials
68 // (this value bounded by server).
69 RequestedExpiry time.Duration
70}
71
72// Retrieve - to satisfy Provider interface; fetches credentials from MinIO.
73func (c *CustomTokenIdentity) Retrieve() (value Value, err error) {
74 u, err := url.Parse(c.STSEndpoint)
75 if err != nil {
76 return value, err
77 }
78
79 v := url.Values{}
80 v.Set("Action", "AssumeRoleWithCustomToken")
81 v.Set("Version", STSVersion)
82 v.Set("RoleArn", c.RoleArn)
83 v.Set("Token", c.Token)
84 if c.RequestedExpiry != 0 {
85 v.Set("DurationSeconds", fmt.Sprintf("%d", int(c.RequestedExpiry.Seconds())))
86 }
87
88 u.RawQuery = v.Encode()
89
90 req, err := http.NewRequest(http.MethodPost, u.String(), nil)
91 if err != nil {
92 return value, err
93 }
94
95 resp, err := c.Client.Do(req)
96 if err != nil {
97 return value, err
98 }
99
100 defer resp.Body.Close()
101 if resp.StatusCode != http.StatusOK {
102 return value, errors.New(resp.Status)
103 }
104
105 r := AssumeRoleWithCustomTokenResponse{}
106 if err = xml.NewDecoder(resp.Body).Decode(&r); err != nil {
107 return
108 }
109
110 cr := r.Result.Credentials
111 c.SetExpiration(cr.Expiration, DefaultExpiryWindow)
112 return Value{
113 AccessKeyID: cr.AccessKey,
114 SecretAccessKey: cr.SecretKey,
115 SessionToken: cr.SessionToken,
116 SignerType: SignatureV4,
117 }, nil
118}
119
120// NewCustomTokenCredentials - returns credentials using the
121// AssumeRoleWithCustomToken STS API.
122func NewCustomTokenCredentials(stsEndpoint, token, roleArn string, optFuncs ...CustomTokenOpt) (*Credentials, error) {
123 c := CustomTokenIdentity{
124 Client: &http.Client{Transport: http.DefaultTransport},
125 STSEndpoint: stsEndpoint,
126 Token: token,
127 RoleArn: roleArn,
128 }
129 for _, optFunc := range optFuncs {
130 optFunc(&c)
131 }
132 return New(&c), nil
133}
134
135// CustomTokenOpt is a function type to configure the custom-token based
136// credentials using NewCustomTokenCredentials.
137type CustomTokenOpt func(*CustomTokenIdentity)
138
139// CustomTokenValidityOpt sets the validity duration of the requested
140// credentials. This value is ignored if the server enforces a lower validity
141// period.
142func CustomTokenValidityOpt(d time.Duration) CustomTokenOpt {
143 return func(c *CustomTokenIdentity) {
144 c.RequestedExpiry = d
145 }
146}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_ldap_identity.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_ldap_identity.go
new file mode 100644
index 0000000..ec5f3f0
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_ldap_identity.go
@@ -0,0 +1,189 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2019-2022 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import (
21 "bytes"
22 "encoding/xml"
23 "fmt"
24 "io"
25 "net/http"
26 "net/url"
27 "strings"
28 "time"
29)
30
31// AssumeRoleWithLDAPResponse contains the result of successful
32// AssumeRoleWithLDAPIdentity request
33type AssumeRoleWithLDAPResponse struct {
34 XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleWithLDAPIdentityResponse" json:"-"`
35 Result LDAPIdentityResult `xml:"AssumeRoleWithLDAPIdentityResult"`
36 ResponseMetadata struct {
37 RequestID string `xml:"RequestId,omitempty"`
38 } `xml:"ResponseMetadata,omitempty"`
39}
40
41// LDAPIdentityResult - contains credentials for a successful
42// AssumeRoleWithLDAPIdentity request.
43type LDAPIdentityResult struct {
44 Credentials struct {
45 AccessKey string `xml:"AccessKeyId" json:"accessKey,omitempty"`
46 SecretKey string `xml:"SecretAccessKey" json:"secretKey,omitempty"`
47 Expiration time.Time `xml:"Expiration" json:"expiration,omitempty"`
48 SessionToken string `xml:"SessionToken" json:"sessionToken,omitempty"`
49 } `xml:",omitempty"`
50
51 SubjectFromToken string `xml:",omitempty"`
52}
53
54// LDAPIdentity retrieves credentials from MinIO
55type LDAPIdentity struct {
56 Expiry
57
58 // Required http Client to use when connecting to MinIO STS service.
59 Client *http.Client
60
61 // Exported STS endpoint to fetch STS credentials.
62 STSEndpoint string
63
64 // LDAP username/password used to fetch LDAP STS credentials.
65 LDAPUsername, LDAPPassword string
66
67 // Session policy to apply to the generated credentials. Leave empty to
68 // use the full access policy available to the user.
69 Policy string
70
71 // RequestedExpiry is the configured expiry duration for credentials
72 // requested from LDAP.
73 RequestedExpiry time.Duration
74}
75
76// NewLDAPIdentity returns new credentials object that uses LDAP
77// Identity.
78func NewLDAPIdentity(stsEndpoint, ldapUsername, ldapPassword string, optFuncs ...LDAPIdentityOpt) (*Credentials, error) {
79 l := LDAPIdentity{
80 Client: &http.Client{Transport: http.DefaultTransport},
81 STSEndpoint: stsEndpoint,
82 LDAPUsername: ldapUsername,
83 LDAPPassword: ldapPassword,
84 }
85 for _, optFunc := range optFuncs {
86 optFunc(&l)
87 }
88 return New(&l), nil
89}
90
91// LDAPIdentityOpt is a function type used to configured the LDAPIdentity
92// instance.
93type LDAPIdentityOpt func(*LDAPIdentity)
94
95// LDAPIdentityPolicyOpt sets the session policy for requested credentials.
96func LDAPIdentityPolicyOpt(policy string) LDAPIdentityOpt {
97 return func(k *LDAPIdentity) {
98 k.Policy = policy
99 }
100}
101
102// LDAPIdentityExpiryOpt sets the expiry duration for requested credentials.
103func LDAPIdentityExpiryOpt(d time.Duration) LDAPIdentityOpt {
104 return func(k *LDAPIdentity) {
105 k.RequestedExpiry = d
106 }
107}
108
109// NewLDAPIdentityWithSessionPolicy returns new credentials object that uses
110// LDAP Identity with a specified session policy. The `policy` parameter must be
111// a JSON string specifying the policy document.
112//
113// Deprecated: Use the `LDAPIdentityPolicyOpt` with `NewLDAPIdentity` instead.
114func NewLDAPIdentityWithSessionPolicy(stsEndpoint, ldapUsername, ldapPassword, policy string) (*Credentials, error) {
115 return New(&LDAPIdentity{
116 Client: &http.Client{Transport: http.DefaultTransport},
117 STSEndpoint: stsEndpoint,
118 LDAPUsername: ldapUsername,
119 LDAPPassword: ldapPassword,
120 Policy: policy,
121 }), nil
122}
123
124// Retrieve gets the credential by calling the MinIO STS API for
125// LDAP on the configured stsEndpoint.
126func (k *LDAPIdentity) Retrieve() (value Value, err error) {
127 u, err := url.Parse(k.STSEndpoint)
128 if err != nil {
129 return value, err
130 }
131
132 v := url.Values{}
133 v.Set("Action", "AssumeRoleWithLDAPIdentity")
134 v.Set("Version", STSVersion)
135 v.Set("LDAPUsername", k.LDAPUsername)
136 v.Set("LDAPPassword", k.LDAPPassword)
137 if k.Policy != "" {
138 v.Set("Policy", k.Policy)
139 }
140 if k.RequestedExpiry != 0 {
141 v.Set("DurationSeconds", fmt.Sprintf("%d", int(k.RequestedExpiry.Seconds())))
142 }
143
144 req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(v.Encode()))
145 if err != nil {
146 return value, err
147 }
148
149 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
150
151 resp, err := k.Client.Do(req)
152 if err != nil {
153 return value, err
154 }
155
156 defer resp.Body.Close()
157 if resp.StatusCode != http.StatusOK {
158 var errResp ErrorResponse
159 buf, err := io.ReadAll(resp.Body)
160 if err != nil {
161 return value, err
162 }
163 _, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
164 if err != nil {
165 var s3Err Error
166 if _, err = xmlDecodeAndBody(bytes.NewReader(buf), &s3Err); err != nil {
167 return value, err
168 }
169 errResp.RequestID = s3Err.RequestID
170 errResp.STSError.Code = s3Err.Code
171 errResp.STSError.Message = s3Err.Message
172 }
173 return value, errResp
174 }
175
176 r := AssumeRoleWithLDAPResponse{}
177 if err = xml.NewDecoder(resp.Body).Decode(&r); err != nil {
178 return
179 }
180
181 cr := r.Result.Credentials
182 k.SetExpiration(cr.Expiration, DefaultExpiryWindow)
183 return Value{
184 AccessKeyID: cr.AccessKey,
185 SecretAccessKey: cr.SecretKey,
186 SessionToken: cr.SessionToken,
187 SignerType: SignatureV4,
188 }, nil
189}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_tls_identity.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_tls_identity.go
new file mode 100644
index 0000000..dee0a8c
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_tls_identity.go
@@ -0,0 +1,211 @@
1// MinIO Go Library for Amazon S3 Compatible Cloud Storage
2// Copyright 2021 MinIO, Inc.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16package credentials
17
18import (
19 "bytes"
20 "crypto/tls"
21 "encoding/xml"
22 "errors"
23 "io"
24 "net"
25 "net/http"
26 "net/url"
27 "strconv"
28 "time"
29)
30
31// CertificateIdentityOption is an optional AssumeRoleWithCertificate
32// parameter - e.g. a custom HTTP transport configuration or S3 credental
33// livetime.
34type CertificateIdentityOption func(*STSCertificateIdentity)
35
36// CertificateIdentityWithTransport returns a CertificateIdentityOption that
37// customizes the STSCertificateIdentity with the given http.RoundTripper.
38func CertificateIdentityWithTransport(t http.RoundTripper) CertificateIdentityOption {
39 return CertificateIdentityOption(func(i *STSCertificateIdentity) { i.Client.Transport = t })
40}
41
42// CertificateIdentityWithExpiry returns a CertificateIdentityOption that
43// customizes the STSCertificateIdentity with the given livetime.
44//
45// Fetched S3 credentials will have the given livetime if the STS server
46// allows such credentials.
47func CertificateIdentityWithExpiry(livetime time.Duration) CertificateIdentityOption {
48 return CertificateIdentityOption(func(i *STSCertificateIdentity) { i.S3CredentialLivetime = livetime })
49}
50
51// A STSCertificateIdentity retrieves S3 credentials from the MinIO STS API and
52// rotates those credentials once they expire.
53type STSCertificateIdentity struct {
54 Expiry
55
56 // STSEndpoint is the base URL endpoint of the STS API.
57 // For example, https://minio.local:9000
58 STSEndpoint string
59
60 // S3CredentialLivetime is the duration temp. S3 access
61 // credentials should be valid.
62 //
63 // It represents the access credential livetime requested
64 // by the client. The STS server may choose to issue
65 // temp. S3 credentials that have a different - usually
66 // shorter - livetime.
67 //
68 // The default livetime is one hour.
69 S3CredentialLivetime time.Duration
70
71 // Client is the HTTP client used to authenticate and fetch
72 // S3 credentials.
73 //
74 // A custom TLS client configuration can be specified by
75 // using a custom http.Transport:
76 // Client: http.Client {
77 // Transport: &http.Transport{
78 // TLSClientConfig: &tls.Config{},
79 // },
80 // }
81 Client http.Client
82}
83
84var _ Provider = (*STSWebIdentity)(nil) // compiler check
85
86// NewSTSCertificateIdentity returns a STSCertificateIdentity that authenticates
87// to the given STS endpoint with the given TLS certificate and retrieves and
88// rotates S3 credentials.
89func NewSTSCertificateIdentity(endpoint string, certificate tls.Certificate, options ...CertificateIdentityOption) (*Credentials, error) {
90 if endpoint == "" {
91 return nil, errors.New("STS endpoint cannot be empty")
92 }
93 if _, err := url.Parse(endpoint); err != nil {
94 return nil, err
95 }
96 identity := &STSCertificateIdentity{
97 STSEndpoint: endpoint,
98 Client: http.Client{
99 Transport: &http.Transport{
100 Proxy: http.ProxyFromEnvironment,
101 DialContext: (&net.Dialer{
102 Timeout: 30 * time.Second,
103 KeepAlive: 30 * time.Second,
104 }).DialContext,
105 ForceAttemptHTTP2: true,
106 MaxIdleConns: 100,
107 IdleConnTimeout: 90 * time.Second,
108 TLSHandshakeTimeout: 10 * time.Second,
109 ExpectContinueTimeout: 5 * time.Second,
110 TLSClientConfig: &tls.Config{
111 Certificates: []tls.Certificate{certificate},
112 },
113 },
114 },
115 }
116 for _, option := range options {
117 option(identity)
118 }
119 return New(identity), nil
120}
121
122// Retrieve fetches a new set of S3 credentials from the configured
123// STS API endpoint.
124func (i *STSCertificateIdentity) Retrieve() (Value, error) {
125 endpointURL, err := url.Parse(i.STSEndpoint)
126 if err != nil {
127 return Value{}, err
128 }
129 livetime := i.S3CredentialLivetime
130 if livetime == 0 {
131 livetime = 1 * time.Hour
132 }
133
134 queryValues := url.Values{}
135 queryValues.Set("Action", "AssumeRoleWithCertificate")
136 queryValues.Set("Version", STSVersion)
137 endpointURL.RawQuery = queryValues.Encode()
138
139 req, err := http.NewRequest(http.MethodPost, endpointURL.String(), nil)
140 if err != nil {
141 return Value{}, err
142 }
143 if req.Form == nil {
144 req.Form = url.Values{}
145 }
146 req.Form.Add("DurationSeconds", strconv.FormatUint(uint64(livetime.Seconds()), 10))
147
148 resp, err := i.Client.Do(req)
149 if err != nil {
150 return Value{}, err
151 }
152 if resp.Body != nil {
153 defer resp.Body.Close()
154 }
155 if resp.StatusCode != http.StatusOK {
156 var errResp ErrorResponse
157 buf, err := io.ReadAll(resp.Body)
158 if err != nil {
159 return Value{}, err
160 }
161 _, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
162 if err != nil {
163 var s3Err Error
164 if _, err = xmlDecodeAndBody(bytes.NewReader(buf), &s3Err); err != nil {
165 return Value{}, err
166 }
167 errResp.RequestID = s3Err.RequestID
168 errResp.STSError.Code = s3Err.Code
169 errResp.STSError.Message = s3Err.Message
170 }
171 return Value{}, errResp
172 }
173
174 const MaxSize = 10 * 1 << 20
175 var body io.Reader = resp.Body
176 if resp.ContentLength > 0 && resp.ContentLength < MaxSize {
177 body = io.LimitReader(body, resp.ContentLength)
178 } else {
179 body = io.LimitReader(body, MaxSize)
180 }
181
182 var response assumeRoleWithCertificateResponse
183 if err = xml.NewDecoder(body).Decode(&response); err != nil {
184 return Value{}, err
185 }
186 i.SetExpiration(response.Result.Credentials.Expiration, DefaultExpiryWindow)
187 return Value{
188 AccessKeyID: response.Result.Credentials.AccessKey,
189 SecretAccessKey: response.Result.Credentials.SecretKey,
190 SessionToken: response.Result.Credentials.SessionToken,
191 SignerType: SignatureDefault,
192 }, nil
193}
194
195// Expiration returns the expiration time of the current S3 credentials.
196func (i *STSCertificateIdentity) Expiration() time.Time { return i.expiration }
197
198type assumeRoleWithCertificateResponse struct {
199 XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleWithCertificateResponse" json:"-"`
200 Result struct {
201 Credentials struct {
202 AccessKey string `xml:"AccessKeyId" json:"accessKey,omitempty"`
203 SecretKey string `xml:"SecretAccessKey" json:"secretKey,omitempty"`
204 Expiration time.Time `xml:"Expiration" json:"expiration,omitempty"`
205 SessionToken string `xml:"SessionToken" json:"sessionToken,omitempty"`
206 } `xml:"Credentials" json:"credentials,omitempty"`
207 } `xml:"AssumeRoleWithCertificateResult"`
208 ResponseMetadata struct {
209 RequestID string `xml:"RequestId,omitempty"`
210 } `xml:"ResponseMetadata,omitempty"`
211}
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_web_identity.go b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_web_identity.go
new file mode 100644
index 0000000..2e2af50
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/credentials/sts_web_identity.go
@@ -0,0 +1,205 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2019-2022 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package credentials
19
20import (
21 "bytes"
22 "encoding/xml"
23 "errors"
24 "fmt"
25 "io"
26 "net/http"
27 "net/url"
28 "strconv"
29 "strings"
30 "time"
31)
32
33// AssumeRoleWithWebIdentityResponse contains the result of successful AssumeRoleWithWebIdentity request.
34type AssumeRoleWithWebIdentityResponse struct {
35 XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleWithWebIdentityResponse" json:"-"`
36 Result WebIdentityResult `xml:"AssumeRoleWithWebIdentityResult"`
37 ResponseMetadata struct {
38 RequestID string `xml:"RequestId,omitempty"`
39 } `xml:"ResponseMetadata,omitempty"`
40}
41
42// WebIdentityResult - Contains the response to a successful AssumeRoleWithWebIdentity
43// request, including temporary credentials that can be used to make MinIO API requests.
44type WebIdentityResult struct {
45 AssumedRoleUser AssumedRoleUser `xml:",omitempty"`
46 Audience string `xml:",omitempty"`
47 Credentials struct {
48 AccessKey string `xml:"AccessKeyId" json:"accessKey,omitempty"`
49 SecretKey string `xml:"SecretAccessKey" json:"secretKey,omitempty"`
50 Expiration time.Time `xml:"Expiration" json:"expiration,omitempty"`
51 SessionToken string `xml:"SessionToken" json:"sessionToken,omitempty"`
52 } `xml:",omitempty"`
53 PackedPolicySize int `xml:",omitempty"`
54 Provider string `xml:",omitempty"`
55 SubjectFromWebIdentityToken string `xml:",omitempty"`
56}
57
58// WebIdentityToken - web identity token with expiry.
59type WebIdentityToken struct {
60 Token string
61 AccessToken string
62 Expiry int
63}
64
65// A STSWebIdentity retrieves credentials from MinIO service, and keeps track if
66// those credentials are expired.
67type STSWebIdentity struct {
68 Expiry
69
70 // Required http Client to use when connecting to MinIO STS service.
71 Client *http.Client
72
73 // Exported STS endpoint to fetch STS credentials.
74 STSEndpoint string
75
76 // Exported GetWebIDTokenExpiry function which returns ID
77 // tokens from IDP. This function should return two values
78 // one is ID token which is a self contained ID token (JWT)
79 // and second return value is the expiry associated with
80 // this token.
81 // This is a customer provided function and is mandatory.
82 GetWebIDTokenExpiry func() (*WebIdentityToken, error)
83
84 // RoleARN is the Amazon Resource Name (ARN) of the role that the caller is
85 // assuming.
86 RoleARN string
87
88 // roleSessionName is the identifier for the assumed role session.
89 roleSessionName string
90}
91
92// NewSTSWebIdentity returns a pointer to a new
93// Credentials object wrapping the STSWebIdentity.
94func NewSTSWebIdentity(stsEndpoint string, getWebIDTokenExpiry func() (*WebIdentityToken, error)) (*Credentials, error) {
95 if stsEndpoint == "" {
96 return nil, errors.New("STS endpoint cannot be empty")
97 }
98 if getWebIDTokenExpiry == nil {
99 return nil, errors.New("Web ID token and expiry retrieval function should be defined")
100 }
101 return New(&STSWebIdentity{
102 Client: &http.Client{
103 Transport: http.DefaultTransport,
104 },
105 STSEndpoint: stsEndpoint,
106 GetWebIDTokenExpiry: getWebIDTokenExpiry,
107 }), nil
108}
109
110func getWebIdentityCredentials(clnt *http.Client, endpoint, roleARN, roleSessionName string,
111 getWebIDTokenExpiry func() (*WebIdentityToken, error),
112) (AssumeRoleWithWebIdentityResponse, error) {
113 idToken, err := getWebIDTokenExpiry()
114 if err != nil {
115 return AssumeRoleWithWebIdentityResponse{}, err
116 }
117
118 v := url.Values{}
119 v.Set("Action", "AssumeRoleWithWebIdentity")
120 if len(roleARN) > 0 {
121 v.Set("RoleArn", roleARN)
122
123 if len(roleSessionName) == 0 {
124 roleSessionName = strconv.FormatInt(time.Now().UnixNano(), 10)
125 }
126 v.Set("RoleSessionName", roleSessionName)
127 }
128 v.Set("WebIdentityToken", idToken.Token)
129 if idToken.AccessToken != "" {
130 // Usually set when server is using extended userInfo endpoint.
131 v.Set("WebIdentityAccessToken", idToken.AccessToken)
132 }
133 if idToken.Expiry > 0 {
134 v.Set("DurationSeconds", fmt.Sprintf("%d", idToken.Expiry))
135 }
136 v.Set("Version", STSVersion)
137
138 u, err := url.Parse(endpoint)
139 if err != nil {
140 return AssumeRoleWithWebIdentityResponse{}, err
141 }
142
143 req, err := http.NewRequest(http.MethodPost, u.String(), strings.NewReader(v.Encode()))
144 if err != nil {
145 return AssumeRoleWithWebIdentityResponse{}, err
146 }
147
148 req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
149
150 resp, err := clnt.Do(req)
151 if err != nil {
152 return AssumeRoleWithWebIdentityResponse{}, err
153 }
154
155 defer resp.Body.Close()
156 if resp.StatusCode != http.StatusOK {
157 var errResp ErrorResponse
158 buf, err := io.ReadAll(resp.Body)
159 if err != nil {
160 return AssumeRoleWithWebIdentityResponse{}, err
161 }
162 _, err = xmlDecodeAndBody(bytes.NewReader(buf), &errResp)
163 if err != nil {
164 var s3Err Error
165 if _, err = xmlDecodeAndBody(bytes.NewReader(buf), &s3Err); err != nil {
166 return AssumeRoleWithWebIdentityResponse{}, err
167 }
168 errResp.RequestID = s3Err.RequestID
169 errResp.STSError.Code = s3Err.Code
170 errResp.STSError.Message = s3Err.Message
171 }
172 return AssumeRoleWithWebIdentityResponse{}, errResp
173 }
174
175 a := AssumeRoleWithWebIdentityResponse{}
176 if err = xml.NewDecoder(resp.Body).Decode(&a); err != nil {
177 return AssumeRoleWithWebIdentityResponse{}, err
178 }
179
180 return a, nil
181}
182
183// Retrieve retrieves credentials from the MinIO service.
184// Error will be returned if the request fails.
185func (m *STSWebIdentity) Retrieve() (Value, error) {
186 a, err := getWebIdentityCredentials(m.Client, m.STSEndpoint, m.RoleARN, m.roleSessionName, m.GetWebIDTokenExpiry)
187 if err != nil {
188 return Value{}, err
189 }
190
191 // Expiry window is set to 10secs.
192 m.SetExpiration(a.Result.Credentials.Expiration, DefaultExpiryWindow)
193
194 return Value{
195 AccessKeyID: a.Result.Credentials.AccessKey,
196 SecretAccessKey: a.Result.Credentials.SecretKey,
197 SessionToken: a.Result.Credentials.SessionToken,
198 SignerType: SignatureV4,
199 }, nil
200}
201
202// Expiration returns the expiration time of the credentials
203func (m *STSWebIdentity) Expiration() time.Time {
204 return m.expiration
205}