Skip to content

Add IAM Auth Method#12583

Merged
pglass merged 10 commits into
mainfrom
pglass/iam-auth-method
Mar 31, 2022
Merged

Add IAM Auth Method#12583
pglass merged 10 commits into
mainfrom
pglass/iam-auth-method

Conversation

@pglass
Copy link
Copy Markdown

@pglass pglass commented Mar 21, 2022

This adds an IAM auth method to Consul to support logging in with AWS IAM identities.

Overview

This PR uses a similar approach as the Vault IAM auth method. Vault's login token format is used here, but with a unique change to avoid the need for config the auth method with AWS credentials.

The "bearer token" contains one or two signed AWS API requests, which are JSON encoded.

  1. A client-signed sts:GetCallerIdentity request (same as Vault).
    • This is generated by consul login -aws-auto-bearer-token ....
    • The auth method must be configured with EnableIAMEntityDetails=false
  2. A client-signed sts:GetCallerIdentity request, with a signed iam:GetRole or iam:GetUser request embedded in headers (unique to Consul).
    • This is generated by consul login -aws-auto-bearer-token -aws-include-entity ...
    • The auth method must be configured with EnableIAMEntityDetails=true

Because the requests are signed with the client credentials, the IAM auth method does not need to be configured with its own AWS credentials.

Code

  • command/login/* - updates consul login with additional flags to support logging into the AWS auth method
    • This calls GenerateLoginData() in the internal iamauth package to do the work of generating the bearer token
    • Then, the existing logic is used to login with the bearer token
  • agent/consul/authmethod/awsauth/* - implements the auth method
    • This implements the existing authmethod.Validator interface
    • This calls ValidateLogin() in the internal iamauth package to do the work of validating the identity of a client attempting to login
  • internal/iamauth/* - an internal package which implements the core logic. This is a mix of new code and code borrowed/modified from the Vault IAM auth method
    • Authenticator.ValidateLogin() validates a client's identity to determine if they are permitted to login
    • The BearerToken type parses the login token and does some validation of the token
    • The GenerateLoginData function is used to generate the login data that forms the bearer token, which involves formatting signed AWS API requests

Usage

Configuring the auth method (example):

consul acl auth-method create -type aws-iam \
  -name <name> \
  -config='{
    "BoundIAMPrincipalARNs": [],
    "EnableIAMEntityDetails": false,
    "IAMEntityTags": []
    "MaxRetries": -1,
    "IAMEndpoint": "",
    "STSEndpoint": "",
    "STSRegion": "",
    "ServerIDHeaderValue": "",
    "AllowedSTSHeaderValues": [],
}'

Login

consul login -type aws-iam -method <name> -aws-auto-bearer-token -token-sink-file token.txt

@pglass pglass requested review from a team, erichaberkorn and rboyer and removed request for a team March 21, 2022 19:13
@github-actions github-actions Bot added pr/dependencies PR specifically updates dependencies of project theme/cli Flags and documentation for the CLI interface labels Mar 21, 2022
Comment thread go.sum Outdated
@rboyer
Copy link
Copy Markdown
Member

rboyer commented Mar 21, 2022

Probably good to in the PR somewhere and likely also in a comment in one of the packages indicating which version/sha of various vault libraries the various AWS bits were lifted from. That way there's a paper trail to figure out which possible future patches on the vault side need to be re-replicated here.

Comment thread internal/iamauth/auth.go Outdated
Comment thread command/login/login.go Outdated
Comment thread command/login/aws.go
creds = sess.Config.Credentials
}

loginData, err := iamauth.GenerateLoginData(&iamauth.LoginInput{
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Vault calls into a GenerateLoginData function, which I didn't end up re-using because (1) it doesn't support encoding the "get entity" request (GetRole or GetUser) in the login data, which is unique to the Consul implementation, and (2) there's a hardcoded vault server id header name, which is also why there are a bunch of header names passed into GenerateLoginData here, so that we're using X-Consul* header names.

Comment thread command/login/aws.go Outdated
)
} else {
// Session loads creds from standard sources (env vars, file, EC2 metadata, ...)
sess, err := session.NewSessionWithOptions(session.Options{Config: cfg})
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This relies the AWS SDK's standard credential chain, whereas Vault credential discovery calls into GenerateCredentialChain, which does some custom things. I haven't deeply compared these. Probably, there's a good reason for what Vault does, and we should adopt their implementation, which I can do now or in a follow up.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It might be worth figuring out what value GenerateCredentialChain is bringing and erring on the side of using it over not.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I've dug through the credential loading a good bit in the past couple days. I time boxed this, but there's nothing I've found that Vault supports in its custom credential chain that the SDK doesn't also support out of the box.

Users have also noticed differences between Vault's credential chain and the SDK, and Vault has generally moved toward matching the SDK behavior where possible (such as: hashicorp/vault#7738 and hashicorp/vault#13807).

So I think we should rely on the SDK's credential discovery in favor of being more standardized.

Comment thread internal/iamauth/auth.go Outdated
Comment thread internal/iamauth/auth.go
return identityDetails, nil
}

// https://github.com/hashicorp/vault/blob/ba533d006f2244103648785ebfe8a9a9763d2b6e/builtin/credential/aws/path_login.go#L1321-L1361
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I referenced the corresponding Vault code, but this is simpler since it doesn't support the unique role/user id check.

Note: I kept the links to Vault code for comparison during this initial code review, but I'm planning on removing those from the source code. I'll add permalinks to the Vault source in the README for this internal module instead.

Comment thread internal/iamauth/responses/arn.go
Comment thread internal/iamauth/token.go Outdated
Comment thread internal/iamauth/token.go Outdated
Comment thread internal/iamauth/util.go Outdated
Comment thread internal/iamauth/util.go
// For backwards compatibility, even if you request a region other than us-east-1, it'll still sign for us-east-1.
// See, e.g., https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html#id_credentials_temp_enable-regions_writing_code
// So we have to shim in this EndpointResolver to force it to sign for the right region
func stsSigningResolver(service, region string, optFns ...func(*endpoints.Options)) (endpoints.ResolvedEndpoint, error) {
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

TODO: Figure out if the STSRegionalEndpoint config option takes care of this for us.

Comment thread internal/iamauth/token.go
@vercel vercel Bot temporarily deployed to Preview – consul March 22, 2022 23:51 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul-ui-staging March 22, 2022 23:51 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul-ui-staging March 22, 2022 23:54 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul March 22, 2022 23:54 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul-ui-staging March 23, 2022 21:10 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul March 23, 2022 21:10 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul March 23, 2022 21:25 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul-ui-staging March 23, 2022 21:25 Inactive
@pglass pglass requested a review from rboyer March 23, 2022 21:34
Comment thread .changelog/12583.txt Outdated
Comment thread command/login/login_test.go Outdated
Comment thread command/login/aws.go

// ServerIDHeaderValue adds a X-Consul-IAM-ServerID header to each AWS API request.
// This helps protect against replay attacks.
ServerIDHeaderValue string `json:",omitempty"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Might want to carry more detail over from the vault equivalent field, or do so on the website pages describing this field: https://www.vaultproject.io/api-docs/auth/aws#iam_server_id_header_value

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yeah, I'll detail this in the docs on consul.io.

@pglass pglass force-pushed the pglass/iam-auth-method branch from c6febdc to 495d3b6 Compare March 25, 2022 20:47
@vercel vercel Bot temporarily deployed to Preview – consul March 25, 2022 20:47 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul-ui-staging March 25, 2022 20:47 Inactive
@rboyer rboyer added this to the 1.12.0-beta1 milestone Mar 30, 2022
Co-authored-by: R.B. Boyer <4903+rboyer@users.noreply.github.com>
@vercel vercel Bot temporarily deployed to Preview – consul-ui-staging March 30, 2022 16:56 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul March 30, 2022 16:56 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul March 30, 2022 18:01 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul-ui-staging March 30, 2022 18:01 Inactive
@pglass
Copy link
Copy Markdown
Author

pglass commented Mar 30, 2022

Created the following couple of issues to follow up on before 1.12 GA:

Comment thread internal/iamauth/auth.go Outdated
@vercel vercel Bot temporarily deployed to Preview – consul March 30, 2022 21:53 Inactive
@vercel vercel Bot temporarily deployed to Preview – consul-ui-staging March 30, 2022 21:53 Inactive
@pglass pglass merged commit 706c844 into main Mar 31, 2022
@pglass pglass deleted the pglass/iam-auth-method branch March 31, 2022 15:18
@hc-github-team-consul-core
Copy link
Copy Markdown
Collaborator

🍒 If backport labels were added before merging, cherry-picking will start automatically.

To retroactively trigger a backport after merging, add backport labels and re-run https://circleci.com/gh/hashicorp/consul/619124.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr/dependencies PR specifically updates dependencies of project pr/no-metrics-test theme/cli Flags and documentation for the CLI interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants