diff --git a/README.md b/README.md index 7e5b8f7..698cb6a 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,9 @@ AWS_SECRET_ACCESS_KEY ``` [https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html) +### Key Rotation +If key rotation is enabled, the most recent next rotation date is cached and if it's in the past we force getting the secrets. + ### Testing ``` bash diff --git a/config/config.php b/config/config.php index cb0988b..85e4056 100644 --- a/config/config.php +++ b/config/config.php @@ -88,6 +88,17 @@ 'cache-store' => 'file', + /* + |-------------------------------------------------------------------------- + | Key rotation + |-------------------------------------------------------------------------- + | + | If key rotation is enabled, force retrieving config if NextRotationDate is in the past + | + */ + + 'key-rotation' => env('AWS_SECRETS_KEY_ROTATION', false), + /* |-------------------------------------------------------------------------- | Debugging diff --git a/src/LaravelAwsSecretsManager.php b/src/LaravelAwsSecretsManager.php index ece8d4c..6921d02 100644 --- a/src/LaravelAwsSecretsManager.php +++ b/src/LaravelAwsSecretsManager.php @@ -3,6 +3,7 @@ namespace Tapp\LaravelAwsSecretsManager; use Aws\SecretsManager\SecretsManagerClient; +use Carbon\Carbon; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Log; @@ -33,6 +34,8 @@ public function __construct() $this->enabledEnvironments = config('aws-secrets-manager.enabled-environments', []); $this->debug = config('aws-secrets-manager.debug', false); + + $this->keyRotation = config('aws-secrets-manager.key-rotation'); } public function loadSecrets() @@ -61,6 +64,16 @@ public function loadSecrets() protected function checkCache() { + if ($this->keyRotation) { + $cachedNextRotationDate = Cache::store($this->cacheStore)->get('AWSSecretsNextRotationDate'); + if ( + blank($cachedNextRotationDate) || + $cachedNextRotationDate < Carbon::now() + ) { + return false; + } + } + foreach ($this->configVariables as $variable => $configPath) { $val = Cache::store($this->cacheStore)->get($variable); @@ -101,6 +114,10 @@ protected function getVariables() return; } + if ($this->keyRotation) { + $nextRotationDateToCache = null; + } + foreach ($secrets['SecretList'] as $secret) { if (isset($secret['ARN'])) { $result = $this->client->getSecretValue([ @@ -110,6 +127,13 @@ protected function getVariables() $secretValues = json_decode($result['SecretString'], true); if (is_array($secretValues) && count($secretValues) > 0) { + if ($this->keyRotation) { + $nextRotationDate = Carbon::instance($secret['NextRotationDate']); + if ($nextRotationDate < $nextRotationDateToCache) { + $nextRotationDateToCache = $nextRotationDate; + } + } + if (isset($secretValues['name']) && isset($secretValues['value'])) { $key = $secretValues['name']; $secret = $secretValues['value']; @@ -124,6 +148,10 @@ protected function getVariables() } } } + + if ($this->keyRotation) { + $this->storeToCache('AWSSecretsNextRotationDate', $nextRotationDateToCache); + } } protected function updateConfigs()