Skip to content

Add support for SSO #1676

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jdussouillez opened this issue Apr 25, 2025 · 10 comments
Closed

Add support for SSO #1676

jdussouillez opened this issue Apr 25, 2025 · 10 comments
Assignees
Labels
enhancement New feature or request

Comments

@jdussouillez
Copy link

jdussouillez commented Apr 25, 2025

I am migrating some Quarkus application to native.

I got a problem with one, which is using sso and ssooidc dependencies (group software.amazon.awssdk) to authenticate the user in SSO (used mostly for testing native apps in local environment).

I didn't see any "sso" module in this extension, so I guess it's a feature request, not a bug. It would be great if the extension could provide a SSO module to wrap AWS SDK dependencies (just like it's done now with STS, S3, etc.).


Here's a simple reproducer (just runs a get-caller-identity request when it starts) : https://github.com/jdussouillez/quarkus-aws-sso-native

  • Dev mode ✅
  • JAR mode ✅
  • Native mode 🔴
Stacktrace
FATAL [com.git.jdu.InitService] (main) Error when fetching caller identity: software.amazon.awssdk.core.exception.SdkClientException: Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain(credentialsProviders=[SystemPropertyCredentialsProvider(), EnvironmentVariableCredentialsProvider(), WebIdentityTokenCredentialsProvider(), ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[profiles, sso-session], profiles=[Profile(name=default, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=ReadOnly, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=Admin, properties=[sso_session, output, sso_role_name, region, sso_account_id])])), ContainerCredentialsProvider(), InstanceProfileCredentialsProvider()]) : [SystemPropertyCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., EnvironmentVariableCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., WebIdentityTokenCredentialsProvider(): Either the environment variable AWS_WEB_IDENTITY_TOKEN_FILE or the javaproperty aws.webIdentityTokenFile must be set., ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[profiles, sso-session], profiles=[Profile(name=default, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=ReadOnly, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=Admin, properties=[sso_session, output, sso_role_name, region, sso_account_id])])): To use Sso related properties in the 'default' profile, the 'sso' service module must be on the class path., ContainerCredentialsProvider(): Cannot fetch credentials from container - neither AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set., InstanceProfileCredentialsProvider(): Failed to load credentials from IMDS.]
	at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:130)
	at software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain.resolveCredentials(AwsCredentialsProviderChain.java:130)
	at software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider.resolveCredentials(LazyAwsCredentialsProvider.java:45)
	at software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.resolveCredentials(DefaultCredentialsProvider.java:129)
	at software.amazon.awssdk.auth.credentials.AwsCredentialsProvider.resolveIdentity(AwsCredentialsProvider.java:54)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.lambda$trySelectAuthScheme$4(StsAuthSchemeInterceptor.java:134)
	at software.amazon.awssdk.core.internal.util.MetricUtils.reportDuration(MetricUtils.java:80)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.trySelectAuthScheme(StsAuthSchemeInterceptor.java:134)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.selectAuthScheme(StsAuthSchemeInterceptor.java:81)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.beforeExecution(StsAuthSchemeInterceptor.java:61)
	at software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain.lambda$beforeExecution$1(ExecutionInterceptorChain.java:59)
	at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1596)
	at software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain.beforeExecution(ExecutionInterceptorChain.java:59)
	at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.runInitialInterceptors(AwsExecutionContextBuilder.java:254)
	at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.invokeInterceptorsAndCreateExecutionContext(AwsExecutionContextBuilder.java:144)
	at software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler.invokeInterceptorsAndCreateExecutionContext(AwsAsyncClientHandler.java:63)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.lambda$execute$1(BaseAsyncClientHandler.java:75)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.measureApiCallSuccess(BaseAsyncClientHandler.java:294)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.execute(BaseAsyncClientHandler.java:73)
	at software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler.execute(AwsAsyncClientHandler.java:49)
	at software.amazon.awssdk.services.sts.DefaultStsAsyncClient.getCallerIdentity(DefaultStsAsyncClient.java:1108)
	at software.amazon.awssdk.services.sts.StsAsyncClient.getCallerIdentity(StsAsyncClient.java:1753)
	at software.amazon.awssdk.services.sts.StsAsyncClient_eFoSmgrcO48ZCGUYLp5mka9QBUA_Synthetic_ClientProxy.getCallerIdentity(Unknown Source)
	at com.github.jdussouillez.InitService.whoami(InitService.java:32)
	at com.github.jdussouillez.InitService.init(InitService.java:22)
	at com.github.jdussouillez.InitService_Observer_Synthetic_L1DGp3b4fZULsIKPpdhyeWn8OVM.notify(Unknown Source)
	at io.quarkus.arc.impl.EventImpl$Notifier.notifyObservers(EventImpl.java:365)
	at io.quarkus.arc.impl.EventImpl$Notifier.notify(EventImpl.java:347)
	at io.quarkus.arc.impl.EventImpl.fire(EventImpl.java:81)
	at io.quarkus.arc.runtime.ArcRecorder.fireLifecycleEvent(ArcRecorder.java:163)
	at io.quarkus.arc.runtime.ArcRecorder.handleLifecycleEvents(ArcRecorder.java:114)
	at io.quarkus.runner.recorded.LifecycleEventsBuildStep$startupEvent1144526294.deploy_0(Unknown Source)
	at io.quarkus.runner.recorded.LifecycleEventsBuildStep$startupEvent1144526294.deploy(Unknown Source)
	at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
	at io.quarkus.runtime.Application.start(Application.java:101)
	at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:119)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:80)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:51)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:144)
	at io.quarkus.runner.GeneratedMain.main(Unknown Source)
Exception message (readable)
Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain(
    credentialsProviders=[
        SystemPropertyCredentialsProvider(),
        EnvironmentVariableCredentialsProvider(),
        WebIdentityTokenCredentialsProvider(),
        ProfileCredentialsProvider(
            profileName=default,
            profileFile=ProfileFile(
                sections=[profiles, sso-session],
                profiles=[
                    Profile(name=default, properties=[sso_session, output, sso_role_name, region, sso_account_id]),
                    Profile(name=ReadOnly, properties=[sso_session, output, sso_role_name, region, sso_account_id]),
                    Profile(name=Admin, properties=[sso_session, output, sso_role_name, region, sso_account_id])
                ]
            )
        ),
        ContainerCredentialsProvider(),
        InstanceProfileCredentialsProvider()
    ]
) : [
    SystemPropertyCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId).,
    EnvironmentVariableCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId).,
    WebIdentityTokenCredentialsProvider(): Either the environment variable AWS_WEB_IDENTITY_TOKEN_FILE or the javaproperty aws.webIdentityTokenFile must be set.,
    ProfileCredentialsProvider(
        profileName=default,
        profileFile=ProfileFile(
            sections=[profiles, sso-session],
            profiles=[
                Profile(name=default, properties=[sso_session, output, sso_role_name, region, sso_account_id]),
                Profile(name=ReadOnly, properties=[sso_session, output, sso_role_name, region, sso_account_id]),
                Profile(name=Admin, properties=[sso_session, output, sso_role_name, region, sso_account_id])
            ]
        )
    ): To use Sso related properties in the 'default' profile, the 'sso' service module must be on the class path.,
    ContainerCredentialsProvider(): Cannot fetch credentials from container - neither AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set.,
    InstanceProfileCredentialsProvider(): Failed to load credentials from IMDS.
]

Judging from the exception message, it seems the SSO service is not in the class path.

To use Sso related properties in the 'default' profile, the 'sso' service module must be on the class path.

I tried to switch to CRT-based HTTP client, add reflection metadata for SSO dependency and playing with initialize-at-run-time option, but so far nothing worked (what I tried is listed here)

I found this post on SO that is very similar: https://stackoverflow.com/questions/79179322/quarkus-is-not-finding-some-aws-classes-when-trying-to-use-neptune

@scrocquesel scrocquesel added the enhancement New feature or request label May 2, 2025
@scrocquesel scrocquesel self-assigned this May 3, 2025
@scrocquesel
Copy link
Member

The issue is that reflection metadata were not kept. The issue you mention in the upstream repo would fix it. While I was adding both services (sso / sso oidc), I added GraalVM substitutions to avoid creating instances with reflection.

Note that all profile provider require a sync http client implementation module (either URL or Apache). Be sure to add one of them, if you use async client for your own needs.

@jdussouillez
Copy link
Author

jdussouillez commented May 6, 2025

Note that all profile provider require a sync http client implementation module (either URL or Apache). Be sure to add one of them, if you use async client for your own needs.

Indeed, I had to add manually the dependencies for this.

<dependency>
    <groupId>io.quarkiverse.amazonservices</groupId>
    <artifactId>quarkus-amazon-sts</artifactId>
</dependency>
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>url-connection-client</artifactId> <!-- SSO sync client -->
</dependency>
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>netty-nio-client</artifactId> <!-- STS async client -->
</dependency>
<dependency>
    <groupId>io.quarkiverse.amazonservices</groupId>
    <artifactId>quarkus-amazon-sso</artifactId>
</dependency>
<dependency>
    <groupId>io.quarkiverse.amazonservices</groupId>
    <artifactId>quarkus-amazon-ssooidc</artifactId>
</dependency>
quarkus.sso.aws.region=eu-west-3
quarkus.sso.sync-client.type=url
quarkus.ssooidc.devservices.enabled=false

quarkus.sts.aws.region=eu-west-3
quarkus.sso.async-client.type=netty
quarkus.sts.devservices.enabled=false

It works fine in JAR mode, just like before. But in native mode I have a different error now:

Caused by: software.amazon.awssdk.core.exception.SdkClientException: Unable to load credentials from any of the providers in the chain [...]

Unable to load SSO token, ContainerCredentialsProvider(): Cannot fetch credentials from container - neither AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set.

@scrocquesel
Copy link
Member

Note that all profile provider require a sync http client implementation module (either URL or Apache). Be sure to add one of them, if you use async client for your own needs.

Indeed, I had to add manually the dependencies for this.

io.quarkiverse.amazonservices quarkus-amazon-sts software.amazon.awssdk url-connection-client software.amazon.awssdk netty-nio-client io.quarkiverse.amazonservices quarkus-amazon-sso io.quarkiverse.amazonservices quarkus-amazon-ssooidc quarkus.sso.aws.region=eu-west-3 quarkus.sso.sync-client.type=url quarkus.ssooidc.devservices.enabled=false

quarkus.sts.aws.region=eu-west-3
quarkus.sso.async-client.type=netty
quarkus.sts.devservices.enabled=false
It works fine in JAR mode, just like before. But in native mode I have a different error now:

Caused by: software.amazon.awssdk.core.exception.SdkClientException: Unable to load credentials from any of the providers in the chain [...]
Unable to load SSO token, ContainerCredentialsProvider(): Cannot fetch credentials from container - neither AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set.

What is the content of your aws profile ?

@scrocquesel
Copy link
Member

scrocquesel commented May 6, 2025

I cannot fully test because I don't have an AWS account. But, with your repro, I have this error

AWS_PROFILE=my-sso-profile ./target/quarkus-aws-sso-native-0.0.0-SNAPSHOT-runner
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2025-05-06 14:28:43,760 FATAL [com.git.jdu.InitService] (main) Error when fetching caller identity:
software.amazon.awssdk.core.exception.SdkClientException:
Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain(
    credentialsProviders=[
        SystemPropertyCredentialsProvider():
            Unable to load credentials from system settings.
            Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID)
            or system property (aws.accessKeyId).

        EnvironmentVariableCredentialsProvider():
            Unable to load credentials from system settings.
            Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID)
            or system property (aws.accessKeyId).

        WebIdentityTokenCredentialsProvider():
            Either the environment variable AWS_WEB_IDENTITY_TOKEN_FILE
            or the java property aws.webIdentityTokenFile must be set.

        ProfileCredentialsProvider(
            profileName=my-sso-profile,
            profileFile=ProfileFile(
                sections=[profiles, sso-session, services],
                profiles=[
                    Profile(
                        name=my-sso-profile,
                        properties=[sso_region, sso_start_url, sso_role_name, sso_account_id]
                    )
                ]
            )
        ):
            java.nio.file.NoSuchFileException:
            /.aws/sso/cache/c7aaaf71fcc8777ae2475525ed049d39fe16c484.json

        ContainerCredentialsProvider():
            Cannot fetch credentials from container -
            neither AWS_CONTAINER_CREDENTIALS_FULL_URI
            nor AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set.

        InstanceProfileCredentialsProvider():
            Failed to load credentials from IMDS.
    ]
)

which I guess, means I am not aws sso login'ed.

The fake profile

profile my-sso-profile]
sso_start_url = https://my-sso-portal.awsapps.com/start
sso_region = us-west-2
sso_account_id = 123456789012
sso_role_name = SSOReadOnlyRole

@scrocquesel
Copy link
Member

Unable to load SSO token is from the ssooidc service. Thought, you were using sso.

https://github.com/aws/aws-sdk-java-v2/blob/d37c139529bdfee1ccde78f8bb6575e746040b02/services/ssooidc/src/main/java/software/amazon/awssdk/services/ssooidc/SsoOidcTokenProvider.java#L88

You should have another warning log with the real exception.

At least, the provider is correctly instantiated.

BTW, you don't need to confire the sync client if you don't use it. quarkus.sso.sync-client.type=url. AWS SDK use it's own internal configuration for the provider.

@jdussouillez
Copy link
Author

What is the content of your aws profile ?

[sso-session frpo245]
sso_start_url = __REDACTED__
sso_region = eu-west-3
sso_registration_scopes = sso:account:access

[default]
sso_session = frpo245
sso_account_id = __REDACTED__
sso_role_name = ReadOnlyAccess
region = eu-west-3
output = json

[profile ReadOnly]
sso_session = frpo245
sso_account_id = __REDACTED__
sso_role_name = ReadOnlyAccess
region = eu-west-3
output = json

[profile Admin]
sso_session = frpo245
sso_account_id = __REDACTED__
sso_role_name = AdminAccess
region = eu-west-3
output = json

BTW, you don't need to confire the sync client if you don't use it. quarkus.sso.sync-client.type=url. AWS SDK use it's own internal configuration for the provider.

Oh, that's true, I was just being sure it was the right one used when desperately trying to get it working.

You should have another warning log with the real exception.

I didn't see anything. Here's the full output:

[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  02:41 min
[INFO] Finished at: 2025-05-06T15:05:54+02:00
[INFO] ------------------------------------------------------------------------
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2025-05-06 15:05:57,015 FATAL [com.git.jdu.InitService] (main) Error when fetching caller identity: software.amazon.awssdk.core.exception.SdkClientException: Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain(credentialsProviders=[SystemPropertyCredentialsProvider(), EnvironmentVariableCredentialsProvider(), WebIdentityTokenCredentialsProvider(), ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[profiles, sso-session], profiles=[Profile(name=default, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=ReadOnly, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=Admin, properties=[sso_session, output, sso_role_name, region, sso_account_id])])), ContainerCredentialsProvider(), InstanceProfileCredentialsProvider()]) : [SystemPropertyCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., EnvironmentVariableCredentialsProvider(): Unable to load credentials from system settings. Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) or system property (aws.accessKeyId)., WebIdentityTokenCredentialsProvider(): Either the environment variable AWS_WEB_IDENTITY_TOKEN_FILE or the javaproperty aws.webIdentityTokenFile must be set., ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[profiles, sso-session], profiles=[Profile(name=default, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=ReadOnly, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=Admin, properties=[sso_session, output, sso_role_name, region, sso_account_id])])): Unable to load SSO token, ContainerCredentialsProvider(): Cannot fetch credentials from container - neither AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment variables are set., InstanceProfileCredentialsProvider(): Failed to load credentials from IMDS.]
	at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:130)
	at software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain.resolveCredentials(AwsCredentialsProviderChain.java:130)
	at software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider.resolveCredentials(LazyAwsCredentialsProvider.java:45)
	at software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.resolveCredentials(DefaultCredentialsProvider.java:129)
	at software.amazon.awssdk.auth.credentials.AwsCredentialsProvider.resolveIdentity(AwsCredentialsProvider.java:54)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.lambda$trySelectAuthScheme$4(StsAuthSchemeInterceptor.java:134)
	at software.amazon.awssdk.core.internal.util.MetricUtils.reportDuration(MetricUtils.java:80)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.trySelectAuthScheme(StsAuthSchemeInterceptor.java:134)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.selectAuthScheme(StsAuthSchemeInterceptor.java:81)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.beforeExecution(StsAuthSchemeInterceptor.java:61)
	at software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain.lambda$beforeExecution$1(ExecutionInterceptorChain.java:59)
	at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1596)
	at software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain.beforeExecution(ExecutionInterceptorChain.java:59)
	at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.runInitialInterceptors(AwsExecutionContextBuilder.java:254)
	at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.invokeInterceptorsAndCreateExecutionContext(AwsExecutionContextBuilder.java:144)
	at software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler.invokeInterceptorsAndCreateExecutionContext(AwsAsyncClientHandler.java:63)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.lambda$execute$1(BaseAsyncClientHandler.java:75)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.measureApiCallSuccess(BaseAsyncClientHandler.java:294)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.execute(BaseAsyncClientHandler.java:73)
	at software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler.execute(AwsAsyncClientHandler.java:49)
	at software.amazon.awssdk.services.sts.DefaultStsAsyncClient.getCallerIdentity(DefaultStsAsyncClient.java:1108)
	at software.amazon.awssdk.services.sts.StsAsyncClient.getCallerIdentity(StsAsyncClient.java:1753)
	at software.amazon.awssdk.services.sts.StsAsyncClient_eFoSmgrcO48ZCGUYLp5mka9QBUA_Synthetic_ClientProxy.getCallerIdentity(Unknown Source)
	at com.github.jdussouillez.InitService.whoami(InitService.java:32)
	at com.github.jdussouillez.InitService.init(InitService.java:22)
	at com.github.jdussouillez.InitService_Observer_Synthetic_L1DGp3b4fZULsIKPpdhyeWn8OVM.notify(Unknown Source)
	at io.quarkus.arc.impl.EventImpl$Notifier.notifyObservers(EventImpl.java:365)
	at io.quarkus.arc.impl.EventImpl$Notifier.notify(EventImpl.java:347)
	at io.quarkus.arc.impl.EventImpl.fire(EventImpl.java:81)
	at io.quarkus.arc.runtime.ArcRecorder.fireLifecycleEvent(ArcRecorder.java:163)
	at io.quarkus.arc.runtime.ArcRecorder.handleLifecycleEvents(ArcRecorder.java:114)
	at io.quarkus.runner.recorded.LifecycleEventsBuildStep$startupEvent1144526294.deploy_0(Unknown Source)
	at io.quarkus.runner.recorded.LifecycleEventsBuildStep$startupEvent1144526294.deploy(Unknown Source)
	at io.quarkus.runner.ApplicationImpl.doStart(Unknown Source)
	at io.quarkus.runtime.Application.start(Application.java:101)
	at io.quarkus.runtime.ApplicationLifecycleManager.run(ApplicationLifecycleManager.java:119)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:80)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:51)
	at io.quarkus.runtime.Quarkus.run(Quarkus.java:144)
	at io.quarkus.runner.GeneratedMain.main(Unknown Source)

@jdussouillez
Copy link
Author

jdussouillez commented May 7, 2025

https://github.com/aws/aws-sdk-java-v2/blob/d37c139529bdfee1ccde78f8bb6575e746040b02/services/ssooidc/src/main/java/software/amazon/awssdk/services/ssooidc/SsoOidcTokenProvider.java#L88

You should have another warning log with the real exception.

Actually no, because I found out it's this line of code : https://github.com/aws/aws-sdk-java-v2/blob/2.31.37/services/ssooidc/src/main/java/software/amazon/awssdk/services/ssooidc/SsoOidcTokenProvider.java#L221

When using quarkus.log.level=DEBUG in my test project, I got the full stacktrace of the Unable to load SSO token exception:

2025-05-07 08:33:41,611 DEBUG [sof.ama.aws.aut.cre.AwsCredentialsProviderChain] (main) Unable to load credentials from ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[profiles, sso-session], profiles=[Profile(name=default, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=ReadOnly, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=Admin, properties=[sso_session, output, sso_role_name, region, sso_account_id])])): Unable to load SSO token: software.amazon.awssdk.core.exception.SdkClientException: Unable to load SSO token
	at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:130)
	at software.amazon.awssdk.core.exception.SdkClientException.create(SdkClientException.java:43)
	at software.amazon.awssdk.services.ssooidc.SsoOidcTokenProvider.lambda$getDefaultSsoTokenRetriever$3(SsoOidcTokenProvider.java:221)
	at [email protected]/java.util.Optional.orElseThrow(Optional.java:403)
	at software.amazon.awssdk.services.ssooidc.SsoOidcTokenProvider.lambda$getDefaultSsoTokenRetriever$4(SsoOidcTokenProvider.java:221)
	at software.amazon.awssdk.awscore.internal.token.CachedTokenRefresher.refreshAndGetTokenFromSupplier(CachedTokenRefresher.java:81)
	at software.amazon.awssdk.awscore.internal.token.CachedTokenRefresher.refreshResult(CachedTokenRefresher.java:89)
	at software.amazon.awssdk.utils.cache.CachedSupplier.lambda$jitteredPrefetchValueSupplier$8(CachedSupplier.java:300)
	at software.amazon.awssdk.utils.cache.CachedSupplier$PrefetchStrategy.fetch(CachedSupplier.java:448)
	at software.amazon.awssdk.utils.cache.CachedSupplier.refreshCache(CachedSupplier.java:208)
	at software.amazon.awssdk.utils.cache.CachedSupplier.get(CachedSupplier.java:135)
	at software.amazon.awssdk.awscore.internal.token.CachedTokenRefresher.refreshIfStaleAndFetch(CachedTokenRefresher.java:76)
	at software.amazon.awssdk.services.ssooidc.SsoOidcTokenProvider.resolveToken(SsoOidcTokenProvider.java:96)
	at software.amazon.awssdk.services.ssooidc.SsoOidcProfileTokenProviderFactory$SsoOidcProfileTokenProvider.resolveToken(SsoOidcProfileTokenProviderFactory.java:148)
	at software.amazon.awssdk.auth.token.internal.ProfileTokenProviderLoader.lambda$ssoProfileCredentialsProvider$0(ProfileTokenProviderLoader.java:67)
	at software.amazon.awssdk.auth.token.credentials.ProfileTokenProvider.resolveToken(ProfileTokenProvider.java:111)
	at software.amazon.awssdk.auth.token.internal.LazyTokenProvider.resolveToken(LazyTokenProvider.java:45)
	at software.amazon.awssdk.services.sso.auth.SsoProfileCredentialsProviderFactory$SsoProfileCredentialsProvider.<init>(SsoProfileCredentialsProviderFactory.java:107)
	at software.amazon.awssdk.services.sso.auth.SsoProfileCredentialsProviderFactory$SsoProfileCredentialsProvider.<init>(SsoProfileCredentialsProviderFactory.java:88)
	at software.amazon.awssdk.services.sso.auth.SsoProfileCredentialsProviderFactory.create(SsoProfileCredentialsProviderFactory.java:68)
	at software.amazon.awssdk.auth.credentials.internal.ProfileCredentialsUtils.ssoProfileCredentialsProvider(ProfileCredentialsUtils.java:198)
	at software.amazon.awssdk.auth.credentials.internal.ProfileCredentialsUtils.credentialsProvider(ProfileCredentialsUtils.java:120)
	at software.amazon.awssdk.auth.credentials.internal.ProfileCredentialsUtils.credentialsProvider(ProfileCredentialsUtils.java:102)
	at software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider.lambda$createCredentialsProvider$1(ProfileCredentialsProvider.java:169)
	at [email protected]/java.util.Optional.flatMap(Optional.java:289)
	at software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider.createCredentialsProvider(ProfileCredentialsProvider.java:169)
	at software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider.handleProfileFileReload(ProfileCredentialsProvider.java:135)
	at software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider.resolveCredentials(ProfileCredentialsProvider.java:126)
	at software.amazon.awssdk.auth.credentials.AwsCredentialsProvider.resolveIdentity(AwsCredentialsProvider.java:54)
	at software.amazon.awssdk.identity.spi.IdentityProvider.resolveIdentity(IdentityProvider.java:60)
	at software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain.resolveCredentials(AwsCredentialsProviderChain.java:109)
	at software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider.resolveCredentials(LazyAwsCredentialsProvider.java:45)
	at software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.resolveCredentials(DefaultCredentialsProvider.java:129)
	at software.amazon.awssdk.auth.credentials.AwsCredentialsProvider.resolveIdentity(AwsCredentialsProvider.java:54)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.lambda$trySelectAuthScheme$4(StsAuthSchemeInterceptor.java:134)
	at software.amazon.awssdk.core.internal.util.MetricUtils.reportDuration(MetricUtils.java:80)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.trySelectAuthScheme(StsAuthSchemeInterceptor.java:134)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.selectAuthScheme(StsAuthSchemeInterceptor.java:81)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.beforeExecution(StsAuthSchemeInterceptor.java:61)
	at software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain.lambda$beforeExecution$1(ExecutionInterceptorChain.java:59)
	at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1596)
	at software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain.beforeExecution(ExecutionInterceptorChain.java:59)
	at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.runInitialInterceptors(AwsExecutionContextBuilder.java:254)
	at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.invokeInterceptorsAndCreateExecutionContext(AwsExecutionContextBuilder.java:144)
	at software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler.invokeInterceptorsAndCreateExecutionContext(AwsAsyncClientHandler.java:63)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.lambda$execute$1(BaseAsyncClientHandler.java:75)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.measureApiCallSuccess(BaseAsyncClientHandler.java:294)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.execute(BaseAsyncClientHandler.java:73)
	at software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler.execute(AwsAsyncClientHandler.java:49)
	at software.amazon.awssdk.services.sts.DefaultStsAsyncClient.getCallerIdentity(DefaultStsAsyncClient.java:1108)
	at software.amazon.awssdk.services.sts.StsAsyncClient.getCallerIdentity(StsAsyncClient.java:1753)
	at software.amazon.awssdk.services.sts.StsAsyncClient_eFoSmgrcO48ZCGUYLp5mka9QBUA_Synthetic_ClientProxy.getCallerIdentity(Unknown Source)
	at com.github.jdussouillez.InitService.whoami(InitService.java:32)
// [...]

So I guess it's here: https://github.com/aws/aws-sdk-java-v2/blob/master/services/ssooidc/src/main/java/software/amazon/awssdk/services/ssooidc/internal/OnDiskTokenManager.java#L66

Because otherwise, I would have a cause exception, but I don't have in my stacktrace. But why would the file being considered not existing in native mode? 🤔

@scrocquesel
Copy link
Member

https://github.com/aws/aws-sdk-java-v2/blob/d37c139529bdfee1ccde78f8bb6575e746040b02/services/ssooidc/src/main/java/software/amazon/awssdk/services/ssooidc/SsoOidcTokenProvider.java#L88
You should have another warning log with the real exception.

Actually no, because I found out it's this line of code : https://github.com/aws/aws-sdk-java-v2/blob/2.31.37/services/ssooidc/src/main/java/software/amazon/awssdk/services/ssooidc/SsoOidcTokenProvider.java#L221

When using quarkus.log.level=DEBUG in my test project, I got the full stacktrace of the Unable to load SSO token exception:

2025-05-07 08:33:41,611 DEBUG [sof.ama.aws.aut.cre.AwsCredentialsProviderChain] (main) Unable to load credentials from ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[profiles, sso-session], profiles=[Profile(name=default, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=ReadOnly, properties=[sso_session, output, sso_role_name, region, sso_account_id]), Profile(name=Admin, properties=[sso_session, output, sso_role_name, region, sso_account_id])])): Unable to load SSO token: software.amazon.awssdk.core.exception.SdkClientException: Unable to load SSO token
	at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:130)
	at software.amazon.awssdk.core.exception.SdkClientException.create(SdkClientException.java:43)
	at software.amazon.awssdk.services.ssooidc.SsoOidcTokenProvider.lambda$getDefaultSsoTokenRetriever$3(SsoOidcTokenProvider.java:221)
	at [email protected]/java.util.Optional.orElseThrow(Optional.java:403)
	at software.amazon.awssdk.services.ssooidc.SsoOidcTokenProvider.lambda$getDefaultSsoTokenRetriever$4(SsoOidcTokenProvider.java:221)
	at software.amazon.awssdk.awscore.internal.token.CachedTokenRefresher.refreshAndGetTokenFromSupplier(CachedTokenRefresher.java:81)
	at software.amazon.awssdk.awscore.internal.token.CachedTokenRefresher.refreshResult(CachedTokenRefresher.java:89)
	at software.amazon.awssdk.utils.cache.CachedSupplier.lambda$jitteredPrefetchValueSupplier$8(CachedSupplier.java:300)
	at software.amazon.awssdk.utils.cache.CachedSupplier$PrefetchStrategy.fetch(CachedSupplier.java:448)
	at software.amazon.awssdk.utils.cache.CachedSupplier.refreshCache(CachedSupplier.java:208)
	at software.amazon.awssdk.utils.cache.CachedSupplier.get(CachedSupplier.java:135)
	at software.amazon.awssdk.awscore.internal.token.CachedTokenRefresher.refreshIfStaleAndFetch(CachedTokenRefresher.java:76)
	at software.amazon.awssdk.services.ssooidc.SsoOidcTokenProvider.resolveToken(SsoOidcTokenProvider.java:96)
	at software.amazon.awssdk.services.ssooidc.SsoOidcProfileTokenProviderFactory$SsoOidcProfileTokenProvider.resolveToken(SsoOidcProfileTokenProviderFactory.java:148)
	at software.amazon.awssdk.auth.token.internal.ProfileTokenProviderLoader.lambda$ssoProfileCredentialsProvider$0(ProfileTokenProviderLoader.java:67)
	at software.amazon.awssdk.auth.token.credentials.ProfileTokenProvider.resolveToken(ProfileTokenProvider.java:111)
	at software.amazon.awssdk.auth.token.internal.LazyTokenProvider.resolveToken(LazyTokenProvider.java:45)
	at software.amazon.awssdk.services.sso.auth.SsoProfileCredentialsProviderFactory$SsoProfileCredentialsProvider.<init>(SsoProfileCredentialsProviderFactory.java:107)
	at software.amazon.awssdk.services.sso.auth.SsoProfileCredentialsProviderFactory$SsoProfileCredentialsProvider.<init>(SsoProfileCredentialsProviderFactory.java:88)
	at software.amazon.awssdk.services.sso.auth.SsoProfileCredentialsProviderFactory.create(SsoProfileCredentialsProviderFactory.java:68)
	at software.amazon.awssdk.auth.credentials.internal.ProfileCredentialsUtils.ssoProfileCredentialsProvider(ProfileCredentialsUtils.java:198)
	at software.amazon.awssdk.auth.credentials.internal.ProfileCredentialsUtils.credentialsProvider(ProfileCredentialsUtils.java:120)
	at software.amazon.awssdk.auth.credentials.internal.ProfileCredentialsUtils.credentialsProvider(ProfileCredentialsUtils.java:102)
	at software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider.lambda$createCredentialsProvider$1(ProfileCredentialsProvider.java:169)
	at [email protected]/java.util.Optional.flatMap(Optional.java:289)
	at software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider.createCredentialsProvider(ProfileCredentialsProvider.java:169)
	at software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider.handleProfileFileReload(ProfileCredentialsProvider.java:135)
	at software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider.resolveCredentials(ProfileCredentialsProvider.java:126)
	at software.amazon.awssdk.auth.credentials.AwsCredentialsProvider.resolveIdentity(AwsCredentialsProvider.java:54)
	at software.amazon.awssdk.identity.spi.IdentityProvider.resolveIdentity(IdentityProvider.java:60)
	at software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain.resolveCredentials(AwsCredentialsProviderChain.java:109)
	at software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider.resolveCredentials(LazyAwsCredentialsProvider.java:45)
	at software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider.resolveCredentials(DefaultCredentialsProvider.java:129)
	at software.amazon.awssdk.auth.credentials.AwsCredentialsProvider.resolveIdentity(AwsCredentialsProvider.java:54)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.lambda$trySelectAuthScheme$4(StsAuthSchemeInterceptor.java:134)
	at software.amazon.awssdk.core.internal.util.MetricUtils.reportDuration(MetricUtils.java:80)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.trySelectAuthScheme(StsAuthSchemeInterceptor.java:134)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.selectAuthScheme(StsAuthSchemeInterceptor.java:81)
	at software.amazon.awssdk.services.sts.auth.scheme.internal.StsAuthSchemeInterceptor.beforeExecution(StsAuthSchemeInterceptor.java:61)
	at software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain.lambda$beforeExecution$1(ExecutionInterceptorChain.java:59)
	at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1596)
	at software.amazon.awssdk.core.interceptor.ExecutionInterceptorChain.beforeExecution(ExecutionInterceptorChain.java:59)
	at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.runInitialInterceptors(AwsExecutionContextBuilder.java:254)
	at software.amazon.awssdk.awscore.internal.AwsExecutionContextBuilder.invokeInterceptorsAndCreateExecutionContext(AwsExecutionContextBuilder.java:144)
	at software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler.invokeInterceptorsAndCreateExecutionContext(AwsAsyncClientHandler.java:63)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.lambda$execute$1(BaseAsyncClientHandler.java:75)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.measureApiCallSuccess(BaseAsyncClientHandler.java:294)
	at software.amazon.awssdk.core.internal.handler.BaseAsyncClientHandler.execute(BaseAsyncClientHandler.java:73)
	at software.amazon.awssdk.awscore.client.handler.AwsAsyncClientHandler.execute(AwsAsyncClientHandler.java:49)
	at software.amazon.awssdk.services.sts.DefaultStsAsyncClient.getCallerIdentity(DefaultStsAsyncClient.java:1108)
	at software.amazon.awssdk.services.sts.StsAsyncClient.getCallerIdentity(StsAsyncClient.java:1753)
	at software.amazon.awssdk.services.sts.StsAsyncClient_eFoSmgrcO48ZCGUYLp5mka9QBUA_Synthetic_ClientProxy.getCallerIdentity(Unknown Source)
	at com.github.jdussouillez.InitService.whoami(InitService.java:32)
// [...]

So I guess it's here: https://github.com/aws/aws-sdk-java-v2/blob/master/services/ssooidc/src/main/java/software/amazon/awssdk/services/ssooidc/internal/OnDiskTokenManager.java#L66

Because otherwise, I would have a cause exception, but I don't have in my stacktrace. But why would the file being considered not existing in native mode? 🤔

Thank you for the analysis. The issue is that

public final class OnDiskTokenManager implements TokenManager<SsoOidcToken> {
    private static final Path DEFAULT_TOKEN_LOCATION = Paths.get(userHomeDirectory(), ".aws", "sso", "cache");

is evaluated at native image compilation to /.aws/sso/cache.

I will fix it in the extension to delay the class initialization at runtime. Meanwhile, if you can try with this addtional properties to see if there is other errors

quarkus.native.additional-build-args=--initialize-at-run-time=software.amazon.awssdk.services.ssooidc.internal.OnDiskTokenManager

@jdussouillez
Copy link
Author

Thank you for the analysis. The issue is that

public final class OnDiskTokenManager implements TokenManager {
private static final Path DEFAULT_TOKEN_LOCATION = Paths.get(userHomeDirectory(), ".aws", "sso", "cache");
is evaluated at native image compilation to /.aws/sso/cache.

I will fix it in the extension to delay the class initialization at runtime. Meanwhile, if you can try with this addtional properties to see if there is other errors

quarkus.native.additional-build-args=--initialize-at-run-time=software.amazon.awssdk.services.ssooidc.internal.OnDiskTokenManager

Perfect! It works now in native.

2025-05-07 12:29:06,578 DEBUG [sof.ama.aws.uti.cac.CachedSupplier] (main) (SsoOidcTokenProvider()) Cached value is stale and will be refreshed.
2025-05-07 12:29:06,578 DEBUG [sof.ama.aws.uti.cac.CachedSupplier] (main) (SsoOidcTokenProvider()) Refreshing cached value.
2025-05-07 12:29:06,579 DEBUG [sof.ama.aws.uti.cac.CachedSupplier] (main) (SsoOidcTokenProvider()) Successfully refreshed cached value. Next Prefetch Time: 2025-05-07T10:58:14.140Z. Next Stale Time: 2025-05-07T11:00:23Z
2025-05-07 12:29:06,579 DEBUG [sof.ama.aws.uti.cac.CachedSupplier] (main) (software.amazon.awssdk.services.sso.auth.SsoCredentialsProvider@1d30c326) Cached value is stale and will be refreshed.
2025-05-07 12:29:06,579 DEBUG [sof.ama.aws.uti.cac.CachedSupplier] (main) (software.amazon.awssdk.services.sso.auth.SsoCredentialsProvider@1d30c326) Refreshing cached value.
[...]
2025-05-07 12:29:07,376 INFO  [com.git.jdu.InitService] (executor-thread-2) I am __REDACTED__

Thank you very much for the details!

@scrocquesel
Copy link
Member

Released in Quarkus Amazon BOM 3.6.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants