ServicesApplications

Install an Application

Approve the scopes and Projects an Application can access in your Organization, for user requests and background work.

In development

Install an Application to give it access to selected Projects, both through signed-in users and while nobody is signed in. For example, Frame Labeler can label new rows of the frames Table as they arrive. An installation is the Application's own identity in your Organization. It has only the scopes and Projects that an Organization owner approves, and it keeps working when the person who requested it leaves the Organization.

A user's sign-in is a poor fit for background work. The Application could act only while that user's session lasts, with that user's roles, and it would stop when the user leaves. An installation separates the two: the Organization decides what the Application can do, and the decision does not depend on any one person.

Prerequisites

  • For background work, the developer configured app authentication by private key or trusted issuer. See Act as an installation.
  • The Application belongs to your Organization, or its audience is public. See Who can sign in.
  • Any member of the Organization can request an installation. Only an Organization owner can approve, suspend, or uninstall it.
  • For HTTP calls, you use a token from your own sign-in to Spiral, for example from spiral login.

Install and review in Studio

Open the installation link from the Application's developer. Studio opens the Application's name, publisher, scopes, and Project selection directly. Check the Organization shown at the top of the dialog, then review access and submit the installation or request approval.

If the Application is already installed, the link opens its configuration dialog with its current access. Select Edit access to change its scopes or Projects.

If the developer configured a Setup URL, Studio returns you to the Application after a successful request or approval. A request still needs owner approval; returning to the Application does not give it the requested access. Developers can follow Return users after installation to build the installation link and check its result.

To start from Studio without an installation link:

  1. Select the Organization that will use the Application.
  2. Open your account menu and select Organization, then Installed applications. This shows installations for the selected Organization.
  3. Select Install application. Enter the client ID from the developer and select Find application. For an Application in your own Project, you can also select Install in the Project's Applications page.
  4. Review the Application's permissions. Select Only selected projects and choose the Projects, or select All projects to include future Projects.
  5. If you are an Organization owner, select Install application to approve this access. Otherwise, select Request installation to ask an owner.

An owner opens Requests, then Review request. The review shows current access and requested access, with additions and removals marked. Select Approve request or Decline request. If the request changed after you opened it, select Reload request and review the new values first.

Declining a new request removes it. Declining a change keeps the previously approved access. From Configure, an owner can also edit access, Suspend, Resume, or Uninstall an installation. Other members can request changes but cannot approve them. If your permissions change, Studio shows an access error and requires you to reload the list.

Request an installation

Name the Application, the scopes it needs, and the Projects it can reach. The scopes must be registered on the Application. This request lets Frame Labeler read and write Tables in demo only:

curl -X POST https://api.spiraldb.dev/api/apps/installations \
  -H "Authorization: Bearer $SPIRAL_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "applicationId": "client_01ABC",
    "scopes": ["tables:read", "tables:write"],
    "projects": { "all": false, "projectIds": ["demo"] }
  }'

The response is the Installation, with an ID such as inst_01JKL and the status requested. To select every Project in the Organization, including Projects created later, send { "all": true, "projectIds": [] }. Otherwise, list 1 to 100 Projects of your Organization.

An Organization has at most one installation of each Application. To ask for more scopes or Projects later, send the same request with the new values. Until an owner approves it, the installation keeps its earlier approval, so a request alone never widens its access.

Approve the request

An Organization owner reviews requested and sends the same grant to the review endpoint:

curl -X POST https://api.spiraldb.dev/api/apps/installations/inst_01JKL/review \
  -H "Authorization: Bearer $SPIRAL_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "requested": {
      "scopes": ["tables:read", "tables:write"],
      "projects": { "all": false, "projectIds": ["demo"] }
    },
    "approve": true
  }'

The status becomes active, and approved now matches requested. Spiral enforces only approved. An installation cannot reach a Project that it did not select, use a permission that its scopes do not cover, or change grants and roles.

The server returns Conflict if the current request differs from the grant you reviewed. Read the installation again before retrying. Send approve as false to decline that request.

Check the installations

List the installations in your Organization, or read one:

curl -X POST https://api.spiraldb.dev/api/apps/installations/list \
  -H "Authorization: Bearer $SPIRAL_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"pageSize": 50}'

curl https://api.spiraldb.dev/api/apps/installations/inst_01JKL \
  -H "Authorization: Bearer $SPIRAL_TOKEN"

Any member of the Organization can read them. The developers of an Application, that is, the viewers of its Project, can list the installations of their Application with POST /api/apps/client_01ABC/installations.

Suspend, resume, or uninstall

An owner suspends an approved installation with enabled set to false, and resumes it with true:

curl -X PUT https://api.spiraldb.dev/api/apps/installations/inst_01JKL/status \
  -H "Authorization: Bearer $SPIRAL_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"enabled": false}'

Uninstalling removes the installation and all of its access:

curl -X DELETE https://api.spiraldb.dev/api/apps/installations/inst_01JKL \
  -H "Authorization: Bearer $SPIRAL_TOKEN"

Both take effect at the installation's next request, even if it holds an access token that has not expired. Deleting the Application also uninstalls it from every Organization.

Act as an installation

Authenticate as the Application with its registered private key or trusted issuer. The SDK exchanges that app token for an installation token and renews credentials. An authenticated installation handle provides access to its approved Projects.

See Rust client authentication for client construction. At the HTTP level this uses the existing JWT-bearer grant:

curl -X POST https://auth.spiraldb.com/oauth/token \
  -d grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
  -d client_id=inst_01JKL \
  -d assertion="$APP_ACCESS_TOKEN"

The installation trusts only its owning Application's token, issued by Spiral for this API audience. User tokens and tokens from other Applications cannot perform this exchange. The resulting token names the installation and carries no project grants; every request checks its current approval. An optional backgroundIdentity can also authorize direct platform-identity exchanges for existing deployments.

For interactive access, keep the user token. installations().for_user() discovers the current Organization's installation, and its Project handles keep the user credential. The server checks user permissions, consented scopes and the current installation approval on every project/resource request. No installation means no project authority for that registered Application, even after successful sign-in.

Troubleshooting

ErrorCauseFix
NotFound on a requestThe Application is not active, or it belongs to another Organization and its audience is not public.Check the client ID with the developer of the Application.
InvalidArgument on a requestA scope is not registered on the Application, or a Project is not in your Organization.Read reason, then correct the request.
Conflict on approval, suspension, or resumptionNo request was approved yet, or the Application is suspended or deleted.Approve the request first, or ask the developer about the Application.
RegistrationUnavailableThe authorization server did not accept the change. The installation is unchanged.Send the same request again.

Availability

Installations are in development, and they work only on deployments where Spiral has turned on Application management.

Discover installations and Projects

Use an app token to find your Application's installations after a restart. Register public jwks for private-key authentication, jwtBearerIssuers for federated authentication, or both. The existing token endpoint issues an app token with client_credentials and private_key_jwt, or with the JWT-bearer grant and an identity token from a registered issuer. Each issuer policy specifies the exact claims that identify your backend. For GCP, bind the Google issuer to the service account's numeric sub.

An app token can read its own registration and installations. Customer data access belongs to installation tokens and depends on approved scopes and Projects. Both app authentication methods can exchange for installation tokens. backgroundIdentity optionally permits a direct platform-identity exchange.

CredentialOperationResult
AppGET /api/apps/selfIts registration and status
AppPOST /api/apps/self/installations/listIts installations, including requested and suspended installations
AppGET /api/apps/self/installations/{installation_id}One of its installations, its API URL, current grant and configurationUrl
Delegated userGET /api/apps/user/installationSetup state for this app in the user's current Organization, absent when setup has not started, and the configurationUrl that starts or changes setup
InstallationGET /api/apps/installationIts identity, API URL, current grant and configurationUrl
InstallationPOST /api/apps/installation/projects/listLive Projects within its approved access
Delegated userPOST /api/apps/user/installations/{installation_id}/projects/listProjects accessible to both the user and that installation

Project lists require projects:read. List requests accept pageSize from 1 to 100 and an optional pageToken; continue with nextPageToken until it is absent. A user token must identify the same app and Organization as the installation. For example, if the installation has access to A/B and the user has access to B/C, the user's installation project list contains only B. Approval changes, suspension, uninstall and membership changes affect the next request, including requests made with an existing token. Project reads and writes still check their own permissions.

The Rust SDK exposes app discovery through client.applications() and installation discovery through client.installations(). Use private_key or trusted_issuer on the client builder, then authenticate through the discovered installation handle. Use a separate client for each app, user or installation identity. The SDK resolves the current credential before every discovery request.

configurationUrl is Studio's installation link for the Application and Organization, without state. It opens the installation dialog when no installation exists and the installation's configuration otherwise. Add your own state before sending a user there. It is absent on deployments that do not name a Studio; handle the missing value explicitly.

The user's installation summary also reports approvedAllProjects: true when the approved grant covers every Project in the Organization, including Projects created later, and false when it covers listed Projects. It is absent until an owner approves a grant.

Found a problem? Edit this page or report an issue.

On this page