summaryrefslogtreecommitdiff
path: root/pkg/credentials/sts_client_grants.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/credentials/sts_client_grants.go')
-rw-r--r--pkg/credentials/sts_client_grants.go162
1 files changed, 162 insertions, 0 deletions
diff --git a/pkg/credentials/sts_client_grants.go b/pkg/credentials/sts_client_grants.go
new file mode 100644
index 0000000..03134c3
--- /dev/null
+++ b/pkg/credentials/sts_client_grants.go
@@ -0,0 +1,162 @@
+/*
+ * MinIO Go Library for Amazon S3 Compatible Cloud Storage
+ * Copyright 2019 MinIO, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package credentials
+
+import (
+ "encoding/xml"
+ "errors"
+ "fmt"
+ "net/http"
+ "net/url"
+ "time"
+)
+
+// AssumedRoleUser - The identifiers for the temporary security credentials that
+// the operation returns. Please also see https://docs.aws.amazon.com/goto/WebAPI/sts-2011-06-15/AssumedRoleUser
+type AssumedRoleUser struct {
+ Arn string
+ AssumedRoleID string `xml:"AssumeRoleId"`
+}
+
+// AssumeRoleWithClientGrantsResponse contains the result of successful AssumeRoleWithClientGrants request.
+type AssumeRoleWithClientGrantsResponse struct {
+ XMLName xml.Name `xml:"https://sts.amazonaws.com/doc/2011-06-15/ AssumeRoleWithClientGrantsResponse" json:"-"`
+ Result ClientGrantsResult `xml:"AssumeRoleWithClientGrantsResult"`
+ ResponseMetadata struct {
+ RequestID string `xml:"RequestId,omitempty"`
+ } `xml:"ResponseMetadata,omitempty"`
+}
+
+// ClientGrantsResult - Contains the response to a successful AssumeRoleWithClientGrants
+// request, including temporary credentials that can be used to make MinIO API requests.
+type ClientGrantsResult struct {
+ AssumedRoleUser AssumedRoleUser `xml:",omitempty"`
+ Audience string `xml:",omitempty"`
+ Credentials struct {
+ AccessKey string `xml:"AccessKeyId" json:"accessKey,omitempty"`
+ SecretKey string `xml:"SecretAccessKey" json:"secretKey,omitempty"`
+ Expiration time.Time `xml:"Expiration" json:"expiration,omitempty"`
+ SessionToken string `xml:"SessionToken" json:"sessionToken,omitempty"`
+ } `xml:",omitempty"`
+ PackedPolicySize int `xml:",omitempty"`
+ Provider string `xml:",omitempty"`
+ SubjectFromClientGrantsToken string `xml:",omitempty"`
+}
+
+// ClientGrantsToken - client grants token with expiry.
+type ClientGrantsToken struct {
+ Token string
+ Expiry int
+}
+
+// A STSClientGrants retrieves credentials from MinIO service, and keeps track if
+// those credentials are expired.
+type STSClientGrants struct {
+ Expiry
+
+ // Required http Client to use when connecting to MinIO STS service.
+ Client *http.Client
+
+ // MinIO endpoint to fetch STS credentials.
+ stsEndpoint string
+
+ // getClientGrantsTokenExpiry function to retrieve tokens
+ // from IDP This function should return two values one is
+ // accessToken which is a self contained access token (JWT)
+ // and second return value is the expiry associated with
+ // this token. This is a customer provided function and
+ // is mandatory.
+ getClientGrantsTokenExpiry func() (*ClientGrantsToken, error)
+}
+
+// NewSTSClientGrants returns a pointer to a new
+// Credentials object wrapping the STSClientGrants.
+func NewSTSClientGrants(stsEndpoint string, getClientGrantsTokenExpiry func() (*ClientGrantsToken, error)) (*Credentials, error) {
+ if stsEndpoint == "" {
+ return nil, errors.New("STS endpoint cannot be empty")
+ }
+ if getClientGrantsTokenExpiry == nil {
+ return nil, errors.New("Client grants access token and expiry retrieval function should be defined")
+ }
+ return New(&STSClientGrants{
+ Client: &http.Client{
+ Transport: http.DefaultTransport,
+ },
+ stsEndpoint: stsEndpoint,
+ getClientGrantsTokenExpiry: getClientGrantsTokenExpiry,
+ }), nil
+}
+
+func getClientGrantsCredentials(clnt *http.Client, endpoint string,
+ getClientGrantsTokenExpiry func() (*ClientGrantsToken, error)) (AssumeRoleWithClientGrantsResponse, error) {
+
+ accessToken, err := getClientGrantsTokenExpiry()
+ if err != nil {
+ return AssumeRoleWithClientGrantsResponse{}, err
+ }
+
+ v := url.Values{}
+ v.Set("Action", "AssumeRoleWithClientGrants")
+ v.Set("Token", accessToken.Token)
+ v.Set("DurationSeconds", fmt.Sprintf("%d", accessToken.Expiry))
+ v.Set("Version", "2011-06-15")
+
+ u, err := url.Parse(endpoint)
+ if err != nil {
+ return AssumeRoleWithClientGrantsResponse{}, err
+ }
+ u.RawQuery = v.Encode()
+
+ req, err := http.NewRequest("POST", u.String(), nil)
+ if err != nil {
+ return AssumeRoleWithClientGrantsResponse{}, err
+ }
+ resp, err := clnt.Do(req)
+ if err != nil {
+ return AssumeRoleWithClientGrantsResponse{}, err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ return AssumeRoleWithClientGrantsResponse{}, errors.New(resp.Status)
+ }
+
+ a := AssumeRoleWithClientGrantsResponse{}
+ if err = xml.NewDecoder(resp.Body).Decode(&a); err != nil {
+ return AssumeRoleWithClientGrantsResponse{}, err
+ }
+ return a, nil
+}
+
+// Retrieve retrieves credentials from the MinIO service.
+// Error will be returned if the request fails.
+func (m *STSClientGrants) Retrieve() (Value, error) {
+ a, err := getClientGrantsCredentials(m.Client, m.stsEndpoint, m.getClientGrantsTokenExpiry)
+ if err != nil {
+ return Value{}, err
+ }
+
+ // Expiry window is set to 10secs.
+ m.SetExpiration(a.Result.Credentials.Expiration, DefaultExpiryWindow)
+
+ return Value{
+ AccessKeyID: a.Result.Credentials.AccessKey,
+ SecretAccessKey: a.Result.Credentials.SecretKey,
+ SessionToken: a.Result.Credentials.SessionToken,
+ SignerType: SignatureV4,
+ }, nil
+}