diff --git a/src/food-market.api/Infrastructure/Tenancy/SuperAdminOverrideClaimsTransformer.cs b/src/food-market.api/Infrastructure/Tenancy/SuperAdminOverrideClaimsTransformer.cs
new file mode 100644
index 0000000..95cfec2
--- /dev/null
+++ b/src/food-market.api/Infrastructure/Tenancy/SuperAdminOverrideClaimsTransformer.cs
@@ -0,0 +1,58 @@
+using Microsoft.AspNetCore.Authentication;
+using System.Security.Claims;
+
+namespace foodmarket.Api.Infrastructure.Tenancy;
+
+/// В режиме «открыть как…» (SuperAdmin + X-Org-Override) сам
+/// SuperAdmin не имеет роли Admin/Storekeeper/Cashier, потому что эти
+/// роли — атрибуты сотрудника тенанта. Без трансформации claim'ов все
+/// мутации, защищённые [Authorize(Roles="Admin,Storekeeper")],
+/// отшиваются 403 даже когда
+/// разрешил мутацию (edit-mode с X-Org-Override-Reason ≥ 10 символов).
+///
+/// Здесь мы временно (на текущий request) добавляем SuperAdmin'у полный
+/// набор tenant-ролей, чтобы он мог пройти атрибуты-гарды контроллеров.
+/// Изоляция и аудит остаются: query filter всё равно скоупится на
+/// X-Org-Override, а пишет запись
+/// в super_admin_audit_log с reason и diff'ом.
+///
+/// Срабатывает только если:
+/// - User имеет роль SuperAdmin,
+/// - запрос содержит заголовок X-Org-Override.
+/// На GET-запросах (read-only override) тоже работает — это безопасно,
+/// потому что мутации остаются за middleware-гардом.
+public class SuperAdminOverrideClaimsTransformer : IClaimsTransformation
+{
+ private readonly IHttpContextAccessor _accessor;
+
+ public SuperAdminOverrideClaimsTransformer(IHttpContextAccessor accessor)
+ => _accessor = accessor;
+
+ public Task TransformAsync(ClaimsPrincipal principal)
+ {
+ var ctx = _accessor.HttpContext;
+ if (ctx is null) return Task.FromResult(principal);
+
+ var isSuper = principal.IsInRole(HttpContextTenantContext.SuperAdminRole);
+ var hasOverride = ctx.Request.Headers.ContainsKey(HttpContextTenantContext.OrgOverrideHeader);
+ if (!isSuper || !hasOverride) return Task.FromResult(principal);
+
+ // Не клонируем — IClaimsTransformation вызывается на каждый запрос,
+ // принципал и так свежий. Мутируем первый identity.
+ var identity = principal.Identities.FirstOrDefault(i => i.IsAuthenticated);
+ if (identity is null) return Task.FromResult(principal);
+
+ foreach (var role in TenantRolesForOverride)
+ {
+ if (!principal.IsInRole(role))
+ identity.AddClaim(new Claim(identity.RoleClaimType, role));
+ }
+
+ return Task.FromResult(principal);
+ }
+
+ private static readonly string[] TenantRolesForOverride =
+ [
+ "Admin", "Storekeeper", "Cashier",
+ ];
+}
diff --git a/src/food-market.api/Program.cs b/src/food-market.api/Program.cs
index 7b94dd9..bc42e06 100644
--- a/src/food-market.api/Program.cs
+++ b/src/food-market.api/Program.cs
@@ -31,6 +31,11 @@
builder.Services.AddHttpContextAccessor();
builder.Services.AddScoped();
+ // ClaimsTransformation для SuperAdmin override: добавляет роли Admin/
+ // Storekeeper/Cashier при наличии X-Org-Override, чтобы [Authorize(Roles=...)]
+ // не отшивал edit-mode мутации SuperAdmin'а. См. SuperAdminOverrideClaimsTransformer.
+ builder.Services.AddScoped();
builder.Services.AddDbContext(opts =>
{