{"id":26125967,"url":"https://github.com/powersync-ja/powersync-jwks-example","last_synced_at":"2026-02-11T20:08:46.884Z","repository":{"id":191679722,"uuid":"685087417","full_name":"powersync-ja/powersync-jwks-example","owner":"powersync-ja","description":null,"archived":false,"fork":false,"pushed_at":"2024-12-16T15:56:59.000Z","size":16,"stargazers_count":1,"open_issues_count":0,"forks_count":2,"subscribers_count":8,"default_branch":"main","last_synced_at":"2025-04-12T02:39:26.652Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/powersync-ja.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-08-30T13:44:14.000Z","updated_at":"2024-12-16T15:57:04.000Z","dependencies_parsed_at":"2023-08-31T04:31:38.579Z","dependency_job_id":"a58a425c-ee6b-498c-b8ca-06b475b2a8bb","html_url":"https://github.com/powersync-ja/powersync-jwks-example","commit_stats":null,"previous_names":["journeyapps/powersync-jwks-example","powersync-ja/powersync-jwks-example"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/powersync-ja%2Fpowersync-jwks-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/powersync-ja%2Fpowersync-jwks-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/powersync-ja%2Fpowersync-jwks-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/powersync-ja%2Fpowersync-jwks-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/powersync-ja","download_url":"https://codeload.github.com/powersync-ja/powersync-jwks-example/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248741198,"owners_count":21154255,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-10T17:27:27.396Z","updated_at":"2026-02-11T20:08:41.863Z","avatar_url":"https://github.com/powersync-ja.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PowerSync Custom Authentication Example\n\nThis demonstrates creating custom JWTs for PowerSync authentication.\n\nThe examples here are for hosting on Supabase, but the same approach could be adapted\nfor any other environment.\n\n# Architecture\n\nA key-pair (public and private key) is generated. The public key is served on a public [JWKS](https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets) URI. The private key is then used to generate JWTs for authenticated Supabase users and/or anonymous users. The PowerSync instance then validates these JWTs against the public key from the JWKS URI.\n\n# Usage\n\n[Deno](https://deno.com/) and [Supabase CLI](https://github.com/supabase/cli) are required.\n\n## 0. Clone this repo\n```sh\ngit clone https://github.com/journeyapps/powersync-jwks-example.git\ncd powersync-jwks-example\n```\n\n## 1. Generate a key-pair\n\n```sh\ndeno run generate-keys.ts\n```\n\nRun the first two `supabase secrets set` commands in the output to configure the keys on Supabase.\n\n## 2. Deploy the functions\n\n```sh\nsupabase init\nsupabase functions deploy --no-verify-jwt powersync-jwks\n# Deploy one or both of these, depending on whether signed-in and/or anonymous users should be allowed.\nsupabase functions deploy powersync-auth\nsupabase functions deploy powersync-auth-anonymous\n```\n\n## 3. Configure PowerSync\n\nConfigure PowerSync to use the `powersync-jwks` auth function by setting the \"JWKS URI\" field to\n`https://\u003csupabase-project-ref\u003e.supabase.co/functions/v1/powersync-jwks`.\n\nThis config field can be found under \"Edit Instance\" -\u003e \"Credentials\" : \n\n\u003cimg src=\"https://github.com/journeyapps/powersync-jwks-example/assets/277659/a37421fe-6f97-4bc7-a73f-d166a07c6b1e\" width=\"500\"\u003e\n\n## 4. Configure POWERSYNC_URL\n\nOnce the PowerSync instance is configured, configure POWERSYNC_URL for the functions:\n\n```sh\nsupabase secrets set POWERSYNC_URL=https://\u003cpowersync-instance-id\u003e.powersync.journeyapps.com\n```\n\nThe PowerSync Instance URL can be found under \"Edit Instance\" -\u003e \"General\"\n\n## 5. Update the client application\n\nUpdate the client application to use the `powersync-auth` or `powersync-auth-anonymous` function to generate the JWT.\n\n* Example usage of `powersync-auth`: https://github.com/powersync-ja/powersync.dart/tree/master/demos/supabase-edge-function-auth\n* Example usage of `powersync-auth-anonymous`: https://github.com/powersync-ja/powersync.dart/tree/master/demos/supabase-anonymous-auth\n* Note that it's possible to use a mix of both methods. This would be done with a token parameter query. In the context of the above examples, this would be done using `token_parameters.user_id != 'anonymous'`. In the future we'll ideally change this to use a separate parameter for authenticated / anonymous queries.\n\n# Rotating keys\n\nRepeat step 1 to generate a new key and update the secrets on Supabase. PowerSync will automatically pick up the new key and verify the new tokens.\n\nThere may be some authentication failures while clients still use old JWTs. The clients should automatically retrieve new keys and retry. To completely prevent those errors, the `powersync-jwks` function could be adapted to serve both the old and the new public keys at the same time.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpowersync-ja%2Fpowersync-jwks-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpowersync-ja%2Fpowersync-jwks-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpowersync-ja%2Fpowersync-jwks-example/lists"}