← Back to Blog

ASP.NET Zero

ASP.NET Zero Feature Dependency: Why Buttons Show but Permissions Fail

ASP.NET Zero Feature Dependency: Why Buttons Show but Permissions Fail

A user opens your application, sees an AI feature button, and clicks it. Instead of opening the feature, the application returns an authorization error.

The button was visible. The user was logged in. So why couldn't they access it?

In many ASP.NET Zero applications, the problem comes from how feature availability and permission checks are configured.

A UI feature flag and an ASP.NET Zero feature dependency are not the same thing. One can control whether a button appears on the screen, while the other can determine whether a permission is available to a user.

If these checks are not aligned, your application can show features that users cannot actually access.

Let's look at why this happens and how to avoid it. Last week we covered ASP.NET Zero background jobs and session context. For authorization review fundamentals, see How to Review an AI-Added Permission in ASP.NET Zero and our guide on preventing multi-tenant data leaks.

Contents

Feature Flags vs Feature Dependencies: What's the Difference?

Both mechanisms help control access to application functionality, but they serve different purposes.

What is a feature flag?

A feature flag is commonly used to control whether a feature or part of the interface is visible or enabled.

For example, imagine your SaaS application has an AI assistant module. You only want customers on selected editions to see it.

Your frontend can check whether the AI feature is enabled and use that result to show or hide the corresponding button.

But hiding a button is not the same as protecting the operation behind it. A user could still attempt to call the backend directly.

What is an ASP.NET Zero feature dependency?

In ASP.NET Zero applications based on ASP.NET Boilerplate, a feature dependency can be attached to a permission definition.

For example, SimpleFeatureDependency("MyAiFeature") makes the permission dependent on the specified feature being enabled:

// Defining a permission with a feature dependency in AppAuthorizationProvider.cs
var aiReportPermission = context.CreatePermission(
    AppPermissions.Pages_Administration_AiReports,
    L("AiReports"),
    featureDependency: new SimpleFeatureDependency("MyAiFeature")
);

If the required feature is disabled, the permission cannot be granted just because a user has been assigned a role containing that permission.

This is important for applications where different tenants have different subscriptions, editions, or enabled features.

The difference is simple: a UI check controls what users see; a permission dependency helps control what they are allowed to do.

Why Does the Button Appear but the Permission Check Fails?

Consider an application with an AI reporting module.

Your team has configured the frontend to display the AI Reports button when a simple UI flag is enabled.

However, the backend permission has a feature dependency:

featureDependency: new SimpleFeatureDependency("MyAiFeature")

Now imagine the following situation:

  • The frontend flag is enabled.
  • The tenant's edition does not have MyAiFeature enabled.
  • The button appears in the Angular interface.
  • The user clicks it.
  • The backend permission check fails because its feature dependency is not satisfied.

From the user's perspective, the application is broken.

From the framework's perspective, the two checks are returning different results because they are configured independently.

The solution is not to remove the permission dependency. It is to make sure that feature visibility and backend authorization follow the same intended access rules.

How MultiTenancySides Affects Permission Access

Another important part of ASP.NET Zero authorization is MultiTenancySides.

In a multi-tenant application, users operate in different contexts:

  • Host: Manages the overall application and its tenants.
  • Tenant: Uses the application within its own tenant environment.

A permission can be configured for the host, the tenant, or both:

// Host-only permission definition
context.CreatePermission(
    AppPermissions.Pages_Administration_HostAiSettings,
    L("HostAiSettings"),
    multiTenancySides: MultiTenancySides.Host
);

// Tenant-only permission definition with feature dependency
context.CreatePermission(
    AppPermissions.Pages_Tenant_AiReports,
    L("TenantAiReports"),
    multiTenancySides: MultiTenancySides.Tenant,
    featureDependency: new SimpleFeatureDependency("MyAiFeature")
);

For example, imagine an AI administration permission that should only be available to host users. If that permission is registered with MultiTenancySides.Host, tenant users should not receive it.

If the Angular interface displays the corresponding action without checking the user's actual permission and tenant context, the interface can become misleading.

When configuring permissions, review both:

  • Whether the permission is available to the correct tenancy side.
  • Whether its required feature dependency is satisfied.

Do not assume that a permission granted to a role is automatically usable in every tenant context.

How to Align Feature Flags, Permissions, and the UI

The safest approach is to review each layer separately and make sure they agree.

1. Check the tenant's enabled features

Start by confirming whether the required feature is enabled for the tenant.

In ASP.NET Zero, tenants inherit features from their assigned editions, and individual tenant feature values can also be overridden.

Check the feature configuration before investigating the permission code.

2. Review the permission definition

Find the permission associated with the feature. Check:

  • Is the permission registered correctly?
  • Does it have the expected feature dependency?
  • Is the correct feature name being used?
  • Is MultiTenancySides configured for the intended users?

A small naming mismatch between the feature provider, permission definition, and UI check can produce confusing results.

3. Check Angular menu and button visibility

Your Angular interface should not rely on an unrelated UI flag if the actual permission depends on a tenant feature.

Use the application's feature and permission checks consistently when deciding whether to display a menu item or action button.

For example, if an AI Reports button requires both an enabled tenant feature and a specific permission, its visibility should reflect those requirements:

<!-- Angular template checking both permission and feature dependency -->
<button *ngIf="isGranted('Pages.Administration.AiReports') && isFeatureEnabled('MyAiFeature')"
        (click)="openAiReports()"
        class="btn btn-primary">
    AI Reports
</button>

However, frontend checks are not security boundaries. The backend must still enforce the permission.

4. Protect the actual AppService

Make sure the backend operation is protected by the appropriate authorization rule, such as [AbpAuthorize] on the relevant application service method.

[AbpAuthorize(AppPermissions.Pages_Administration_AiReports)]
public class AiReportsAppService : MyAppServiceBase, IAiReportsAppService
{
    public async Task<AiReportDto> GenerateReportAsync(GenerateReportInput input)
    {
        // Business logic runs safely under verified authorization and feature dependency
        return await _reportGenerator.CreateAsync(input);
    }
}

Do not leave an alternative API path that bypasses the permission check.

A hidden button cannot protect an API endpoint, and a frontend feature flag cannot replace server-side authorization.

5. Test host and tenant access separately

Do not test only with a host administrator.

Create test scenarios for:

  • Host user with the required permission.
  • Tenant user with the required feature enabled.
  • Tenant user with the feature disabled.
  • Tenant user without the required permission.
  • Tenant user on an edition that does not include the feature.

For each scenario, check the button visibility, permission result, and actual backend response.

This helps identify whether the problem comes from feature configuration, permission registration, tenancy restrictions, or frontend visibility.

A Practical Checklist for ASP.NET Zero Feature Dependencies

Before releasing a new module, review each layer:

Application layer What to verify
Edition and tenant features Is the required feature enabled for this tenant?
Permission definition Is the correct feature dependency configured?
MultiTenancySides Is the permission available to the intended host or tenant users?
Angular menu and buttons Does visibility follow the same feature and permission rules?
AppService Is the actual backend operation protected?
API testing Does direct API access correctly reject unauthorized users?

If your application uses background jobs for the same feature, also verify how user and tenant context are established when the job executes. Background execution should not become a way around the same authorization rules.

Frequently Asked Questions

Why is my button visible when the user does not have permission?

Your frontend may be checking a separate feature flag instead of the actual permission. Review the feature and permission checks used by the menu or button, then verify the backend authorization independently.

What is SimpleFeatureDependency in ASP.NET Zero?

SimpleFeatureDependency is an ASP.NET Boilerplate implementation of IFeatureDependency. It makes a permission dependent on a named application feature being enabled.

What does MultiTenancySides mean?

MultiTenancySides determines whether a permission is available to host users, tenant users, or both. It helps keep permission availability aligned with the application's multi-tenant structure.

Can a user have a permission but still be unable to use the feature?

Yes. A role may contain a permission, but the permission's feature dependency or tenancy-side restriction can prevent it from being granted or used.

Should I use a feature flag or a permission check to hide a button?

Use feature checks to determine whether functionality is available in the application or tenant configuration. Use permission checks to determine whether the current user is allowed to perform an action. In many applications, both conditions should be reflected in the UI, while the backend enforces authorization.

Conclusion: Make the UI and Authorization Agree

A button appearing on the screen does not guarantee that the user can access the feature behind it.

In ASP.NET Zero, feature availability, permission dependencies, and tenancy restrictions each play a role in determining what users can access.

When these checks are configured independently, you can end up with visible buttons, failed permission checks, and confusing authorization errors.

Before releasing your next AI or SaaS module, verify the tenant feature, permission dependency, MultiTenancySides, Angular visibility, and backend authorization together.

A feature should not just look available. It should be available to the right users, in the right tenant, with the right permissions.

Have you ever faced a situation where a button was visible but the backend rejected the permission? What caused the mismatch in your application?

Need Help Aligning Feature Dependencies and Permissions?

If your team is building multi-tenant SaaS features, AI integrations, or custom editions in ASP.NET Zero and needs help aligning features, permissions, and Angular UI security, our dedicated development team can help. Get in touch, or explore our Development from Zero services.

Sources: ASP.NET Boilerplate, Feature Management accessed 2026-10-30; ASP.NET Boilerplate, Authorization & Permissions accessed 2026-10-30; ASP.NET Zero, Angular Permission Handling accessed 2026-10-30.

Get In Touch

Ready to start your ASP.NET Zero project?

Hire ASP.Net Zero Application Developers that will provide the perfect solution to your business issues. Our technical experts will provide you with a free consultation.

More from the Blog