Aspire Configuration Example¶
Demonstrates Aspire publish-time configuration generation for security and infrastructure settings.
📋 Overview¶
This example shows how to:
- Define security permissions and business roles in C# code
- Configure upstream API dependencies with required permissions
- Generate YAML configuration files during
aspire publish
🏗️ Architecture¶
flowchart TB
subgraph AppHost["AspireConfig.AppHost"]
direction TB
Auth["Auth/<br/>Permissions.cs<br/>BusinessRoles.cs"]
Config["AppHost.cs<br/>AddSaifEnvironment()"]
end
subgraph Resources["Resource Model"]
SaifEnv["SaifEnvironmentResource"]
Security["SecurityResource<br/>(child)"]
Upstream["UpstreamApiResource"]
SaifEnv --> Security
end
subgraph Publish["aspire publish"]
Generator["SecurityResource<br/>Pipeline Step"]
end
subgraph Output["Generated YAML"]
API["infra/api/config.yml"]
Corp["infra/auth/corp/config.yml"]
ExtUser["infra/auth/ext/user/<br/>business-role-app-role.yml"]
ExtApp["infra/auth/ext/app/<br/>authorized-apps.yml"]
end
AppHost --> Resources
Security --> Generator
Upstream --> Generator
Generator --> Output
🧩 Components¶
| File | Description |
|---|---|
Auth/Permissions.cs |
Defines app roles and scopes |
Auth/BusinessRoles.cs |
Groups permissions into business roles |
AppHost.cs |
Configures security for publish |
🔑 Key Features¶
- Composite Resource Pattern -
SaifEnvironmentResourceaggregates child resources likeSecurityResource - Compile-Time Safety - Invalid configurations fail at build time
- IntelliSense Support - Discover permissions and roles while coding
- Type-Safe Permissions -
AppRolevsScopeenforced by compiler - Dual Identity Support - Corporate (Entra) and external (Okta) users
📂 Project Structure¶
foundry/dotnet/aspire-config/
├── AspireConfig.sln
├── src/
│ ├── AspireConfig.AppHost/
│ │ ├── Auth/
│ │ │ ├── Permissions.cs # App roles and scopes
│ │ │ └── BusinessRoles.cs # Business role definitions
│ │ ├── AppHost.cs # Security configuration
│ │ └── ResourceBuilders/ # Generated API builder
│ ├── AspireConfig/ # API project
│ ├── AspireConfig.UnitTests/
│ └── AspireConfig.IntegrationTests/
└── infra/ # Infrastructure config
🚀 Getting Started¶
Prerequisites¶
- .NET 10.0 SDK
- Aspire 13.x
Running the Example¶
Publishing Configuration¶
To generate the security YAML files:
📝 Code Walkthrough¶
1. Define Permissions¶
// Auth/Permissions.cs
public static class Permissions
{
// App roles exposed by this API
public static readonly AppRole ClaimsRead = new("Claims.Read", "Read Claims");
public static readonly AppRole ClaimsWrite = new("Claims.Write", "Write Claims");
// Scopes for upstream API calls
public static readonly Scope OrdersRead = new("Orders.Read", "Read Orders");
}
2. Define Business Roles¶
// Auth/BusinessRoles.cs
public static class BusinessRoles
{
public static readonly BusinessRole ClaimsAdjuster = new("Claims Adjuster");
public static readonly BusinessRole InjuredWorker = new("Injured Worker");
}
3. Define App Role Assignments¶
// Auth/AppRoleAssignments.cs
public static class AppRoleAssignments
{
public static readonly AppRoleAssignment ClaimsAdjuster = new(
BusinessRoles.ClaimsAdjuster,
[Permissions.ClaimsRead, Permissions.ClaimsWrite]);
public static readonly AppRoleAssignment InjuredWorker = new(
BusinessRoles.InjuredWorker,
[Permissions.ClaimsRead]);
}
4. Configure in AppHost¶
// AppHost.cs
builder.AddSecurity()
.WithCorporateAssignment(AppRoleAssignments.ClaimsAdjuster) // Entra users
.WithExternalAssignment(AppRoleAssignments.InjuredWorker); // Okta users
builder.AddUpstreamApi("it-api-proc-orders")
.WithScope(Permissions.OrdersRead);
📄 Generated Output¶
infra/api/config.yml¶
app_roles:
- value: Claims.Read
display_name: Read Claims
- value: Claims.Write
display_name: Write Claims
scopes: []
infra/auth/corp/config.yml¶
business_roles:
- name: Claims Adjuster
app_roles:
- Claims.Read
- Claims.Write
authorized_apps:
- project_id: it-api-proc-orders
scopes:
- Orders.Read
🔗 Related Documentation¶
📍 Source Code¶
Location: foundry/dotnet/aspire-config/