README.md

aws_credentials
===============

[![Actions Status](https://github.com/aws-beam/aws_credentials/workflows/Build/badge.svg)](https://github.com/aws-beam/aws_credentials/actions)

This is a library to retrieve AWS credentials from a variety of possible
sources in the following default order:

1. Erlang environment variables
2. OS environment variables
3. An AWS [credentials file][1]
4. ECS task credentials
5. EC2 metadata

Dependencies
------------
This library depends on the following libraries:

* [iso8601][2]
* [jsx][6]
* [eini][3]

Implementation
--------------
Each possible location for credentials is an Erlang module which implements the
[aws_credentials_provider][4] behaviour.  The first provider to respond with
(apparently) valid credentials stops evaluation of later providers.

### Adding a new provider ###
If you want to add a new provider, you simply implement the behaviour and add
the module name to the default list of modules to attempt.

### Provider return values ###
Providers are expected to return either `{error, Reason :: term()}` or
`{ok, Credentials :: map(), Expiration :: infinity | binary() | pos_integer()}`.
The Credentials map typically looks like the following:

```erlang
#{
  provider_source => Provider :: atom(),
  access_key_id => AccessKey :: binary(),
  secret_access_key => SecretKey :: binary(),
  token => Token :: binary(),
  region => Region :: binary()
}
```
Not all providers will populate all map keys.

The expiration time from a provider can either be expressed as:
* the atom `infinity`,
* epoch seconds as an integer, or,
* as an ISO8601 time/date string (e.g., "2019-03-14T23:45:56Z").

If you specify the expiration as `infinity` the library will *never* attempt to
refresh credentials.

When credentials have been found, they will be cached in a gen_server until the
credential's expiration time. 5 minutes before expiration time the gen_server
will attempt to acquire new credentials, so credentials will automatically be
refreshed in the background.

Usage
-----
Include the library in your rebar.config file, and then...

```erlang
{ok, _} = application:ensure_all_started(aws_credentials),
Credentials = aws_credentials:get_credentials(),
```

By default if the library is unable to obtain credentials, it will fail to
start with a `bad_match` exception, however if you set `fail_if_unavailable`
to `false` then the library will ignore the exception and attempt to
fetch credentials again after 5 seconds.

It is best practice to **not** cache these credentials inside of your own
application. Always use the aws_credentials library to retrieve them - this way
you will always get "fresh" credentials from the internal state of the
application.

### Choosing certain credentials providers ###

If you want to change the order of providers used to retrieve credentials, you
can change the list of modules in your erlang environment variables as in
this example:

```erlang
  {aws_credentials, [{credential_providers, [aws_credentials_ecs]}]
  },
```

Different credential providers may have other settings which you can use to
change their behaviors.  See the documentation for each provider for more
details.

Error Logging
-------------

If you prefer to not log errors as they happen (the default behavior), but accumulate
them for later, you can set erlang environment variable `log_errors_immediately` to
`false` as in this example:

```erlang
  {aws_credentials, [{log_errors_immediately, false}]
  },
```

License and copyright
---------------------
This project is licensed under the terms of the Apache 2 license. It is a
heavily modified fork of the original [aws-erlang-metadata][5] project.

Copyright (C) 2018 by Mark R. Allen.

[1]: https://docs.aws.amazon.com/cli/latest/userguide/cli-config-files.html
[2]: https://github.com/erlsci/iso8601
[3]: https://github.com/aws-beam/eini
[4]: src/aws_credentials_provider.erl
[5]: https://github.com/aws-beam/aws-erlang-metadata
[6]: https://github.com/talentdeficit/jsx