Skip to content

Add Aspire hosting extension for AuthProxy - #48

Merged
einari merged 5 commits into
mainfrom
copilot/aspire-authproxy-setup
Jun 1, 2026
Merged

Add Aspire hosting extension for AuthProxy#48
einari merged 5 commits into
mainfrom
copilot/aspire-authproxy-setup

Conversation

Copilot AI commented May 30, 2026

Copy link
Copy Markdown
Contributor

Adds a dedicated Aspire hosting integration library so any Aspire AppHost can add and configure AuthProxy with a fluent, idiomatic API — either as a container resource (external consumers) or layered on top of a ProjectResource (in-repo development).

Added

  • Source/Aspire class library (Aspire.Hosting 9.5.2) with AuthProxyResource : ContainerResource pointing at cratis/authproxy and a full set of fluent extension methods on IResourceBuilder<T> where T : IResourceWithEnvironment — works on both container and project resources

    // Container-based (external consumers)
    builder.AddAuthProxy("authproxy", tag: "1.2.3")
        .WithHttpEndpoint(port: 8080)
        .WithBackend("main", apiResource)
        .WithFrontend("main", webResource)
        .WithOidcProvider("Microsoft", OidcProviderType.Microsoft, authority, clientId, secret)
        .WithHostTenantResolution()
        .WithTenantVerification(platformApi, "/api/tenants/{tenantId}")
        .WithSelectionTenantResolution(platformApi, "/api/tenants/selectable")
        .WithInvite(publicKeyPem, studioApi, "/internal/invites/exchange", issuer: "https://studio.example.com")
        .WithInviteClaimForwarding("organization_id", toClaimType: "organization")
        .WithLobbyFrontend(lobbyResource);
    
    // Project-based (in-repo dev — same extension methods apply)
    builder.AddProject("authproxy")
        .WithBackend("main", testApp)
        .WithFrontend("main", web);

    Available methods: AddAuthProxy, WithBackend, WithFrontend, WithOidcProvider, WithOAuthProvider, WithHostTenantResolution, WithSubHostTenantResolution, WithClaimTenantResolution, WithRouteTenantResolution, WithSpecifiedTenantResolution, WithDefaultTenantResolution, WithSelectionTenantResolution, WithTenantVerification, WithInvite, WithInviteClaimForwarding, WithLobbyFrontend, WithLobbyBackend

  • OidcProviderType enum (Custom, Microsoft, Google, GitHub, Apple) in the Aspire library — standalone, no dependency on the AuthProxy web project

  • Documentation/aspire/index.md — how-to guide covering container vs project resource setup, all With* extension methods, the OidcProviderType enum, tenant selection, invites & lobby, identity details resolution, resource-based endpoint references, and cross-links to the existing configuration reference

  • publish-nuget job in .github/workflows/publish.yml using OIDC trusted publishing (NuGet/login@v1) — packs and pushes only Source/Aspire/Aspire.csproj as Cratis.AuthProxy.Aspire to NuGet.org; runs independently of the Docker pipeline

Changed

  • Composition/AppHost.cs updated to use WithBackend / WithFrontend instead of bare WithReference, and now wires up the frontend (web) service as well

  • Source/Aspire/Aspire.csproj updated with full NuGet package metadata (PackageId, Title, Description, Authors, PackageLicenseExpression, RepositoryUrl, PackageTags, IsPackable)

  • WithSelectionTenantResolution updated to accept an optional tenantsEndpoint parameter that maps to TenantResolutions[n].Options.TenantsEndpoint, and a new resource-based overload that accepts an IResourceBuilder<IResourceWithEndpoints> + route so Aspire resolves the base URL automatically

  • WithTenantVerification gains a resource-based overload — pass an Aspire service resource and a route template instead of a full URL

  • WithInvite gains a resource-based overload — pass the exchange service resource and route instead of a hardcoded exchange URL

  • WithBackend gains an optional resolveIdentityDetails parameter (bool?) that maps to Services[name].ResolveIdentityDetails, controlling whether AuthProxy calls /.cratis/me on that service's backend to enrich the identity cookie

Copilot AI linked an issue May 30, 2026 that may be closed by this pull request
Introduces Source/Aspire — a dedicated Aspire hosting integration library
that lets any Aspire AppHost wire up AuthProxy with a fluent, idiomatic API.

New files:
- Source/Aspire/Aspire.csproj
- Source/Aspire/GlobalUsings.cs
- Source/Aspire/AuthProxyResource.cs     – ContainerResource for cratis/authproxy
- Source/Aspire/AuthProxyConfigAnnotation.cs – per-resource annotation for index tracking
- Source/Aspire/OidcProviderType.cs      – provider brand enum (mirrors Configuration counterpart)
- Source/Aspire/AuthProxyExtensions.cs   – AddAuthProxy + full fluent configuration API

Updated files:
- AuthProxy.slnx                          – adds Aspire project
- Directory.Packages.props                – pins Aspire.Hosting 9.5.2
- Source/Composition/Composition.csproj  – references Aspire library (IsAspireProjectResource=false)
- Source/Composition/AppHost.cs          – uses new WithBackend/WithFrontend extension methods
Copilot AI changed the title [WIP] Add Aspire Extension for setting up AuthProxy Add Aspire hosting extension for AuthProxy May 30, 2026
Copilot AI requested a review from einari May 30, 2026 08:42
Copilot finished work on behalf of einari May 30, 2026 08:42
@einari

einari commented May 31, 2026

Copy link
Copy Markdown
Collaborator

@copilot Great, add documentation and also add NuGet publishing to the publish workflow using trusted publishing (see here for inspiration https://github.com/Cratis/Arc/blob/main/.github/workflows/publish.yml). We do not want any other projects to publish to NuGet, only the Aspire one.

Copilot AI commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Great, add documentation and also add NuGet publishing to the publish workflow using trusted publishing (see here for inspiration https://github.com/Cratis/Arc/blob/main/.github/workflows/pub...

Done in the latest commit. Here's what was added:

Documentation (Documentation/aspire/index.md):

  • How-to guide covering container-based and project-based setup, all With* extension methods, authentication (OIDC + OAuth), and tenant resolution with verification. The new section is wired into the top-level toc.yml.

NuGet publishing (.github/workflows/publish.yml):

  • New publish-nuget job that depends only on release (independent of the Docker pipeline). It packs Source/Aspire/Aspire.csproj only, authenticates via NuGet/login@v1 (OIDC trusted publishing using NUGET_USER), then pushes the resulting .nupkg to api.nuget.org. The job has its own id-token: write permission; the global id-token: write was also added so the OIDC token is available to the runner.

Source/Aspire/Aspire.csproj has the required NuGet package metadata (PackageId: Cratis.AuthProxy.Aspire, description, license, repository URL, tags, etc.).

Copilot finished work on behalf of einari May 31, 2026 07:45
@einari einari added the minor label May 31, 2026
@einari

einari commented May 31, 2026

Copy link
Copy Markdown
Collaborator

Copilot AI commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

@copilot We also need to add support for the entire invites system;
https://github.com/Cratis/AuthProxy/blob/main/Documentation/configuration/invites.md

...

Done in the latest commit. Here's what was added:

WithSelectionTenantResolution now accepts an optional tenantsEndpoint parameter that maps to TenantResolutions[n].Options.TenantsEndpoint:

authproxy.WithSelectionTenantResolution("https://platform.example.com/api/tenants/selectable");

Invite system — four new methods:

Method Purpose
WithInvite(publicKeyPem, exchangeUrl, ...) Core invite config (public key, exchange URL, issuer, audience, tenant claim, subject-already-exists redirect)
WithInviteClaimForwarding(fromClaimType, toClaimType?) Adds a claim forwarding entry (call once per claim); tracked with a new InviteClaimForwardingCount on the annotation
WithLobbyFrontend(serviceResource, endpointName?) Sets the lobby frontend URL from an Aspire resource reference
WithLobbyBackend(serviceResource, endpointName?) Sets the optional lobby backend URL

Documentation/aspire/index.md has new sections for Tenant Selection and Invites & Lobby, cross-linked to the existing configuration reference pages.

Copilot finished work on behalf of einari May 31, 2026 13:37
@einari

einari commented May 31, 2026

Copy link
Copy Markdown
Collaborator

@copilot We also need to be able to configure services for resolving identity details: (https://github.com/Cratis/AuthProxy/blob/main/Documentation/configuration/services.md). And, not sure if this is covered, but setting the different endpoints the auth proxy should call (tenant verification ++) - it would be nice to then use a reference to which other service holds it and then the route on it and then automatically internally we resolve that - so we don't have to put in the full http:// addresses.

Copilot AI commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

@copilot We also need to be able to configure services for resolving identity details: (https://github.com/Cratis/AuthProxy/blob/main/Documentation/configuration/services.md). And, not sure if this is...

Done in the latest commit. Here's what was added:

Identity details resolutionWithBackend now accepts an optional resolveIdentityDetails parameter that maps to Services[name].ResolveIdentityDetails. Omitting it preserves AuthProxy's default (on when a backend is present); pass false to explicitly opt a service out:

authproxy.WithBackend("reporting", reportingApi, resolveIdentityDetails: false)

Resource-based endpoint overloads — three methods now have a second overload that takes an IResourceBuilder<IResourceWithEndpoints> + route string so Aspire resolves the base URL automatically at startup instead of requiring hardcoded https:// addresses:

Method Resource overload signature
WithTenantVerification (serviceResource, routeTemplate, endpointName?)
WithSelectionTenantResolution (serviceResource, route, endpointName?)
WithInvite (publicKeyPem, exchangeServiceResource, exchangeRoute, exchangeEndpointName?, ...)

Example:

authproxy
    .WithTenantVerification(platformApi, "/api/tenants/{tenantId}")
    .WithSelectionTenantResolution(platformApi, "/api/tenants/selectable")
    .WithInvite(publicKeyPem, studioApi, "/internal/invites/exchange", issuer: "...");

The string-based overloads are unchanged for callers that don't use Aspire resources.

Copilot finished work on behalf of einari May 31, 2026 16:30
@einari
einari marked this pull request as ready for review June 1, 2026 04:56
@einari
einari merged commit e4fce94 into main Jun 1, 2026
5 checks passed
@einari
einari deleted the copilot/aspire-authproxy-setup branch June 1, 2026 04:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Aspire Extension for setting up AuthProxy

2 participants