People, machines, and tenants

Most hosted identity products collapse the world into one user table. An app gets a shared pool of humans. Organizations are a field on the user, or a thin wrapper around the same accounts. Machines borrow a person’s session or a long-lived secret with no principal of their own.

M7 does not work that way. People, machines, and tenants are different kinds of principal. That is the product, not a footnote.

The install walkthrough gets Sign in with M7 on a PHP site. This post is why the token you get back is not “just a user.”

Three separate objects on a workbench: a wallet, a machine plate, and a fenced enclosure.

Three principals

A consumer user is a person with an M7 account. They sign in with authorization code and PKCE. They own personal applications. They can manage organizations when they have Management access. They are not automatically a member of every tenant they can see.

A tenant member lives inside an organization. Their session is fenced. The same human may exist as a consumer and as a member; those are not the same security context. Org tokens do not manage the consumer control plane. Member credentials stay in the tenant they were issued for.

A machine is an OAuth application using client_credentials, or another non-human client. It has its own client ID, audience, and scope. It does not wear a user’s session. Public clients cannot use client credentials. Confidential clients authenticate as themselves.

If your design needs “the bot is Alice,” that is a bug in the model. Issue the machine a machine credential.

What a tenant is

An organization is a security context: members, groups, applications, policy, and (where you use it) hosted login. It is not a label on a global user row.

Registration can be personal or organization-owned. Audience and scope are registered per client. Groups can gate who may register or sign in. Archive and disable fail closed on refresh and UserInfo. Management-group access on the consumer side is how a person administers the tenant; it is not a substitute for member identity inside the tenant.

That is why M7 is a poor clone of a shared-user-pool CIAM and a better fit for custom applications that already have their own accounts, or for operators who need more than one organization without flattening everyone into one directory.

What the token is allowed to mean

An access token names issuer, subject, client, audience, and scope. Resource servers still decide the route. API User classifies its /api/v2 routes and enforces scope on top of principal, tenant, and object checks. Local JWT validation proves the signature and claims. It does not, by itself, mean the caller may hit every API.

Stock OIDC is enough for many apps: authorization code, PKCE S256, ID token from the published JWKS, JSON or signed UserInfo, refresh without M7 binding fields. DPoP, ACK, and required bindings are the M7 path when you want sender constraint and explicit promotion. Next post is when to use which.

What we are not claiming

This is not “we replaced Clerk.” Clerk is a strong product for app-level user pools. M7 is an authorization server plus fenced tenants plus machines. Different job.

It is also not GA, not certified, and not a promise that every unmodified library will light up. Development access. PHP SDK. MTL-10.

If you need one directory of humans for a single app, a user-pool vendor is simpler. If you need people, services, and organizations to stay distinct, start at M7 Identity and the SDK.