Skip to content

Discord OIDC Provider for Cloudflare Access. Check the without-email branch to run this without email scope.

License

Notifications You must be signed in to change notification settings

Aiko-IT-Systems/cloudflare-discord-oidc-worker

Repository files navigation

Discord OIDC Provider for Cloudflare Access

Simply put: Allows you to authorize with Cloudflare Access using your Discord account via a Cloudflare Worker. Wraps OIDC around the Discord OAuth2 API to achieve this, storing signing keys in KV.

Process flow was inspired by kimcore/discord-oidc but rewritten entirely for Cloudflare Workers and Hono.

Some ideas were also taken from eidam/cf-access-workers-oidc.

Important Notice

Original code from Erisa modified to work with role checks.

Repo is distributed seperate because the pr wasn't accepted. Some users depend on that and we use it heavily internally.

Please consider sponsoring Erisa as well.

Setup

Requirements:

  • A Cloudflare Access account - make sure you've gone through the onboarding flow and have a NAME.cloudflareaccess.com subddomain.
  • A Discord developer application to use for OAuth2.
    • Add a redirect URI https://YOURNAME.cloudflareaccess.com/cdn-cgi/access/callback to the Discord application.
  • NodeJS

Steps:

  • Clone the repository.
  • Install dependencies: npm install
  • Install npx if you don't have it: npm install -g npx
  • Create a KV namespace on Cloudflare here.
  • Edit wrangler.toml to use your new KV namespace ID.
  • Copy config.sample.json to config.json.
  • Add your Discord application ID and OAuth2 secret to config.json.
  • Edit your Cloudflare Access subdomain into config.json under redirectUrls. This should be the same URL you added to Discord.
  • Publish the Worker with npx wrangler deploy!

Usage

  • Go to the Cloudflare Zero Trust dashboard
  • Navigate to Settings > Authentication, select "Add new" under Login methods, select OpenID Connect.
  • Fill the following fields:
    • Name: Whatever you want, e.g. Discord
    • App ID: Your Discord application ID.
    • Client secret: Your Discord application OAuth2 secret.
    • Auth URL: https://discord-oidc.YOURNAME.workers.dev/authorize/email or swap out /email for /guilds to include the Guilds scope.
    • Token URL: https://discord-oidc.YOURNAME.workers.dev/token
    • Certificate URL: https://discord-oidc.YOURNAME.workers.dev/jwks.json
    • Proof Key for Code Exchange (PKCE): Enabled
    • OIDC Claims:
  • See the Examples section below for help with constructing policies.

Usage with roles (Bot required)

⚠️ This method can run into ratelimits pretty quickly if used by many users at the same time. It is recommended to use the cached roles method.

  • Follow the above setup, making sure to use the /guilds auth URL.
  • Create a Discord Bot for the OAuth2 application, generate an OAuth2 URL with the bot scope and use it to invite the bot to your server.
    • The bot does not need any permissions, it just needs to exist in the server.
  • Generate a bot token and paste it into npx wrangler secret put DISCORD_TOKEN.
  • Populate config.json with a list of server IDs that you wish to check user roles for. Make sure the bot is a member of all servers in this list.
  • Edit the OIDC provider in Cloudflare Access and add the server IDs as claims prefixed with roles:, e.g. roles:438781053675634713
  • When creating a policy, reference the roles: claims as the name, and use the role ID as the claim value. This will match users in that server who have that role.

Example config for a roles setup:

{
    "clientId": "1056005449054429204",
    "clientSecret": "aaaaaaaaaaaaa",
    "redirectUrls": [
        "https://erisa.cloudflareaccess.com/cdn-cgi/access/callback"
    ],
    "serversToCheckRolesFor": [
        "438781053675634713"
    ],
    "cacheRoles": false
}

Usage with roles (Without bot)

⚠️ This method relies on bearer tokens and runs into rate limits very quickly. It is not recommended to use this method unless you have a very small number of servers to check roles for.

  • Follow the above setup, making sure to use the /roles auth URL.
  • Populate config.json with a list of server IDs that you wish to check user roles for.
  • Edit the OIDC provider in Cloudflare Access and add the server IDs as claims prefixed with roles:, e.g. roles:438781053675634713
  • When creating a policy, reference the roles: claims as the name, and use the role ID as the claim value. This will match users in that server who have that role.

Example config for a roles setup:

{
    "clientId": "1056005449054429204",
    "clientSecret": "aaaaaaaaaaaaa",
    "redirectUrls": [
        "https://erisa.cloudflareaccess.com/cdn-cgi/access/callback"
    ],
    "serversToCheckRolesFor": [
        "438781053675634713"
    ],
    "cacheRoles": false
}

Usage with cached roles (Bot required, safer method)

  • Follow the above setup, making sure to use the /guilds auth URL.
  • Create a Discord Bot for the OAuth2 application, generate an OAuth2 URL with the bot scope and use it to invite the bot to your server.
    • The bot does not need any permissions, it just needs to exist in the server.
  • Generate a bot token and paste it into npx wrangler secret put DISCORD_TOKEN.
  • Populate config.json with a list of server IDs that you wish to check user roles for. Make sure the bot is a member of all servers in this list.
  • Edit the OIDC provider in Cloudflare Access and add the server IDs as claims prefixed with roles:, e.g. roles:438781053675634713
  • When creating a policy, reference the roles: claims as the name, and use the role ID as the claim value. This will match users in that server who have that role.
  • Set cacheRoles to true in config.json. This will cache the roles every hour, and will not check the API for roles until the cache expires.

Example config for a roles setup:

{
    "clientId": "1056005449054429204",
    "clientSecret": "aaaaaaaaaaaaa",
    "redirectUrls": [
        "https://erisa.cloudflareaccess.com/cdn-cgi/access/callback"
    ],
    "serversToCheckRolesFor": [
        "438781053675634713"
    ],
    "cacheRoles": true
}

Examples

My setup, as an example:

To use this in a policy, simply enable it as an Identity provider in your Access application and then create a rule using OIDC Claims and the relevant claim above. Make sure the claim has been added to your provider in the steps above.

With roles:

This example would allow me to access the application if I was myself on Discord or if I was a member of a specific server:

About

Discord OIDC Provider for Cloudflare Access. Check the without-email branch to run this without email scope.

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks