Identity Model
Every connection to an Aether gateway authenticates as exactly one principal type. The principal type determines the connection’s identity fields, uniqueness constraints, topic subscriptions, and message routing permissions.
Principal Types
Section titled “Principal Types”| Type | Identity Fields | Uniqueness | Purpose |
|---|---|---|---|
| Agent | workspace + implementation + specifier | Exactly one connection per identity | Long-running service |
| Task (Unique) | workspace + implementation + unique_specifier | Exactly one connection per identity | Named finite unit of work (e.g., “nightly-backup”) |
| Task (Non-Unique) | workspace + implementation (server assigns ID) | Multiple connections allowed | Workers competing on a shared broadcast topic |
| User | user_id + window_id | One connection per window | Human operator; multiple browser tabs allowed via distinct window IDs |
| Workflow Engine | (optional workspace scope) | One active connection | Sole subscriber to event::receiver{N} fan-in shard; processes broadcast events |
| Metrics Bridge | (none) | One active connection per shard | Subscribes to metric::receiver{N} fan-in shard; receive-only |
| Orchestrator | implementation + specifier | One per specifier | Receives task assignments to spin up compute on demand |
| Service | implementation + specifier | One per specifier | Cross-workspace HTTP proxy (sv::{impl}::{spec}) |
An eighth type, Bridge, is used for cross-workspace messaging integrations (e.g., Discord, Teams, email). Bridges have no workspace component and can send to any topic in any workspace. Bridge is experimental — prefer Service for new cross-workspace integrations.
Agents are long-running services. An agent identity is globally unique across all gateway instances: only one client can hold ag::{workspace}::{implementation}::{specifier} at any time.
Topic: ag::{workspace}::{implementation}::{specifier}
Subscriptions on connect:
- Exclusive (offset-tracked):
ag::{ws}::{impl}::{spec}— messages replayed from last offset on reconnect - Shared:
ga::{ws}— broadcast to all agents in workspace - Shared:
pg::{ws}— progress updates with recipient filtering
Can send to: Agents, Tasks, Users, Events (event::), Metrics (metric::), Progress (pg::)
Agents are the producers of progress updates. They submit a ProgressReport upstream (via the gRPC stream), and the gateway publishes it to the appropriate pg:: stream. Agents cannot subscribe to pg:: as receivers of arbitrary progress — they receive task-lifecycle notifications from the gateway via the pg::{ws} shared subscription, with server-side recipient filtering ensuring each agent only sees notifications for tasks it spawned.
Agents receive a ConfigSnapshot on connect. The snapshot contains:
| Field | Notes |
|---|---|
task_context | Populated from TaskAssignment when this agent was started via orchestration. Contains task_id, workspace, user, implementation, specifier, profile, all metadata entries, and launch_params (prefixed lp.). Empty when not orchestrated. |
workspace_exclusive_kv | Per-agent, per-workspace KV pre-loaded at connect time. |
global_exclusive_kv | Per-agent, tenant-wide KV pre-loaded at connect time. |
Task (Unique)
Section titled “Task (Unique)”Unique tasks are named finite units of work. Like agents, they have globally unique identities. The specifier acts as a human-readable name (e.g., nightly-backup, report-2024-01).
Topic: tu::{workspace}::{implementation}::{unique_specifier}
Subscriptions on connect:
- Exclusive (offset-tracked):
tu::{ws}::{impl}::{spec}
Can send to: Agents, Tasks, Users, Events, Metrics, Progress (pg::)
Cannot send to: Orchestrators
Task (Non-Unique)
Section titled “Task (Non-Unique)”Non-unique tasks are pool workers. Multiple instances can connect simultaneously with the same implementation. The gateway assigns each a unique server-generated ID. Workers compete for work dispatched on the broadcast topic.
Topics:
- Direct:
ta::{workspace}::{implementation}::{server_assigned_id} - Broadcast:
tb::{workspace}::{implementation}(shared with all workers of this implementation)
Subscriptions on connect:
- Exclusive (offset-tracked):
ta::{ws}::{impl}::{id}— direct messages - Shared:
tb::{ws}::{impl}— broadcast/load-balanced work
Can send to: Agents, Tasks, Users, Events, Metrics, Progress (pg::)
Cannot send to: Orchestrators
Users represent human operators. A user may have multiple simultaneous connections from different browser tabs or windows, each identified by a distinct window_id.
Topics:
- Window-specific:
us::{user_id}::{window_id} - Workspace-scoped:
uw::{user_id}::{workspace}
Subscriptions on connect:
- Exclusive:
us::{uid}::{wid}— window-specific messages - Shared:
gu::{ws}— broadcast to all users in workspace - Shared:
uw::{uid}::{ws}— user scoped to workspace - Shared:
pg::{ws}— progress updates
Users can switch workspaces with SwitchWorkspace, which updates their uw:: and gu:: subscriptions while preserving their us:: window subscription.
Can send to: Agents, Tasks, Users
Cannot send to: Events, Metrics, Progress
Workflow Engine
Section titled “Workflow Engine”The Workflow Engine subscribes to all event traffic across all workspaces. Only one Workflow Engine connection is active at a time.
Subscription: Exclusive (offset-tracked): event::receiver{N} — a sharded fan-in topic. All event:: publishes from all workspaces are routed into a shard determined by workspace hash. Currently the system runs with one shard (event::receiver0). A Workflow Engine with any workspace scope subscribes to event::receiver0 regardless of that scope. The workspace of each event is preserved in the IncomingMessage.workspace field so the engine can filter per-workspace without needing separate subscriptions.
Can send to: Everything (agents, tasks, users, events, metrics, progress)
The Workflow Engine skips workspace ACL checks — it operates at system level. In production it should be authenticated via mTLS with a dedicated certificate.
Metrics Bridge
Section titled “Metrics Bridge”The Metrics Bridge is a receive-only subscriber. It subscribes to all metric traffic across all workspaces and forwards it to external observability systems (Prometheus, Datadog, etc.).
Subscription: Exclusive (offset-tracked): metric::receiver{N} — same sharded fan-in topology as the Workflow Engine. Today this is metric::receiver0. All metric:: publishes from all workspaces fan in to this single shard; workspace attribution is preserved in IncomingMessage.workspace.
Can send to: Nothing (receive-only)
Like the Workflow Engine, the Metrics Bridge skips workspace ACL checks and should use mTLS in production.
Orchestrator
Section titled “Orchestrator”Orchestrators are responsible for spinning up compute on demand. When an agent or unique task is needed but offline, the gateway sends a TaskAssignment to a registered orchestrator that matches the required profile.
Orchestrators do not subscribe to a message topic. They receive task assignments directly through the gRPC stream.
Can send to: Agent and Task topics only (for status updates)
Cannot send to: Events, Metrics, Progress
Service
Section titled “Service”Services are cross-workspace HTTP proxy principals. They act as the gateway-side identity for the built-in HTTP proxy sidecar, enabling legacy HTTP clients to send requests through the Aether gRPC stream to a target service topic without speaking the bidirectional protocol directly.
Topic: sv::{implementation}::{specifier}
Subscription on connect: Exclusive (offset-tracked): sv::{impl}::{spec} — messages are not lost on brief disconnects
Can send to: Agent and task topics (for forwarding HTTP responses)
Services have no workspace scope. ACL checks are performed per-message against the target topic.
Bridge
Section titled “Bridge”Bridges are cross-workspace integration relays (e.g., Discord, Teams, email gateways). They have no workspace component in their identity, allowing them to send to any workspace. Bridge is an experimental principal type — prefer Service for new cross-workspace integrations.
Topic: br::{implementation}::{specifier}
Can send to: Everything in any workspace
Bridge ACL checks are performed per-message against the target workspace rather than at connection time.
Routing Permission Matrix
Section titled “Routing Permission Matrix”| Sender | Agents | Tasks | Users | Events | Metrics | Orchestrators | Progress |
|---|---|---|---|---|---|---|---|
| Agent | Yes | Yes | Yes | Yes | Yes | No | Yes (produce) |
| Task | Yes | Yes | Yes | Yes | Yes | No | Yes (produce) |
| User | Yes | Yes | Yes | No | No | No | No |
| Workflow Engine | Yes | Yes | Yes | Yes | Yes | No | Yes |
| Metrics Bridge | No | No | No | No | No | No | No |
| Orchestrator | Yes | Yes | No | No | No | No | No |
| Service | Yes | Yes | No | No | No | No | No |
| Bridge | Yes | Yes | Yes | Yes | Yes | No | No |
Progress column note: “Yes (produce)” means the principal can submit a ProgressReport upstream, which the gateway publishes to pg::{ws}. Agents and tasks cannot send arbitrary messages with pg:: as the target topic — the gateway enforces this distinction at the handleProgressReport handler boundary.
Cross-Workspace Enforcement
Section titled “Cross-Workspace Enforcement”Cross-workspace sends are default-deny: the routing layer does not unconditionally block them, but an explicit ACL authority grant on the target workspace is required for any workspace-scoped principal sending to a topic outside its home workspace.
The enforcement path is:
enforceTopicPermissions— checks principal-type-level rules (e.g., MetricsBridge is receive-only, Orchestrators are limited to agent/task topics). Does not hard-block cross-workspace sends.checkMessageSend— evaluates ACL against the target workspace when the target workspace differs from the sender’s home workspace. If the sender holds an explicit ACL grant on the target workspace, the send proceeds. If not, it is denied and the denial is recorded in the audit log.
Bridges and Services have no home workspace; ACL is always evaluated against the target workspace for their messages.
System Principals
Section titled “System Principals”Orchestrators, Workflow Engines, and Metrics Bridges are system principals. They skip workspace-level ACL checks because they operate across workspaces by design. In production deployments these should be authenticated via mTLS with dedicated certificates, not API keys.
See Also
Section titled “See Also”- Connection = Lock = Heartbeat — how identity exclusivity is enforced
- Message Routing — topic schema and permission enforcement