fai-aspire-orchestration — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited fai-aspire-orchestration (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Configures .NET Aspire to compose multi-container AI applications with automatic service discovery, environment variable injection, OpenTelemetry pipeline, and local Azure emulators. Solves the dev-setup friction where developers spend a day configuring connection strings that Aspire injects automatically.
| Signal | Example |
|---|---|
| Running multiple .NET services locally | API + worker + Redis + PostgreSQL |
| Hardcoded connection strings in appsettings | "Host=localhost;Port=5432" in source code |
| No local Azure emulators wired up | Azurite, Service Bus emulator not running |
| Distributed traces missing in local dev | No correlation between service calls |
// AppHost/Program.cs -- the orchestration entry point
var builder = DistributedApplication.CreateBuilder(args);
// Backing services -- Aspire manages lifecycle and connection strings
var redis = builder.AddRedis("redis-cache");
var cosmos = builder.AddAzureCosmosDB("cosmos").AddDatabase("chatdb");
var storage = builder.AddAzureStorage("storage").AddBlobs("documents");
var servicebus = builder.AddAzureServiceBus("servicebus").AddQueue("embedding-jobs");
// AI service endpoints from environment (Managed Identity in prod, env vars locally)
var aoai = builder.AddConnectionString("aoai-endpoint");
var search = builder.AddConnectionString("search-endpoint");
// Application projects -- Aspire injects all connection strings automatically
var api = builder.AddProject<Projects.Api>("api")
.WithReference(redis)
.WithReference(cosmos)
.WithReference(aoai)
.WithReference(search)
.WithReference(servicebus);
var worker = builder.AddProject<Projects.EmbeddingWorker>("worker")
.WithReference(storage)
.WithReference(servicebus)
.WithReference(aoai);
builder.Build().Run();// api/Program.cs -- inject discovered endpoints, no hardcoded URLs
var builder = WebApplication.CreateBuilder(args);
builder.AddServiceDefaults(); // Aspire extension: health, OTEL, discovery
// Redis -- name matches the AppHost reference name
builder.AddRedisDistributedCache("redis-cache");
// Cosmos DB -- connection string injected from AppHost
builder.AddAzureCosmosClient("cosmos");
// HTTP client to worker -- resolved via Aspire service discovery
builder.Services.AddHttpClient<EmbeddingClient>(c =>
c.BaseAddress = new Uri("https+http://worker")); // Aspire resolves this at runtime
var app = builder.Build();
app.MapDefaultEndpoints(); // /health/live, /health/ready
app.Run();// ServiceDefaults/Extensions.cs -- generated by Aspire, customise here
public static IHostApplicationBuilder AddServiceDefaults(
this IHostApplicationBuilder builder)
{
builder.ConfigureOpenTelemetry();
builder.AddDefaultHealthChecks();
builder.Services.AddServiceDiscovery();
builder.Services.ConfigureHttpClientDefaults(http =>
{
http.AddStandardResilienceHandler(); // Retry + circuit breaker
http.AddServiceDiscovery();
});
return builder;
}
// OpenTelemetry -- traces, metrics, logs to OTEL collector
builder.Services.AddOpenTelemetry()
.WithTracing(t => t
.AddAspNetCoreInstrumentation()
.AddHttpClientInstrumentation()
.AddRedisInstrumentation()
.AddOtlpExporter())
.WithMetrics(m => m
.AddAspNetCoreInstrumentation()
.AddRuntimeInstrumentation()
.AddOtlpExporter());// AppHost -- use emulators locally, real Azure services in CI/prod
var storage = builder.AddAzureStorage("storage")
.RunAsEmulator(cfg => cfg
.WithBlobPort(10000)
.WithQueuePort(10001));
var servicebus = builder.AddAzureServiceBus("servicebus")
.RunAsEmulator(); // Uses the Service Bus emulator Docker image
var cosmos = builder.AddAzureCosmosDB("cosmos")
.RunAsEmulator(cfg => cfg.WithGatewayPort(8081));# Deploy Aspire manifest to Azure Container Apps
azd init --template aspire
azd env new prod
azd env set AZURE_SUBSCRIPTION_ID <sub>
azd env set AZURE_LOCATION eastus2
azd up # Provisions ACA environment, deploys all projects
# Verify running services
az containerapp list --resource-group rg-aspire-prod \
--query "[].{name:name, url:properties.configuration.ingress.fqdn}" \
--output tableAspire provides a local developer dashboard at http://localhost:15888:
| View | What You See |
|---|---|
| Resources | All services with clickable endpoints and status |
| Console | Real-time structured logs with trace correlation |
| Traces | OpenTelemetry span waterfall across all services |
| Metrics | Request rate, error rate, duration per service |
| Environment | All injected environment variables per service |
| Pattern | Resolution |
|---|---|
https+http://worker | HTTPS in prod, HTTP in dev; resolved by Aspire service discovery |
redis-cache | Redis connection string injected via REDIS__CONNECTIONSTRING env var |
cosmos | Cosmos connection string injected via ConnectionStrings__cosmos |
| Pillar | Contribution |
|---|---|
| Reliability | AddStandardResilienceHandler() adds retry + circuit breaker to all HTTP clients automatically |
| Operational Excellence | Automatic OTEL correlation enables distributed trace analysis without per-service code changes |
| Security | Service-to-service URLs injected at runtime -- no connection strings committed to source control |
| Performance Efficiency | Local emulators eliminate cloud round-trips during development; faster inner dev loop |
AddServiceDefaults() must be called as the first extension in every app projectRunAsEmulator() for local dev; emulators are not started in CI unless explicitly configuredWithReference() on a project creates both the connection string env var and a health dependency~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.