Concepts · 02

Identities and boundaries

The single most important design decision in this platform is that an agent is a citizen, not a service account. Once you accept that, everything else — multi-agent collaboration, memory, autonomy, audit — becomes a permissions problem with familiar shape.

Everyone is a principal

A principal is anything that can act on the platform. Ergon has one principal model. The policy engine asks the same question for everything that ever arrives at any endpoint:

Does this principal have permission to perform this action on this resource?

Actions and resources are hierarchical strings — workflows:workflows:items:route on org/{cid}/workflow/{wid}. Wildcards are allowed at any level. Deny overrides allow. Default is deny. That is the entire vocabulary, and it is the same vocabulary for an admin user, a third-party integration, and a fully autonomous agent.

The engine does not care why a request arrived. It cares whether the principal carrying that request is allowed it. Uniformity at the policy layer is what makes mixed teams of humans and AI legible.

Principal kinds

All organization-scoped principals flow through the same gates. They differ only in how they authenticate and what lifecycle owns them.

User

Auth

Email + password, then short-lived JWT in an HttpOnly cookie.

Who

A human who logs in. May belong to multiple organizations.

Note

Roles, grants, and service access are attached at the company-membership level — so a single human can be an admin in one org and a viewer in another.

API Key

Auth

Client credentials exchanged for a short-lived bearer token.

Who

Programmatic actors: integrations, scripts, the customer's own backend.

Note

Holds explicit grants in exactly the same graph as a human or an agent. There is no shadow ‘service account with admin’ pattern.

Agent

First-class

Auth

Short-lived JWT minted by the agents service when the agent runs.

Who

An AI actor. Owns its configuration, prompts, model, tool set, and semantic memories.

Note

When the agent calls a downstream service, the request carries principal_type: agent and the policy engine evaluates it the same way it evaluates a human request.

Team

Auth

No credentials of its own — a team is a grouping, not a login.

Who

A named group of members (and, optionally, nested teams).

Note

A team is a first-class principal: it holds roles and grants directly, and its members inherit them through the subject graph. Prefer permissions → role → team → members over per-member grants, so onboarding someone is a single team assignment.

Machine Principal

Auth

Short-lived IAM-minted JWT for automations, workflows, and worksheets.

Who

A service-owned actor that performs work on behalf of a concrete resource.

Note

Automations, workflows, and worksheets can hold grants and service access through the same principals table. Internal service keys only authenticate substrate calls; they do not replace IAM permission checks.

Federated Zones

A federated zone is the authorization boundary around a single concrete resource. The rule it encodes is simple: access is granted on that one instance — a specific workflow, bucket, agent, skill, or LLM config — never on its parent or on the resource type as a whole, and you manage who can use it from the instance's own security page. A zone does not need to contain anything: a skill or an LLM config has no sub-resources, yet each is still its own zone because access to it is delegated on its own. The platform controls who can create that instance at the organization border; once it exists, the owning service controls delegation inside it.

The creator receives the first local bundle for the zone — service-local permissions plus the right to manage access on that root. Everyone else must be invited from the owning service's security page. That is why a broad company role can authorize creating a new workflow but does not automatically reveal every workflow already created by someone else.

Federated zones are the zero-trust unit of delegation: IAM stores and evaluates the grants, while each service validates the resource lineage inside its own zone.

Connections — joining a zone

Having access to a service is not the same as belonging to a specific zone inside it. If it were, every principal with Workflows access would surface in the security page of every workflow in the company — thousands of irrelevant names, and a permission UI nobody can use. So a principal becomes eligible in a zone only after an explicit connection is established. No connection, no eligibility — and the connection is also a runtime gate: revoke it and every grant on that zone goes inert instantly, without deleting a single grant.

For people-like principals (members, agents, API keys, teams, roles) the order is deliberate: an administrator grants service access first, then a connection ties the principal to a specific zone, then the zone owner issues grants. Service-owned principals (automations, workflows, worksheets) skip the manual steps — connecting auto-provisions their service access when the company has that service enabled.

Connections are always a two-party handshake, and the zone owner is always the gatekeeper:

Request

The principal asks to come in.

Someone wiring up a dependency they don't own requests a connection to the target zone; an administrator of that zone approves it. Approval can connect and grant the requested permissions in one step.

Offer

The zone invites the principal in.

A zone owner invites a principal from the zone's Connections tab, optionally pre-selecting the permissions to grant on acceptance. The invited side accepts; the inviting side can withdraw but never self-accepts.

Neither side approves its own move

A request is approved by the zone, never the requester; an offer is accepted by the invited principal's controller, never the inviting zone. Both halves require two parties — which is exactly what keeps every zone's access list intentional.

Connection is the gate; grants live downstream

Connection and grant are two separate ideas, and the connection always comes first. A grant never establishes a connection on its own: the standalone Access panel only lists principals already connected to the zone, and the backend rejects a grant to an unconnected principal. So the Permission-grants drawer is, by construction, “who is connected here, and what they can do.”

Connecting and granting in one action is still a single round trip — but it happens through the connection flows, not the grant drawer. An approved request or an accepted offer can carry its grants (“connect + grant”), so an accepted connection is immediately usable. The connect dialog even pre-checks the zone's view permission by default, so the canonical first step is simply “request view access”: connect, become eligible, then manage the rest of the grants.

Creating a resource is the same idea applied to yourself: the creator receives the zone bundle and the connection to the new zone in one explicit step, so you can immediately work inside something you just made — create a workflow in a folder you own, open your own agent conversation — with no extra chore. That self-connection is part of the create action, not a side effect of a grant.

Revoking and deleting clean up after themselves

Revoking a connection is an instant kill switch: every grant on that zone goes inert at once, without deleting a single grant, and re-connecting reactivates them. Deleting a resource, or retiring a principal (including a team), purges the connections and any pending connection requests that pointed at it — nothing is left dangling behind a gone resource or identity.

The two-way handshake

Agents come with a problem you do not have for human users: you must bound both ends of every interaction. Who is allowed to invoke this agent? and what is this agent allowed to do once invoked? Confusing the two is the classic failure mode of agentic systems — an admin invokes a “summarizer” which silently deletes every record it summarizes because nobody bounded its tool surface.

We refuse the confusion at the substrate level. Every agent has two grant graphs:

Inbound

Who may invoke this agent.

Modelled as IAM grants on agents:invoke:execute scoped to org/{cid}/agent/{aid}. Grant the action to a member, an API key, another agent, or a role. Without that grant, the invoke attempt 403s — the same way it would for any other resource.

Outbound

What this agent may reach.

Modelled as the agent's own grants in IAM. The runtime mints a JWT carrying principal_type: agent and the agent's ID. Every tool call goes back through the same policy engine that protects human actions. There is no privileged tunnel.

The two graphs are independent. A user with access to invoke an agent does not automatically inherit the agent's capabilities — and the agent does not automatically inherit the user's. The capability surface of any invocation is the intersection: “user can invoke agent” AND “agent can perform action X”.

Why this matters

You can give a junior teammate the right to invoke an autonomous “close-the-month” agent — without giving that teammate the right to do any of the things the agent does. The agent acts under its grants, not the caller's.

Tool Access

An agent often needs to behave differently in different contexts. The same legal-research agent should be read-only when a paralegal is exploring case law, and should be allowed to update matter records when a partner is closing a deal. That mandate is expressed through IAM grants.

Each agent tool declares the IAM permission it requires and an action type such as:

  • list, read, and search for viewer-style work.
  • create, update, send, and execute for active work.
  • delete and manage for high-impact operations.

IAM grants remain the hard authorization layer. Action types give the platform a shared vocabulary for future mode selectors without adding customer-managed permission presets.

The autonomy spectrum

Trust is built in stages. Ergon does not have a “supervised” product and an “autonomous” product — it has one platform with a sliding mandate, expressed entirely as grants and process design.

1

Copilot

The agent suggests; humans execute. Narrow grants, every action is a draft until a human approves it.

2

Evidence

Acceptances, rejections, and outcomes accumulate in the same event log as everything else. The organization has data to decide whether to trust the agent more.

3

Expanded mandate

Administrators widen grants. Transitions, sends, writes — more tools, larger blast radius — become available.

4

Autonomous operation inside boundaries

Self-governing execution where policy allows. Humans focus on exceptions, edge cases, and direction. The agent runs continuously, on events, with audit.

Same agent. Same code. Different mandate. The difference between “a bot that drafts emails” and “a bot that sends them” is an IAM grant change.

Why “agent A on behalf of agent B” is structurally safe

One of the failure modes of multi-agent systems is the confused deputy: agent A is allowed to invoke agent B, and agent B does something on A's implied authority that A could never have done alone. We make this attack structurally impossible.

When agent A invokes agent B, B does not inherit A's permissions. B's tool calls execute under B's own principal, against B's own grants. A cannot trick B into doing something B was not independently authorized to do. The two grant graphs do not merge.

The capability surface of “A delegates to B” is the intersection of:

  • What A is allowed to invoke (B must be reachable to A).
  • What B is allowed to do (B's own grants).

Both halves are computable from IAM. There is no third graph. No delegation tokens. No “effective principal” trick. Multi-agent systems do not require a new protocol — they require principals and conversations.

A boutique litigation practice runs four agents:

  • Intake — talks to prospective clients via a public form and an inbound email channel; classifies the matter type; opens a row in the matter intake worksheet; never writes to billable files.
  • Researcher — given a matter ID, runs case-law searches, cites authorities, writes draft research memos to a draft folder in buckets; cannot send anything to clients.
  • Drafter — given a research memo and a matter ID, drafts pleadings and correspondence to a draft folder; cannot send.
  • Filer — given a final document and a matter ID, files with the court (via an integrated channel) and updates the workflow item; cannot draft, cannot research.

Each agent has its own principal. Each has its own grants. None of them has all four capabilities. A paralegal can invoke any of them. Only a partner can invoke the Filer.

On a typical matter, an automation chains them: Intake opens a workflow item; the workflow auto-invokes Researcher when the item enters the “research” phase; the partner reviews; on approval, the workflow auto-invokes Drafter; after partner sign-off, Filer runs. Four agents, one matter, no agent ever did anything outside its own grants.

What this buys you

When the regulator audits the firm, the firm produces one event log. Every agent action is in it, with its principal, its grants at the time of action, and the evidence that produced it. There is no “the AI did it” — there is this principal performed this action under this grant at this timestamp.