Cloud applications rarely live inside a single subscription forever. As an organization grows, different teams may own different Azure subscriptions, environments may be separated by business unit, and shared infrastructure can live in a dedicated platform subscription.
That creates a practical infrastructure problem for application developers: an application deployed from one Azure subscription may need to reference resources that belong to another subscription or tenant.
.NET Aspire 13.5 introduces improvements for modeling Azure resources across subscription and tenant boundaries. This makes the AppHost more useful for applications where infrastructure ownership does not follow a single-subscription model.
The important part is understanding what Aspire can model, what Azure still controls, and where permissions become the real constraint.
Why Cross-Tenant Infrastructure Is Difficult
A simple application might have everything in one subscription:
Azure Subscription
|
+-- Resource Group
|
+-- Application
+-- Database
+-- Storage
+-- Messaging
An enterprise environment may look more like this:
Tenant A
|
+-- Subscription A
| |
| +-- Application
|
+-- Subscription B
|
+-- Shared Infrastructure
Tenant B
|
+-- Subscription C
|
+-- Shared Service
The application can therefore have dependencies outside the subscription where the application itself is deployed.
This is where resource references become important.
What Is a Cross-Tenant Resource Reference?
A resource reference represents an existing Azure resource that an application needs to consume without necessarily owning or provisioning that resource as part of the application's deployment.
For example:
Application
|
+----> Storage Account
|
+----> Key Vault
|
+----> Service Bus
The application may be deployed from one subscription while the referenced resource belongs somewhere else.
The distinction between resource ownership and resource consumption is important.
The application deployment does not automatically gain permissions merely because a resource is referenced.
How Aspire Fits Into the Architecture
.NET Aspire uses the AppHost as a central place to describe application resources and their relationships.
A simplified model looks like this:
AppHost
|
+-----------+-----------+
| |
v v
Application Azure Resource
| |
+-----------> Reference+
The AppHost describes the relationship.
Azure remains responsible for:
Resource existence
Identity
Authorization
Subscription boundaries
Tenant boundaries
Deployment permissions
This means Aspire should be viewed as an infrastructure modeling layer rather than an authorization bypass.
Cross-Subscription vs Cross-Tenant
These two scenarios are related but should not be treated as identical.
Cross-Subscription
Two subscriptions belong to the same Microsoft Entra tenant.
Tenant
|
+-- Subscription A
| |
| +-- Application
|
+-- Subscription B
|
+-- Database
Identity and authorization can often be managed within the same organizational identity boundary.
Cross-Tenant
The resources belong to different Microsoft Entra tenants.
Tenant A
|
+-- Application
Tenant B
|
+-- Shared Resource
This introduces additional identity and trust considerations.
The deployment identity needs appropriate access in the target tenant, and the application identity may also need permissions to consume the external resource.
This is fundamentally an Azure identity and authorization problem, not simply an Aspire configuration problem.
Modeling Existing Azure Resources
The general pattern is to distinguish an Azure resource that Aspire manages from one that the application consumes as an existing resource.
Conceptually:
var builder = DistributedApplication.CreateBuilder(args);
var existingStorage = builder.AddAzureStorage(
"shared-storage");
builder.AddProject<Projects.Api>("api")
.WithReference(existingStorage);
builder.Build().Run();
The exact resource API and configuration depend on the Azure resource type and the Aspire version being used.
The important architectural concept is the dependency:
API
|
+-- requires --> Shared Storage
Rather than embedding resource-specific configuration throughout the application, the dependency is represented centrally.
Why Resource References Matter
Without a centralized infrastructure model, configuration often becomes scattered:
appsettings.json
Environment Variables
CI Variables
Deployment Templates
Secrets
Application Code
This can make it difficult to determine which resource an application actually depends on.
A resource reference provides a more explicit relationship.
For example:
Order API
|
+-- PostgreSQL
|
+-- Service Bus
|
+-- Shared Blob Storage
This improves the readability of the application's infrastructure model.
Identity Is the Critical Part
Cross-tenant access usually becomes difficult at the identity layer.
Suppose an application in Tenant A needs to access a storage account in Tenant B.
The architecture might look like:
Application Identity
|
v
Microsoft Entra ID
|
v
Tenant B
|
v
Storage Account
The application identity must be recognized and authorized appropriately.
Simply adding a resource reference does not grant access.
This distinction should be made explicit when designing the deployment.
Avoid Connection Strings Where Managed Identity Is Appropriate
A common pattern in cloud applications is to put a connection string into configuration:
{
"Storage": {
"ConnectionString": "..."
}
}
This can work, but it introduces secret-management responsibilities.
Where the target Azure service supports Microsoft Entra authentication and the application's identity model permits it, managed identity or workload identity can reduce the need to distribute long-lived credentials.
The application might instead authenticate using a credential chain:
var credential = new DefaultAzureCredential();
var client = new BlobServiceClient(
new Uri(storageEndpoint),
credential);
The important production consideration is not simply using DefaultAzureCredential, but ensuring that the deployed identity has exactly the permissions it needs.
Least-Privilege Access
Cross-tenant infrastructure should follow least privilege.
Suppose the application only needs to read blobs.
Do not grant broad administrative permissions when a narrower data-plane role is sufficient.
Think about permissions at multiple levels:
Tenant
|
+-- Subscription
|
+-- Resource Group
|
+-- Resource
|
+-- Data Plane
The correct permission depends on whether the application needs to manage the resource or merely consume its data.
Configuration Example
A production application can separate resource identity from application behavior.
For example:
public sealed class StorageOptions
{
public required string Endpoint { get; init; }
}
Then:
builder.Services.Configure<StorageOptions>(
builder.Configuration.GetSection("Storage"));
The endpoint can come from deployment configuration, while authentication is handled by the application's identity.
This avoids coupling application code to a specific credential format.
Testing Cross-Tenant Dependencies
Do not wait until production to discover an authorization problem.
A useful test environment should reproduce the relevant trust relationship.
Test the following:
| Test | Expected Result |
|---|---|
| Application starts | Pass |
| External resource resolves | Pass |
| Authentication succeeds | Pass |
| Authorized operation succeeds | Pass |
| Unauthorized operation fails | Expected failure |
| Resource unavailable | Graceful handling |
| Identity missing | Clear failure |
Testing the negative cases is particularly important.
For example, an application should not silently receive elevated permissions simply because its deployment identity changed.
Common Failure Scenario
Consider this architecture:
Tenant A
|
+-- App Subscription
|
+-- API
Tenant B
|
+-- Data Subscription
|
+-- Storage
The API starts successfully but receives:
403 Forbidden
The problem may not be the Aspire configuration.
Potential causes include:
The application identity is not recognized in the target tenant.
The identity has insufficient permissions.
The resource endpoint is incorrect.
Network restrictions prevent access.
The wrong identity is being used in the deployed environment.
This is why debugging should begin by separating configuration problems from identity and networking problems.
Troubleshooting Cross-Tenant Access
403 Forbidden
Check the application's effective identity and target resource permissions.
Do not immediately add broader permissions.
401 Unauthorized
Verify that authentication is actually being performed and that the credential chain resolves to the expected identity.
Resource Not Found
Confirm:
Subscription
Resource group
Resource name
Resource ID
Tenant
Region where applicable
A resource can exist but still be invisible to an identity that lacks appropriate permissions.
Works Locally but Fails in Azure
This is a common identity boundary problem.
Locally, DefaultAzureCredential may use a developer login.
In Azure, it may use a managed or workload identity.
Those identities can have completely different permissions.
Production Deployment Pattern
A clean architecture can look like this:
Aspire AppHost
|
Infrastructure Model
|
+-------------+-------------+
| |
v v
Application Resources Existing Resources
| |
v v
Subscription A Subscription B
|
v
Shared Service
For cross-tenant resources:
Subscription A
|
v
Application Identity
|
+------ Trust / Authorization ------+
|
v
Tenant B
|
v
Azure Resource
Each boundary should be explicit.
Best Practices
Keep Resource Ownership Clear
Document which team or subscription owns each shared resource.
Separate Provisioning From Consumption
An application may consume a resource without being responsible for provisioning it.
Keep those responsibilities clear.
Use Stable Resource References
Avoid scattering resource IDs and endpoints across source files.
Centralize infrastructure configuration.
Use Least Privilege
Grant only the permissions required by the application.
Test the Real Identity
A developer identity is not a substitute for the identity used by the deployed application.
Validate Network Boundaries
Private endpoints, firewalls, virtual networks, and DNS can prevent access even when identity permissions are correct.
Log Useful Identity Information
For troubleshooting, record non-sensitive identity and resource metadata where appropriate.
Never log access tokens, client secrets, or other credentials.
Advantages and Disadvantages
Advantages
Makes cross-subscription dependencies easier to model.
Keeps application resource relationships visible.
Reduces scattered infrastructure configuration.
Supports architectures where shared infrastructure has separate ownership.
Fits better with enterprise environments containing multiple subscriptions.
Disadvantages
Cross-tenant authorization remains complex.
Resource references do not automatically grant permissions.
Deployment identities must be configured correctly.
Network policies can introduce another layer of failure.
Teams need clear ownership of shared infrastructure.
A Practical Adoption Approach
For teams introducing cross-boundary Azure resources into an Aspire application:
Identify every external dependency.
Document the owning subscription and tenant.
Decide whether Aspire provisions or references the resource.
Define the application identity.
Configure least-privilege permissions.
Model the resource relationship in the AppHost.
Test authentication independently.
Test authorization.
Validate network connectivity.
Test the complete deployment from a production-like environment.
This process prevents infrastructure modeling and identity configuration from becoming one large troubleshooting problem.
Conclusion
Cross-subscription and cross-tenant architectures are increasingly common in larger Azure environments. Applications may consume shared databases, storage, messaging systems, or other services that are owned by a separate platform team or subscription.
.NET Aspire 13.5 improves the ability to represent Azure infrastructure relationships in the application model, making these dependencies easier to understand and manage.
However, Aspire does not remove Azure's security boundaries. The most important part of a cross-tenant design remains identity, authorization, and network access.
The strongest implementation is therefore one where the AppHost clearly describes resource dependencies, while Azure identity and access controls enforce who can actually use those resources. That separation makes the architecture easier to reason about, test, and operate in production.

Join the conversation! Your thoughts help the community grow.