ServicesApplications

Sign users in

Send your users to Spiral to sign in and approve scopes, then exchange the code for tokens.

In development

Let the users of your application sign in with their Spiral account. Your application sends the user to Spiral, the user approves the scopes it asks for, and your application receives a token that acts for that user.

The flow is the standard OAuth 2.0 authorization code grant with PKCE, so the easiest path is an OAuth client library that supports PKCE. Give it these values:

SettingValue
Authorization URLhttps://auth.spiraldb.com/oauth/authorize
Token URLhttps://auth.spiraldb.com/oauth/token
Client IDYour Application's ID, such as client_01ABC. There is no client secret.
ResourceThe API of the stack that owns your Application's Project, such as https://api.spiraldb.dev or https://eu.api.spiraldb.dev.

The rest of this guide shows the requests the library sends, so you can build them yourself or debug them.

Prerequisites

  • A registered Application and its client ID.
  • The user can sign in to the Application: its audience, Spiral's review, and the app access of the user's Organization allow it. See Who can sign in.

By default, sign-in can succeed before installation. Project and resource access also requires the Organization's active installation. Enable Install during sign-in to combine the steps, or use installation setup separately.

Send the user to sign in

  1. Create a PKCE code verifier: a random string of 43 to 128 characters. Compute the code challenge as the base64url-encoded SHA-256 hash of the verifier (RFC 7636). The server accepts only the S256 method.

  2. Create a random state value, and store it with the verifier in the session of the user.

  3. Redirect the user to the authorization endpoint:

    https://auth.spiraldb.com/oauth/authorize
      ?response_type=code
      &client_id=client_01ABC
      &redirect_uri=https%3A%2F%2Flabeler.example.com%2Foauth%2Fcallback
      &scope=projects%3Aread%20tables%3Aread
      &resource=https%3A%2F%2Fapi.spiraldb.dev
      &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
      &code_challenge_method=S256
      &state=af0ifjsldkj
    ParameterValue
    redirect_uriOne of the exact redirect URIs of the Application.

| scope | Space-separated scopes. Register each resource scope, such as tables:read, on the Application. Add openid to the sign-in request for identity, with profile or email for those claims. Identity scopes are requested during sign-in, not included in the Application registration. | | resource | The API of the stack that owns the Application's Project, from the table above (RFC 8707). To read Tables through ScanDAL, add a second resource=https://scandal.spiraldb.dev; the user's consent covers the API only, and the access token names both. | | organization_id | Optional. Preselects one of the user's Organizations. | | prompt | Optional. consent shows the consent page even when the user already approved these scopes. |

The user signs in, selects an Organization, and sees a consent page. The page shows the name of the Application, "Built by" with the name and ID of your Organization, and each requested scope.

Install during sign-in

Enable Install during sign-in in the Application's registration, or set installOnSignIn to true over HTTP. Your OAuth request stays the same. After login and Organization selection, the consent page shows two sections:

  • Installation in the Organization lists the registered resource scopes. An Organization owner selects Projects, or all current and future Projects.
  • Access to your account lists the scopes in the OAuth request. These permissions remain limited by the user's own access.

The owner selects Install and allow access. Spiral completes the installation before returning an authorization code to your OAuth callback. The browser stays in Spiral throughout login, installation, and consent. This flow does not use the Setup URL.

If an active installation already covers the requested scopes, members select Allow access without changing its permissions or Projects. If installation is needed and the user is not an owner, completion is disabled and the page asks them to contact an owner. A suspended installation or insufficient approved scopes requires an owner to update the installation in Studio.

Turning the option off restores separate sign-in and installation. It does not remove existing installations or change their permissions.

Users can select another Organization on the consent page or on the error page if the Application is unavailable in the selected Organization. Spiral switches the existing session and checks the Application's availability again. The consent page then shows the selected Organization's installation, Projects, and permissions. The user must review access again after switching. An Organization that requires additional authentication, such as SSO, may require a new sign-in.

Returning users

Spiral keeps one consent for each Application, user, and Organization. When a user signs in to your Application again and it asks for no scopes beyond the ones they approved, Spiral skips the consent page and redirects straight back with a code. This saves the user a step on every visit without letting the Application widen its access silently: a request for a new scope shows the page again.

Spiral skips the page only when the redirect_uri uses https. An Application that returns to the user's own computer, such as a command-line tool on a loopback address, always shows the consent page, because any program on that computer could receive the code. To show the page on purpose, for example after you change what your Application does with the data, send prompt=consent.

When Install during sign-in is enabled, skipping consent also requires an active installation that covers the requested resource scopes.

Exchange the code for tokens

The authorization server redirects the user to redirect_uri with code, state, and iss. Check that state matches the stored value. Then exchange the code at the token endpoint:

curl -X POST https://auth.spiraldb.com/oauth/token \
  -d grant_type=authorization_code \
  -d client_id=client_01ABC \
  -d code="$CODE" \
  -d code_verifier="$CODE_VERIFIER" \
  -d redirect_uri=https://labeler.example.com/oauth/callback \
  -d resource=https://api.spiraldb.dev

The response contains access_token, refresh_token, expires_in, the granted scope, and resource. Send the access token as a bearer token to the API at resource. A token request that names fewer of the authorized resources gets a token for only those.

Refresh the access token

curl -X POST https://auth.spiraldb.com/oauth/token \
  -d grant_type=refresh_token \
  -d client_id=client_01ABC \
  -d refresh_token="$REFRESH_TOKEN"

Each refresh checks again who can sign in, the user's consent, and the registered scopes. Refresh fails if the user revoked consent, if the Application is suspended or deleted, or if the user's Organization no longer allows it. To request fewer scopes, pass scope. The refresh token keeps its original scopes, so a later refresh can ask for the others again. To add a scope that the user has not consented to, start a new authorization request. Increasing the installation's approved scopes does not expand the user's consent or their existing tokens.

Read the user's identity

If the user approved openid with email or profile, read the claims:

curl https://auth.spiraldb.com/userinfo \
  -H "Authorization: Bearer $ACCESS_TOKEN"

An Application token cannot read the account profile from the Spiral API, so use /userinfo for the user's identity.

Sign the user out

Revoke the refresh token when the user signs out of your application (RFC 7009):

curl -X POST https://auth.spiraldb.com/oauth/revoke \
  -d client_id=client_01ABC \
  -d token="$REFRESH_TOKEN" \
  -d token_type_hint=refresh_token

Troubleshooting

ProblemCauseFix
The user sees "Contact us to use this app."The user is in another Organization, and the Application is internal or Spiral has not reviewed it yet.Set the audience to public, and ask Spiral to review the Application.
The user sees "Your organization has blocked this app."An owner of the user's Organization blocked the Application, or blocks every Application that it did not allow.Ask that Organization's owner to allow the Application.
invalid_request at the authorization endpointA parameter is missing or wrong, for example code_challenge_method is not S256.Read error_description, then correct the request.
invalid_grant at the token endpointThe code expired or was used, or the verifier does not match.Start the sign-in again.
Refresh fails after it workedThe user revoked consent, the Application was suspended, or the user's Organization blocked it.Send the user through sign-in again.

Where next: let users manage their connected applications.

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

On this page