Skip to content

Plan a tenant hierarchy: parent tenants that create and enter their own child tenants - #767

Draft
MikeAlhayek wants to merge 2 commits into
mainfrom
claude/orchardcore-umbrella-tenants-a7a279
Draft

MikeAlhayek wants to merge 2 commits into
mainfrom
claude/orchardcore-umbrella-tenants-a7a279

Conversation

@MikeAlhayek

@MikeAlhayek MikeAlhayek commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Adds a design plan, docs/engineering/tenant-hierarchy/tenant-hierarchy-plan.md. It covers a module that lets a non-Default "parent" tenant create and manage its own "child" tenants, and lets parent users move between those children without signing in again. The motivating case is a bookkeeping firm that runs one tenant per client business. Nothing is built yet; this PR is the plan only.

What the plan concludes

  • No Orchard Core changes are needed. The host services that create, set up, disable and remove tenants work from any tenant. Only the Tenants module itself is limited to Default, so the new module must not depend on it.
  • Default stays the only platform root. It still manages every parent and child through the standard Tenants admin. The plan explains why Orchard Core has a single Default tenant and why this use case doesn't need a second one.
  • Delegated access uses a brokered, in-process sign-in, not the stock OpenID modules. The flow has the shape of an OAuth code flow with PKCE, and the child authenticates by its own shell settings. The stock OpenID setup has no per-user gate, the child's admin can repoint the client authority, and parent tokens would carry Administrator rights into the child.
  • Each parent user gets a linked user in the child. It is created on first entry, the parent user's actions are recorded under it, and the child's admin can't sign in as it or edit it.
  • A parent can reach only itself and its own children. Requests carry the firm's own registry ids, never tenant names. Only the broker opens another tenant. A host-level guard on IShellHost refuses any scope a parent or child opens outside its hierarchy, and hides other tenants' settings from it. A feature audit covers what opens other tenants by design, including this repo's AI Agent tenant tools.
  • Isolation rules:
    • every tenant gets its own host name, never a path prefix;
    • Default owns each parent's policy (URLs, databases, recipes, quotas), and a parent never chooses a host, prefix or connection string;
    • the list of other children never appears inside a child page;
    • parent and child tenants use __Host- cookie names;
    • an egress guard blocks requests to the app's own tenants;
    • a feature guard blocks features that would reveal or reach sibling tenants.

The plan also covers the threat model, the Orchard Core code it relies on (with file and line references at 988c29a406), alternatives, deployment needs, a phased plan starting with ten phase 0 spikes, the recorded decisions and the risks.

Naming

The plan was first drafted as "Umbrella Tenants". It was renamed to Tenant Hierarchy because "umbrella" isn't a standard software term, already means a specific kind of employer in UK payroll and tax, and is the name of a well-known security product. The new terms are:

  • parent and child tenants (hierarchical multi-tenancy);
  • delegated access for entering a child;
  • a linked user, created just-in-time;
  • the tenant switcher for the bar.

The labels people see on screen can be set per parent, so a firm can show "Clients" instead of "Child tenants".

🤖 Generated with Claude Code

Design plan for a module that lets a parent tenant create and manage its
own child tenants, and lets parent users enter those children through
delegated access with strict isolation and attribution. Covers the Orchard
Core findings it relies on, the threat model, the architecture, policies,
alternatives, a phased plan and the recorded decisions. Nothing is built.
Adds goal G8 and a scope containment section: requests carry registry ids
instead of tenant names, only the broker reaches other tenants, a host-level
IShellHost guard refuses and filters anything outside the hierarchy, and a
feature audit covers the features that open other tenants by design. Adds
the matching phase 0 spike, phase 1 deliverables and tests, and explains the
two ways a firm works with a business.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant