BaryoDev / BaryoDev/barakoCMS

Tenants: lifecycle status (Active, Suspended, Archived) enforced once at resolution

Open
#894 0 comments 0 reactions 0 assignees View on GitHub
core design migration security
Dominant language
C#
Stars
6
Forks
7
Avg merge
4h 42m
Merged PRs (30d)
307

Description

A tenant has one `IsActive` flag (`barakoCMS/Models/Tenant.cs:48`) and it is checked in four places, each on its own: `barakoCMS/Infrastructure/Auth/TokenIssuer.cs:120`, `barakoCMS/Infrastructure/Auth/ApiKeyAuthenticationHandler.cs:114`, `barakoCMS/Infrastructure/Multitenancy/TenantDomainSource.cs:78` and `barakoCMS/Infrastructure/Services/ScheduledContentService.cs:141`. Resolution never checks it. `barakoCMS/Infrastructure/Multitenancy/TenantResolutionMiddleware.cs:42-47` takes any `X-Tenant` header as the slug, and the subdomain rule at `:83` still resolves a deactivated tenant's slug even though its custom domains drop out of the map. Nothing under `barakoCMS/Features/Public` reads the Tenant document, so a deactivated tenant keeps serving published content by header or subdomain.

### Why it matters

A paused client (a bakery that stopped paying, a school closed for the year) has to be switched off, not just locked out of sign-in. Today their public pages stay up. The scheduled sweep skips inactive tenants, so every publish and unpublish that fell due while the tenant was off applies at once on the first sweep after it is reactivated. There is also no way to say "archived, keep the data, refuse everything" as distinct from "suspended for a week".

### The general concept

A `Status` on the tenant (Active, Suspended, Archived), read once in tenant resolution. Public delivery for a tenant that is not Active answers 404, authoring answers 403, and scheduled work for it is paused rather than skipped, with a stated rule for what happens to items that fell due while paused. The four scattered checks read the same status instead of their own copies. #858 covers a site's Private mode, which is the site half of this; it does not cover the tenant being off.

### Where it lives

Core: multitenancy, auth and scheduled content.

### Compatibility

Released. `IsActive` is stored on every Tenant document, so it needs a migration to `Status` (true to Active, false to Suspended), and `IsActive` stays on the tenant response as a derived field so the console keeps working. Public routes answering 404 for a suspended tenant is a status code change for that case, so it rides the contract bump already in flight for 4.2.0 (#867, #861).

### Done when

- An anonymous public read with `X-Tenant` set to a suspended tenant returns 404, by header and by subdomain, and a test showing that fails before the change.
- A signed-in request to a suspended tenant's authoring routes returns 403.
- A scheduled publish that falls due while the tenant is suspended does not apply, and applies by the stated rule after reactivation.
- Stored `IsActive` values are migrated, and the tenant response still carries `IsActive`.

Found in the architecture sweep of 15 September 2026.

Contributor guide

Open the contributing guide

Research direction

Start with Tenant.cs:48 and TenantResolutionMiddleware.cs:42-47,83 to trace current tenant lookup, then compare the four IsActive checks in TokenIssuer.cs, ApiKeyAuthenticationHandler.cs, TenantDomainSource.cs, and ScheduledContentService.cs. Review the contract bump and migration implications before deciding the paused-schedule rule. Done means the listed header/subdomain, authoring, scheduling, migration, and response-compatibility cases have coverage and pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
authentication, backend, database
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.