Skip to main content
MeshAgent IAM controls access to project resources. It answers four questions:
  • Who is requesting access: a user, group, agent, service account, or userset.
  • What they are accessing: a project, room, repository, feed, secret, service account, or other project resource.
  • Which role they have on that resource.
  • Which room API scope a participant token carries after access is granted.
Use the smallest role or scope that lets the subject do its job.

Principals

Anonymous website access

Grant a resource role to everyone:all through its permissions dialog or the CLI:
The same principal works with room roles. Public grants also apply to signed-in callers. They do not create project membership. Managed agents must use thread_isolation: participant for anonymous connections; global thread sharing cannot provide private visitor conversations. On a website bound to a room or agent, send a POST to /.well-known/meshagent/authorize. Requests are same-origin by default. To allow cross-origin callers, include their exact origins (or * for all origins) in the route’s existing paths[].targetContent.cors[].allowedOrigins lists. The endpoint uses the combined origin lists across content paths; no separate authorization origin setting is needed. Content allowedMethods do not restrict the authorization POST. The response includes a short-lived jwt, expires_in, and connect_path for the room or agent WebSocket. The server sets an HttpOnly browser cookie to retain the anonymous identity across visits. Keep the cookie when renewing credentials. Clearing it creates a new identity. The TypeScript and Dart SDKs handle this exchange through RoomClient.withAnonymous() and WebSocketChatClient.withAnonymous(). Call start() as usual. They obtain fresh credentials before the initial connection and every reconnect, using the same anonymous cookie. An open WebSocket is not interrupted when its connection token expires. Outside a browser, pass an absolute authorizationUrl; native clients retain the cookie for the provider’s lifetime. For custom authentication, the existing WebSocket clients accept a tokenProvider callback in TypeScript or an AccessTokenProvider in Dart. Authorization and connection paths must reach the router without CDN caching. The server checks the current Everyone permissions when issuing and validating credentials. Browser sessions can be revoked, and credentials stop working if the site is rebound to another resource. The visitor ID is not itself a credential.

Resources

Project Roles

Project roles apply at the project level. The user who creates a project becomes its owner and automatically inherits admin access. Admins inherit user_profile_editor along with the other administrative project permissions. developer inherits a focused operational subset and does not include user_profile_editor. Direct, narrower roles can also be granted independently. Project role guards enforce the requested effective role for both users and service accounts. A valid service-account credential alone does not authorize project operations: the caller needs the applicable creator, inventory, manager, member, billing, or other role, directly or through inheritance. OAuth credentials must also satisfy the endpoint’s scope requirement; native API keys do not carry OAuth scopes. Roles are checked on each request, including when the API-key identity is cached, so revoking a role removes the corresponding access. This includes API-key listing and revocation (api_key_inventory and api_key_manager), service-account creation and management, custom-domain creation, and project feed inventory. Service-account feed listings require feed_inventory even when view is omitted or set to my. Default service-account grants are unchanged, but operations outside those grants now require explicit delegation. Project IAM policy operations require the caller’s effective project admin role. Managing project groups and their membership requires group_manager, which admins inherit. These checks apply to service-account API keys as well as users; service-account OAuth tokens also require the admin scope. Default service accounts have neither administrative role and cannot assign themselves project roles or add themselves to privileged groups. An authorized administrator must delegate these permissions. Treat group_manager as privileged access: it permits changing membership in groups that may carry project admin or API-key roles. Policy operations on a service_account resource require the caller’s effective project service_account_manager role and, for OAuth credentials, the developer scope. This prevents default service accounts from assigning themselves run_service_as on another account. A delegated policy manager can grant run-as access to any service account in the project, including an administrator, so this role also carries sensitive delegation authority. Project membership APIs accept a roles list. The server normalizes project membership to include member and expands inherited admin and developer roles. Older member records and Studio convenience settings map to roles like this:

User profile permissions

Users can edit their own global names and metadata with profile:write. Project roles cannot edit global account defaults. Global annotations and editing other accounts require sysadmin endpoints, the OAuth sysadmin scope, and registered sysadmin membership. Editing any project-local user profile, including your own, requires user_profile_editor, a token covering the project with projects:iam.write, and target membership. The legacy admin scope is accepted in place of projects:iam.write. Owners and admins inherit the editor permission; developers and ordinary members need an explicit grant. Project profile reads and listings accept --view project|user|merged (default merged). All views require project access; project returns stored overrides, user returns global defaults, and merged applies overrides to defaults. Metadata and annotations merge by key.
CLI profile reads and updates use the selected project, including MESHAGENT_PROJECT_ID or the active project. Use --global for personal account defaults. Without a project, ordinary profile commands address only your own global profile. Supplied maps replace the selected layer’s map; {} clears it. --inherit removes a project override and can be repeated. Annotations require string values. Global annotations can only be changed with sysadmin user update. Sysadmin CLI commands require a login token containing sysadmin. For a dedicated administrator login, use MESHAGENT_OAUTH_SCOPES='profile:read profile:write sysadmin' meshagent auth login. Registered sysadmin membership is still required; adding the scope does not grant that membership. See User profiles in the REST API for SDK examples, or Editing user profiles in Accounts for the app workflow.

Room, Agent, and Repository Roles

These roles apply to resource policies for rooms and repositories. They also describe the effective role set used for room and agent access decisions. For rooms, viewer, operator, developer, and admin map to room API scopes:

Group Roles

Feed Roles

Secret Roles

Service Account Roles

OAuth Scopes

OAuth scopes are token scopes, not OpenFGA resource roles. MeshAgent accepts the current scope names below for OAuth access tokens. Project and room wildcard scopes (project/*, room/*) still identify the project or room boundary for token checks. Current tokens also accept compatibility aliases used by older clients, such as profile, create_rooms, connect_room, managed_agents, llm_proxy, developer, and admin, when they map to the current scope names.

Effective Permissions

Effective permissions are the checks MeshAgent evaluates after combining direct resource roles with inherited project roles. You do not assign these directly; you grant the roles that satisfy them.

Room API Scope Permissions

Room API scopes are embedded in participant tokens. They are not project roles. They control what a connected participant can call inside a room. If a grant object is absent, that API surface is denied. When a grant object exists, None in an allowlist generally means unrestricted access within that grant, and a boolean set to false disables that operation.

livekit

queues

messaging

dataset

If dataset.tables is None, the participant may read, write, and alter every dataset table allowed by the grant.

sqlite

If sqlite.databases is None, the participant may use all SQLite databases allowed by the grant. If a matching database grant has tables: None, table read, write, and alter access applies to all tables in that database.

memory

If memory.memories is None, the participant may use all memories allowed by the grant.

sync

If sync.paths is None, the participant may read and write all sync paths allowed by the grant.

storage

If storage.paths is None, the participant may read and write all storage paths allowed by the grant.

containers

If containers.registry is absent, registry list, pull, run, and write checks allow any repository covered by the container grant.

developer

agents

llm

admin

secrets

tunnels

services

Built-in Room API Scope Presets

Managing IAM

Use MeshAgent Studio for day-to-day member management. Use the CLI or SDKs when provisioning access from automation.