Troupe Cloud
Organizations and projects
An organization is the tenant in Troupe Cloud: it owns members, API keys, signing credentials, limits and projects, and every device session, build and test run belongs to one of its projects. This page covers organizations, projects, the three roles, and inviting people.
Organizations
Create one from the organization switcher in the web app's header (New organization…), or from the welcome page a new account sees. It takes a name of up to 100 characters and, optionally, a slug: lowercase letters, digits and inner hyphens, up to 48 characters, derived from the name when you leave it out. Whoever creates the organization becomes its first owner.
A person can belong to several organizations and switches between them in the header. Each organization has these sections:
| Section | What is there | Who sees it |
|---|---|---|
| Projects | The projects, and each project's devices, builds and test runs | Every member |
| Members | Members, their roles, pending invitations | Every member; owners and admins change them |
| API keys | The organization's API keys | Owners and admins |
| Signing | Signing credentials | Owners and admins |
| Identity | Trusted issuers and sign-in connections: see CI without stored secrets | Owners and admins |
| Usage | Usage and limits | Owners and admins |
| Settings | The id, slug and status, renaming, placement, leaving | Every member; owners and admins rename |
Projects
Every device session, build, artifact and test run belongs to one project, and an API key or a sign-in can be restricted to one. Use a project per app, or per team that should not see another's work.
Owners and admins create a project on the Projects page with a name and an optional slug, and rename or archive it from the project's own page. An archived project leaves the project list; its builds, runs and usage stay. There is no procedure that restores one.
A project's id looks like prj_ followed by 26 characters. Calls that work inside a project name it: the
cloud procedures take it as projectId, and the device procedures take it from the caller, as
choosing the project explains.
If your own system already has an identifier for what a project stands for, store it as the project's
externalRef (printable ASCII without spaces, up to 256 characters, unique in the organization).
projects.ensure returns the project for a reference and
creates it the first time; concurrent first calls create exactly one.
projects.resolve only looks it up.
Roles
A member has one of three roles. Owners and admins hold the same scopes; a few changes are an owner's alone.
| A member may | member | admin | owner |
|---|---|---|---|
| See the organization, its members and its projects | yes | yes | yes |
| Start, watch, drive and release devices; install apps; read logs | yes | yes | yes |
| Start and cancel builds; read and download artifacts | yes | yes | yes |
| Create, rename and archive projects | no | yes | yes |
| Invite people; change or remove members and admins | no | yes | yes |
| Create, list and revoke API keys | no | yes | yes |
| Read usage and limits; set a project's limits | no | yes | yes |
| See signing credentials and sign builds with them; add and change them | no | yes | yes |
| Register trusted issuers and sign-in connections | no | yes | yes |
| Rename the organization | no | yes | yes |
| Make someone an owner, or change or remove an owner | no | no | yes |
| Change the organization's placement | no | no | yes |
| Let a signing credential sign for every project | no | no | yes |
In scopes: a member holds org:read, projects:read, builds:read, builds:write, artifacts:read,
artifacts:write, devices:read, devices:acquire, devices:drive, apps:install, logs:read, runs:read
and runs:report. An admin and an owner also hold org:manage, projects:write, keys:read, keys:write,
usage:read and signing:use. The runtime scopes and the
cloud scopes list what each one opens.
A role is checked on every call. An API key or an approved app never holds more than the scopes it was given, and an approved app never more than its person's role allows now.
Members and invitations
Owners and admins invite people on the Members page: an email address and a role. An admin can invite members and admins, not owners. Troupe mails the invitation.
- The invitation is accepted by an account whose verified email is that address, on the Invitations page the mail links to. An account with another address does not see it.
- One invitation can be pending per address in an organization.
- It expires after 7 days. An owner or admin can revoke it before then.
On the same page an owner or admin changes a member's role or removes a member. A removed member loses access from their next request. API keys they created keep working, because a key belongs to the organization.
Anyone can leave an organization under Settings, except its last owner: make someone else an owner first.
Inviting, changing a role and removing a member need a password confirmation.
Placement
Placement decides which of the organization's work may run on the same device host, one after another. It is under Settings.
| Placement | Meaning |
|---|---|
org, the default | The organization's projects use the same hosts in turn |
project | Every project gets hosts of its own, so one project's apps never run where another project's did |
Only an owner changes it, with a password confirmation, and every owner is mailed. The change applies to new
devices. Moving to project needs a placement_units limit on the organization (see
limits) and no signing credential that signs for every project. Moving back to org is
refused while a trusted issuer gives each of its sub-tenants a project of its
own.
With the API
Each action in the web app is one procedure of the cloud contract.
| Action | Procedure |
|---|---|
| Create, list, read, rename an organization | orgs.create, orgs.list, orgs.get, orgs.update |
| Change placement | orgs.setPlacementScope |
| Create, list, read, rename, archive a project | projects.create, projects.list, projects.get, projects.update, projects.archive |
| List, change, remove members; leave | members.list, members.updateRole, members.remove, members.leave |
| Invite, list, revoke | invitations.create, invitations.list, invitations.revoke |
| See and accept your own invitations | invitations.received, invitations.accept |
Creating an organization, leaving one and accepting an invitation are a person's own acts: they take a signed-in person, not an API key.
curl "https://api.troupe.ali.ve/v1/projects/list?orgId=org_…" \
--header "Authorization: Bearer $TROUPE_API_KEY" \
--header "Troupe-Contract: 1.0"