Outbound backend credential federation (OIDC identity → backend cloud STS)

オープン
#56 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
35/100
issue の種類
機能追加
明瞭さ
おおむね明確
活発さ
静か
技術スタック
aws, azure, google-cloud, rust

調査の方向性

ファイルやテストは指定されていないため、まず既存の multistore-sts と multistore-oidc-provider コンポーネントを読み、次にブランチ feat/backend-federation 上で新しい multistore-federation crate のスコープを定めます。完了とは、ロードマップの加算的交換プリミティブ、XML パース、および FederatedCredentials::apply_to(&mut BucketConfig) が実装され、記載された AWS エンドツーエンド検証に合格することです。

索引モデルが issue の本文から書いたものです。

説明

Summary

multistore federates identity inbound (callers → proxy, via multistore-sts + multistore-oidc-provider). The symmetric outbound half is missing: the proxy presenting its own identity to a backend cloud to obtain short-lived credentials for a private bucket.

Today a backend is either anonymous (anonymous_access / skip_signature) or configured with long-lived static keys in BucketConfig.backend_options. This issue tracks adding first-class outbound credential federation so deployments can serve private buckets without storing long-lived backend secrets. PRs below reference this issue.

Motivation

  • Operators increasingly want to front customer-owned buckets. Long-lived keys at the edge are a liability: rotation, blast radius, secret-at-rest.
  • With OIDC federation the bucket config holds only a role ARN; the proxy assumes a short-lived, optionally prefix-scoped role at request time. Trust and blast radius are governed by the bucket owner's IAM policies, not the proxy's correctness.
  • multistore already has the building blocks — it can act as an OIDC provider and already does inbound STS — so this simply completes the symmetry.

Design

At bucket-resolution time, per backend:

  1. Mint a short-lived OIDC assertion with the proxy's signing key (multistore-oidc-provider), scoped via its aud / sub claims.
  2. Exchange it at the backend cloud's STS — AWS AssumeRoleWithWebIdentity, with Azure / GCS workload-identity analogs — for temporary credentials.
  3. Inject those into BucketConfig.backend_options so the existing backend signs requests with them instead of going anonymous.

No long-lived secret is stored anywhere; credentials are short-lived and refreshed before expiry.

Constraints discovered while prototyping

  • S3 needs no core change. object_store's AmazonS3ConfigKey::Token accepts the token alias, and token is already in REDACTED_OPTION_KEYS, so temporary creds (access key + secret + session token) flow through and are redacted in logs.
  • Azure / GCS need a bearer-credential source. Workload-identity federation yields an OAuth bearer token, but the Azure backend takes a shared access_key and GCS a service_account_key — neither accepts a bearer token. Parity requires accepting bearer/access-token credentials (likely an object_store contribution).
  • Caching matters and is subtle. Short-lived creds must be cached and refreshed per backend, independent of the caller. Anything varied at assume-time is baked into the credential and fragments the cache, so the cache key should track the credential identity (role / subject), not the caller. This is a generic concern every integrator would otherwise reinvent.

Roadmap

  • Federation exchange primitive — new multistore-federation crate: a runtime-agnostic AssumeRoleWithWebIdentity request builder + XML response parser (caller owns HTTP), and FederatedCredentials::apply_to(&mut BucketConfig). Additive, no core changes. Branch: feat/backend-federation. Validated end-to-end against real AWS STS in a downstream deployment (mint → AssumeRoleWithWebIdentity → signed ListObjectsV2, including a sub trust-policy condition).
  • Caching credential provider — a BackendCredentialProvider trait + a caching wrapper (TTL, refresh-ahead, single-flight) so integrators get correct, non-thundering-herd refresh for free.
  • Azure / GCS bearer credential source — accept OAuth bearer tokens for the Azure and GCS backends to bring them to parity with S3.
  • Docs / example — wire federation into the example server / cf-workers runtimes.

Out of scope

Application-specific policy — which role to use for which bucket, and how the OIDC sub is structured/scoped — stays in the integrator's BucketRegistry. multistore provides the mechanism, not the policy.

主要言語
Rust
スター
21
フォーク
1
平均マージ
8時間 29分
マージ済み PR(30日)
2

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

developmentseed/multistore のほかの issue

developmentseed/multistore の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。