Skip to content

Release v2.12.0

Choose a tag to compare

@github-actions github-actions released this 09 Aug 14:06
14cc2ae

Summary

AuthProxy authenticated but never authorized. On a public host with a public identity provider that means every account on the internet completes sign-in and reaches the application. Cratis:AuthProxy:Authorization makes the proxy the first gate: an authenticated caller who does not carry what you require never reaches a service at all. It is off unless configured, so an existing deployment is unaffected.

Added

  • Cratis:AuthProxy:Authorization:RequiredClaims — require an authenticated caller to carry a claim, optionally with a set of accepted values, before any request is forwarded. Every requirement must be satisfied (an and); within one requirement any listed value will do (an or). Values are compared case-insensitively.
  • The same section on a service (Cratis:AuthProxy:Services:<key>:Authorization) applies in addition to the proxy-wide requirements, so a service can narrow who reaches it but never widen it. The targeted service is resolved the way the route table resolves it — the single configured service, otherwise the Service-ID header or the service query parameter.
  • GitHub organization and team membership as claims. A GitHub OAuth provider that requests the read:org scope has its organizations and teams read once while sign-in completes and added to the session as urn:github:organization and urn:github:team (as organization/team-slug). The claims also travel to the application on the forwarded principal. GitHub Enterprise works without extra configuration — the endpoints are derived from the configured UserInformationEndpoint.
  • not-authorized.html, a new well-known page served at 403 to a signed-in caller who does not satisfy a requirement. It carries a sign-out link, since coming back as a different account is the only way forward, and can be overridden like every other page through PagesPath.
  • Aspire builders WithRequiredClaim(claim, anyOf…) and WithRequiredClaimForService(service, claim, anyOf…). Repeated calls append.
  • Documentation: a new Authorization page with a worked GitHub organization and team example, and an OAuth 2.0 provider section in Authentication, which was previously undocumented.

Changed

  • A claim requirement that names no claim type now fails startup, naming the exact configuration key. It could never be satisfied, so starting would refuse every caller and ignoring it would leave the gate silently open.

Notes on behavior worth knowing before configuring it:

  • Paths a service declares in AnonymousPaths are not gated. They exist for callers with no session, who carry no claims, so gating them would refuse every one of them — a webhook receiver would get a 403 it could do nothing about.
  • The authentication endpoints and callers with no session are not gated either; the existing sign-in machinery handles them.
  • GitHub membership is read at sign-in and lives in the session, so revoked membership takes effect when the session ends — bounded by Cratis:AuthProxy:Session:Lifetime.