Install an Application
Approve the scopes and Projects an Application can access in your Organization, for user requests and background work.
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
ownercan 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:
- Select the Organization that will use the Application.
- Open your account menu and select Organization, then Installed applications. This shows installations for the selected Organization.
- 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.
- Review the Application's permissions. Select Only selected projects and choose the Projects, or select All projects to include future Projects.
- 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
| Error | Cause | Fix |
|---|---|---|
NotFound on a request | The 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 request | A 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 resumption | No request was approved yet, or the Application is suspended or deleted. | Approve the request first, or ask the developer about the Application. |
RegistrationUnavailable | The 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.
| Credential | Operation | Result |
|---|---|---|
| App | GET /api/apps/self | Its registration and status |
| App | POST /api/apps/self/installations/list | Its installations, including requested and suspended installations |
| App | GET /api/apps/self/installations/{installation_id} | One of its installations, its API URL, current grant and configurationUrl |
| Delegated user | GET /api/apps/user/installation | Setup state for this app in the user's current Organization, absent when setup has not started, and the configurationUrl that starts or changes setup |
| Installation | GET /api/apps/installation | Its identity, API URL, current grant and configurationUrl |
| Installation | POST /api/apps/installation/projects/list | Live Projects within its approved access |
| Delegated user | POST /api/apps/user/installations/{installation_id}/projects/list | Projects 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.