source-cooperative / source-cooperative/data.source.coop
STS roles should support multiple trusted OIDC providers, each with their own audience and subject conditions
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 24
- Forks
- 6
- Avg merge
- 1h 32m
- Merged PRs (30d)
- 1
Description
Context
PR #132 adds the /.sts token-exchange endpoint. Role trust policies come from multistore::types::RoleConfig, which currently models trust as:
pub trusted_oidc_issuers: Vec<String>, // N issuers
pub required_audience: Option<String>, // but ONE audience, shared across all of them
pub subject_conditions: Vec<String>, // and ONE set of sub conditions, shared too
A role can trust multiple OIDC issuers, but the aud and sub constraints apply uniformly across all of them — and required_audience only holds a single value.
Problem
We will definitely want multiple OIDC providers to be able to assume the same role, each with its own audience and subject conditions. In AWS IAM this is the norm: a role's trust policy can contain multiple statements, one per federated provider, each with its own aud/sub conditions. For example, a single product role trusted by both:
- source.coop web flow (Ory):
aud= the web app's OAuth client_id,sub= the Ory user id - GitHub Actions OIDC (
token.actions.githubusercontent.com):aud= a custom audience,submatchingrepo:<org>/<repo>:ref:refs/heads/main
With the current shape this is unrepresentable: an audience valid for one issuer is wrong for the other, and subject patterns for Ory user ids vs GitHub repo: subjects can't be scoped to their issuer.
Proposal
Restructure role trust as a list of per-provider entries, e.g.:
pub struct TrustedProvider {
pub issuer: String,
pub audiences: Vec<String>, // also fixes the single-client_id limitation
pub subject_conditions: Vec<String>, // glob patterns, scoped to this issuer
}
pub struct RoleConfig {
// ...
pub trusted_providers: Vec<TrustedProvider>,
}
Token exchange validates the subject token against the entry matching its iss, then enforces that entry's aud/sub conditions.
Dependencies
- The type and its enforcement live upstream in the
multistore/multistore-stscrates (RoleConfig, JWKS validation), so this needs a crate release first, then adoption here (src/sts.rsbuilds the_defaultrole;AUTH_AUDIENCEwould become that role's first trusted-provider audience). - Related: the role registry is currently a single hardcoded
_defaultrole (see TODO insrc/sts.rs); per-role trust config becomes most useful once roles are served from the Source Cooperative API.
Spun out of review feedback on #132 (finding 1: audience restriction).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the upstream multistore and multistore-sts releases implementing per-provider RoleConfig trust, then inspect src/sts.rs where the _default role is built. Trace how AUTH_AUDIENCE feeds that role and how token exchange performs JWKS and issuer validation. Done means this project adopts the released types so each trusted OIDC provider can have its own audiences and subject conditions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- authentication, authorization
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100