Automated AWS Credential Renewal Using SPIFFE Helper and IAM Roles Anywhere
In Grant AWS Access to GitHub Codespaces via SPIFFE/SPIRE & IAM Roles Anywhere, we demonstrated how to authenticate to AWS using SPIRE-issued X.509 certificates and IAM Roles Anywhere.
While it works, this approach requires manual intervention: you need to repeatedly request new SVIDs when they expire after an hour, as well as manually call the Roles Anywhere credential helper each time to obtain AWS credentials. But what if we could automate this entire process?
Enter spiffe-helper. It takes care of fetching X.509 SVID certificates from the SPIFFE agent, launching a process to use them, and automatically renewing and reloading certificates as needed. Let's combine these two to good use.
We'll use the serve
command of the rolesanywhere credential helper which vends temporary security credentials from IAM Roles Anywhere through a local endpoint. We'll invoke this via spiffe-helper and if all goes to plan, never need to lift a finger.
Set up the aws rolesanywhere credential helper
You can download the roles anywhere credential helper from the AWS docs page here but if you encounter issues running the executable like I did, you could also just build from source.
-
Clone the repo
-
Follow the instructions in the readme to download the build dependencies for your OS. Basically, you need
git
,gcc
,GNU make
, andgolang
. -
Build the executable
-
Copy the executable and test it by running the help menu
&&
You should see :
$ ~/aws_signing_helper -h A tool that utilizes certificates and their associated private keys to sign requests to AWS IAM Roles Anywhere's CreateSession API and retrieve temporary AWS security credentials. This tool exposes multiple commands to make credential retrieval and rotation more convenient. Usage: aws_signing_helper [command] [flags] aws_signing_helper [command] Available Commands: completion Generate the autocompletion script for the specified shell credential-process Retrieve AWS credentials in the appropriate format for external credential processes help Help about any command read-certificate-data Diagnostic command to read certificate data serve Serve AWS credentials through a local endpoint sign-string Signs a fixed string using the passed-in private key (or reference to private key) update Updates a profile in the AWS credentials file with new AWS credentials version Prints the version number of the credential helper Flags: -h, --help help for aws_signing_helper Use "aws_signing_helper [command] --help" for more information about a command.
Set up spiffe-helper
If you're on a linux machine, you're in luck - you can just grab the binaries from the releases page and move on to the next section. The rest of us have to build it ourselves, but since its a go
project, this is pretty straightforward.
-
Clone the repo
-
Build the executable
-
Test the executable by running the help menu
You should see :
$ ./spiffe-helper -h Usage of ./spiffe-helper: -config string <configFile> Configuration file path (default "helper.conf") -daemon-mode Toggle running as a daemon
-
Configure SPIFFE Helper
The repository includes a
helper.conf
configuration file that needs customization. Make these essential changes:- Set the command to be executed (
cmd
) - Specify the command arguments (
cmd_args
) - Enable
add_intermediates_to_bundle
by setting it totrue
The last setting is particularly important - it ensures the SPIRE intermediate CA certificate is included in the bundle file after the Root CA certificate. Without this, you'll encounter an
AccessDeniedException: Untrusted signing certificate
error when trying to authenticate."/tmp/spire-agent/public/api.sock" "~/aws_signing_helper" "serve --certificate /tmp/svid.0.pem --private-key /tmp/svid.0.key --intermediates /tmp/bundle.0.pem --trust-anchor-arn arn:aws:rolesanywhere:us-east-1:012345678901:trust-anchor/9f455be1-f25f-495b-9e99-f6a630d62cbb --profile-arn arn:aws:rolesanywhere:us-east-1:012345678901:profile/737869f1-ffd0-4674-ac2b-f3d6895b4499 --role-arn arn:aws:iam::012345678901:role/test" "/tmp" "SIGUSR1" "svid.0.pem" "svid.0.key" "bundle.0.pem" true
- Set the command to be executed (
-
Run the helper
You should see the following:
$ ./spiffe-helper -config helper.conf INFO[0000] Using configuration file: "helper.conf" system=spiffe-helper INFO[0000] Launching daemon system=spiffe-helper INFO[0000] Watching for X509 Context system=spiffe-helper INFO[0000] Received update spiffe_id="spiffe://misaac.me/myservice" system=spiffe-helper INFO[0000] X.509 certificates updated system=spiffe-helper 2025/05/24 09:19:18 Local server started on port: 9911 2025/05/24 09:19:18 Make it available to the sdk by running: 2025/05/24 09:19:18 export AWS_EC2_METADATA_SERVICE_ENDPOINT=http://127.0.0.1:9911/
Profit
The final steps are simple. Open a terminal and set the AWS_EC2_METADATA_SERVICE_ENDPOINT
environment variable to point to your local endpoint:
Then delete any existing credentials:
Now, simply run your application or any AWS CLI command as usual. The AWS SDKs and CLI will automatically detect the AWS_EC2_METADATA_SERVICE_ENDPOINT
environment variable and fetch credentials from the local endpoint provided by the credential helper. No changes to your application code are required—credential renewal and retrieval are handled transparently in the background.
Let's run whoami
.
$ aws sts get-caller-identity
{
"UserId": "AROADBQP57FF2AEXAMPLE:30a7fe7d714958787f6075c9904ce642",
"Account": "012345678901",
"Arn": "arn:aws:sts::012345678901:assumed-role/test/30a7fe7d714958787f6075c9904ce642"
}
Wrapping Up
By integrating the SPIFFE Helper with IAM Roles Anywhere’s credential helper, we’ve removed the need for manual SVID renewals and AWS credential refreshes. This approach is especially useful for legacy applications that need certificates but can't natively support SPIFFE authentication.
A natural next step is deploying this setup on Kubernetes with the spiffe-helper and the rolesanywhere helper running as sidecars alongside another application. In a future post, we’ll walk through exactly that.