feat(credentials): configurable audience for keyless AWS, Databricks, Snowflake, Microsoft, and Google credentials
Merged
WA
2d ago+1229+1229+0123456789012345678901234567890123456789-211-211-012345678901234567890123456789
Summary
- Keyless saved credentials can set their own
audience(theaudclaim of the token Sim signs). A trust configuration can then pin a value specific to the customer instead of the shared default, so a Sim token isn't accepted somewhere it wasn't meant for. This covers all five keyless providers:- AWS: the IAM OIDC provider client ID and the trust policy
audcondition - Databricks: federation policy
audiences. Databricks' own default is the account ID. - Snowflake:
OIDC_AUDIENCE_LIST. Snowflake's docs warn that the sharedsnowflakecomputing.comallows cross-account reuse. - Microsoft Entra: the federated credential's single audience
- Google: the provider's
allowedAudiences. STS still exchanges at the provider resource name.
- AWS: the IAM OIDC provider client ID and the trust policy
- One shared mechanism in
workload-identity/audiences.ts:- a submit schema: at most 255 characters (AWS's client ID cap), limited to URI/ID characters so every setup snippet pastes without escaping, and refusing another cloud's default audience;
- a stored field schema;
storedAudienceField, which stores nothing for the default.
- Same audience everywhere: every mint uses the stored audience, including the connect-time subject-pin probe, so the probe tests what runs will present.
- Reconnect: reopens on the stored audience. Each provider now has one
stored<X>ReconnectFieldsreader (one parse) instead of separate auth-type and audience readers. - Connect dialogs: an editable Audience field, defaulting to the current value. The trust snippets update to match: AWS trust policy, Databricks policy command, Snowflake
CREATE USER, gcloud--allowed-audiences. - Docs, API and CLI: each provider page has a "use your own audience" section. The API and CLI document
keylessConfig.audience. - Backward compatibility: credentials saved without an audience mint exactly the old default and keep the same stored shape, so the old strict schemas still read them. A custom-audience credential is refused by older pods during a mixed-version window; it is never sent with the wrong audience.
Type of Change
- New feature
Testing
- Each provider's server tests cover:
- a custom audience in verification, the pin probe and runs;
- default stored shape unchanged;
- cross-cloud refusal before any network call;
- the error copy naming the audience;
- the Microsoft token cache, which never serves a token minted for an old audience.
prepare-workload-identitycovers reconnect reopening on a custom audience for all five providers.audiences.test.tscovers the shared schema.- Revert proofs: each guard was reverted and its test went red.
- 1,841 tests pass across
lib/credentials,app/api/v2/credentialsandlib/api/contracts, plus 554 sim-cli tests. bun run lintandcheck-block-registry.ts origin/stagingpass.- These audits pass:
check:openapi,check:cli-api,check:cli-docs,check:mcp-operations,check:api-validation:strict,check:test-patterns,check:comment-hygiene,check:explicit-any,check:client-boundary,check:boundaries,check:utils,check:file-namesandcheck:docs. - Type-check and the full suite run in CI.
- I checked each provider's official docs for custom-audience support and syntax (IAM
CreateOpenIDConnectProvider, Databricks federation policy API, Snowflake workload identity federation, Entra federated identity credentials, Google workload identity pool providers).
Checklist
- Code follows project style guidelines
- Self-reviewed my changes
- Tests added/updated and passing (new tests pass the
test-auditauthoring gate) - No new warnings introduced
- I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)