Skip to content
Africa OS Knowledgebase
Esc
navigateopen⌘Jpreview
On this page

Architecture

The mental model behind Africa OS - how tenants, identity, request context, permissions, and the application registry fit together.

This section explains how Africa OS behaves at runtime. Start here before reading the platform packages in detail: architecture pages give you the mental model, and the platform pages give you the code.

The core idea is a series of layers, each solving one problem:

The three questions every request answers

Every server call in Africa OS ultimately answers three questions:

  1. Who is calling? - resolved by authentication from the request’s session.
  2. Which tenant are they acting in? - the active organization, resolved from the URL slug or the africaos.active_org cookie.
  3. What are they allowed to do? - the permission set, resolved from the member’s roles in that organization.

The request context package answers all three at once and hands the result to server functions.

The tenant boundary

The organization is the unit of tenancy. Every permission, every query, and every feature is scoped to an organization:

A user is one identity with memberships in many organizations. What they can see in an organization depends on the memberships and roles attached there. The platform never trusts the client with the tenant id - it always comes from the request runtime.

Authentication vs authorization

Africa OS separates the two cleanly:

  • Authentication (@africaos/auth) answers “who is calling?” It owns sessions and identity, powered by Better Auth.
  • Authorization (@africaos/permissions) answers “what may they do?” It owns capability strings, roles, and guards.

They meet in the request runtime: authentication resolves the identity, authorization resolves the permission set, and both are packaged into the context that server functions receive.

The application registry

Applications are not hardcoded into the platform. Each application self-describes through an app.config.ts, and RegistryService stores that metadata in the database. The web app reads the registry to build the launcher and to mount modules, so adding an application is mostly writing its config and re-registering.

Where the pieces live

Concern Package Key files
Multi-tenancy @africaos/organizations service.ts, lifecycle.ts, membership.ts, registry.ts
Authentication @africaos/auth service.ts, provider.ts, session.ts
Request context @africaos/request-context runtime.ts
Permissions @africaos/permissions permission.ts, guard.ts, service.ts
Unified shell @africaos/shell + apps/web app-registry.tsx, $organization.tsx

Last updated on August 18, 2026