Needroleshere - Yet Another AWS IAM Roles Anywhere helper

This tool is a helper program for AWS IAM Roles Anywhere to obtain credentials using a X.509 ceritificate and corresponding private key. It works well as a drop-in replacement of the official rolesanywhere-credential-helper with some advantages including:

Install

cargo build --release --locked (not released yet)

Usage

Needroleshere offers the following modes:

Comparisons explained later.

Process credentials provider mode (process-credentials)

Needroleshere acts as a credentials helper program for process credentials provider defined in AWS SDK.

This can be used a drop-in replacement for the official and original rolesanywhere-credential-helper because this supports the same parameters and usage:

https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html

[profile myrole] credential_process = needroleshere credential-process --certificate /path/to/certificate.pem --private-key /path/to/private-key.pem --trust-anchor-arn arn:aws:rolesanywhere:region:account:trust-anchor/TA_ID --profile-arn arn:aws:rolesanywhere:region:account:profile/PROFILE_ID --role-arn arn:aws:iam::account:role/role-name-with-path

The advantage of Needroleshere than the original is a certificate PEM file passed to --certificate can contain multiple certificates so you don't have to use --intermediates if you have intermediate CAs and put such certificates in a single file (fullchain.pem).

Server mode (serve)

Server mode runs a HTTP server to act as other AWS SDK credential providers to enable using IAM Roles Anywhere for SDKs and libraries don't support process credentials provider. Currently ECS container credentials provider is implemented.

Run a server

Needroleshere supports (only) launching through systemd socket activation. Configure systemd units like as follows:

```systemd

/etc/systemd/system/needroleshere.service

[Unit] Wants=needroleshere.socket

[Service] Type=simple ExecStart=/usr/bin/needroleshere serve --region AWS_REGION RuntimeDirectory=needroleshere ```

```systemd

/etc/systemd/system/needroleshere.socket

[Socket] ListenStream=127.0.0.1:7224 FreeBind=yes IPAddressAllow=localhost IPAddressDeny=any

[Install] WantedBy=sockets.target ```

Specify User=, Group= as needed.

Use as ECS container credentials provider

Server mode supports ECS container credentials provider. To use this provider, you first need to generate a binding configuration and environment variables file using a helper command.

This provider supports using multiple roles on a single server process.

Generate binding

needroleshere bind myrole \ --mode ecs-full \ --url http://127.0.0.1:7224 \ --certificate /path/to/certificate.pem \ --private-key /path/to/private-key.pem \ --trust-anchor-arn arn:aws:rolesanywhere:region:account:trust-anchor/TA_ID \ --profile-arn arn:aws:rolesanywhere:region:account:profile/PROFILE_ID \ --role-arn arn:aws:iam::account:role/myrole \ --configuration-directory /path/to/etc/needroleshere

This will generate a configuration at /path/to/etc/needroleshere/bindings/myrole and a environment file at /path/to/etc/needroleshere/env/myrole. Treat a environment file as a secret as it includes a shared secret between Needroleshere and credentials consumer.

Running this through systemd unit is a recommended way:

```systemd

/etc/systemd/system/needroleshere-bind-somethingawesome.service

[Unit] Before=somethingawesome.service After=needroleshere.socket PartOf=somethingawesome.service Wants=needroleshere.socket needroleshere.service

[Service] Type=oneshot RemainAfterExit=yes

use of --no-validate is recommended if you run bind in a systemd unit

ExecStart=/usr/bin/needroleshere bind somethingawesome --no-validate ... ExecStop=/usr/bin/needroleshere unbind somethingawesome RuntimeDirectory=needroleshere

[Install] WantedBy=somethingawesome.service

and run systemctl enable needroleshere-bind-somethingawesome.service, or specify Wants= in somethingawesome.service

```

Load environment file and use

```systemd

/etc/systemd/system/somethingawesome.service

[Unit]

You can specify Wants= here instead of systemctl enable:

Wants=needroleshere-bind-somethingawesome.service

[Service] Type=simple EnvironmentFile=/run/needroleshere/env/somethingawesome ExecStart=...

DynamicUser=yes ```

needroleshere-bind-somethingawesome.service and needroleshere.socket will be started before somethingawesome.service automatically. If you restart somethingawesome.service, needroleshere bind will automatically re-run to rotate a shared shared secret (thanks to PartOf=).

Comparison between modes

Compatibility matrix:

  | process-credentials | ecs-full | ecs-full-query | ecs-relative | ecs-relative-query -- | -- | -- | -- | -- | -- AWS CLI v2 | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for C++ | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for Go V2 (1.x) | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for Go 1.x (V1) | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for Java 2.x | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for Java 1.x | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for JavaScript 3.x | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for JavaScript 2.x | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for .NET 3.x | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for PHP 3.x | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for Python (Boto3) | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: AWS SDK for Ruby 3.x | :whitecheckmark: |   |   |   | :whitecheckmark: AWS SDK for Rust (preview) | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: Rusoto | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: minio-go |   | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: | :whitecheckmark: fog-aws |   |   |   |   | :whitecheckmark:

process-credentials is most preferred and easy way, and use ecs-relative-query as a last resort option.

Security Model

Caveats

Configuration Examples

Setup for ecs-relative mode variants

Reconfigure your socket unit like the following. You need to update --url if you're also using ecs-full mode variants.

```systemd

/etc/systemd/system/needroleshere.socket

[Socket] ListenStream=169.254.170.2:80 FreeBind=yes

ExecStartPre=-/bin/ip address add 169.254.170.2/32 dev lo

IPAddressAllow=localhost IPAddressAllow=169.254.170.2/32 IPAddressDeny=any ```

Utilizing systemd unit template

It is possible to use systemd unit template for the needroleshere bind service unit explained above:

```systemd

/etc/systemd/system/needroleshere-bind@.service

[Unit] Before=%i.service After=needroleshere.socket PartOf=%i.service Wants=needroleshere.socket

[Service] Type=oneshot RemainAfterExit=yes ExecStart=/home/sorah/git/github.com/sorah/needroleshere/target/debug/needroleshere bind %i ... --role-arn arn:aws:iam::...:role/%i ExecStop=/home/sorah/git/github.com/sorah/needroleshere/target/debug/needroleshere unbind %i RuntimeDirectory=needroleshere

[Install] WantedBy=%i.service ```

then systemctl enable needroleshere-bind@somethingawesome.service to pair with somethingawesome.service.

Development

Server

run with systemfd and cargo-watch. the following is a shorthand to start on 127.0.0.1:3000:

./dev/serve.sh

To test credentials provider is working, use the following script; it run needroleshere bind with the given argument and pass to aws sts get-caller-identity.

./dev/roundtrip-gci.sh --region ap-northeast-1 \ --trust-anchor-arn TA_ARN \ --profile-arn PROFILE_ARN \ --role-arn ROLE_ARN \ --private-key path/to/key.pem \ --certificate path/to/fullchain.pem \ --no-validate \ --mode ecs-full

License

This project is licensed under the Apache-2.0 License.

Copyright 2022 Sorah Fukumori

Copyright Notice