Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

aws/credential: Added credential_process provider #1874

Closed
wants to merge 1 commit into from

Conversation

micahhausler
Copy link
Member

Adds support for calling credential_process like the aws cli.

I can add more to the docs once the design/implementation is cleared. Let me know if you want more tests on some of the failure cases.

Fixes #1834

ping @jasdel @kyleknap

@jasdel jasdel self-assigned this Apr 2, 2018
@jasdel jasdel requested review from jasdel and xibz and removed request for jasdel April 2, 2018 17:25
@jasdel
Copy link
Contributor

jasdel commented Apr 2, 2018

Thanks for creating this PR @micahhausler. We'll review this and get back to you with feedback.

Initially my feedback is that the ProcessProvider's reading of the configuration file duplicates the logic in the session package's sharedConfig type. I don't think we want this file to be read multiple times. I think if we were going to add this feature, the session.sharedConfig and co types should be exported (probably to an external package similar to v2) instead of duplicating the logic. This was done for the V2 SDK's refactor of configuration loading specifically for this reason.

In addition, I think we'd want to remove the auto loading of configuration file from the ProcessProvider, requiring the command to be set when the ProcessProvider was created. With this the ProcessProvider's role would be limited to executing the command and reading its input. The ProcessProvider wouldn't need to reach out to the configuration file directly. If a user wants to use the ProcessProvider outside of the default credential chain (i.e. session.NewSession) they would be able to use the would-be exported SharedConfig type to read the credentials file, and pass the command to execute to the ProcessProvider.

Session's configuration currently reads the configuration file's contents and determines which credential provider to use based on configuration of the Session's Options and content of the configuration file. The defaults.CredChain only really exists for backwards compatibility for users if they want to original features, but it is not used by the SDK.

@jmassara
Copy link
Contributor

jmassara commented Jul 2, 2018

Would love to see this integrated.

@jasdel jasdel added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Jul 5, 2018
@lorengordon
Copy link

@micahhausler @jasdel Any updates on this feature?

@tahoward
Copy link

Would also like to see this implemented. We have a use case with aws-iam-authenticator with K8 and Okta.

@xibz
Copy link
Contributor

xibz commented Sep 10, 2018

Hello @tahoward, thank you for posting your interesting on this feature. Out of curiosity what is the use case? I'm a little concerned for allowing reading of a file to fork and run a process. Sends a lot of red flags towards my way when I hear that.

@tahoward
Copy link

Hello @xibz we assume roles in AWS with SAML in order to access EKS clusters as we would like to keep access control bound to our domain. ATM we run an okta client CLI command and export AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN before executing kubectl with a config utilizing aws-iam-authenticator. While this works OK saving okta client commands as native AWS credential profiles is lost. This also requires us to run the okta client command independently of our kubectl commands to ensure the session is still current. Preferably, aws-sdk-go would interpret an AWS credential profile utilizing credential_process in the same manner as botocore.

It would also be great to see this implemented just for the sake of consistency when it comes to interpreting profile configurations in ~/.aws/credentials.

Copy link
Contributor

@jasdel jasdel left a comment

Choose a reason for hiding this comment

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

Thanks for taking the time and effort to create this PR. We do have concerns about enabling this feature by default. Specifically the case where a file added to an executable would cause a user's application to execute arbitrary commands.

@@ -9,3 +9,4 @@ awstesting/integration/smoke/_test/
/vendor/pkg/
/vendor/src/
/private/model/cli/gen-api/gen-api
.*.swp
Copy link
Contributor

Choose a reason for hiding this comment

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

nit this file probably shouldn't change

@@ -0,0 +1,228 @@
package credentials
Copy link
Contributor

Choose a reason for hiding this comment

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

would you mind moving the process_provider.go and _test files to a processcreds package. Having the credential provider in their own package allow them to depend on the aws package if needed. the credentials package cannot use the aws package since aws imports `credentials.

func (p *ProcessProvider) loadProfile(filename, profile string) (Value, error) {
config, err := ini.Load(filename)
if err != nil {
return Value{ProviderName: ProcessProviderName}, awserr.New("ProcessProviderLoad", "failed to load shared config file", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

For these error messages could you please create consts to make comparing against them easier.

e.g:

const (
     ErrCodeProcessProviderLoad = `ProcessProviderLoad`
)

return Value{ProviderName: ProcessProviderName}, err
}

creds, err := p.loadProfile(filename, p.profile())
Copy link
Contributor

Choose a reason for hiding this comment

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

Loading the shared config file each time the credentials are retrieved have issues that I don't think is good for the SDK to perform. per #1993

// file, and returns the credentials retrieved. An error will be returned if it
// fails to read from the file, or the data is invalid.
func (p *ProcessProvider) loadProfile(filename, profile string) (Value, error) {
config, err := ini.Load(filename)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we need to look at exporting aws/session/shard_config.go or at least put it under the SDK's root internal package so it can be reused by the process provider. There are modifications to the shared config logic that will be important for this utility.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think ideally the ProcessProvider doesn't need to read/load the shared config file at all. The loading of the contents of the shared config's credential_process value should be passed in via an input parameter. Similar to the stscreds's credential provider.

If the shared_config.go logic is exported it would make it easier for the ProcessProvider to have access to the credential_provider value.

}

// Handle expiration
if len(resp.Expiration) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Using a pointer for resp.Expiration would simplify receiving the time value. This is done for the SDK's endpoint credential provider

// filename returns the filename to use to read AWS shared credentials.
//
// Will return an error if the user's home directory path cannot be found.
func (p *ProcessProvider) filename() (string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This information should come from the SDK's session similar to stscreds There are several locations, and various env var names that can drive the config file to load within the SDK. Having loading the shared config file utility do this work, will help reduce duplication.

p.Profile = os.Getenv("AWS_PROFILE")
}
if p.Profile == "" {
p.Profile = os.Getenv("AWS_DEFAULT_PROFILE")
Copy link
Contributor

Choose a reason for hiding this comment

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

The SDK does not use the AWS_DEFAULT_PROFILE by default. this was a purely CLI environment variable that still exists for backwards compatibility. The SDK's session and env_config. go provides the logic to determine which environment variable to use.

"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
Copy link
Contributor

Choose a reason for hiding this comment

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

The SDK is looking to move away from testify and use pure go testing. It would be great to the pure go testing package for these tests.

@@ -55,6 +58,9 @@ type sharedConfig struct {
AssumeRole assumeRoleConfig
AssumeRoleSource *sharedConfig

// An external process to request credentials
CredentialProcess string
Copy link
Contributor

Choose a reason for hiding this comment

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

The sharedConfig utility is the utility that should be solely responsible for loading the shared config file.

@lorengordon
Copy link

@micahhausler Are you still working in this one? Would love to see this implemented!

@YakDriver
Copy link
Contributor

Please see PR #2217 where I have addressed each of @jasdel 's review points on top of this original PR.

@jasdel
Copy link
Contributor

jasdel commented Oct 30, 2018

Thanks for taking the time to create this PR @micahhausler. Since we have two PRs for similar features. I think we should consolidate, and continue this discussion on #2217.

@jasdel jasdel closed this Oct 30, 2018
@jasdel jasdel added duplicate This issue is a duplicate. and removed review-needed labels Oct 30, 2018
@diehlaws diehlaws removed the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Nov 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue is a duplicate.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Support for Sourcing Credentials From External Processes
8 participants