Use a credential provider
A credential provider is a function that returns a
GuzzleHttp\Promise\PromiseInterface
that is fulfilled with an
Aws\Credentials\CredentialsInterface
instance or rejected with an
Aws\Exception\CredentialsException
. You can use credential providers to
implement your own custom logic for creating credentials or to optimize credential
loading.
Credential providers are passed into the credentials
client constructor
option. Credential providers are asynchronous, which forces them to be lazily evaluated each
time an API operation is invoked. As such, passing in a credential provider function to an
SDK client constructor doesn’t immediately validate the credentials. If the credential
provider doesn’t return a credentials object, an API operation will be rejected with an
Aws\Exception\CredentialsException
.
use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; // Use the default credential provider $provider = CredentialProvider::defaultProvider(); // Pass the provider to the client $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);
Built-In Providers in the SDK
The SDK provides several built-in providers that you can combine with any custom providers. For more information on configuring the standardized providers and the credential provider chain in AWS SDKs, see Standardized credential providers in the AWS SDKs and Tools Reference Guide.
Important
Credential providers are invoked every time an API operation is performed. If
loading credentials is an expensive task (e.g., loading from disk or a network
resource), or if credentials are not cached by your provider, consider wrapping your
credential provider in an Aws\Credentials\CredentialProvider::memoize
function. The default credential provider used by the SDK is automatically
memoized.
assumeRole provider
If you use Aws\Credentials\AssumeRoleCredentialProvider
to create
credentials by assuming a role, you need to provide 'client'
information
with an StsClient
object and 'assume_role_params'
details, as
shown.
Note
To avoid unnecessarily fetching AWS STS credentials on every API operation, you can
use the memoize
function to handle automatically refreshing the
credentials when they expire. See the following code for an example.
use Aws\Credentials\CredentialProvider; use Aws\Credentials\InstanceProfileProvider; use Aws\Credentials\AssumeRoleCredentialProvider; use Aws\S3\S3Client; use Aws\Sts\StsClient; // Passing Aws\Credentials\AssumeRoleCredentialProvider options directly $profile = new InstanceProfileProvider(); $ARN = "arn:aws:iam::123456789012:role/xaccounts3access"; $sessionName = "s3-access-example"; $assumeRoleCredentials = new AssumeRoleCredentialProvider([ 'client' => new StsClient([ 'region' => 'us-east-2', 'version' => '2011-06-15', 'credentials' => $profile ]), 'assume_role_params' => [ 'RoleArn' => $ARN, 'RoleSessionName' => $sessionName, ], ]); // To avoid unnecessarily fetching STS credentials on every API operation, // the memoize function handles automatically refreshing the credentials when they expire $provider = CredentialProvider::memoize($assumeRoleCredentials); $client = new S3Client([ 'region' => 'us-east-2', 'version' => '2006-03-01', 'credentials' => $provider ]);
For more information regarding 'assume_role_params'
, see AssumeRole.
SSO provider
Aws\Credentials\CredentialProvider::sso
is the single sign-on credential
provider. This provider is also known as the AWS IAM Identity Center credential provider.
use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $credentials = new Aws\CredentialProvider::sso('profile default'); $s3 = new Aws\S3\S3Client([ 'version' => 'latest', 'region' => 'us-west-2', 'credentials' => $credentials ]);
If you use a named profile, substitute the name of your profile for
‘default
’ in the previous example. To learn more about setting up named
profiles, see Shared
config
and credentials
files in the
AWS SDKs and Tools Reference Guide. Alternatively, you can use the AWS_PROFILE
environment variable to specify which
profile's settings to use.
To understand more how the IAM Identity Center provider works, see Understand IAM Identity Center authentication in the AWS SDKs and Tools Reference Guide.
Chaining providers
You can chain credential providers by using the
Aws\Credentials\CredentialProvider::chain()
function. This function
accepts a variadic number of arguments, each of which are credential provider functions.
This function then returns a new function that’s the composition of the provided
functions, such that they are invoked one after the other until one of the providers
returns a promise that is fulfilled successfully.
The defaultProvider
uses this composition to check multiple providers
before failing. The source of the defaultProvider
demonstrates the use of
the chain
function.
// This function returns a provider public static function defaultProvider(array $config = []) { // This function is the provider, which is actually the composition // of multiple providers. Notice that we are also memoizing the result by // default. return self::memoize( self::chain( self::env(), self::ini(), self::instanceProfile($config) ) ); }
Creating a custom provider
Credential providers are simply functions that when invoked return a promise
(GuzzleHttp\Promise\PromiseInterface
) that is fulfilled with an
Aws\Credentials\CredentialsInterface
object or rejected with an
Aws\Exception\CredentialsException
.
A best practice for creating providers is to create a function that is invoked to
create the actual credential provider. As an example, here’s the source of the
env
provider (slightly modified for example purposes). Notice that it
is a function that returns the actual provider function. This allows you to easily
compose credential providers and pass them around as values.
use GuzzleHttp\Promise; use GuzzleHttp\Promise\RejectedPromise; // This function CREATES a credential provider public static function env() { // This function IS the credential provider return function () { // Use credentials from environment variables, if available $key = getenv(self::ENV_KEY); $secret = getenv(self::ENV_SECRET); if ($key && $secret) { return Promise\promise_for( new Credentials($key, $secret, getenv(self::ENV_SESSION)) ); } $msg = 'Could not find environment variable ' . 'credentials in ' . self::ENV_KEY . '/' . self::ENV_SECRET; return new RejectedPromise(new CredentialsException($msg)); }; }
defaultProvider provider
Aws\Credentials\CredentialProvider::defaultProvider
is the default
credential provider. This provider is used if you omit a credentials
option
when creating a client. It first attempts to load credentials from environment
variables, then from an .ini file (an .aws/credentials
file first, followed
by an .aws/config
file), and then from an instance profile
(EcsCredentials
first, followed by Ec2
metadata).
Note
The result of the default provider is automatically memoized.
ecsCredentials provider
Aws\Credentials\CredentialProvider::ecsCredentials
attempts to load
credentials by a GET
request, whose URI is specified by the environment
variable AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
in the container.
use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $provider = CredentialProvider::ecsCredentials(); // Be sure to memoize the credentials $memoizedProvider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $memoizedProvider ]);
env provider
Aws\Credentials\CredentialProvider::env
attempts to load credentials from
environment variables.
use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => CredentialProvider::env() ]);
assumeRoleWithWebIdentityCredentialProvider provider
Aws\Credentials\CredentialProvider::assumeRoleWithWebIdentityCredentialProvider
attempts to load credentials by assuming a role. If the environment variables
AWS_ROLE_ARN
and AWS_WEB_IDENTITY_TOKEN_FILE
are present,
the provider will attempt to assume the role specified at AWS_ROLE_ARN
using the token on disk at the full path specified in
AWS_WEB_IDENTITY_TOKEN_FILE
. If environment variables are used, the
provider will attempt to set the session from the AWS_ROLE_SESSION_NAME
environment variable.
If environment variables are not set, the provider will use the default profile, or
the one set as AWS_PROFILE
. The provider reads profiles from
~/.aws/credentials
and ~/.aws/config
by default, and can
read from profiles specified in the filename
config option. The provider
will assume the role in role_arn
of the profile, reading a token from the
full path set in web_identity_token_file
. role_session_name
will be used if set on the profile.
The provider is called as part of the default chain and can be called directly.
use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $provider = CredentialProvider::assumeRoleWithWebIdentityCredentialProvider(); // Cache the results in a memoize function to avoid loading and parsing // the ini file on every API operation $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);
By default, this credential provider will inherit the configured region which will be
used by the StsClient to assume the role. Optionally, a full StsClient can be provided.
Credentials should be set as false
on any provided StsClient.
use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; use Aws\Sts\StsClient; $stsClient = new StsClient([ 'region' => 'us-west-2', 'version' => 'latest', 'credentials' => false ]) $provider = CredentialProvider::assumeRoleWithWebIdentityCredentialProvider([ 'stsClient' => $stsClient ]); // Cache the results in a memoize function to avoid loading and parsing // the ini file on every API operation $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);
ini provider
Aws\Credentials\CredentialProvider::ini
attempts to load credentials from
an ini credential file. By default, the SDK attempts
to load the “default” profile from the shared AWS credentials
file located at
~/.aws/credentials
.
use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $provider = CredentialProvider::ini(); // Cache the results in a memoize function to avoid loading and parsing // the ini file on every API operation $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);
You can use a custom profile or .ini file location by providing arguments to the function that creates the provider.
$profile = 'production'; $path = '/full/path/to/credentials.ini'; $provider = CredentialProvider::ini($profile, $path); $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);
process provider
Aws\Credentials\CredentialProvider::process
attempts to load credentials
from a credential_process specified in an ini credential
file. By default, the SDK attempts to load the “default” profile from the
shared AWS credentials
file located at ~/.aws/credentials
. The SDK will call the
credential_process command exactly as given and then read JSON data from stdout. The
credential_process must write credentials to stdout in the following format:
{ "Version": 1, "AccessKeyId": "", "SecretAccessKey": "", "SessionToken": "", "Expiration": "" }
SessionToken
and Expiration
are optional. If present, the
credentials will be treated as temporary.
use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $provider = CredentialProvider::process(); // Cache the results in a memoize function to avoid loading and parsing // the ini file on every API operation $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);
You can use a custom profile or .ini file location by providing arguments to the function that creates the provider.
$profile = 'production'; $path = '/full/path/to/credentials.ini'; $provider = CredentialProvider::process($profile, $path); $provider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $provider ]);
instanceProfile provider
Aws\Credentials\CredentialProvider::instanceProfile
attempts to load
credentials from Amazon EC2 instance profiles.
use Aws\Credentials\CredentialProvider; use Aws\S3\S3Client; $provider = CredentialProvider::instanceProfile(); // Be sure to memoize the credentials $memoizedProvider = CredentialProvider::memoize($provider); $client = new S3Client([ 'region' => 'us-west-2', 'version' => '2006-03-01', 'credentials' => $memoizedProvider ]);
By default, the provider retries fetching credentials up to three times. The number of
retries can be set with the retries
option, and disabled entirely by
setting the option to 0
.
use Aws\Credentials\CredentialProvider; $provider = CredentialProvider::instanceProfile([ 'retries' => 0 ]); $memoizedProvider = CredentialProvider::memoize($provider);
Note
You can disable this attempt to load from Amazon EC2 instance profiles by setting the
AWS_EC2_METADATA_DISABLED
environment variable to
true
.
Memoizing credentials
At times you might need to create a credential provider that remembers the previous
return value. This can be useful for performance when loading credentials is an
expensive operation or when using the Aws\Sdk
class to share a credential
provider across multiple clients. You can add memoization to a credential provider by
wrapping the credential provider function in a memoize
function.
use Aws\Credentials\CredentialProvider; $provider = CredentialProvider::instanceProfile(); // Wrap the actual provider in a memoize function $provider = CredentialProvider::memoize($provider); // Pass the provider into the Sdk class and share the provider // across multiple clients. Each time a new client is constructed, // it will use the previously returned credentials as long as // they haven't yet expired. $sdk = new Aws\Sdk(['credentials' => $provider]); $s3 = $sdk->getS3(['region' => 'us-west-2', 'version' => 'latest']); $ec2 = $sdk->getEc2(['region' => 'us-west-2', 'version' => 'latest']); assert($s3->getCredentials() === $ec2->getCredentials());
When the memoized credentials are expired, the memoize wrapper invokes the wrapped provider in an attempt to refresh the credentials.