From b729c60ce5fc3501337d0f9d4ea9ca1ba5366ccd Mon Sep 17 00:00:00 2001 From: stevethomas Date: Sat, 23 May 2026 17:14:43 +1000 Subject: [PATCH 1/2] feat: resolve local AWS credentials via the full provider chain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switch the local credential branch from CredentialProvider::ini() to defaultProvider() (with AWS_PROFILE set from the keyed env) so a credential_process profile — e.g. 1Password-backed short-lived credentials — resolves alongside plain static access keys. Backwards compatible: only the local branch changes (CI and on-AWS paths untouched), and a static key+secret profile still resolves via the chain's ini link. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/Concerns/RegistersAws.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Concerns/RegistersAws.php b/src/Concerns/RegistersAws.php index 6fd516b..8567779 100644 --- a/src/Concerns/RegistersAws.php +++ b/src/Concerns/RegistersAws.php @@ -85,11 +85,19 @@ protected static function awsCredentials(): callable|array|null } // otherwise we are using a local env value to point to the correct AWS profile. - if (in_array(Helpers::keyedEnv('AWS_PROFILE'), ['', null, 'default'])) { + $profile = Helpers::keyedEnv('AWS_PROFILE'); + + if (in_array($profile, ['', null, 'default'])) { throw new IntegrityCheckException(sprintf('Using the default AWS profile in your credentials file is risky. Name your profile to something specific and update %s in your .env file before proceeding.', Helpers::keyedEnvName('AWS_PROFILE'))); } - return CredentialProvider::ini(Helpers::keyedEnv('AWS_PROFILE')); + // Resolve through the full credential chain rather than ini() alone, so a + // `credential_process` profile (e.g. 1Password-backed short-lived creds) + // resolves alongside plain static keys. defaultProvider() selects the + // profile from the AWS_PROFILE env var. + putenv("AWS_PROFILE={$profile}"); + + return CredentialProvider::defaultProvider(); } protected static function detectLocalEnvironment(): bool From 34295d54c1bfdfb6a113081c725effd12fe7b36d Mon Sep 17 00:00:00 2001 From: stevethomas Date: Sat, 23 May 2026 17:23:36 +1000 Subject: [PATCH 2/2] refactor: scope credential chain to the profile without env mutation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit defaultProvider() only selects the profile from $AWS_PROFILE, so the earlier approach set it via putenv. Replace with an explicit memoised chain (process + ini against both the credentials and config files) scoped to the keyed profile — no environment mutation, and no fall- through to the IMDS provider on a misconfigured local profile. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/Concerns/RegistersAws.php | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Concerns/RegistersAws.php b/src/Concerns/RegistersAws.php index 8567779..6bccc79 100644 --- a/src/Concerns/RegistersAws.php +++ b/src/Concerns/RegistersAws.php @@ -91,13 +91,22 @@ protected static function awsCredentials(): callable|array|null throw new IntegrityCheckException(sprintf('Using the default AWS profile in your credentials file is risky. Name your profile to something specific and update %s in your .env file before proceeding.', Helpers::keyedEnvName('AWS_PROFILE'))); } - // Resolve through the full credential chain rather than ini() alone, so a - // `credential_process` profile (e.g. 1Password-backed short-lived creds) - // resolves alongside plain static keys. defaultProvider() selects the - // profile from the AWS_PROFILE env var. - putenv("AWS_PROFILE={$profile}"); - - return CredentialProvider::defaultProvider(); + // Resolve the named profile through credential_process and static keys in + // both the credentials and config files, so a `credential_process` profile + // (e.g. 1Password-backed short-lived creds) resolves alongside plain static + // keys. Built explicitly rather than via defaultProvider() — which only + // reads the profile from $AWS_PROFILE — so the profile stays scoped without + // mutating the environment. Memoised so credentials resolve once per run. + $configFile = CredentialProvider::getConfigFileName(); + + return CredentialProvider::memoize( + CredentialProvider::chain( + CredentialProvider::process($profile), + CredentialProvider::ini($profile), + CredentialProvider::process('profile ' . $profile, $configFile), + CredentialProvider::ini('profile ' . $profile, $configFile), + ) + ); } protected static function detectLocalEnvironment(): bool