refactor(federation): dissolve backend-federation into oidc-provider; hoist credential type to core#67
Merged
Conversation
…, drop the duplicate oidc-provider and backend-federation each modeled temporary backend credentials. Collapse to one source of truth in the mechanism crate: - Delete oidc-provider's CloudCredentials (+ its redacting Debug and the From<FederatedCredentials> bridge); re-export and consume multistore_backend_federation::FederatedCredentials throughout the AWS/Azure/GCP exchanges, CredentialExchange, CredentialCache, and get_credentials. - backend_auth.rs injects via FederatedCredentials::apply_to instead of re-inserting access_key_id/secret_access_key/token inline. This also clears skip_signature, fixing a latent bug where an anonymous bucket (source.coop's registry.rs starting state) stayed unsigned after federation. OidcProviderError::StsError stays as the boundary translation of FederationError::Sts (signing/key/HTTP failures + status mapping need their own enum) — a bridge, not duplicated mechanism. backend-federation owns the outbound exchange, the credential value type, and BucketConfig injection; oidc-provider owns identity (JWT mint, JWKS, discovery) + orchestration and delegates the rest. Single path for source.coop's OIDC-IdP backend auth. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…dentials to core Outbound federation lived in two crates with a backwards-feeling edge (oidc-provider -> backend-federation). backend-federation bundled two things of different altitude: the credential value type (foundational) and the AWS STS exchange mechanism. With the proxy as the only consumer of the creds it obtains -- multistore never spends a token it didn't mint nor brokers cloud access to third parties -- the separate "spender" crate had no future tenant. - Move FederatedCredentials (+ apply_to + redacting Debug) into multistore core (crates/core/src/types.rs), beside its inbound sibling TemporaryCredentials. - Absorb the AWS AssumeRoleWithWebIdentity mechanism + FederationError into oidc-provider's exchange/aws.rs (no more delegation); the StsError mapping is now intra-crate. oidc-provider re-exports FederatedCredentials so it stays the single front door for consumers (source.coop never names a federation crate). - Drop the unused body()/endpoint() helpers (body duplicated the form_pairs path; endpoint was never wired in) and the now-unused url dep. - Delete crates/backend-federation; update workspace Cargo.toml, README, release-please config, the wrangler example, and the smoke-test docstring. oidc-provider now depends only on multistore core. Tests: core 74, oidc-provider 29 default / 37 with azure,gcp; no new clippy warnings; cf-workers wasm passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
🚀 Latest commit deployed to https://multistore-proxy-pr-67.development-seed.workers.dev
|
…ange in oidc-provider The crate-layout page predates `backend-federation` and already describes `oidc-provider` owning the AWS exchange and depending only on core, so this refactor needs no removals — just two clarifications matching its outcome: - Name `FederatedCredentials` among core's type definitions (it now lives in core, next to `TemporaryCredentials`). - Note that `oidc-provider` owns the `AssumeRoleWithWebIdentity` request/parse mechanism itself, not only the `AwsBackendAuth` middleware. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
📖 Docs preview deployed to https://multistore-docs-pr-67.development-seed.workers.dev
|
Names the type by what it is for (signing backend object-store requests), matching core's backend_* vocabulary (backend_type / backend_options / backend_prefix) and the apply_to(&mut BucketConfig) -> backend_options flow. "Federated" described how the creds are obtained, but that does not distinguish them from the sibling TemporaryCredentials, which are also a product of AssumeRoleWithWebIdentity (inbound, minted for callers); the axis that actually differs is purpose -- backend-facing vs caller-facing -- which this name names. Pure rename across multistore core + oidc-provider (which re-exports it) and the crate-layout doc. Tests unchanged: core 74, oidc-provider 29 / 37 (azure,gcp). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
What & why
Outbound federation spanned two crates with a backwards-feeling dependency edge:
multistore-oidc-provider(the IdP/orchestrator) imported frommultistore-backend-federation(the AWS STS mechanism). That crate bundled two things of different altitude — a foundational credential value type and an AWS-specific exchange mechanism.The only thing its separateness bought was a future "bring-your-own-token" consumer that spends a token the proxy didn't mint. That tenant will never arrive: the proxy is the only consumer of the credentials it obtains, multistore never spends a token it didn't mint at a cloud STS nor brokers cloud access to third parties, and its minted identity is reused only for the proxy authenticating itself (backend STS, the Source API, inbound STS). So this PR collapses the federation concern into one crate and puts the shared vocabulary where it belongs.
Changes
1. Hoist the credential type into
multistorecoreFederatedCredentials(fields +apply_to(&mut BucketConfig)+ secret-redactingDebug) moves tocrates/core/src/types.rs, beside its inbound siblingTemporaryCredentials(kept distinct: that one carries the proxy's authz model —allowed_scopes/assumed_role_id/source_identity— this one only what an object-store client needs to sign).2. Dissolve
backend-federationintooidc-providerAssumeRoleWithWebIdentitymechanism +FederationErrormove intooidc-provider/src/exchange/aws.rs(no more cross-crate delegation); theStsErrormapping is now intra-crate.oidc-providerre-exportsFederatedCredentials, so it stays the single front door — consumers (e.g.source.coop) import the type fromoidc-providerand never name a federation crate or core'stypesmodule.crates/backend-federation/is deleted; workspaceCargo.toml,README, release-please config, the wrangler example, and the smoke-test docstring are updated.Net:
oidc-providernow depends only onmultistorecore. −208 lines.Note: removed two dead helpers
The moved mechanism's
body()(a second encoding path — the exchange usesform_pairs()) andendpoint()(a regional-URL helper never wired in) were dead in the internal-only context, so I removed them (and the now-unusedurldep) rather than carry dead code + a clippy warning; their duration/policy coverage was rewritten againstform_pairs(). Easy to restore if regional-endpoint support is anticipated.Verification
cargo build— workspace compiles with the crate gone (Cargo.lockregenerated).oidc-provider29 default / 37 with--features azure,gcp(incl. 6 AWS-mechanism tests).cargo clippy --all-features— no new warnings (3 reported are pre-existing inauth/tests.rs,middleware.rs,jwks.rs).wasm32-unknown-unknowncheck — passes.🤖 Generated with Claude Code