Identity and tenancy
Turning a credential into actor context, and why proving who someone is says nothing about where they may act.
Every governed action, projection decision, grant and audit record derives from actor context. It is the first thing to get right, and the most expensive to retrofit: change it after your integrations are built and you rebuild the integrations.
The platform does not authenticate
PlatformHost accepts actorId and actorType and trusts them. That is deliberate — it has no
opinion about your identity provider — but it means something upstream must establish identity before
the platform is called, and that something is yours.
IdentityPort is the seam. It is OAuth2/OIDC-shaped, so a gateway that already validates JWTs
implements it without a second identity model.
const claims = await identity.verify(credential);
if (!claims) throw new Error("unauthenticated");verify returns null for anything it cannot positively verify. It never returns partially trusted
claims, and it never echoes credential material back — identityPortChecks asserts both.
Verification is half the job
A credential proves who the caller is. It does not prove they may act in the tenant and space this particular request names. A valid credential for one tenant, replayed against another, is a valid credential.
// Refuses expired, not-yet-valid, cross-tenant and out-of-space claims.
const actor = actorContextFromClaims(claims, { tenantId, spaceId });Derive the submission fields from claims that passed this check rather than from request input. That is what keeps the audit trail tied to something that was actually proven.
Three details that decide whether this fails open
Space coverage is spelled out. spaceIds is either an explicit array or the literal
"tenant-wide". There is no absent-means-everything case, because claims that simply forgot to carry
coverage would otherwise read as covering everything.
Timestamps carry an offset. issuedAt and expiresAt must be RFC 3339 with an explicit offset.
Date.parse accepts timezone-less strings and reads them in the host's local zone, which would make
the same credential expire at different instants on different machines.
The clock is checked before it is trusted. Every comparison against an invalid clock is false, so
an unvalidated now would let an expired credential through rather than reject it.
Actor kinds
Six, not two: natural_person, agent, system, service_account, external_system,
integration. Policy treats them by capability rather than by kind, but a gateway design has to
handle the last three differently from a human session, and they are easy to discover late.
What is still yours
Session management, token refresh, the login surface, and mapping your provider's claims onto
ActorClaims. Fabric defines what verified identity looks like once it reaches the platform.
The standard
What a team has to get right to build a composable application on Fabric Platform, and which of those things the build refuses to let them get wrong.
Authoring and grants
How a screen says what it needs, why contract membership is not authorization, and what variants have to satisfy to be safe.