diff --git a/README.md b/README.md index aa5069d..5a0ec71 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,7 @@ Add dynamodb configs to `config/database.php`: 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 'token' => env('AWS_SESSION_TOKEN', null), 'endpoint' => env('DYNAMODB_ENDPOINT', null), + 'assume_role' => env('AWS_ASSUME_ROLE', null), 'prefix' => '', // table prefix ], @@ -121,12 +122,22 @@ $connection = new Kitar\Dynamodb\Connection([ 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 'token' => env('AWS_SESSION_TOKEN', null), 'endpoint' => env('DYNAMODB_ENDPOINT', null), + 'assume_role' => env('AWS_ASSUME_ROLE', null), 'prefix' => '', // table prefix ]); $connection->table('your-table')->... ``` +### Assume Role Important Notes +The `assume_role` option should be used when you need to explicitly define an IAM role. There are two main scenarios where this is supported: + +1. Using Default Credentials (e.g., EC2 IAM Role): + - Leave the `key` and `secret` parameters empty, and define the `assume_role`. The application will automatically use the default credentials available (such as the IAM role assigned to an AWS EC2 instance). + +2. Using Explicit IAM User Credentials: + - Provide both the `key` and `secret` for an IAM user that has permission to assume the specified IAM role. The application will use these credentials to assume the given IAM role. + ## Sample data Many of the example codes in this document are querying to [DynamoDB's official sample data](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AppendixSampleTables.html). If you want to try these codes with actual DynamoDB tables, it's handy to load them to your tables before. diff --git a/src/Kitar/Dynamodb/Connection.php b/src/Kitar/Dynamodb/Connection.php index e0d40be..3f14341 100644 --- a/src/Kitar/Dynamodb/Connection.php +++ b/src/Kitar/Dynamodb/Connection.php @@ -3,6 +3,8 @@ namespace Kitar\Dynamodb; use Aws\Sdk as AwsSdk; +use Aws\Sts\StsClient; +use Aws\Credentials\CredentialProvider; use Aws\DynamoDb\DynamoDbClient; use Illuminate\Database\Connection as BaseConnection; use Illuminate\Support\Arr; @@ -93,6 +95,42 @@ protected function createClient(array $config) unset($config['secret_key']); } + // Handle the AssumeRole if one is set + if ( !empty($config['assume_role']) && preg_match('/^arn:aws:iam::\d{12}:role\/[a-zA-Z0-9+=,.@_-]+$/', $config['assume_role']) ) { + try { + + // Use IAM credentials if provided, if not, try to use default discovery. e.g. Default EC2 role. + $credentials = [ + 'key' => $config['key'], + 'secret' => $config['secret'], + ]; + if ( empty($config['key']) && empty($config['secret']) ) { + $credentials = CredentialProvider::defaultProvider(); + } + + $stsClient = new StsClient([ + 'version' => '2011-06-15', + 'region' => $dynamoConfig['region'], + 'credentials' => $credentials + ]); + + // Assume the provided role + $roleCredentials = $stsClient->assumeRole([ + 'RoleArn' => $config['assume_role'], + 'RoleSessionName' => 'KitarDynamodDBConnection', + ]); + + $config = [ + 'key' => $roleCredentials['Credentials']['AccessKeyId'], + 'secret' => $roleCredentials['Credentials']['SecretAccessKey'], + 'token' => $roleCredentials['Credentials']['SessionToken'] + ]; + } catch (\Exception $e) { + throw new \Exception("The assume role failed with message: ".$e->getMessage()); + } + + } + if (isset($config['key']) && isset($config['secret'])) { $dynamoConfig['credentials'] = Arr::only( $config,