feat(aws): support container credentials in AwsNativeSource#659
Closed
nidcode wants to merge 1 commit into
Closed
Conversation
When running on ECS Fargate (task IAM role), EKS Pod Identity, AWS Greengrass, or any other environment exposing credentials through the container credentials provider, AWS does not place the static credentials in the standard `AWS_*_KEY_ID` environment variables and the EC2 IMDS-style `securityCredentialsUrl` does not apply because the endpoint returns the credential JSON directly without a role-name suffix. Today `AwsNativeSource::fetchSubjectToken()` only attempts environment variables and the `securityCredentialsUrl` constructor argument, which makes the WIF flow unusable in those environments without a separate shim that resolves AWS credentials via aws-sdk-php and re-exports them into `putenv` before the call. Add a third resolution path that consumes `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` / `AWS_CONTAINER_CREDENTIALS_FULL_URI` (with optional `AWS_CONTAINER_AUTHORIZATION_TOKEN` / `AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE` headers), per https://docs.aws.amazon.com/sdkref/latest/guide/feature-container-credentials.html. The endpoint returns a JSON body using the same `AccessKeyId` / `SecretAccessKey` / `Token` schema as the EC2 credentials endpoint, so the rest of the SigV4 signing pipeline is unchanged. Resolution order in `fetchSubjectToken`: 1. `AWS_ACCESS_KEY_ID` env (existing) 2. Container credentials endpoint (new) 3. EC2 IMDS-style `securityCredentialsUrl` (existing) 4. throw `LogicException` The exception message is updated to reflect the new third option, and the existing tests for the throw path are adjusted accordingly. New unit tests cover: - container env vars unset → return null - relative-uri → http://169.254.170.2 endpoint, no Authorization - full-uri + AWS_CONTAINER_AUTHORIZATION_TOKEN, optional Token field - end-to-end fetchSubjectToken from container credentials produces a SigV4-signed subject token using the access key returned by the container endpoint.
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Author
|
Apologies for the noise — closing this for now while we keep using a downstream env-var bridge in our application bootstrap. Happy to re-open later if there is upstream interest in container credentials support for AwsNativeSource. Feel free to reuse the patch from https://github.com/nidcode/google-auth-library-php/tree/feat/aws-native-source-ecs-container-credentials. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When running on ECS Fargate (task IAM role), EKS Pod Identity, AWS Greengrass, or any other environment that exposes credentials via the container credentials provider, the WIF (
external_account/ AWS) credential flow fails:AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYare not in the environment — the credential URI is exposed viaAWS_CONTAINER_CREDENTIALS_RELATIVE_URI/AWS_CONTAINER_CREDENTIALS_FULL_URIinstead.AwsNativeSource::getSigningVarsFromUrl()is hard-coded to the EC2 IMDS pattern (<securityCredentialsUrl>/<role-name>); the ECS / EKS endpoint returns the credential JSON directly without a role-name suffix, so even pointingsecurityCredentialsUrlat the ECS URL would not work.The user-visible failure today is:
…even though the same task can resolve credentials with
aws-sdk-php'sCredentialProvider::defaultProvider(). This forces downstream applications to add a "bridge" in their bootstrap code that resolves AWS credentials via aws-sdk-php andputenvs them so thatAwsNativeSourcecan pick them up — clearly something the auth library should be able to do natively.Change
Add a third credential resolution step in
AwsNativeSource::fetchSubjectToken(), slotted between the existing ENV lookup and the existing IMDS-stylesecurityCredentialsUrlfallback:AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYenvAWS_CONTAINER_CREDENTIALS_{RELATIVE,FULL}_URIsecurityCredentialsUrlconstructor argLogicExceptionThe new path:
AWS_CONTAINER_CREDENTIALS_RELATIVE_URIand prefixes it withhttp://169.254.170.2, OR usesAWS_CONTAINER_CREDENTIALS_FULL_URIdirectly.AWS_CONTAINER_AUTHORIZATION_TOKEN(literal) andAWS_CONTAINER_AUTHORIZATION_TOKEN_FILE(file contents) by setting anAuthorization:header on the GET request — required by EKS Pod Identity and IAM Roles Anywhere container scenarios.AccessKeyId/SecretAccessKey/Token) — same schema as the EC2 metadata response — so the rest of the SigV4 pipeline is unchanged.nullwhen no container credentials env var is set, so the caller falls through to the existingsecurityCredentialsUrlpath.The new method
getSigningVarsFromContainerCredentials()mirrors the visibility (public static, marked@internal) ofgetSigningVarsFromEnv()/getSigningVarsFromUrl()for consistency and testability.Tests
Four new tests under
tests/CredentialSource/AwsNativeSourceTest.php:testGetSigningVarsFromContainerCredentialsReturnsNullWhenEnvNotSet— guarantees the new path is opt-in (HTTP handler must not be invoked when no env var is set).testGetSigningVarsFromContainerCredentialsRelativeUri— verifies thehttp://169.254.170.2prefix and the absence of anAuthorization:header for the ECS Fargate task-role case.testGetSigningVarsFromContainerCredentialsFullUriWithAuthToken— covers EKS Pod Identity (FULL_URI+AWS_CONTAINER_AUTHORIZATION_TOKEN) and the optional-Token-in-response case.testFetchSubjectTokenFromContainerCredentials— end-to-end: withAWS_CONTAINER_CREDENTIALS_RELATIVE_URIset and nosecurityCredentialsUrl,fetchSubjectToken()produces a SigV4-signed STS GetCallerIdentity request whoseAuthorizationheader references the access key fetched from the container endpoint.The existing
testFetchSubjectTokenWithoutSecurityCredentialsUrlOrEnvThrowsExceptionis updated for the new exception message.Backwards compatibility
LogicExceptionmessage is updated from "Unable to get credentials from ENV, and no security credentials URL provided" to mention container credentials. This message is not part of the public API; if keeping the legacy wording is preferred I'm happy to drop the rewording in a follow-up commit.CLA
Will sign the individual CLA when the bot prompts.