2023-03-15 16:00:52 +00:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
2015-03-20 16:59:48 +00:00
package aws
import (
2018-01-19 06:44:44 +00:00
"context"
2015-04-19 05:13:12 +00:00
"fmt"
2015-03-20 16:59:48 +00:00
"log"
2018-09-18 20:26:06 +00:00
"net/http"
2015-03-20 16:59:48 +00:00
"os"
2018-08-16 10:38:13 +00:00
"reflect"
2019-03-31 13:10:17 +00:00
"strings"
2018-09-26 00:10:53 +00:00
"sync"
2015-03-20 16:59:48 +00:00
"testing"
"time"
2022-11-17 18:55:27 +00:00
"github.com/aws/aws-sdk-go-v2/config"
2015-08-06 16:26:41 +00:00
"github.com/aws/aws-sdk-go/aws"
2018-08-16 10:38:13 +00:00
"github.com/aws/aws-sdk-go/aws/awserr"
2015-08-06 16:37:08 +00:00
"github.com/aws/aws-sdk-go/aws/credentials"
2023-03-23 17:02:24 +00:00
"github.com/aws/aws-sdk-go/aws/request"
2015-10-30 22:22:48 +00:00
"github.com/aws/aws-sdk-go/aws/session"
2018-08-16 10:38:13 +00:00
"github.com/aws/aws-sdk-go/service/dynamodb"
2015-08-06 16:26:41 +00:00
"github.com/aws/aws-sdk-go/service/ec2"
2016-04-12 02:30:30 +00:00
"github.com/aws/aws-sdk-go/service/iam"
2018-09-18 20:26:06 +00:00
"github.com/aws/aws-sdk-go/service/iam/iamiface"
2020-06-09 23:56:12 +00:00
"github.com/aws/aws-sdk-go/service/s3"
2018-03-13 14:35:10 +00:00
"github.com/aws/aws-sdk-go/service/sts"
2019-01-09 00:48:57 +00:00
cleanhttp "github.com/hashicorp/go-cleanhttp"
2018-09-26 00:10:53 +00:00
"github.com/hashicorp/vault/helper/testhelpers"
2019-04-12 21:54:35 +00:00
logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical"
2019-04-13 07:44:06 +00:00
"github.com/hashicorp/vault/sdk/logical"
2015-03-20 16:59:48 +00:00
"github.com/mitchellh/mapstructure"
)
2018-09-26 00:10:53 +00:00
var initSetup sync . Once
2018-09-18 20:26:06 +00:00
type mockIAMClient struct {
iamiface . IAMAPI
}
2023-03-23 17:02:24 +00:00
func ( m * mockIAMClient ) CreateUserWithContext ( _ aws . Context , input * iam . CreateUserInput , _ ... request . Option ) ( * iam . CreateUserOutput , error ) {
2018-09-18 20:26:06 +00:00
return nil , awserr . New ( "Throttling" , "" , nil )
}
2015-12-01 05:05:04 +00:00
func getBackend ( t * testing . T ) logical . Backend {
2018-01-19 06:44:44 +00:00
be , _ := Factory ( context . Background ( ) , logical . TestBackendConfig ( ) )
2015-12-01 05:05:04 +00:00
return be
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_basic ( t * testing . T ) {
2018-09-26 00:10:53 +00:00
t . Parallel ( )
2015-03-20 16:59:48 +00:00
logicaltest . Test ( t , logicaltest . TestCase {
2016-04-05 19:10:44 +00:00
AcceptanceTest : true ,
PreCheck : func ( ) { testAccPreCheck ( t ) } ,
2018-11-07 01:21:24 +00:00
LogicalBackend : getBackend ( t ) ,
2015-03-20 16:59:48 +00:00
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
2018-08-16 10:38:13 +00:00
testAccStepWritePolicy ( t , "test" , testDynamoPolicy ) ,
testAccStepRead ( t , "creds" , "test" , [ ] credentialTestFunc { listDynamoTablesTest } ) ,
2015-03-20 16:59:48 +00:00
} ,
} )
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_IamUserWithPermissionsBoundary ( t * testing . T ) {
2019-09-19 23:35:12 +00:00
t . Parallel ( )
roleData := map [ string ] interface { } {
"credential_type" : iamUserCred ,
"policy_arns" : adminAccessPolicyArn ,
"permissions_boundary_arn" : iamPolicyArn ,
}
logicaltest . Test ( t , logicaltest . TestCase {
AcceptanceTest : true ,
PreCheck : func ( ) { testAccPreCheck ( t ) } ,
LogicalBackend : getBackend ( t ) ,
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
testAccStepWriteRole ( t , "test" , roleData ) ,
testAccStepRead ( t , "creds" , "test" , [ ] credentialTestFunc { listIamUsersTest , describeAzsTestUnauthorized } ) ,
} ,
} )
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_basicSTS ( t * testing . T ) {
2018-09-26 00:10:53 +00:00
t . Parallel ( )
awsAccountID , err := getAccountID ( )
if err != nil {
t . Logf ( "Unable to retrive user via sts:GetCallerIdentity: %#v" , err )
t . Skip ( "Could not determine AWS account ID from sts:GetCallerIdentity for acceptance tests, skipping" )
}
2021-11-30 00:00:42 +00:00
roleName := generateUniqueRoleName ( t . Name ( ) )
userName := generateUniqueUserName ( t . Name ( ) )
2018-03-13 14:35:10 +00:00
accessKey := & awsAccessKey { }
2016-01-08 22:19:53 +00:00
logicaltest . Test ( t , logicaltest . TestCase {
2016-04-05 19:10:44 +00:00
AcceptanceTest : true ,
2016-04-12 02:30:30 +00:00
PreCheck : func ( ) {
testAccPreCheck ( t )
2018-09-26 00:10:53 +00:00
createUser ( t , userName , accessKey )
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
createRole ( t , roleName , awsAccountID , [ ] string { ec2PolicyArn } )
2018-03-13 14:35:10 +00:00
// Sleep sometime because AWS is eventually consistent
// Both the createUser and createRole depend on this
log . Println ( "[WARN] Sleeping for 10 seconds waiting for AWS..." )
time . Sleep ( 10 * time . Second )
2016-04-12 02:30:30 +00:00
} ,
2018-11-07 01:21:24 +00:00
LogicalBackend : getBackend ( t ) ,
2016-01-08 22:19:53 +00:00
Steps : [ ] logicaltest . TestStep {
2018-03-13 14:35:10 +00:00
testAccStepConfigWithCreds ( t , accessKey ) ,
2018-09-26 14:10:00 +00:00
testAccStepRotateRoot ( accessKey ) ,
2018-08-16 10:38:13 +00:00
testAccStepWritePolicy ( t , "test" , testDynamoPolicy ) ,
testAccStepRead ( t , "sts" , "test" , [ ] credentialTestFunc { listDynamoTablesTest } ) ,
testAccStepWriteArnPolicyRef ( t , "test" , ec2PolicyArn ) ,
2016-02-23 13:55:43 +00:00
testAccStepReadSTSWithArnPolicy ( t , "test" ) ,
2018-09-26 00:10:53 +00:00
testAccStepWriteArnRoleRef ( t , "test2" , roleName , awsAccountID ) ,
testAccStepRead ( t , "sts" , "test2" , [ ] credentialTestFunc { describeInstancesTest } ) ,
2016-01-08 22:19:53 +00:00
} ,
2018-03-13 14:35:10 +00:00
Teardown : func ( ) error {
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
if err := deleteTestRole ( roleName ) ; err != nil {
return err
}
return deleteTestUser ( accessKey , userName )
2018-03-13 14:35:10 +00:00
} ,
2016-01-08 22:19:53 +00:00
} )
}
2015-04-19 05:13:12 +00:00
func TestBackend_policyCrud ( t * testing . T ) {
2018-09-26 00:10:53 +00:00
t . Parallel ( )
2018-08-16 10:38:13 +00:00
compacted , err := compactJSON ( testDynamoPolicy )
if err != nil {
2015-04-19 05:13:12 +00:00
t . Fatalf ( "bad: %s" , err )
}
logicaltest . Test ( t , logicaltest . TestCase {
2021-11-30 00:00:42 +00:00
AcceptanceTest : false ,
2018-11-07 01:21:24 +00:00
LogicalBackend : getBackend ( t ) ,
2015-04-19 05:13:12 +00:00
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
2018-08-16 10:38:13 +00:00
testAccStepWritePolicy ( t , "test" , testDynamoPolicy ) ,
testAccStepReadPolicy ( t , "test" , compacted ) ,
2015-04-19 05:13:12 +00:00
testAccStepDeletePolicy ( t , "test" ) ,
testAccStepReadPolicy ( t , "test" , "" ) ,
} ,
} )
}
2018-09-18 20:26:06 +00:00
func TestBackend_throttled ( t * testing . T ) {
2018-09-26 00:10:53 +00:00
t . Parallel ( )
2018-09-18 20:26:06 +00:00
config := logical . TestBackendConfig ( )
config . StorageView = & logical . InmemStorage { }
b := Backend ( )
if err := b . Setup ( context . Background ( ) , config ) ; err != nil {
t . Fatal ( err )
}
connData := map [ string ] interface { } {
"credential_type" : "iam_user" ,
}
confReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "roles/something" ,
Storage : config . StorageView ,
Data : connData ,
}
resp , err := b . HandleRequest ( context . Background ( ) , confReq )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "failed to write configuration: resp:%#v err:%s" , resp , err )
}
// Mock the IAM API call to return a throttled response to the CreateUser API
// call
b . iamClient = & mockIAMClient { }
credReq := & logical . Request {
Operation : logical . UpdateOperation ,
Path : "creds/something" ,
Storage : config . StorageView ,
}
credResp , err := b . HandleRequest ( context . Background ( ) , credReq )
if err == nil {
t . Fatalf ( "failed to trigger expected throttling error condition: resp:%#v" , credResp )
}
rErr := credResp . Error ( )
expected := "Error creating IAM user: Throttling: "
if rErr . Error ( ) != expected {
t . Fatalf ( "error message did not match, expected (%s), got (%s)" , expected , rErr . Error ( ) )
}
// verify the error we got back is returned with a http.StatusBadGateway
code , err := logical . RespondErrorCommon ( credReq , credResp , err )
if err == nil {
t . Fatal ( "expected error after running req/resp/err through RespondErrorCommon, got nil" )
}
if code != http . StatusBadGateway {
t . Fatalf ( "expected HTTP status 'bad gateway', got: (%d)" , code )
}
}
2015-03-20 16:59:48 +00:00
func testAccPreCheck ( t * testing . T ) {
2022-11-17 18:55:27 +00:00
if ! hasAWSCredentials ( ) {
t . Skip ( "Skipping because AWS credentials could not be resolved. See https://docs.aws.amazon.com/sdk-for-go/v1/developer-guide/configuring-sdk.html#specifying-credentials for information on how to set up AWS credentials." )
}
2018-09-26 00:10:53 +00:00
initSetup . Do ( func ( ) {
if v := os . Getenv ( "AWS_DEFAULT_REGION" ) ; v == "" {
log . Println ( "[INFO] Test: Using us-west-2 as test region" )
os . Setenv ( "AWS_DEFAULT_REGION" , "us-west-2" )
2016-04-12 02:30:30 +00:00
}
2018-09-26 00:10:53 +00:00
} )
2016-04-12 02:30:30 +00:00
}
2022-11-17 18:55:27 +00:00
func hasAWSCredentials ( ) bool {
ctx , cancel := context . WithTimeout ( context . Background ( ) , 5 * time . Second )
defer cancel ( )
cfg , err := config . LoadDefaultConfig ( ctx )
if err != nil {
return false
}
creds , err := cfg . Credentials . Retrieve ( ctx )
if err != nil {
return false
}
return creds . HasKeys ( )
}
2018-09-18 20:26:06 +00:00
func getAccountID ( ) ( string , error ) {
2016-04-12 02:30:30 +00:00
awsConfig := & aws . Config {
2018-03-13 14:35:10 +00:00
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
2016-04-12 02:30:30 +00:00
}
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
return "" , err
}
svc := sts . New ( sess )
2016-04-12 02:30:30 +00:00
2018-03-13 14:35:10 +00:00
params := & sts . GetCallerIdentityInput { }
res , err := svc . GetCallerIdentity ( params )
2016-04-12 02:30:30 +00:00
if err != nil {
return "" , err
}
2018-03-13 14:35:10 +00:00
if res == nil {
return "" , fmt . Errorf ( "got nil response from GetCallerIdentity" )
}
2016-04-12 02:30:30 +00:00
2018-03-13 14:35:10 +00:00
return * res . Account , nil
2016-04-12 02:30:30 +00:00
}
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
func createRole ( t * testing . T , roleName , awsAccountID string , policyARNs [ ] string ) {
2016-04-12 02:30:30 +00:00
const testRoleAssumePolicy = ` {
"Version" : "2012-10-17" ,
"Statement" : [
{
"Effect" : "Allow" ,
"Principal" : {
"AWS" : "arn:aws:iam::%s:root"
} ,
2022-10-31 14:52:35 +00:00
"Action" : [
"sts:AssumeRole" ,
"sts:SetSourceIdentity"
]
}
2016-04-12 02:30:30 +00:00
]
}
`
awsConfig := & aws . Config {
2018-03-13 14:35:10 +00:00
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
2016-04-12 02:30:30 +00:00
}
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
t . Fatal ( err )
}
svc := iam . New ( sess )
2018-09-26 00:10:53 +00:00
trustPolicy := fmt . Sprintf ( testRoleAssumePolicy , awsAccountID )
2016-04-12 02:30:30 +00:00
params := & iam . CreateRoleInput {
AssumeRolePolicyDocument : aws . String ( trustPolicy ) ,
2018-09-26 00:10:53 +00:00
RoleName : aws . String ( roleName ) ,
2016-04-12 02:30:30 +00:00
Path : aws . String ( "/" ) ,
}
2018-09-26 00:10:53 +00:00
log . Printf ( "[INFO] AWS CreateRole: %s" , roleName )
2020-01-09 22:58:33 +00:00
if _ , err := svc . CreateRole ( params ) ; err != nil {
2016-12-21 18:08:27 +00:00
t . Fatalf ( "AWS CreateRole failed: %v" , err )
2016-04-12 02:30:30 +00:00
}
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
for _ , policyARN := range policyARNs {
attachment := & iam . AttachRolePolicyInput {
PolicyArn : aws . String ( policyARN ) ,
RoleName : aws . String ( roleName ) , // Required
}
_ , err = svc . AttachRolePolicy ( attachment )
2016-04-12 02:30:30 +00:00
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
if err != nil {
t . Fatalf ( "AWS AttachRolePolicy failed: %v" , err )
}
2016-04-12 02:30:30 +00:00
}
}
2018-09-26 00:10:53 +00:00
func createUser ( t * testing . T , userName string , accessKey * awsAccessKey ) {
2018-03-13 14:35:10 +00:00
// The sequence of user creation actions is carefully chosen to minimize
// impact of stolen IAM user credentials
// 1. Create user, without any permissions or credentials. At this point,
// nobody cares if creds compromised because this user can do nothing.
// 2. Attach the timebomb policy. This grants no access but puts a time limit
2019-03-19 13:32:45 +00:00
// on validity of compromised credentials. If this fails, nobody cares
2018-03-13 14:35:10 +00:00
// because the user has no permissions to do anything anyway
// 3. Attach the AdminAccess policy. The IAM user still has no credentials to
// do anything
// 4. Generate API creds to get an actual access key and secret key
timebombPolicyTemplate := ` {
"Version" : "2012-10-17" ,
"Statement" : [
{
"Effect" : "Deny" ,
"Action" : "*" ,
"Resource" : "*" ,
"Condition" : {
"DateGreaterThan" : {
"aws:CurrentTime" : "%s"
}
}
}
]
}
`
validity := time . Duration ( 2 * time . Hour )
expiry := time . Now ( ) . Add ( validity )
timebombPolicy := fmt . Sprintf ( timebombPolicyTemplate , expiry . Format ( time . RFC3339 ) )
awsConfig := & aws . Config {
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
}
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
t . Fatal ( err )
}
svc := iam . New ( sess )
2018-03-13 14:35:10 +00:00
createUserInput := & iam . CreateUserInput {
2018-09-26 00:10:53 +00:00
UserName : aws . String ( userName ) ,
2018-03-13 14:35:10 +00:00
}
2018-09-26 00:10:53 +00:00
log . Printf ( "[INFO] AWS CreateUser: %s" , userName )
2020-01-09 22:58:33 +00:00
if _ , err := svc . CreateUser ( createUserInput ) ; err != nil {
2018-03-13 14:35:10 +00:00
t . Fatalf ( "AWS CreateUser failed: %v" , err )
}
putPolicyInput := & iam . PutUserPolicyInput {
PolicyDocument : aws . String ( timebombPolicy ) ,
PolicyName : aws . String ( "SelfDestructionTimebomb" ) ,
2018-09-26 00:10:53 +00:00
UserName : aws . String ( userName ) ,
2018-03-13 14:35:10 +00:00
}
_ , err = svc . PutUserPolicy ( putPolicyInput )
if err != nil {
t . Fatalf ( "AWS PutUserPolicy failed: %v" , err )
}
attachUserPolicyInput := & iam . AttachUserPolicyInput {
PolicyArn : aws . String ( "arn:aws:iam::aws:policy/AdministratorAccess" ) ,
2018-09-26 00:10:53 +00:00
UserName : aws . String ( userName ) ,
2018-03-13 14:35:10 +00:00
}
_ , err = svc . AttachUserPolicy ( attachUserPolicyInput )
if err != nil {
t . Fatalf ( "AWS AttachUserPolicy failed, %v" , err )
}
createAccessKeyInput := & iam . CreateAccessKeyInput {
2018-09-26 00:10:53 +00:00
UserName : aws . String ( userName ) ,
2018-03-13 14:35:10 +00:00
}
createAccessKeyOutput , err := svc . CreateAccessKey ( createAccessKeyInput )
if err != nil {
t . Fatalf ( "AWS CreateAccessKey failed: %v" , err )
}
if createAccessKeyOutput == nil {
t . Fatalf ( "AWS CreateAccessKey returned nil" )
}
genAccessKey := createAccessKeyOutput . AccessKey
2018-09-18 20:26:06 +00:00
accessKey . AccessKeyID = * genAccessKey . AccessKeyId
2018-03-13 14:35:10 +00:00
accessKey . SecretAccessKey = * genAccessKey . SecretAccessKey
}
2016-04-12 02:30:30 +00:00
2020-06-09 23:56:12 +00:00
// Create an IAM Group and add an inline policy and managed policies if specified
func createGroup ( t * testing . T , groupName string , inlinePolicy string , managedPolicies [ ] string ) {
awsConfig := & aws . Config {
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
}
sess , err := session . NewSession ( awsConfig )
if err != nil {
t . Fatal ( err )
}
svc := iam . New ( sess )
createGroupInput := & iam . CreateGroupInput {
GroupName : aws . String ( groupName ) ,
}
log . Printf ( "[INFO] AWS CreateGroup: %s" , groupName )
if _ , err := svc . CreateGroup ( createGroupInput ) ; err != nil {
t . Fatalf ( "AWS CreateGroup failed: %v" , err )
}
if len ( inlinePolicy ) > 0 {
putPolicyInput := & iam . PutGroupPolicyInput {
PolicyDocument : aws . String ( inlinePolicy ) ,
PolicyName : aws . String ( "InlinePolicy" ) ,
GroupName : aws . String ( groupName ) ,
}
_ , err = svc . PutGroupPolicy ( putPolicyInput )
if err != nil {
t . Fatalf ( "AWS PutGroupPolicy failed: %v" , err )
}
}
for _ , mp := range managedPolicies {
attachGroupPolicyInput := & iam . AttachGroupPolicyInput {
PolicyArn : aws . String ( mp ) ,
GroupName : aws . String ( groupName ) ,
}
_ , err = svc . AttachGroupPolicy ( attachGroupPolicyInput )
if err != nil {
t . Fatalf ( "AWS AttachGroupPolicy failed, %v" , err )
}
}
}
2018-09-26 00:10:53 +00:00
func deleteTestRole ( roleName string ) error {
2016-04-12 02:30:30 +00:00
awsConfig := & aws . Config {
2018-03-13 14:35:10 +00:00
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
2016-04-12 02:30:30 +00:00
}
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
return err
}
svc := iam . New ( sess )
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
listAttachmentsInput := & iam . ListAttachedRolePoliciesInput {
RoleName : aws . String ( roleName ) ,
}
detacher := func ( result * iam . ListAttachedRolePoliciesOutput , lastPage bool ) bool {
for _ , policy := range result . AttachedPolicies {
detachInput := & iam . DetachRolePolicyInput {
PolicyArn : policy . PolicyArn ,
RoleName : aws . String ( roleName ) , // Required
}
_ , err := svc . DetachRolePolicy ( detachInput )
if err != nil {
log . Printf ( "[WARN] AWS DetachRolePolicy failed for policy %s: %v" , * policy . PolicyArn , err )
}
}
return true
2016-04-12 02:30:30 +00:00
}
2020-01-09 22:58:33 +00:00
if err := svc . ListAttachedRolePoliciesPages ( listAttachmentsInput , detacher ) ; err != nil {
2017-07-07 12:23:12 +00:00
log . Printf ( "[WARN] AWS DetachRolePolicy failed: %v" , err )
}
2016-04-12 02:30:30 +00:00
params := & iam . DeleteRoleInput {
2018-09-26 00:10:53 +00:00
RoleName : aws . String ( roleName ) ,
2016-04-12 02:30:30 +00:00
}
2018-09-26 00:10:53 +00:00
log . Printf ( "[INFO] AWS DeleteRole: %s" , roleName )
2016-04-12 02:30:30 +00:00
_ , err = svc . DeleteRole ( params )
if err != nil {
log . Printf ( "[WARN] AWS DeleteRole failed: %v" , err )
2017-07-07 12:23:12 +00:00
return err
2016-04-12 02:30:30 +00:00
}
2018-08-16 10:38:13 +00:00
return nil
}
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
func deleteTestUser ( accessKey * awsAccessKey , userName string ) error {
2018-08-16 10:38:13 +00:00
awsConfig := & aws . Config {
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
}
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
return err
}
svc := iam . New ( sess )
2018-03-13 14:35:10 +00:00
userDetachment := & iam . DetachUserPolicyInput {
PolicyArn : aws . String ( "arn:aws:iam::aws:policy/AdministratorAccess" ) ,
2018-09-26 00:10:53 +00:00
UserName : aws . String ( userName ) ,
2018-03-13 14:35:10 +00:00
}
2020-01-09 22:58:33 +00:00
if _ , err := svc . DetachUserPolicy ( userDetachment ) ; err != nil {
2018-03-13 14:35:10 +00:00
log . Printf ( "[WARN] AWS DetachUserPolicy failed: %v" , err )
return err
}
deleteAccessKeyInput := & iam . DeleteAccessKeyInput {
2018-09-18 20:26:06 +00:00
AccessKeyId : aws . String ( accessKey . AccessKeyID ) ,
2018-09-26 00:10:53 +00:00
UserName : aws . String ( userName ) ,
2018-03-13 14:35:10 +00:00
}
_ , err = svc . DeleteAccessKey ( deleteAccessKeyInput )
if err != nil {
log . Printf ( "[WARN] AWS DeleteAccessKey failed: %v" , err )
return err
}
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
deleteTestUserPolicyInput := & iam . DeleteUserPolicyInput {
2018-03-13 14:35:10 +00:00
PolicyName : aws . String ( "SelfDestructionTimebomb" ) ,
2018-09-26 00:10:53 +00:00
UserName : aws . String ( userName ) ,
2018-03-13 14:35:10 +00:00
}
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
_ , err = svc . DeleteUserPolicy ( deleteTestUserPolicyInput )
2018-03-13 14:35:10 +00:00
if err != nil {
log . Printf ( "[WARN] AWS DeleteUserPolicy failed: %v" , err )
return err
}
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
deleteTestUserInput := & iam . DeleteUserInput {
2018-09-26 00:10:53 +00:00
UserName : aws . String ( userName ) ,
2018-03-13 14:35:10 +00:00
}
2018-09-26 00:10:53 +00:00
log . Printf ( "[INFO] AWS DeleteUser: %s" , userName )
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
_ , err = svc . DeleteUser ( deleteTestUserInput )
2018-03-13 14:35:10 +00:00
if err != nil {
log . Printf ( "[WARN] AWS DeleteUser failed: %v" , err )
return err
}
2017-07-07 12:23:12 +00:00
return nil
2015-03-20 16:59:48 +00:00
}
2020-06-09 23:56:12 +00:00
func deleteTestGroup ( groupName string ) error {
awsConfig := & aws . Config {
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
}
sess , err := session . NewSession ( awsConfig )
if err != nil {
return err
}
svc := iam . New ( sess )
// Detach any managed group policies
getGroupsInput := & iam . ListAttachedGroupPoliciesInput {
GroupName : aws . String ( groupName ) ,
}
getGroupsOutput , err := svc . ListAttachedGroupPolicies ( getGroupsInput )
if err != nil {
log . Printf ( "[WARN] AWS ListAttachedGroupPolicies failed: %v" , err )
return err
}
for _ , g := range getGroupsOutput . AttachedPolicies {
detachGroupInput := & iam . DetachGroupPolicyInput {
GroupName : aws . String ( groupName ) ,
PolicyArn : g . PolicyArn ,
}
if _ , err := svc . DetachGroupPolicy ( detachGroupInput ) ; err != nil {
log . Printf ( "[WARN] AWS DetachGroupPolicy failed: %v" , err )
return err
}
}
// Remove any inline policies
listGroupPoliciesInput := & iam . ListGroupPoliciesInput {
GroupName : aws . String ( groupName ) ,
}
listGroupPoliciesOutput , err := svc . ListGroupPolicies ( listGroupPoliciesInput )
if err != nil {
log . Printf ( "[WARN] AWS ListGroupPolicies failed: %v" , err )
return err
}
for _ , g := range listGroupPoliciesOutput . PolicyNames {
deleteGroupPolicyInput := & iam . DeleteGroupPolicyInput {
GroupName : aws . String ( groupName ) ,
PolicyName : g ,
}
if _ , err := svc . DeleteGroupPolicy ( deleteGroupPolicyInput ) ; err != nil {
log . Printf ( "[WARN] AWS DeleteGroupPolicy failed: %v" , err )
return err
}
}
// Delete the group
deleteTestGroupInput := & iam . DeleteGroupInput {
GroupName : aws . String ( groupName ) ,
}
log . Printf ( "[INFO] AWS DeleteGroup: %s" , groupName )
_ , err = svc . DeleteGroup ( deleteTestGroupInput )
if err != nil {
log . Printf ( "[WARN] AWS DeleteGroup failed: %v" , err )
return err
}
return nil
}
2015-03-20 16:59:48 +00:00
func testAccStepConfig ( t * testing . T ) logicaltest . TestStep {
return logicaltest . TestStep {
2016-01-07 15:30:47 +00:00
Operation : logical . UpdateOperation ,
2015-04-19 05:21:31 +00:00
Path : "config/root" ,
2015-03-20 16:59:48 +00:00
Data : map [ string ] interface { } {
2018-03-13 14:35:10 +00:00
"region" : os . Getenv ( "AWS_DEFAULT_REGION" ) ,
} ,
}
}
func testAccStepConfigWithCreds ( t * testing . T , accessKey * awsAccessKey ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . UpdateOperation ,
Path : "config/root" ,
Data : map [ string ] interface { } {
"region" : os . Getenv ( "AWS_DEFAULT_REGION" ) ,
} ,
PreFlight : func ( req * logical . Request ) error {
// Values in Data above get eagerly evaluated due to the testing framework.
// In particular, they get evaluated before accessKey gets set by CreateUser
// and thus would fail. By moving to a closure in a PreFlight, we ensure that
// the creds get evaluated lazily after they've been properly set
2018-09-18 20:26:06 +00:00
req . Data [ "access_key" ] = accessKey . AccessKeyID
2018-03-13 14:35:10 +00:00
req . Data [ "secret_key" ] = accessKey . SecretAccessKey
return nil
2015-03-20 16:59:48 +00:00
} ,
}
}
2018-09-26 14:10:00 +00:00
func testAccStepRotateRoot ( oldAccessKey * awsAccessKey ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . UpdateOperation ,
Path : "config/rotate-root" ,
Check : func ( resp * logical . Response ) error {
if resp == nil {
return fmt . Errorf ( "received nil response from config/rotate-root" )
}
newAccessKeyID := resp . Data [ "access_key" ] . ( string )
if newAccessKeyID == oldAccessKey . AccessKeyID {
return fmt . Errorf ( "rotate-root didn't rotate access key" )
}
awsConfig := & aws . Config {
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
Credentials : credentials . NewStaticCredentials ( oldAccessKey . AccessKeyID , oldAccessKey . SecretAccessKey , "" ) ,
}
// sigh....
oldAccessKey . AccessKeyID = newAccessKeyID
log . Println ( "[WARN] Sleeping for 10 seconds waiting for AWS..." )
time . Sleep ( 10 * time . Second )
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
return err
}
svc := sts . New ( sess )
2018-09-26 14:10:00 +00:00
params := & sts . GetCallerIdentityInput { }
2020-01-09 22:58:33 +00:00
if _ , err := svc . GetCallerIdentity ( params ) ; err == nil {
2018-09-26 14:10:00 +00:00
return fmt . Errorf ( "bad: old credentials succeeded after rotate" )
}
if aerr , ok := err . ( awserr . Error ) ; ok {
if aerr . Code ( ) != "InvalidClientTokenId" {
return fmt . Errorf ( "Unknown error returned from AWS: %#v" , aerr )
}
return nil
}
return err
} ,
}
}
2018-08-16 10:38:13 +00:00
func testAccStepRead ( t * testing . T , path , name string , credentialTests [ ] credentialTestFunc ) logicaltest . TestStep {
2015-03-20 16:59:48 +00:00
return logicaltest . TestStep {
Operation : logical . ReadOperation ,
2018-08-16 10:38:13 +00:00
Path : path + "/" + name ,
2015-03-20 16:59:48 +00:00
Check : func ( resp * logical . Response ) error {
var d struct {
AccessKey string ` mapstructure:"access_key" `
SecretKey string ` mapstructure:"secret_key" `
2018-08-16 10:38:13 +00:00
STSToken string ` mapstructure:"security_token" `
2015-03-20 16:59:48 +00:00
}
if err := mapstructure . Decode ( resp . Data , & d ) ; err != nil {
return err
}
log . Printf ( "[WARN] Generated credentials: %v" , d )
2018-08-16 10:38:13 +00:00
for _ , test := range credentialTests {
err := test ( d . AccessKey , d . SecretKey , d . STSToken )
if err != nil {
return err
2018-03-13 14:35:10 +00:00
}
2015-03-20 16:59:48 +00:00
}
2018-08-16 10:38:13 +00:00
return nil
2015-03-20 16:59:48 +00:00
} ,
}
}
2022-10-31 14:52:35 +00:00
func testAccStepReadSTSResponse ( name string , maximumTTL uint64 ) logicaltest . TestStep {
2018-10-02 14:14:16 +00:00
return logicaltest . TestStep {
Operation : logical . ReadOperation ,
Path : "creds/" + name ,
Check : func ( resp * logical . Response ) error {
2022-10-31 14:52:35 +00:00
if resp . Secret != nil {
return fmt . Errorf ( "bad: STS tokens should return a nil secret, received: %+v" , resp . Secret )
2018-10-02 14:14:16 +00:00
}
2022-10-31 14:52:35 +00:00
if ttl , exists := resp . Data [ "ttl" ] ; exists {
ttlVal := ttl . ( uint64 )
if ttlVal > maximumTTL {
return fmt . Errorf ( "bad: ttl of %d greater than maximum of %d" , ttl , maximumTTL )
}
return nil
2018-10-02 14:14:16 +00:00
}
2022-10-31 14:52:35 +00:00
return fmt . Errorf ( "response data missing ttl, received: %+v" , resp . Data )
2018-10-02 14:14:16 +00:00
} ,
}
}
2018-08-16 10:38:13 +00:00
func describeInstancesTest ( accessKey , secretKey , token string ) error {
creds := credentials . NewStaticCredentials ( accessKey , secretKey , token )
awsConfig := & aws . Config {
Credentials : creds ,
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
}
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
return err
}
client := ec2 . New ( sess )
2018-08-16 10:38:13 +00:00
log . Printf ( "[WARN] Verifying that the generated credentials work with ec2:DescribeInstances..." )
return retryUntilSuccess ( func ( ) error {
_ , err := client . DescribeInstances ( & ec2 . DescribeInstancesInput { } )
return err
} )
}
2016-01-08 22:19:53 +00:00
2018-08-16 10:38:13 +00:00
func describeAzsTestUnauthorized ( accessKey , secretKey , token string ) error {
creds := credentials . NewStaticCredentials ( accessKey , secretKey , token )
awsConfig := & aws . Config {
Credentials : creds ,
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
}
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
return err
}
client := ec2 . New ( sess )
2018-08-16 10:38:13 +00:00
log . Printf ( "[WARN] Verifying that the generated credentials don't work with ec2:DescribeAvailabilityZones..." )
return retryUntilSuccess ( func ( ) error {
_ , err := client . DescribeAvailabilityZones ( & ec2 . DescribeAvailabilityZonesInput { } )
// Need to make sure AWS authenticates the generated credentials but does not authorize the operation
if err == nil {
return fmt . Errorf ( "operation succeeded when expected failure" )
}
if aerr , ok := err . ( awserr . Error ) ; ok {
if aerr . Code ( ) == "UnauthorizedOperation" {
return nil
2016-01-08 22:19:53 +00:00
}
2018-08-16 10:38:13 +00:00
}
return err
} )
}
2016-01-08 22:19:53 +00:00
2019-03-31 13:10:17 +00:00
func assertCreatedIAMUser ( accessKey , secretKey , token string ) error {
creds := credentials . NewStaticCredentials ( accessKey , secretKey , token )
awsConfig := & aws . Config {
Credentials : creds ,
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
}
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
return err
}
client := iam . New ( sess )
2019-03-31 13:10:17 +00:00
log . Printf ( "[WARN] Checking if IAM User is created properly..." )
userOutput , err := client . GetUser ( & iam . GetUserInput { } )
if err != nil {
return err
}
if * userOutput . User . Path != "/path/" {
return fmt . Errorf ( "bad: got: %#v\nexpected: %#v" , userOutput . User . Path , "/path/" )
}
return nil
}
2018-08-16 10:38:13 +00:00
func listIamUsersTest ( accessKey , secretKey , token string ) error {
creds := credentials . NewStaticCredentials ( accessKey , secretKey , token )
awsConfig := & aws . Config {
Credentials : creds ,
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
}
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
return err
}
client := iam . New ( sess )
2018-08-16 10:38:13 +00:00
log . Printf ( "[WARN] Verifying that the generated credentials work with iam:ListUsers..." )
return retryUntilSuccess ( func ( ) error {
_ , err := client . ListUsers ( & iam . ListUsersInput { } )
return err
} )
}
func listDynamoTablesTest ( accessKey , secretKey , token string ) error {
creds := credentials . NewStaticCredentials ( accessKey , secretKey , token )
awsConfig := & aws . Config {
Credentials : creds ,
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
}
2020-01-09 22:58:33 +00:00
sess , err := session . NewSession ( awsConfig )
if err != nil {
return err
}
client := dynamodb . New ( sess )
2018-08-16 10:38:13 +00:00
log . Printf ( "[WARN] Verifying that the generated credentials work with dynamodb:ListTables..." )
return retryUntilSuccess ( func ( ) error {
_ , err := client . ListTables ( & dynamodb . ListTablesInput { } )
return err
} )
}
2016-01-08 22:19:53 +00:00
2020-06-09 23:56:12 +00:00
func listS3BucketsTest ( accessKey , secretKey , token string ) error {
creds := credentials . NewStaticCredentials ( accessKey , secretKey , token )
awsConfig := & aws . Config {
Credentials : creds ,
Region : aws . String ( "us-east-1" ) ,
HTTPClient : cleanhttp . DefaultClient ( ) ,
}
sess , err := session . NewSession ( awsConfig )
if err != nil {
return err
}
client := s3 . New ( sess )
log . Printf ( "[WARN] Verifying that the generated credentials work with s3:ListBuckets..." )
return retryUntilSuccess ( func ( ) error {
_ , err := client . ListBuckets ( & s3 . ListBucketsInput { } )
return err
} )
}
2018-08-16 10:38:13 +00:00
func retryUntilSuccess ( op func ( ) error ) error {
retryCount := 0
success := false
var err error
for ! success && retryCount < 10 {
err = op ( )
if err == nil {
2016-01-08 22:19:53 +00:00
return nil
2018-08-16 10:38:13 +00:00
}
time . Sleep ( time . Second )
retryCount ++
2016-01-08 22:19:53 +00:00
}
2018-08-16 10:38:13 +00:00
return err
2016-01-08 22:19:53 +00:00
}
2016-02-23 13:55:43 +00:00
func testAccStepReadSTSWithArnPolicy ( t * testing . T , name string ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . ReadOperation ,
Path : "sts/" + name ,
ErrorOk : true ,
Check : func ( resp * logical . Response ) error {
if resp . Data [ "error" ] !=
2018-08-16 10:38:13 +00:00
"attempted to retrieve iam_user credentials through the sts path; this is not allowed for legacy roles" {
2016-02-23 13:55:43 +00:00
t . Fatalf ( "bad: %v" , resp )
}
return nil
} ,
}
}
2015-03-20 16:59:48 +00:00
func testAccStepWritePolicy ( t * testing . T , name string , policy string ) logicaltest . TestStep {
return logicaltest . TestStep {
2016-01-07 15:30:47 +00:00
Operation : logical . UpdateOperation ,
2015-04-27 21:20:28 +00:00
Path : "roles/" + name ,
2015-03-20 16:59:48 +00:00
Data : map [ string ] interface { } {
2018-08-16 10:38:13 +00:00
"policy" : policy ,
2015-03-20 16:59:48 +00:00
} ,
}
}
2015-04-19 05:13:12 +00:00
func testAccStepDeletePolicy ( t * testing . T , n string ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . DeleteOperation ,
2015-04-27 21:20:28 +00:00
Path : "roles/" + n ,
2015-04-19 05:13:12 +00:00
}
}
func testAccStepReadPolicy ( t * testing . T , name string , value string ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . ReadOperation ,
2015-04-27 21:20:28 +00:00
Path : "roles/" + name ,
2015-04-19 05:13:12 +00:00
Check : func ( resp * logical . Response ) error {
if resp == nil {
if value == "" {
return nil
}
return fmt . Errorf ( "bad: %#v" , resp )
}
2018-08-16 10:38:13 +00:00
expected := map [ string ] interface { } {
2019-09-19 23:35:12 +00:00
"policy_arns" : [ ] string ( nil ) ,
"role_arns" : [ ] string ( nil ) ,
"policy_document" : value ,
"credential_type" : strings . Join ( [ ] string { iamUserCred , federationTokenCred } , "," ) ,
"default_sts_ttl" : int64 ( 0 ) ,
"max_sts_ttl" : int64 ( 0 ) ,
"user_path" : "" ,
"permissions_boundary_arn" : "" ,
2020-06-09 23:56:12 +00:00
"iam_groups" : [ ] string ( nil ) ,
2021-11-30 00:00:42 +00:00
"iam_tags" : map [ string ] string ( nil ) ,
2015-04-19 05:13:12 +00:00
}
2018-08-16 10:38:13 +00:00
if ! reflect . DeepEqual ( resp . Data , expected ) {
return fmt . Errorf ( "bad: got: %#v\nexpected: %#v" , resp . Data , expected )
2015-04-19 05:13:12 +00:00
}
return nil
} ,
}
}
2018-08-16 10:38:13 +00:00
const testDynamoPolicy = ` {
2015-03-20 16:59:48 +00:00
"Version" : "2012-10-17" ,
"Statement" : [
{
"Sid" : "Stmt1426528957000" ,
"Effect" : "Allow" ,
"Action" : [
2018-08-16 10:38:13 +00:00
"dynamodb:List*"
2015-03-20 16:59:48 +00:00
] ,
"Resource" : [
"*"
]
}
]
}
`
2015-12-30 18:05:54 +00:00
2020-06-09 23:56:12 +00:00
const testS3Policy = ` {
"Version" : "2012-10-17" ,
"Statement" : [
{
"Effect" : "Allow" ,
"Action" : [
"s3:Get*" ,
"s3:List*"
] ,
"Resource" : "*"
}
]
} `
2021-04-08 16:43:39 +00:00
const (
adminAccessPolicyArn = "arn:aws:iam::aws:policy/AdministratorAccess"
ec2PolicyArn = "arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"
iamPolicyArn = "arn:aws:iam::aws:policy/IAMReadOnlyAccess"
dynamoPolicyArn = "arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess"
)
2018-08-16 10:38:13 +00:00
func testAccStepWriteRole ( t * testing . T , name string , data map [ string ] interface { } ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . UpdateOperation ,
Path : "roles/" + name ,
Data : data ,
}
}
func testAccStepReadRole ( t * testing . T , name string , expected map [ string ] interface { } ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . ReadOperation ,
Path : "roles/" + name ,
Check : func ( resp * logical . Response ) error {
if resp == nil {
if expected == nil {
return nil
}
return fmt . Errorf ( "bad: nil response" )
}
if ! reflect . DeepEqual ( resp . Data , expected ) {
return fmt . Errorf ( "bad: got %#v\nexpected: %#v" , resp . Data , expected )
}
return nil
} ,
}
}
2015-12-30 18:05:54 +00:00
func testAccStepWriteArnPolicyRef ( t * testing . T , name string , arn string ) logicaltest . TestStep {
return logicaltest . TestStep {
2016-01-21 20:04:16 +00:00
Operation : logical . UpdateOperation ,
2015-12-30 18:05:54 +00:00
Path : "roles/" + name ,
Data : map [ string ] interface { } {
2018-08-16 10:38:13 +00:00
"arn" : ec2PolicyArn ,
2015-12-30 18:05:54 +00:00
} ,
}
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_basicPolicyArnRef ( t * testing . T ) {
2018-09-26 00:10:53 +00:00
t . Parallel ( )
2015-12-30 18:05:54 +00:00
logicaltest . Test ( t , logicaltest . TestCase {
2016-04-05 19:10:44 +00:00
AcceptanceTest : true ,
PreCheck : func ( ) { testAccPreCheck ( t ) } ,
2018-11-07 01:21:24 +00:00
LogicalBackend : getBackend ( t ) ,
2015-12-30 18:05:54 +00:00
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
2018-08-16 10:38:13 +00:00
testAccStepWriteArnPolicyRef ( t , "test" , ec2PolicyArn ) ,
testAccStepRead ( t , "creds" , "test" , [ ] credentialTestFunc { describeInstancesTest } ) ,
} ,
} )
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_iamUserManagedInlinePoliciesGroups ( t * testing . T ) {
2018-09-26 00:10:53 +00:00
t . Parallel ( )
2018-08-16 10:38:13 +00:00
compacted , err := compactJSON ( testDynamoPolicy )
if err != nil {
t . Fatalf ( "bad: %#v" , err )
}
2021-11-30 00:00:42 +00:00
groupName := generateUniqueGroupName ( t . Name ( ) )
2018-08-16 10:38:13 +00:00
roleData := map [ string ] interface { } {
"policy_document" : testDynamoPolicy ,
"policy_arns" : [ ] string { ec2PolicyArn , iamPolicyArn } ,
2020-06-09 23:56:12 +00:00
"iam_groups" : [ ] string { groupName } ,
2018-08-16 10:38:13 +00:00
"credential_type" : iamUserCred ,
2019-03-31 13:10:17 +00:00
"user_path" : "/path/" ,
2018-08-16 10:38:13 +00:00
}
expectedRoleData := map [ string ] interface { } {
2019-09-19 23:35:12 +00:00
"policy_document" : compacted ,
"policy_arns" : [ ] string { ec2PolicyArn , iamPolicyArn } ,
"credential_type" : iamUserCred ,
"role_arns" : [ ] string ( nil ) ,
"default_sts_ttl" : int64 ( 0 ) ,
"max_sts_ttl" : int64 ( 0 ) ,
"user_path" : "/path/" ,
"permissions_boundary_arn" : "" ,
2020-06-09 23:56:12 +00:00
"iam_groups" : [ ] string { groupName } ,
2021-11-30 00:00:42 +00:00
"iam_tags" : map [ string ] string ( nil ) ,
2018-08-16 10:38:13 +00:00
}
2019-03-31 13:10:17 +00:00
2018-08-16 10:38:13 +00:00
logicaltest . Test ( t , logicaltest . TestCase {
AcceptanceTest : true ,
2020-06-09 23:56:12 +00:00
PreCheck : func ( ) {
testAccPreCheck ( t )
createGroup ( t , groupName , testS3Policy , [ ] string { } )
} ,
2018-11-07 01:21:24 +00:00
LogicalBackend : getBackend ( t ) ,
2018-08-16 10:38:13 +00:00
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
testAccStepWriteRole ( t , "test" , roleData ) ,
testAccStepReadRole ( t , "test" , expectedRoleData ) ,
2020-06-09 23:56:12 +00:00
testAccStepRead ( t , "creds" , "test" , [ ] credentialTestFunc { describeInstancesTest , listIamUsersTest , listDynamoTablesTest , assertCreatedIAMUser , listS3BucketsTest } ) ,
testAccStepRead ( t , "sts" , "test" , [ ] credentialTestFunc { describeInstancesTest , listIamUsersTest , listDynamoTablesTest , listS3BucketsTest } ) ,
} ,
Teardown : func ( ) error {
return deleteTestGroup ( groupName )
} ,
} )
}
// Similar to TestBackend_iamUserManagedInlinePoliciesGroups() but managing
// policies only with groups
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_iamUserGroups ( t * testing . T ) {
2020-06-09 23:56:12 +00:00
t . Parallel ( )
2021-11-30 00:00:42 +00:00
group1Name := generateUniqueGroupName ( t . Name ( ) )
group2Name := generateUniqueGroupName ( t . Name ( ) )
2020-06-09 23:56:12 +00:00
roleData := map [ string ] interface { } {
"iam_groups" : [ ] string { group1Name , group2Name } ,
"credential_type" : iamUserCred ,
"user_path" : "/path/" ,
}
expectedRoleData := map [ string ] interface { } {
"policy_document" : "" ,
"policy_arns" : [ ] string ( nil ) ,
"credential_type" : iamUserCred ,
"role_arns" : [ ] string ( nil ) ,
"default_sts_ttl" : int64 ( 0 ) ,
"max_sts_ttl" : int64 ( 0 ) ,
"user_path" : "/path/" ,
"permissions_boundary_arn" : "" ,
"iam_groups" : [ ] string { group1Name , group2Name } ,
2021-11-30 00:00:42 +00:00
"iam_tags" : map [ string ] string ( nil ) ,
2020-06-09 23:56:12 +00:00
}
logicaltest . Test ( t , logicaltest . TestCase {
AcceptanceTest : true ,
PreCheck : func ( ) {
testAccPreCheck ( t )
createGroup ( t , group1Name , testS3Policy , [ ] string { ec2PolicyArn , iamPolicyArn } )
createGroup ( t , group2Name , testDynamoPolicy , [ ] string { } )
} ,
LogicalBackend : getBackend ( t ) ,
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
testAccStepWriteRole ( t , "test" , roleData ) ,
testAccStepReadRole ( t , "test" , expectedRoleData ) ,
testAccStepRead ( t , "creds" , "test" , [ ] credentialTestFunc { describeInstancesTest , listIamUsersTest , listDynamoTablesTest , assertCreatedIAMUser , listS3BucketsTest } ) ,
testAccStepRead ( t , "sts" , "test" , [ ] credentialTestFunc { describeInstancesTest , listIamUsersTest , listDynamoTablesTest , listS3BucketsTest } ) ,
} ,
Teardown : func ( ) error {
if err := deleteTestGroup ( group1Name ) ; err != nil {
return err
}
return deleteTestGroup ( group2Name )
2015-12-30 18:05:54 +00:00
} ,
} )
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_AssumedRoleWithPolicyDoc ( t * testing . T ) {
2018-09-26 00:10:53 +00:00
t . Parallel ( )
2021-12-01 18:44:22 +00:00
roleName := generateUniqueRoleName ( t . Name ( ) )
2018-08-16 10:38:13 +00:00
// This looks a bit curious. The policy document and the role document act
// as a logical intersection of policies. The role allows ec2:Describe*
// (among other permissions). This policy allows everything BUT
// ec2:DescribeAvailabilityZones. Thus, the logical intersection of the two
// is all ec2:Describe* EXCEPT ec2:DescribeAvailabilityZones, and so the
// describeAZs call should fail
allowAllButDescribeAzs := `
{
"Version" : "2012-10-17" ,
"Statement" : [ {
"Effect" : "Allow" ,
"NotAction" : "ec2:DescribeAvailabilityZones" ,
"Resource" : "*"
} ]
}
`
2018-09-26 00:10:53 +00:00
awsAccountID , err := getAccountID ( )
if err != nil {
t . Logf ( "Unable to retrive user via sts:GetCallerIdentity: %#v" , err )
t . Skip ( "Could not determine AWS account ID from sts:GetCallerIdentity for acceptance tests, skipping" )
}
2018-08-16 10:38:13 +00:00
roleData := map [ string ] interface { } {
"policy_document" : allowAllButDescribeAzs ,
2018-09-26 00:10:53 +00:00
"role_arns" : [ ] string { fmt . Sprintf ( "arn:aws:iam::%s:role/%s" , awsAccountID , roleName ) } ,
2018-08-16 10:38:13 +00:00
"credential_type" : assumedRoleCred ,
}
logicaltest . Test ( t , logicaltest . TestCase {
AcceptanceTest : true ,
PreCheck : func ( ) {
testAccPreCheck ( t )
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
createRole ( t , roleName , awsAccountID , [ ] string { ec2PolicyArn } )
2018-08-16 10:38:13 +00:00
// Sleep sometime because AWS is eventually consistent
log . Println ( "[WARN] Sleeping for 10 seconds waiting for AWS..." )
time . Sleep ( 10 * time . Second )
} ,
2018-11-07 01:21:24 +00:00
LogicalBackend : getBackend ( t ) ,
2018-08-16 10:38:13 +00:00
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
testAccStepWriteRole ( t , "test" , roleData ) ,
testAccStepRead ( t , "sts" , "test" , [ ] credentialTestFunc { describeInstancesTest , describeAzsTestUnauthorized } ) ,
testAccStepRead ( t , "creds" , "test" , [ ] credentialTestFunc { describeInstancesTest , describeAzsTestUnauthorized } ) ,
} ,
2018-09-26 00:10:53 +00:00
Teardown : func ( ) error {
return deleteTestRole ( roleName )
} ,
2018-08-16 10:38:13 +00:00
} )
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_AssumedRoleWithPolicyARN ( t * testing . T ) {
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
t . Parallel ( )
2021-11-30 00:00:42 +00:00
roleName := generateUniqueRoleName ( t . Name ( ) )
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
awsAccountID , err := getAccountID ( )
if err != nil {
t . Logf ( "Unable to retrive user via sts:GetCallerIdentity: %#v" , err )
t . Skip ( "Could not determine AWS account ID from sts:GetCallerIdentity for acceptance tests, skipping" )
}
roleData := map [ string ] interface { } {
"policy_arns" : iamPolicyArn ,
"role_arns" : [ ] string { fmt . Sprintf ( "arn:aws:iam::%s:role/%s" , awsAccountID , roleName ) } ,
"credential_type" : assumedRoleCred ,
}
logicaltest . Test ( t , logicaltest . TestCase {
AcceptanceTest : true ,
PreCheck : func ( ) {
testAccPreCheck ( t )
createRole ( t , roleName , awsAccountID , [ ] string { ec2PolicyArn , iamPolicyArn } )
log . Printf ( "[WARN] Sleeping for 10 seconds waiting for AWS..." )
time . Sleep ( 10 * time . Second )
} ,
LogicalBackend : getBackend ( t ) ,
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
testAccStepWriteRole ( t , "test" , roleData ) ,
testAccStepRead ( t , "sts" , "test" , [ ] credentialTestFunc { listIamUsersTest , describeAzsTestUnauthorized } ) ,
testAccStepRead ( t , "creds" , "test" , [ ] credentialTestFunc { listIamUsersTest , describeAzsTestUnauthorized } ) ,
} ,
Teardown : func ( ) error {
return deleteTestRole ( roleName )
} ,
} )
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_AssumedRoleWithGroups ( t * testing . T ) {
2020-06-09 23:56:12 +00:00
t . Parallel ( )
2021-11-30 00:00:42 +00:00
roleName := generateUniqueRoleName ( t . Name ( ) )
groupName := generateUniqueGroupName ( t . Name ( ) )
2020-06-09 23:56:12 +00:00
// This looks a bit curious. The policy document and the role document act
// as a logical intersection of policies. The role allows ec2:Describe*
// (among other permissions). This policy allows everything BUT
// ec2:DescribeAvailabilityZones. Thus, the logical intersection of the two
// is all ec2:Describe* EXCEPT ec2:DescribeAvailabilityZones, and so the
// describeAZs call should fail
allowAllButDescribeAzs := ` {
"Version" : "2012-10-17" ,
"Statement" : [
{
"Effect" : "Allow" ,
"NotAction" : "ec2:DescribeAvailabilityZones" ,
"Resource" : "*"
}
]
} `
awsAccountID , err := getAccountID ( )
if err != nil {
t . Logf ( "Unable to retrive user via sts:GetCallerIdentity: %#v" , err )
t . Skip ( "Could not determine AWS account ID from sts:GetCallerIdentity for acceptance tests, skipping" )
}
roleData := map [ string ] interface { } {
"iam_groups" : [ ] string { groupName } ,
"role_arns" : [ ] string { fmt . Sprintf ( "arn:aws:iam::%s:role/%s" , awsAccountID , roleName ) } ,
"credential_type" : assumedRoleCred ,
}
logicaltest . Test ( t , logicaltest . TestCase {
AcceptanceTest : true ,
PreCheck : func ( ) {
testAccPreCheck ( t )
createRole ( t , roleName , awsAccountID , [ ] string { ec2PolicyArn } )
createGroup ( t , groupName , allowAllButDescribeAzs , [ ] string { } )
// Sleep sometime because AWS is eventually consistent
log . Println ( "[WARN] Sleeping for 10 seconds waiting for AWS..." )
time . Sleep ( 10 * time . Second )
} ,
LogicalBackend : getBackend ( t ) ,
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
testAccStepWriteRole ( t , "test" , roleData ) ,
testAccStepRead ( t , "sts" , "test" , [ ] credentialTestFunc { describeInstancesTest , describeAzsTestUnauthorized } ) ,
testAccStepRead ( t , "creds" , "test" , [ ] credentialTestFunc { describeInstancesTest , describeAzsTestUnauthorized } ) ,
} ,
Teardown : func ( ) error {
if err := deleteTestGroup ( groupName ) ; err != nil {
return err
}
return deleteTestRole ( roleName )
} ,
} )
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_FederationTokenWithPolicyARN ( t * testing . T ) {
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
t . Parallel ( )
2021-11-30 00:00:42 +00:00
userName := generateUniqueUserName ( t . Name ( ) )
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
accessKey := & awsAccessKey { }
roleData := map [ string ] interface { } {
"policy_arns" : dynamoPolicyArn ,
"credential_type" : federationTokenCred ,
}
logicaltest . Test ( t , logicaltest . TestCase {
AcceptanceTest : true ,
PreCheck : func ( ) {
testAccPreCheck ( t )
createUser ( t , userName , accessKey )
// Sleep sometime because AWS is eventually consistent
log . Println ( "[WARN] Sleeping for 10 seconds waiting for AWS..." )
time . Sleep ( 10 * time . Second )
} ,
LogicalBackend : getBackend ( t ) ,
Steps : [ ] logicaltest . TestStep {
testAccStepConfigWithCreds ( t , accessKey ) ,
testAccStepWriteRole ( t , "test" , roleData ) ,
testAccStepRead ( t , "sts" , "test" , [ ] credentialTestFunc { listDynamoTablesTest , describeAzsTestUnauthorized } ) ,
testAccStepRead ( t , "creds" , "test" , [ ] credentialTestFunc { listDynamoTablesTest , describeAzsTestUnauthorized } ) ,
} ,
Teardown : func ( ) error {
2019-09-13 18:05:43 +00:00
return deleteTestUser ( accessKey , userName )
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
} ,
} )
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_FederationTokenWithGroups ( t * testing . T ) {
2020-06-09 23:56:12 +00:00
t . Parallel ( )
2021-11-30 00:00:42 +00:00
userName := generateUniqueUserName ( t . Name ( ) )
groupName := generateUniqueGroupName ( t . Name ( ) )
2020-06-09 23:56:12 +00:00
accessKey := & awsAccessKey { }
// IAM policy where Statement is a single element, not a list
iamSingleStatementPolicy := ` {
"Version" : "2012-10-17" ,
"Statement" : {
"Effect" : "Allow" ,
"Action" : [
"s3:Get*" ,
"s3:List*"
] ,
"Resource" : "*"
}
} `
roleData := map [ string ] interface { } {
"iam_groups" : [ ] string { groupName } ,
"policy_document" : iamSingleStatementPolicy ,
"credential_type" : federationTokenCred ,
}
logicaltest . Test ( t , logicaltest . TestCase {
AcceptanceTest : true ,
PreCheck : func ( ) {
testAccPreCheck ( t )
createUser ( t , userName , accessKey )
createGroup ( t , groupName , "" , [ ] string { dynamoPolicyArn } )
// Sleep sometime because AWS is eventually consistent
log . Println ( "[WARN] Sleeping for 10 seconds waiting for AWS..." )
time . Sleep ( 10 * time . Second )
} ,
LogicalBackend : getBackend ( t ) ,
Steps : [ ] logicaltest . TestStep {
testAccStepConfigWithCreds ( t , accessKey ) ,
testAccStepWriteRole ( t , "test" , roleData ) ,
testAccStepRead ( t , "sts" , "test" , [ ] credentialTestFunc { listDynamoTablesTest , describeAzsTestUnauthorized , listS3BucketsTest } ) ,
testAccStepRead ( t , "creds" , "test" , [ ] credentialTestFunc { listDynamoTablesTest , describeAzsTestUnauthorized , listS3BucketsTest } ) ,
} ,
Teardown : func ( ) error {
if err := deleteTestGroup ( groupName ) ; err != nil {
return err
}
return deleteTestUser ( accessKey , userName )
} ,
} )
}
2021-11-30 00:00:42 +00:00
func TestAcceptanceBackend_RoleDefaultSTSTTL ( t * testing . T ) {
2018-10-02 14:14:16 +00:00
t . Parallel ( )
2021-11-30 00:00:42 +00:00
roleName := generateUniqueRoleName ( t . Name ( ) )
2018-10-02 14:14:16 +00:00
minAwsAssumeRoleDuration := 900
awsAccountID , err := getAccountID ( )
if err != nil {
t . Logf ( "Unable to retrive user via sts:GetCallerIdentity: %#v" , err )
t . Skip ( "Could not determine AWS account ID from sts:GetCallerIdentity for acceptance tests, skipping" )
}
roleData := map [ string ] interface { } {
"role_arns" : [ ] string { fmt . Sprintf ( "arn:aws:iam::%s:role/%s" , awsAccountID , roleName ) } ,
"credential_type" : assumedRoleCred ,
"default_sts_ttl" : minAwsAssumeRoleDuration ,
2018-10-20 14:36:47 +00:00
"max_sts_ttl" : minAwsAssumeRoleDuration ,
2018-10-02 14:14:16 +00:00
}
logicaltest . Test ( t , logicaltest . TestCase {
AcceptanceTest : true ,
PreCheck : func ( ) {
testAccPreCheck ( t )
secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles (#6789)
* secret/aws: Pass policy ARNs to AssumedRole and FederationToken roles
AWS now allows you to pass policy ARNs as well as, and in addition to,
policy documents for AssumeRole and GetFederationToken (see
https://aws.amazon.com/about-aws/whats-new/2019/05/session-permissions/).
Vault already collects policy ARNs for iam_user credential types; now it
will allow policy ARNs for assumed_role and federation_token credential
types and plumb them through to the appropriate AWS calls.
This brings along a minor breaking change. Vault roles of the
federation_token credential type are now required to have either a
policy_document or a policy_arns specified. This was implicit
previously; a missing policy_document would result in a validation error
from the AWS SDK when retrieving credentials. However, it would still
allow creating a role that didn't have a policy_document specified and
then later specifying it, after which retrieving the AWS credentials
would work. Similar workflows in which the Vault role didn't have a
policy_document specified for some period of time, such as deleting the
policy_document and then later adding it back, would also have worked
previously but will now be broken.
The reason for this breaking change is because a credential_type of
federation_token without either a policy_document or policy_arns
specified will return credentials that have equivalent permissions to
the credentials the Vault server itself is using. This is quite
dangerous (e.g., it could allow Vault clients access to retrieve
credentials that could modify Vault's underlying storage) and so should
be discouraged. This scenario is still possible when passing in an
appropriate policy_document or policy_arns parameter, but clients should
be explicitly aware of what they are doing and opt in to it by passing
in the appropriate role parameters.
* Error out on dangerous federation token retrieval
The AWS secrets role code now disallows creation of a dangerous role
configuration; however, pre-existing roles could have existed that would
trigger this now-dangerous code path, so also adding a check for this
configuration at credential retrieval time.
* Run makefmt
* Fix tests
* Fix comments/docs
2019-08-20 19:34:41 +00:00
createRole ( t , roleName , awsAccountID , [ ] string { ec2PolicyArn } )
2018-10-02 14:14:16 +00:00
log . Println ( "[WARN] Sleeping for 10 seconds waiting for AWS..." )
time . Sleep ( 10 * time . Second )
} ,
2018-11-07 01:21:24 +00:00
LogicalBackend : getBackend ( t ) ,
2018-10-02 14:14:16 +00:00
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
testAccStepWriteRole ( t , "test" , roleData ) ,
2022-10-31 14:52:35 +00:00
testAccStepReadSTSResponse ( "test" , uint64 ( minAwsAssumeRoleDuration ) ) , // allow a little slack
2018-10-02 14:14:16 +00:00
} ,
Teardown : func ( ) error {
return deleteTestRole ( roleName )
} ,
} )
}
2015-12-30 18:05:54 +00:00
func TestBackend_policyArnCrud ( t * testing . T ) {
2018-09-26 00:10:53 +00:00
t . Parallel ( )
2015-12-30 18:05:54 +00:00
logicaltest . Test ( t , logicaltest . TestCase {
2021-11-30 00:00:42 +00:00
AcceptanceTest : false ,
2018-11-07 01:21:24 +00:00
LogicalBackend : getBackend ( t ) ,
2015-12-30 18:05:54 +00:00
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
2018-08-16 10:38:13 +00:00
testAccStepWriteArnPolicyRef ( t , "test" , ec2PolicyArn ) ,
testAccStepReadArnPolicy ( t , "test" , ec2PolicyArn ) ,
2015-12-30 18:05:54 +00:00
testAccStepDeletePolicy ( t , "test" ) ,
testAccStepReadArnPolicy ( t , "test" , "" ) ,
} ,
} )
}
func testAccStepReadArnPolicy ( t * testing . T , name string , value string ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . ReadOperation ,
Path : "roles/" + name ,
Check : func ( resp * logical . Response ) error {
if resp == nil {
if value == "" {
return nil
}
return fmt . Errorf ( "bad: %#v" , resp )
}
2018-08-16 10:38:13 +00:00
expected := map [ string ] interface { } {
2019-09-19 23:35:12 +00:00
"policy_arns" : [ ] string { value } ,
"role_arns" : [ ] string ( nil ) ,
"policy_document" : "" ,
"credential_type" : iamUserCred ,
"default_sts_ttl" : int64 ( 0 ) ,
"max_sts_ttl" : int64 ( 0 ) ,
"user_path" : "" ,
"permissions_boundary_arn" : "" ,
2020-06-09 23:56:12 +00:00
"iam_groups" : [ ] string ( nil ) ,
2021-11-30 00:00:42 +00:00
"iam_tags" : map [ string ] string ( nil ) ,
2015-12-30 18:05:54 +00:00
}
2018-08-16 10:38:13 +00:00
if ! reflect . DeepEqual ( resp . Data , expected ) {
return fmt . Errorf ( "bad: got: %#v\nexpected: %#v" , resp . Data , expected )
2015-12-30 18:05:54 +00:00
}
return nil
} ,
}
}
2016-04-12 02:30:30 +00:00
2018-09-26 00:10:53 +00:00
func testAccStepWriteArnRoleRef ( t * testing . T , vaultRoleName , awsRoleName , awsAccountID string ) logicaltest . TestStep {
2016-04-12 02:30:30 +00:00
return logicaltest . TestStep {
Operation : logical . UpdateOperation ,
2018-09-26 00:10:53 +00:00
Path : "roles/" + vaultRoleName ,
2016-04-12 02:30:30 +00:00
Data : map [ string ] interface { } {
2018-09-26 00:10:53 +00:00
"arn" : fmt . Sprintf ( "arn:aws:iam::%s:role/%s" , awsAccountID , awsRoleName ) ,
2016-04-12 02:30:30 +00:00
} ,
}
}
2018-03-13 14:35:10 +00:00
2020-06-09 23:56:12 +00:00
func TestBackend_iamGroupsCrud ( t * testing . T ) {
t . Parallel ( )
logicaltest . Test ( t , logicaltest . TestCase {
2021-11-30 00:00:42 +00:00
AcceptanceTest : false ,
2020-06-09 23:56:12 +00:00
LogicalBackend : getBackend ( t ) ,
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
testAccStepWriteIamGroups ( t , "test" , [ ] string { "group1" , "group2" } ) ,
testAccStepReadIamGroups ( t , "test" , [ ] string { "group1" , "group2" } ) ,
testAccStepDeletePolicy ( t , "test" ) ,
testAccStepReadIamGroups ( t , "test" , [ ] string { } ) ,
} ,
} )
}
func testAccStepWriteIamGroups ( t * testing . T , name string , groups [ ] string ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . UpdateOperation ,
Path : "roles/" + name ,
Data : map [ string ] interface { } {
"credential_type" : iamUserCred ,
"iam_groups" : groups ,
} ,
}
}
func testAccStepReadIamGroups ( t * testing . T , name string , groups [ ] string ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . ReadOperation ,
Path : "roles/" + name ,
Check : func ( resp * logical . Response ) error {
if resp == nil {
if len ( groups ) == 0 {
return nil
}
return fmt . Errorf ( "bad: %#v" , resp )
}
expected := map [ string ] interface { } {
"policy_arns" : [ ] string ( nil ) ,
"role_arns" : [ ] string ( nil ) ,
"policy_document" : "" ,
"credential_type" : iamUserCred ,
"default_sts_ttl" : int64 ( 0 ) ,
"max_sts_ttl" : int64 ( 0 ) ,
"user_path" : "" ,
"permissions_boundary_arn" : "" ,
"iam_groups" : groups ,
2021-11-30 00:00:42 +00:00
"iam_tags" : map [ string ] string ( nil ) ,
2020-06-09 23:56:12 +00:00
}
if ! reflect . DeepEqual ( resp . Data , expected ) {
return fmt . Errorf ( "bad: got: %#v\nexpected: %#v" , resp . Data , expected )
}
return nil
} ,
}
}
2021-02-26 00:03:24 +00:00
func TestBackend_iamTagsCrud ( t * testing . T ) {
logicaltest . Test ( t , logicaltest . TestCase {
2021-11-30 00:00:42 +00:00
AcceptanceTest : false ,
2021-02-26 00:03:24 +00:00
LogicalBackend : getBackend ( t ) ,
Steps : [ ] logicaltest . TestStep {
testAccStepConfig ( t ) ,
testAccStepWriteIamTags ( t , "test" , map [ string ] string { "key1" : "value1" , "key2" : "value2" } ) ,
testAccStepReadIamTags ( t , "test" , map [ string ] string { "key1" : "value1" , "key2" : "value2" } ) ,
testAccStepDeletePolicy ( t , "test" ) ,
testAccStepReadIamTags ( t , "test" , map [ string ] string { } ) ,
} ,
} )
}
func testAccStepWriteIamTags ( t * testing . T , name string , tags map [ string ] string ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . UpdateOperation ,
Path : "roles/" + name ,
Data : map [ string ] interface { } {
"credential_type" : iamUserCred ,
"iam_tags" : tags ,
} ,
}
}
func testAccStepReadIamTags ( t * testing . T , name string , tags map [ string ] string ) logicaltest . TestStep {
return logicaltest . TestStep {
Operation : logical . ReadOperation ,
Path : "roles/" + name ,
Check : func ( resp * logical . Response ) error {
if resp == nil {
if len ( tags ) == 0 {
return nil
}
return fmt . Errorf ( "vault response not received" )
}
expected := map [ string ] interface { } {
"policy_arns" : [ ] string ( nil ) ,
"role_arns" : [ ] string ( nil ) ,
"policy_document" : "" ,
"credential_type" : iamUserCred ,
"default_sts_ttl" : int64 ( 0 ) ,
"max_sts_ttl" : int64 ( 0 ) ,
"user_path" : "" ,
"permissions_boundary_arn" : "" ,
"iam_groups" : [ ] string ( nil ) ,
"iam_tags" : tags ,
}
if ! reflect . DeepEqual ( resp . Data , expected ) {
return fmt . Errorf ( "bad: got: %#v\nexpected: %#v" , resp . Data , expected )
}
return nil
} ,
}
}
2021-11-30 00:00:42 +00:00
func generateUniqueRoleName ( prefix string ) string {
return generateUniqueName ( prefix , 64 )
}
func generateUniqueUserName ( prefix string ) string {
return generateUniqueName ( prefix , 64 )
}
func generateUniqueGroupName ( prefix string ) string {
return generateUniqueName ( prefix , 128 )
}
func generateUniqueName ( prefix string , maxLength int ) string {
name := testhelpers . RandomWithPrefix ( prefix )
if len ( name ) > maxLength {
return name [ : maxLength ]
}
return name
2018-09-26 00:10:53 +00:00
}
2018-03-13 14:35:10 +00:00
type awsAccessKey struct {
2018-09-18 20:26:06 +00:00
AccessKeyID string
2018-03-13 14:35:10 +00:00
SecretAccessKey string
}
2018-08-16 10:38:13 +00:00
type credentialTestFunc func ( string , string , string ) error