Raster

Authentication

Sign users in with a code they approve in Raster, or connect an organization API key, and choose where the credential is stored.

A client uses one credential: a user sign-in or an organization API key. The client checks it with Raster, then saves it in the credentials store you pass to createRasterClient.

Device sign-in

auth.signInWithDevice uses the OAuth device authorization grant:

import { createRasterClient, localStorageCredentialStore } from '@raster-app/sdk'

const raster = createRasterClient({
  host: { name: 'My App', openExternal: (url) => window.open(url, '_blank') },
  credentials: localStorageCredentialStore(),
})

const controller = new AbortController()
const credentials = await raster.auth.signInWithDevice({
  onCode: (device) => console.log(`Approve ${device.userCode} in your browser`),
  signal: controller.signal,
})
  1. onCode receives the code. Show device.userCode to the user.
  2. The client opens device.verificationUrl through host.openExternal. Pass openBrowser: false to open it yourself.
  3. On the Connect page, the user signs in, checks the code, and allows access.
  4. The call resolves with the stored credentials, including userName and organizations ({ id, name } each).

To cancel, abort the signal. The call rejects with ABORTED when cancelled, access_denied when the user denies access, and expired_token when the code expires (see Errors).

Users can revoke your app, listed by host.name, under Settings → Connected apps.

Sign in to one organization

By default, the user grants every organization they belong to, or picks one. To require exactly one, pass scope: 'org' and the organization's slug as organizationId:

await raster.auth.signInWithDevice({
  scope: 'org',
  organizationId: 'acme',
  onCode: (device) => console.log(`Approve ${device.userCode} in your browser`),
  signal: controller.signal,
})

The slug is the first path segment of the organization's URL, like acme in https://raster.app/acme. Tell the user which organization to choose. If they grant another one or the whole account, the call rejects with ORGANIZATION_MISMATCH and the previous credential stays.

API keys

An organization API key reaches one organization, with the library access set on the key. Create one under Organization settings → API keys (see API keys), then connect it:

await raster.auth.connect({ apiKey: 'your-api-key' })

auth.connect checks the key and resolves with the stored credentials: userName is null, and organizations lists the key's organization.

  • An empty key fails with API_KEY_REQUIRED.
  • A rejected key fails with the API's error, such as INVALID_API_KEY, and the previous credential stays.

Where the credential is stored

The credential holds tokens or the API key in plain text, so keep it in a store as private as you need. The SDK ships two:

StoreWhere the credential lives
memoryCredentialStore()In memory. The user signs in on every load.
localStorageCredentialStore(key?)In localStorage under key (default raster.credentials). Any script on your origin can read it. If localStorage is blocked, it lasts until reload.

Or pass your own CredentialStore:

interface CredentialStore {
  load(): Promise<StoredCredentials | null>
  save(credentials: StoredCredentials): Promise<void>
  clear(): Promise<void>
}

load resolves with the saved credentials, or null. save receives the whole StoredCredentials object; store it as one value. If save rejects, the call that triggered it rejects with that error.

Give each client its own store, for example a localStorageCredentialStore with a different key per organization.

Sign out

await raster.auth.signOut()

Signing out saves a signed-out credential and revokes the sign-in, which removes your app from Connected apps. It completes even when Raster can't be reached.

For an API key, signing out only removes it from the store. The key stays valid until you regenerate or delete it in Organization settings.

On this page