Skip to main content

ARC 2.0.0-beta.28

Caller context

ARC resolves caller identity and optional instance membership on trusted server context, not from a UI message or a path supplied by the client.

ARC resolves caller information from trusted credentials before it builds a session view. The resulting CallerInfo can carry a DID, authentication method, roles, and, when the server supplies a trusted instance context, an instance DID.

What the runtime knows

CallerInfo (AFS core type) is the handoff shape after resolution:

FieldMeaning
didCaller DID, or null for anonymous. Treat null as anonymous, never as a sentinel string.
rolesRole strings after resolution (often a one-element array).
pkPublic key (hex) when available.
authMethodHow the caller authenticated (for example passkey, access-key, did-connect).
instanceDidInstance context stamped by the server when membership or display needs it.
displayNameOptional display name for UI.
authSource"cookie" or "bearer" — how the credential arrived.

Mutating AFS RPC operations that care about CSRF require authSource: "bearer". A cookie alone is not enough for those writes.

Credential inputs

The shared caller core (services/shared → both Node and Cloudflare) accepts:

InputResolution path
Cookie: login_token=<JWT>Browser session JWT.
Authorization: Bearer <JWT>Programmatic / mobile JWT (not an access key).
Authorization: Bearer blocklet-…Blocklet-service access key.

Anonymous requests (no JWT candidate and no Authorization header) resolve to null. Invalid or unresolvable credentials also return null; the core does not throw for ordinary unauthenticated traffic.

Membership overlay

Instance membership is an overlay on trusted server context:

  1. The server resolves the request's tenant / instance DID.
  2. When that value is present, the general caller path sets membership: true and feeds it into connect-service resolveIdentity.
  3. Connect-service can return a per-instance role (owner / admin / member / guest) on top of the user's global role.
  4. The client cannot create that relationship by naming an instance in a UI message or by forging an instance header on paths that strip or replace client-supplied instance identifiers.

Some ingress paths remove or replace a client-supplied instance header before resolution. Treat that as an ingress-specific safeguard, not as a universal guarantee for every ARC entry point you invent later.

Role ordering fails closed

Role comparison uses a fixed ordinal:

RoleLevel
guest0
member1
admin2
owner3

Any unrecognised or absent role maps to level 0 (guest). Do not invent intermediate roles in application code and assume the runtime will honor them.

Keep presentation separate from authorization

Use a session fact to decide whether a page should show an action. Do not treat that condition as the authorization check. The provider and runtime still decide whether the resolved caller may read, write, execute, or traverse a resource.

The same rule applies to identity input. A text field, a URL parameter, a page route, or a $session substitution cannot establish a caller identity. It may name a resource, but only server-side credential resolution can determine who is asking.

AUP-facing guidance for the same boundary: Caller identity and safety.

Evidence

ClaimEvidence
Shared credential → CallerInfo mappingservices/shared/src/caller.ts (mapToCallerInfo, resolveCallerFromCredentials)
Node daemon auth wire-upruntimes/node/src/daemon/auth/index.ts (setupAuthService, resolveCaller)
Role fail-closed ordinalpackages/aos/src/session/role-level.ts
CallerInfo field contractpackages/core/src/type.ts
Read-only memberships AFS view@aigne/afs-members (providers/basic/members/) — list/get only; not a membership-admin API

Current boundary

This page documents caller resolution and its fail-closed role behavior. It does not document account creation, DID recovery, membership administration UI, or a complete instance-identity lifecycle. Do not infer those flows from the presence of a DID or a role in a session.