We recommend splitting up your client-side implementation into four phases:

1. Generate Development Token

The recommended approach is to initially use a short-lived development token and then wire up production auth at a later stage.

  1. Generate a temporary private/public key-pair (RS256) or shared key (HS256) for JWT signing and verification.

  2. Add the key to your PowerSync Service configuration file, e.g.:

# config.yaml

client_auth:
  # static collection of public keys for JWT verification
  jwks:
    keys:
      - kty: oct
        alg: 'HS256'
        kid: 'powersync-dev'
        k: '[secret]'
  1. Generate a signed JWT. We have two options to get you started:

    1. If you have a .yaml configuration file and HS256 key, we recommending using the generate-token script from the Test Client in the powersync-service repo, as described here Self-hosted Setup / Local Development. You need to clone this repo to use this option.

    2. Alternatively:

      1. Save the private key into a .env file.

      2. Generate a JWT, loading the .env file and inputting a user UUID. See example script:

import * as jose from 'jose';

// get this from .env
const powerSyncPrivateKey = {
  alg: 'RS256',
  k: '[secret]'
  ...
};

const powerSyncKey = (await jose.importJWK(powerSyncPrivateKey)) as jose.KeyLike;

const token = await new jose.SignJWT({})
  .setProtectedHeader({
    alg: powerSyncPrivateKey.alg!,
    kid: powerSyncPrivateKey.kid
  })
  .setSubject('b29a2678-91c3-406a-9109-2cb99bcc6a01') // set user id, maybe as cli arg
  .setIssuedAt()
  // .setIssuer()
  .setAudience('powersync-dev')
  .setExpirationTime('12h')
  .sign(powerSyncKey);

console.log(token);

2. Run the Diagnostics app using a development token

With the Diagnostics web app you can quickly inspect a user’s local database. By using this you can confirm that the PowerSync Service configuration and sync rules behave as expected without needing to set up authentication or app UI.

The app is currently available at https://diagnostics-app.powersync.com

It can also be run as a local standalone web app - see the README for instructions on running it locally.

Sign into app

Enter the generated token into the app’s sign in screen.

Enter your PowerSync Service endpoint (see the port number specified in your config file e.g. http://localhost:8080).

Checkpoint:

Inspect your global bucket and synced table (from the PowerSync Service Setup section) in the diagnostics app — these should match the sync rules you defined previously.

3. Use the Client SDK with a development token

Install the PowerSync client SDK in your app. Refer to the client-side installation instructions here: Client-Side Setup

Hardcode the development token you generated above in the fetchCredentials method, which you’ll implement as part of Integrate with your Backend

4. Implement authentication

Read about how authentication works in PowerSync here: Authentication Setup

If you are using Supabase or Firebase authentication, PowerSync can verify JWTs for users directly:

Supabase Auth

Under client_auth in your config file, enable Supabase authentication:

# config.yaml

client_auth:
  # Enable this if using Supabase Auth
  supabase: true
  supabase_jwt_secret: your-secret

For more details, see Supabase Auth.

Firebase Auth

Under client_auth in your config file, add your Firebase JWKS URI and audience.

# config.yaml

client_auth:
  # JWKS URIs can be specified here.
  jwks_uri:
'https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com'

  audience: ['<your Firebase project ID>']

For more details, see Firebase Auth.

Custom auth

Refer to: Custom

PowerSync supports both RS256 and HS256. Insert your auth details into your configuration file:

# config.yaml

client_auth:
  # JWKS URIs can be specified here.
  jwks_uri: http://demo-backend:6060/api/auth/keys

  # Optional static collection of public keys for JWT verification
  # jwks:
  #   keys:
  #     - kty: 'RSA'
  #       n: '${PS_JWK_N}'
  #       e: '${PS_JWK_E}'
  #       alg: 'RS256'
  #       kid: '${PS_JWK_KID}'

  audience: ['powersync-dev', 'powersync']