ExternalInstallation
A verified, Workspace-owned installation of one provider, such as one Slack app installation.
exti_…SurfaceScope
A governed place inside that installation: the provider root, a team, a channel, or a DM.
surf_…AgentInstallation
The binding that places one Agent on specific surface scopes under a declared identity posture.
aini_…The provider installation
An ExternalInstallation is an authenticated link to one provider tenant your integration operates. A given(provider, external tenant) has at most one active Checkfu Workspace owner.
Creating or reactivating one requires a signed pairing proof bound to the exact Workspace, provider tenant, operation, and installation, and valid for at most five minutes. Your provider adapter produces that proof; Checkfu verifies it.
state (active, disabled, disconnected, or uninstalled). Provider credential material never appears on the resource, in a Session, or in a harness.
The surface hierarchy
A SurfaceScope is a governed place in an installation, and it is the provider-neutral handle everything else uses. PermissionAssignments, ActionPolicies, Memory, Budgets, Automations, audit, and retention all address a SurfaceScope. Provider-specific channel or DM identifiers never enter Session state. Each scope has akind and, unless it is the root, a parent_id:
A scope also declares
visibility (public, private, personal), membership (public, provider_members, personal), and inheritance (inherit or isolate). The tree must be acyclic, (installation, external_id) is unique, and there is no DELETE. A scope’s lifecycle ends by patching its state to archived.
A thread inside a channel is not another SurfaceScope. A thread maps to a Session through a conversation binding; the SurfaceScope is the channel it lives in.
Placing the agent
An AgentInstallation is the binding that makes an Agent answerable on surfaces. It coordinates references: it never copies the definition, and it never introduces a second access-control list.
There are no harness or model “override” objects here. The logical names name the same contract the Agent’s published release already resolves to; the installation coordinates, it does not reconfigure.
The identity posture declares whose authority the placement runs under, and admission rejects a mismatch rather than guessing:
autonomous(the default whenidentity_postureis omitted): the placement acts as its own credential-bearingservicePrincipal, which owns its Connections and PermissionAssignments.acted_asmust be aservice-kind Principal in the Workspace.delegated: the placement acts on behalf of a resolved user.acted_asmust be aperson-kind Principal, so per-user PermissionAssignment intersection evaluates a real human.
active ↔ disabled → archived; archived is terminal. Changing acted_as or identity_posture revalidates authority and fences both the old and new Principal.
Installed session admission derives everything
When a Session starts from an installation, the caller supplies almost nothing. The platform derives the rest from the placement, and supplying a derived field is rejected, not ignored. An installed session request may set only:agent_installation: the placementsurface_scope: which scope, within that placement, the Session runs inprincipal: the human on whose behalf it is being startedmounts: Project mounts onlytitle: an optional human label for the Sessioninitial_events: up to 50 optional events, applied in order, to seed the log with at creation
agent_deployment_id, agent_deployment_revision_number, version_policy, acted_as, caused_by, harness, model_routing_profile_key, environment, or compaction. Each of those is derived from the installation. Sending any of them fails validation with 400 validation.malformed. The request is refused, so a caller can never quietly override the Harness, model, or acting identity a placement was governed to use.
Admission then checks the full chain: an active placement in an active ExternalInstallation; the selected SurfaceScope and its complete ancestor chain all active; the requester is an active person holding invoke on both the Agent and the SurfaceScope; the placement’s acting Principal is active, matches the declared identity posture, and holds act_as; and the deployment still pins its own use_harness, use_model, and use_environment authority. The resulting Session freezes the placement, surface, requester, actor, the exact deployment revision, and the release hash it pins. See Two freeze horizons.
Where a Session comes from
You rarely create an installed Session directly. On a live surface, the first message in a thread creates it through a conversation binding, which runs exactly this installed admission for you. DirectPOST /v1/sessions with an installed request is the path only when you are not routing through a provider conversation.
Next steps
Conversation bindings
Turn an inbound thread into a Session, race-safely.
Add an agent to your app
The full placement-to-billing journey, end to end.