You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
source-cooperative/data.source.coop#184 aims to make the proxy's /.sts endpoint a drop-in AWS STS replacement so standard tooling can exchange OIDC tokens without custom code. aws-actions/configure-aws-credentials is the flagship consumer — but after assuming a role it unconditionally validates the returned credentials with a SigV4-signed sts:GetCallerIdentity call against the configured sts-endpoint (no input skips it; 12 retries, then the step fails). multistore-sts currently parses only Action=AssumeRoleWithWebIdentity (request.rs), so the action can never succeed against a multistore-sts endpoint.
Proposal
Handle Action=GetCallerIdentity in multistore-sts:
Authenticate: verify the request's SigV4 signature (service sts, region-agnostic — clients sign with whatever region they're configured for) against the sealed-token credentials minted by AssumeRoleWithWebIdentity.
Errors: unsigned/invalid-signature requests get STS-shaped error XML, not a proxy error.
Canonical-URI gotcha
AWS SDK JS v3 builds request paths as basePath + "/", so an endpoint of https://host/.sts receives POST /.sts/ — and the client signs the canonical URI /.sts/. Signature verification must run over the raw path as sent, not a normalized form (data.source.coop normalizes the trailing slash for routing only).
Non-goals
AssumeRole, AssumeRoleWithSAML, session tags — nothing else in the STS surface is needed for the drop-in story.
Motivation
source-cooperative/data.source.coop#184 aims to make the proxy's
/.stsendpoint a drop-in AWS STS replacement so standard tooling can exchange OIDC tokens without custom code.aws-actions/configure-aws-credentialsis the flagship consumer — but after assuming a role it unconditionally validates the returned credentials with a SigV4-signedsts:GetCallerIdentitycall against the configuredsts-endpoint(no input skips it; 12 retries, then the step fails). multistore-sts currently parses onlyAction=AssumeRoleWithWebIdentity(request.rs), so the action can never succeed against a multistore-sts endpoint.Proposal
Handle
Action=GetCallerIdentityin multistore-sts:sts, region-agnostic — clients sign with whatever region they're configured for) against the sealed-token credentials minted byAssumeRoleWithWebIdentity.Account,Arn,UserIdinsideGetCallerIdentityResult. The account id should be the fabricated one used in the ARN alias (000000000000per fix(core): percent-encode object keys in raw-signed backend URLs #105/feat(sts): accept AssumeRoleWithWebIdentity params from form-encoded POST bodies #112 discussion) soAssumedRoleUser.ArnandGetCallerIdentity.Accountagree —configure-aws-credentialssurfaces it as theaws-account-idoutput and checks it againstallowed-account-ids.Canonical-URI gotcha
AWS SDK JS v3 builds request paths as
basePath + "/", so an endpoint ofhttps://host/.stsreceivesPOST /.sts/— and the client signs the canonical URI/.sts/. Signature verification must run over the raw path as sent, not a normalized form (data.source.coop normalizes the trailing slash for routing only).Non-goals
AssumeRole,AssumeRoleWithSAML, session tags — nothing else in the STS surface is needed for the drop-in story.🤖 Generated with Claude Code