Class TokenSourceChain
The consumer never chooses, and the CLI never branches
That constraint is the reason this class exists. AWS's SDKs resolve credentials through an ordered provider chain in which the first source that yields anything wins and, in their own words, no additional code is required. Google's Workload Identity Federation - which is precisely the scenario here - puts the decision in a local configuration file naming where the external token comes from, with three source kinds, and states that application code remains largely identical across all three. Both settled on the same answer: the environment decides, the code does not. A public API that made the caller name a mechanism would push a deployment decision into a compile-time one, and every consumer would then need a branch per provider - which is the exact outcome this feature exists to prevent.
The order, and why it is this order
TokenSourceChain.Link.EXTERNAL_TOKEN- a token supplied verbatimTokenSourceChain.Link.EXTERNAL_TOKEN_FILE- a file named by configurationTokenSourceChain.Link.EXTERNAL_TOKEN_COMMAND- a command named by configurationTokenSourceChain.Link.EXTERNAL_CLIENT_CREDENTIALS- the workload's own client-credentials grant, performed by this SDK against the workload's own authorization serverTokenSourceChain.Link.ACTOR_KEY_PAIR- a registered key pair this process signs withTokenSourceChain.Link.NATIVE_CLIENT_SECRET- an ANKASecure client secret
Specific before ambient: the first four are statements about an identity issued elsewhere, which somebody configured on purpose for this workload. Native is last, and that placement carries the whole safety argument. A client secret is the value most likely to be left behind in a configuration file from an earlier setup, so had it been preferred, a deployment that deliberately moved to federated identity would keep authenticating with the old secret, succeed every time, and never report that the new configuration was being ignored. Silent success is the failure mode with no symptom.
Two external sources at once is refused, not resolved
The first four links are four spellings of ONE mechanism - Google models this as a single
credential_source per configuration, never a list. Picking one silently is how an
operator who adds a command discovers, months later, that a stale file has been answering all
along. So an ambiguity among those four throws, naming both, at resolution time.
Reading a token somebody else obtained and obtaining one here are the same mechanism for this purpose: both end with ONE externally minted token being carried across ONE hop. Where it came from is the provider's business, and two of them at once is still an operator who cannot be told which one answered.
External-versus-native is a different case and is NOT an error: those are different credential
kinds, and preferring one is a stated policy rather than a guess. Which link answered is reported
by TokenSource.mechanism() and by selected(AuthSettings), so the preference is
observable rather than merely silent.
There is still no URL source, and the reason has narrowed to the one that survives
Google offers a kind that fetches the external token by HTTP from a URL named in configuration. It is not reproduced here.
One of the reasons this class used to give has been superseded and is recorded as superseded
rather than quietly deleted: contacting a host the ANKASecure configuration does not name is no
longer something this SDK never does. TokenSourceChain.Link.EXTERNAL_CLIENT_CREDENTIALS does exactly that.
What made that admissible is not that the objection was wrong - it is that the case answers it:
the host is an issuer, screened by ExternalIssuerAdmission before anything dials
it, resolved once and pinned to the addresses it resolved to, reached over a client that trusts
the platform anchors and follows no redirect, and asked for a document with a protocol - OIDC
discovery - whose issuer must equal the configured one exactly.
A bare URL returning a bearer token has none of that. There is no protocol to conform to, no
discovery document to compare against, no issuer to validate and no client authentication: the
SDK would GET whatever address configuration named and believe the bytes. That is the reason the
rejection rests on, and it is unchanged. The remaining objection is unchanged too - it buys
nothing a consumer cannot already do, since a workload able to reach a metadata endpoint can
perform that one GET itself and hand the result to ExplicitExternalTokenProvider, or
point FileExternalTokenProvider at whatever wrote it down.
The command source covers the same ground with a better trust story - an operator names a program, not a URL, and it will not run at all without an environment opt-in that no configuration file can set.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumOne resolvable credential configuration, in the order they are considered. -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final List<TokenSourceChain.Link>The chain, in the order it is evaluated. -
Method Summary
Modifier and TypeMethodDescriptionstatic List<TokenSourceChain.Link>configuredLinks(AuthSettings settings) Reports which links the given settings configure, in chain order, without building anything.static TokenSourceresolve(co.ankatech.ankasecure.openapi.client.AnkaSecureOpenApiClient client, AuthSettings settings) Builds the token source the configuration calls for.static Optional<TokenSourceChain.Link>selected(AuthSettings settings) The link that would answer, applying the order and the ambiguity rule.
-
Field Details
-
ORDER
The chain, in the order it is evaluated. Exposed so the order is asserted by a test against a declaration rather than inferred from the body of a resolution method.
-
-
Method Details
-
configuredLinks
Reports which links the given settings configure, in chain order, without building anything.Pure and side-effect free: it reads no file, starts no process and opens no connection. A caller can therefore ask what WOULD be used - to display it, to log it, to check a deployment - without that question having consequences.
- Parameters:
settings- the configuration; must not benull- Returns:
- the configured links in chain order; empty when nothing is configured
-
selected
public static Optional<TokenSourceChain.Link> selected(AuthSettings settings) throws AnkaSecureSdkException The link that would answer, applying the order and the ambiguity rule.- Parameters:
settings- the configuration; must not benull- Returns:
- the winning link, or empty when nothing is configured
- Throws:
AnkaSecureSdkException- if two or more external-token sources are configured at once
-
resolve
public static TokenSource resolve(co.ankatech.ankasecure.openapi.client.AnkaSecureOpenApiClient client, AuthSettings settings) throws AnkaSecureSdkException Builds the token source the configuration calls for.- Parameters:
client- the transport the resulting source mints against; must not benullsettings- the configuration; must not benull- Returns:
- a token source; never
null - Throws:
AnkaSecureSdkException- if nothing is configured, if two external-token sources are configured at once, or if the winning link is configured incompletely
-