Multi-tenant Platforms
You serve multiple customers from shared infrastructure. Isolation must be enforced. Entitlements differ per tenant.
What decisions matter here?
Multi-tenancy turns every request into a boundary decision:
- Which tenant is this? Identify the customer from the request context.
- What are they entitled to? Features, quotas, rate limits—all tenant-specific.
- Are they isolated from other tenants? Can tenant A’s request ever see tenant B’s data?
- What tier are they on? Free tenants get basic features. Enterprise tenants get everything.
These decisions happen at the edge, before requests reach your services.
What goes wrong today?
Tenant checks in application code
Every service checks if (tenant.tier === 'enterprise'). The logic is scattered, inconsistent, and hard to audit.
Feature flag sprawl You use LaunchDarkly for features, a homegrown system for entitlements, and application code for tenant isolation. Three systems, three sources of truth.
Noisy neighbor problems One tenant’s traffic spike affects others. Rate limiting is per-service, not per-tenant. You can’t enforce fair usage at the gateway.
Entitlement disputes Customer claims they should have access to a feature. You check the feature flag system, the billing system, and the entitlement database. They all say different things.
What Hexarch changes structurally
Application Identity Hub
From the Application interface and IdentityManager.tsx:
interface Application {
id: string;
name: string;
owner: string;
subscriptions: Subscription[];
credentials: Credential[];
}
Each tenant is a formal application identity. Their subscriptions, credentials, and entitlements are managed in one place. The gateway knows this identity and enforces accordingly.
Before: Tenant context scattered across services After: Centralized tenant identity with gateway-enforced entitlements
Granular Policy Scoping
From the PolicyScope enum:
enum PolicyScope {
GLOBAL, // All tenants
API, // Specific API
VERSION, // Specific version
PLAN, // Specific access plan (tenant tier)
ROUTE // Specific endpoint
}
Policies apply at different granularities. A global security policy for all tenants. A rate limit policy per plan tier. A route-level policy for sensitive endpoints.
Before: One-size-fits-all or per-service configuration After: Hierarchical scoping from global to route-level
Tier-Based Entitlements
From the AccessPlan interface:
interface AccessPlan {
name: string; // 'Free', 'Business', 'Enterprise'
quota: { value: number; unit: 'Requests'; period: string };
rateLimit: { requestsPerSecond: number; burst: number };
policies: Policy[]; // Tier-specific policies
}
Each tier has its own quotas, rate limits, and policies. Free tenants get 100 requests/day. Enterprise gets unlimited. The gateway enforces—your services receive only authorized, within-quota requests.
Before: Tier checks in application code After: Tier enforcement at gateway, services receive clean traffic
Feature Entitlements via Policy
From the AdminDecisionDashboard.tsx decision feed:
interface DecisionRecord {
feature: string; // 'policy_generation', 'analytics', 'custom_policies'
tier: string; // 'free', 'pro', 'enterprise'
decision: 'ALLOW' | 'DENY';
reason: string; // 'tier=pro, feature not in plan'
}
Features are policy decisions. Tenant on Free tier tries to access Analytics → DENY, reason: “feature not in tier.” The decision is recorded, auditable, consistent.
Before: Feature flags + entitlement database + billing check After: One policy decision with full audit trail
Per-Tenant Rate Limiting
From the Policy interface with targetRef:
interface Policy {
scope: 'PLAN';
targetRef: { planId: string };
config: {
ratePerMinute: number;
burstBuffer: number;
};
}
Rate limits are per-plan, not global. Free tier gets 1 req/s. Enterprise gets 100 req/s. No noisy neighbors—each tenant’s traffic is shaped independently.
Before: Global rate limit, hope for fairness After: Per-tenant limits enforced at gateway
Tenant Isolation Model
| Layer | Traditional | Hexarch |
|---|---|---|
| Identity | JWT claims + application parsing | Formal Application entity |
| Entitlements | Feature flags + billing lookup | Subscription with version-locked plans |
| Rate limiting | Per-service, inconsistent | Per-plan at gateway |
| Feature access | if (tier === 'enterprise') | Policy decision with audit |
| Audit trail | Scattered logs | Per-tenant decision stream |
The Developer Portal for Tenants
From DeveloperPortal.tsx:
Tenants can self-serve through the portal:
- Register Application: Create their tenant identity
- Browse API Catalog: See available APIs and versions
- Subscribe to Plans: Select their tier
- Track Entitlements: View active subscriptions and quotas
Governance happens in the background. The gateway propagates entitlements. Traffic is shaped before it reaches your services.
Try It
- Developer Portal — see how tenant self-service works
- AI Policy Generation — create tier-specific policies from natural language
- Fleet Governance — how entitlements propagate to gateway nodes