Hi,
TokenCleanupBackgroundWorker — runs every 1 hour (cleans up expired OpenIddict tokens older than 14 days)IdentitySessionCleanupBackgroundWorker — runs every 1 hour (cleans up inactive sessions older than 30 days)ExcelFileCleanupWorker — already runs daily at 23:00ExpiredAuditLogDeleterWorker — already runs daily at 23:00So only the first 2 are running hourly. Changing them to daily is totally fine — they're cleaning up data that's 14-30 days old, so a few hours delay doesn't matter at all.
You're right that the Hangfire dashboard is read-only for recurring jobs. You need to configure them in your code:
Configure<TokenCleanupOptions>(options =>
{
options.CleanupPeriod = (int)TimeSpan.FromDays(1).TotalMilliseconds;
});
Configure<IdentitySessionCleanupOptions>(options =>
{
options.CleanupPeriod = (int)TimeSpan.FromDays(1).TotalMilliseconds;
});
However, I should mention that these 4 workers are very unlikely to be the cause of your socket growth issue. Even at hourly frequency, they only create a few database connections per run. That's nothing compared to the ~120 sockets/minute growth you're seeing.
The socket issue is more likely caused by something else in your application — maybe manually created SqlConnection or HttpClient instances that aren't being disposed, or Azure SNAT port exhaustion. I'd recommend using dotnet-counters to monitor what's actually consuming the sockets:
dotnet-counters monitor --process-id <PID> --counters "Microsoft.Data.SqlClient.EventSource,System.Net.Sockets,System.Net.Http"
Thanks
Hi,
Yes, the Scriban vulnerability has been fixed. We addressed this in two steps:
Both fixes are included in version 10.2.0 and later.
Thanks
Thanks, we will check your new question.
Hi,
Thanks for sharing the error. Yes, Scriban 7.0.0 changed ParserOptions from struct to record, so overriding the version doesn't work with ABP 8.2.x.
The good news is ABP's Scriban usage does not trigger this vulnerability:
TemplateContext instance for every render call — it never reuses TemplateContext across renders.MemberFilter or MemberRenamer on TemplateContext at all.Since the vulnerability requires reusing a TemplateContext with dynamically tightened member access restrictions, and ABP doesn't do that, the actual risk is very low.
You can suppress this specific advisory warning by adding the following to your project file:
<ItemGroup>
<NuGetAuditSuppress Include="https://github.com/advisories/GHSA-5wr9-m6jw-xx44" />
</ItemGroup>
Thanks
Hi,
The performance issue is resolved. This feature filtering question is a different topic — please create a new support question so we can track it separately.
Based on the code, ABP checks feature values in this order: Tenant (T) → Edition (E) → Configuration (C) → Default (D). The first non-null value wins. Your feature has defaultValue: "false", so if no other provider returns a value, the feature should be disabled and permissions should not show.
Since the permissions are still showing, some provider must be returning a value that enables the feature. To find out which one, please run this SQL on your SaaS/Administration service database (in microservices, AbpFeatureValues is typically NOT in the tenant database):
SELECT * FROM AbpFeatureValues
WHERE Name LIKE '%TourModule%' OR Name LIKE '%TourService%'
ORDER BY ProviderName, ProviderKey;
Please share the result in the new question, along with:
Thanks
Hi,
The performance issue is resolved now. The feature filtering question is a separate topic — could you please create a new support question for it?
To help us investigate quickly, please include the following in the new question:
TMSMSFeature.cs and your FeatureDefinitionProvider.cs)TourServicePermissionDefinitionProvider.cs showing the .RequireFeatures() usageSELECT * FROM AbpFeatureValues
WHERE Name LIKE '%TourModule%' OR Name LIKE '%TourService%'
ORDER BY ProviderName, ProviderKey;
Thanks
Hi,
The CWE-693 vulnerability (GHSA-5wr9-m6jw-xx44) in Scriban is about TemplateContext caching type member accessors by Type only. It can be exploited when a TemplateContext instance is reused across renders and the MemberFilter or MemberRenamer is tightened between renders — previously cached accessors may still be exposed.
However, ABP's Scriban usage does not trigger this vulnerability:
TemplateContext instance for every render call — it never reuses TemplateContext across renders.MemberFilter or MemberRenamer on TemplateContext at all.Since the vulnerability requires reusing a TemplateContext with dynamically tightened member access restrictions, and ABP doesn't do that, the actual risk is very low.
That said, if you want to eliminate the warning entirely, you can override the Scriban version to 7.0.0 in your project file. We tested this with ABP 8.2.3 on .NET 8 and it works without any issues:
<ItemGroup>
<PackageReference Include="Scriban" Version="7.0.0" />
</ItemGroup>
This will resolve all Scriban-related security warnings.
Alternatively, if you prefer to keep the original version, you can suppress specific advisories:
<ItemGroup>
<NuGetAuditSuppress Include="https://github.com/advisories/GHSA-5wr9-m6jw-xx44" />
</ItemGroup>
Thanks
Hi,
Looking at your screenshots, the TourModule feature is disabled in the Feature Management UI, but TourService permissions still show up. Let me explain why.
ABP has two separate feature systems, and they work differently with permissions:
1. Features (RequireFeatures) — per-tenant, managed in Feature Management UI
This is what your Feature Management UI controls. To make permissions respect this, each permission must explicitly call .RequireFeatures() in its definition:
public class TourServicePermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var group = context.AddGroup("TourService");
group.AddPermission("TourService.Tours")
.RequireFeatures("TourServiceModule"); // ← links to tenant feature
group.AddPermission("TourService.Tours.Create")
.RequireFeatures("TourServiceModule"); // ← each permission needs this
}
}
If .RequireFeatures("TourServiceModule") is missing from the permission definition, disabling the feature in the UI won't filter out that permission.
2. Global Features (RequireGlobalFeatures) — application-level, configured in code
This is a different system — it's enabled/disabled at the application level (not per-tenant), and the Feature Management UI does NOT control it. It looks like this:
group.AddPermission("CmsKit.Comments")
.RequireGlobalFeatures(typeof(CommentsFeature));
What's happening in your case:
Your TourService permissions most likely don't have .RequireFeatures("TourServiceModule") in their permission definition code. So even though you disabled TourServiceModule in the Feature Management UI, the permission system doesn't know they're linked — it shows them regardless.
To fix this, you need to add .RequireFeatures("TourServiceModule") to each TourService permission in your TourServicePermissionDefinitionProvider. Same for other modules — each module's permissions should reference their module feature.
After adding this, when the feature is disabled:
Thanks
Hi,
ABP actually already handles this through the Feature system.
When permissions are defined in a module, they're typically linked to a feature using RequireFeatures. The permission management UI filters permissions through these feature checks — so if a module's feature is disabled, its permissions won't show up in the UI, and "Grant all permissions" won't grant them either.
So in your scenario with 20 microservices:
The reason you're seeing 4000+ permissions is likely because all module features are currently enabled in your environments (or were enabled when "Grant all" was clicked). The old grants for disabled features stay in the database but are ignored at runtime.
If you want to keep things clean for a new production that only uses 1 module:
Thanks