Skip to content
OpenAppPhysical access, fully managed
Login

Roles

Roles are permission grants assigned to a user in an organization. A role granted on an org also applies in every org below it.

For each operation, OpenApp asks whether the caller holds the required role string in the resource’s organization or in any of its ancestors:

  • admin on that org or an ancestor satisfies every role in the list below.
  • platform_admin on that org or an ancestor also satisfies every role below. A few system operations need platform_admin on the root org specifically (see System roles).
  • Otherwise the caller needs the exact role string.

Roles are stored on the org where you assign them. A user with admin on a parent org only has that access in every sub-org without copying the role onto each child.

A scoped API key, voice key, or agent credential can only exercise roles named in its scope. The owner’s admin or platform_admin does not widen it: a key scoped to entities:set_state can use only that role, even when its owner is an admin.

This is the complete list of permission role strings OpenApp checks.

RoleGrants
api_keys:createCreate API keys and voice keys for the organization. Listing, renaming, revoking, restoring, and deleting keys is limited to the keys you own.
RoleGrants
audit:readRead the organization audit log and request historical exports.
audit:webhooks:manageManage outbound audit webhook endpoints.
RoleGrants
billing:readRead plan, quota usage, and invoices.
billing:manageChange plan and payment settings. On the entity-action API, a caller holding it is treated as an organization admin for policy exemptions (for example lockdown and maintenance window).
RoleGrants
devices:createCreate devices.
devices:readRead one device.
devices:updateUpdate a device, and read credential-bearing provisioning data (for example Tasmota provisioning).
devices:deleteDelete, purge, or restore a device.
devices:listList devices.
RoleGrants
entities:createCreate entities.
entities:readRead one entity.
entities:updateUpdate an entity, and manage directory-listing members and site people.
entities:set_stateRun switchable.* actions (open, close, toggle) except the relay latch.
entities:set_holdSet or clear an entity hold, and run switchable.set_relay_mode. Not implied by entities:set_state.
entities:deleteDelete, purge, or restore an entity.
entities:listList entities.
RoleGrants
groups:createCreate a non-household group.
groups:readRead a group, its members, links, and admissions.
groups:updateUpdate a group, its members, and admissions.
groups:deleteDelete a group.
groups:listList groups linked into the organization.
groups:shareOffer a group to another organization.
groups:linkAccept an offered group into this organization.
RoleGrants
integrations:createCreate integrations.
integrations:readRead an integration, its invitations, and its secrets.
integrations:updateUpdate an integration, manage portals and invitations, and read provisioning status (for example Waveshare).
integrations:deleteDelete, purge, or restore an integration.
integrations:listList integrations.
integrations:users:listList users in the upstream vendor directory (for example PalGate gate users).
integrations:users:writeAdd or remove users in the upstream vendor directory.
RoleGrants
orgs:createReported by GET /orgs/{id}/permissions. Creating a sub-org is decided by admin on the parent, not by this role — see the note below.
orgs:readRead an organization. Any role in an org also lets you read that org.
orgs:updateUpdate an organization. Moving it to another parent also needs admin on the destination.
orgs:deleteDelete an organization.
orgs:listList organizations below the one where you hold it.
RoleGrants
policies:createCreate org, integration, and device policies.
policies:readReported by GET /orgs/{id}/permissions. Reading policies uses policies:list.
policies:updateUpdate policies, set the org timezone, and vote on pending policy approvals.
policies:deleteDelete policies.
policies:listList policies, effective policies, the org timezone, and pending approvals.
RoleGrants
executeSubmit OpenApp Scripting executions (POST /api/v1/scripting/executions, openapp scripting, SDK client.scripting). It grants nothing inside the script: every operation a script performs needs its own role.
RoleGrants
users:createCreate users in the organization.
users:readRead a user who belongs to the organization.
users:updateUpdate such a user.
users:deleteDelete such a user.
users:listList users in the organization.
RoleGrants
zones:createCreate zones.
zones:readRead a zone.
zones:updateUpdate a zone.
zones:deleteDelete a zone.
zones:listList zones.

These are not implied by any users:* role. The two system:* roles take effect only on the root org: an admin of any other org does not hold them, and GET /orgs/{id}/permissions reports them only for the root org.

RoleGrants
system:list_kratos_identitiesList sign-in identities across the deployment.
system:delete_kratos_identitiesDelete a sign-in identity that is still pending registration.
platform_adminEverything admin grants. On the root org it also allows creating an org with an explicit id, creating users without assigning roles, managing any user, merging accounts, and other deployment-wide operations.

Site (Virtual Access) roles are granted per integration and have the form:

virtual_access:integration:{integration_id}:{role}
{role}Who holds it
adminA site administrator, or a listing admin.
residentA person who lives or works at the site.
memberA listing member added through directory listings.
technicianMaintenance staff. Matches technician in who may invite and maintenance window policies.

OpenApp writes these roles when you add someone to a site (POST /integrations/{id}/people, or a site grant on an org invitation, which accepts admin, resident, or technician) or to a listing (which accepts admin or member). Assign them through those routes, not by hand. A site role alone grants no permission role above; what it lets someone open comes from listing membership and site access rules.