Skip to content

Add AWS IAM Roles Anywhere authentication to s3, sqs and sqs-files adapters#302

Open
maximelb wants to merge 2 commits into
masterfrom
aws-roles-anywhere
Open

Add AWS IAM Roles Anywhere authentication to s3, sqs and sqs-files adapters#302
maximelb wants to merge 2 commits into
masterfrom
aws-roles-anywhere

Conversation

@maximelb

@maximelb maximelb commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds support for authenticating to AWS using IAM Roles Anywhere as an alternative to long-lived access keys, for the three adapters that talk to AWS: s3, sqs and sqs-files (which covers CloudTrail-style S3 bucket ingestion).

Instead of pasting a permanent access_key/secret_key, users can now provide an X.509 certificate + private key issued under a CA they registered as a Roles Anywhere trust anchor, along with the trust anchor / profile / role ARNs. The adapter exchanges the certificate for temporary session credentials via the Roles Anywhere CreateSession API and refreshes them automatically before expiry. The AWS credentials in use are always short-lived, the certificate is revocable and expiring, and no permanent IAM user is needed.

Configuration

New optional roles_anywhere block on the three adapter configs, mutually exclusive with access_key/secret_key:

roles_anywhere:
  certificate: <PEM leaf cert, optionally followed by its chain>
  private_key: <PEM RSA or ECDSA key (PKCS#8, PKCS#1 or SEC1)>
  trust_anchor_arn: arn:aws:rolesanywhere:us-east-1:123456789012:trust-anchor/UUID
  profile_arn: arn:aws:rolesanywhere:us-east-1:123456789012:profile/UUID
  role_arn: arn:aws:iam::123456789012:role/my-role

PEM values may also be passed on a single line with \n escapes (convenient for UI/CLI configs). The region and endpoint are derived from the trust anchor ARN, including GovCloud and CN partitions. Existing configs using access keys are unaffected.

Implementation notes

  • CreateSession uses a SigV4 variant (SigV4-X509) that is deliberately not implemented in any AWS SDK. The official rolesanywhere-credential-helper cannot be imported as a library without pulling in a cgo PKCS#11 dependency, which would break this repo's cross-compilation (AIX, Solaris, BSDs...). The signing process is small and publicly documented, so it is implemented directly in utils/aws_roles_anywhere.go per the official signing spec, using only the standard library.
  • The provider plugs into the existing aws-sdk-go v1 credentials.Provider interface with expiry-based auto-refresh (5 minutes before expiration).
  • Certificate chains are supported via the X-Amz-X509-Chain signed header for setups where the trust anchor is a root CA and the client cert is issued by an intermediate.

Testing

  • Mock Roles Anywhere server that validates requests exactly like the real service: it rebuilds the canonical request from the received headers and verifies the SigV4-X509 signature against the public key of the certificate presented in X-Amz-X509, for both RSA and ECDSA keys, including the serial-number credential field and algorithm/key-type match.
  • Tests for certificate chain handling, single-line escaped PEM input, non-2xx API responses, endpoint derivation from ARNs across partitions, and invalid PEM/ARN inputs.
  • Config validation tests for all three adapters covering the static-keys/Roles-Anywhere either-or logic.
  • go build ./..., go vet and go test on all touched packages pass, plus cross-compile checks for aix/ppc64 and windows/amd64.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SiRyZ4DwMZtcpeYWh8oFFx

…apters

Allows authenticating to AWS with short-lived credentials derived from
an X.509 certificate instead of long-lived access keys. The adapter
calls the Roles Anywhere CreateSession API (SigV4-X509, implemented
here since no AWS SDK supports it natively and the official credential
helper pulls in cgo, breaking cross-compilation) and refreshes the
temporary session credentials automatically before expiry.

Configured via a new roles_anywhere config block (certificate,
private_key, trust_anchor_arn, profile_arn, role_arn) that is mutually
exclusive with access_key/secret_key. Existing configs are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SiRyZ4DwMZtcpeYWh8oFFx
lcbill
lcbill previously approved these changes Jul 6, 2026
- Propagate request contexts into the credential fetch
  (credentials.ProviderWithContext) and retry transient CreateSession
  failures (network errors, 429, 5xx) so a blip during a mid-run
  credential refresh no longer kills SQS-based adapters.
- Resolve the Roles Anywhere endpoint through the SDK endpoint data
  instead of hand-building the domain, fixing GovCloud/CN/ISO
  partition suffixes.
- Identify the leaf certificate by matching the private key so PEM
  bundles work in any order (CA-first or leaf-first), with a clear
  local error when the key matches no certificate.
- Floor the credential expiration so a badly skewed local clock
  degrades to a periodic refresh instead of one CreateSession call
  per SDK request.
- Enforce the auth config rules in NewAWSCredentials as well, since
  the general container builds adapters without calling Validate().
- sqs-files: use the configured credentials for the bucket-region
  lookup (previously fell back to the default ambient chain), build
  the S3 client from the S3 session, and actually mark the S3 SDK
  as initialized instead of rebuilding it for every file.
- Redact secret_key/private_key values in the config printed by the
  general container at startup.
- Precompute the immutable signed-request components at provider
  construction.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SiRyZ4DwMZtcpeYWh8oFFx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants