{"id":28916011,"url":"https://github.com/celsiusnarhwal/snowflake","last_synced_at":"2026-02-01T02:16:47.713Z","repository":{"id":295543867,"uuid":"985006490","full_name":"celsiusnarhwal/snowflake","owner":"celsiusnarhwal","description":"Use Discord as an OpenID Connect provider","archived":false,"fork":false,"pushed_at":"2026-01-28T17:20:35.000Z","size":491,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-29T07:55:20.096Z","etag":null,"topics":["authentication","discord","oauth","oauth2","oidc","openid","openid-connect"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/celsiusnarhwal.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-05-16T22:28:34.000Z","updated_at":"2026-01-28T17:19:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"8f715575-5f8f-4947-94cc-a59c40a99707","html_url":"https://github.com/celsiusnarhwal/snowflake","commit_stats":null,"previous_names":["celsiusnarhwal/snowflake"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/celsiusnarhwal/snowflake","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/celsiusnarhwal%2Fsnowflake","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/celsiusnarhwal%2Fsnowflake/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/celsiusnarhwal%2Fsnowflake/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/celsiusnarhwal%2Fsnowflake/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/celsiusnarhwal","download_url":"https://codeload.github.com/celsiusnarhwal/snowflake/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/celsiusnarhwal%2Fsnowflake/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28965059,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T02:14:24.993Z","status":"ssl_error","status_checked_at":"2026-02-01T02:13:55.706Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["authentication","discord","oauth","oauth2","oidc","openid","openid-connect"],"created_at":"2025-06-21T23:07:28.947Z","updated_at":"2026-02-01T02:16:47.702Z","avatar_url":"https://github.com/celsiusnarhwal.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Snowflake\n\nSnowflake enables you to use [Discord](https://discord.com) as\nan [OpenID Connect](https://auth0.com/docs/authenticate/protocols/openid-connect-protocol) (OIDC) provider. With it, you\ncan use Discord to identify your application's users without needing to implement specific support for Discord's OAuth2\nAPI.\n\n\u003e [!important]\n\u003e Snowflake requires HTTPS for external connections. (By default, HTTP connections on `localhost` are fine; see\n\u003e [Configuration](#configuration).)\n\n## Installation\n\n[Docker](https://docs.docker.com/get-started) is the only supported way of running Snowflake. You will almost always \nwant to set the `SNOWFLAKE_ALLOWED_HOSTS` environment variable; see [Configuration](#configuration).\n\n\u003e [!note]\n\u003e Throughout this README, `snowflake.example.com` will be used as a placeholder for the domain at which your\n\u003e Snowflake instace is reachable.\n\n\u003chr\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eSupported tags\u003c/summary\u003e\n\u003cbr\u003e\n\n| **Name**             | **Description**                                                                               | **Example**                                                                            |\n|----------------------|-----------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|\n| `latest`             | The latest stable version of Snowflake.                                                       | `ghcr.io/celsiusnarhwal/snowflake:latest`                                              |\n| Major version number | The latest release of this major version of Snowflake. May be optionally prefixed with a `v`. | `ghcr.io/celsiusnarhwal/snowflake:1`\u003cbr/\u003e`ghcr.io/celsiusnarhwal/snowflake:v1`         |\n| Minor version number | The latest release of this minor version of Snowflake. May be optionally prefixed with a `v`. | `ghcr.io/celsiusnarhwal/snowflake:1.0`\u003cbr/\u003e`ghcr.io/celsiusnarhwal/snowflake:v1.0`     |\n| Exact version number | This version of Snowflake exactly. May be optionally prefixed with a `v`.                     | `ghcr.io/celsiusnarhwal/snowflake:1.0.0`\u003cbr/\u003e`ghcr.io/celsiusnarhwal/snowflake:v1.0.0` |\n| `edge`               | The latest commit to Snowflake's `main` branch. Unstable.                                     | `ghcr.io/celsiusnarhwal/snowflake:edge`                                                |\n\n\u003c/details\u003e\n\n\u003chr\u003e\n\n### Docker Compose\n\n```yaml\nservices:\n  snowflake:\n    image: ghcr.io/celsiusnarhwal/snowflake:latest\n    container_name: snowflake\n    restart: unless-stopped\n    ports:\n      - \"8000:8000\"\n    environment:\n      - SNOWFLAKE_ALLOWED_HOSTS=snowflake.example.com\n    volumes:\n      - /some/directory/on/your/machine:/app/snowflake/data\n```\n\n### Docker CLI\n\n```shell\ndocker run --name snowflake \\\n--restart unless-stopped \\\n-p \"8000:8000\" \\\n-e \"SNOWFLAKE_ALLOWED_HOSTS=snowflake.example.com\"\n-v \"/some/directory/on/your/machine:/app/snowflake/data\" \\\nghcr.io/celsiusnarhwal/snowflake:latest\n```\n\n## Usage\n\nFirst, [create an application in the Discord Developer Portal](https://discord.com/developers/applications?new_application=true). \nIn your application's OAuth2 settings, note your client ID and client secret, then set your redirect URIs.\n\nYour redirect URIs must be in the form `https://snowflake.example.com/r/{YOUR_REDIRECT_URI}`,\nwhere `{YOUR_REDIRECT_URI}` is the actual intended redirect URI for your application. For example, a redirect\nURI of `https://myapp.example.com/callback` would be set in the Developer Portal\nas `https://snowflake.example.com/r/https://myapp.example.com/callback`.\n\n\u003e [!tip]\n\u003e If you're unable to control the redirect URI your OIDC client provides to Snowflake, set\n\u003e the `SNOWFLAKE_FIX_REDIRECT_URIS` environment variable to `true`. See [Configuration](#configuration)\n\u003e for details.\n\nFrom there, Snowflake works just like any other OIDC provider. Your app redirects to Snowflake for authorization;\nupon succcessful authorization, Snowflake provides your app with an authorization code, which your app returns\nto Snowflake in exchange for an access token and an ID token. The access token can be sent to Snowflake's\n`/userinfo` endpoint to obtain the associated identity claims, or your application can decode the ID token\ndirectly to obtain the same claims.\n\nFrankly, if you're reading this then you should already know how this works.\n\n## OIDC Information\n\n### Endpoints\n\n| **Endpoint**                    | **Path**                            |\n|---------------------------------|-------------------------------------|\n| Authorization                   | `/authorize`                        |\n| Token                           | `/token`                            |\n| User Info                       | `/userinfo`                         |\n| JSON Web Key Set                | `/.well-known/jwks.json`            |\n| OIDC Discovery                  | `/.well-known/openid-configuration` |\n| [WebFinger](#webfinger-support) | `/.well-known/webfinger`            |\n\n### Supported Scopes\n\n| **Scope** | **Requests**                                                                                    | **Required?** |\n|-----------|-------------------------------------------------------------------------------------------------|---------------|\n| `openid`  | To authenticate using OpenID Connect.                                                           | Yes           |\n| `profile` | Basic information about the user's Discord account.                                             | No            |\n| `email`   | The email address associated with the user's Discord account and whether or not it is verified. | No            |\n| `groups`  | A list of IDs of guilds (a.k.a. \"servers\") the user is a member of.                             | No            |\n\n\u003e [!warning]\n\u003e Scopes are persistent. Once a scope is granted, your app maintains perpetual access to it — even if it later stops\n\u003e asking for it — until the user manually revokes their authorization. Applications should be prepared to\n\u003e receive data from scopes they did not explicitly request at authorization.\n\u003e\n\u003e This is a technical limitation of Discord's OAuth2 API.\n\n### Supported Claims\n\n#### Tokens\n\nDepending on the provided scopes, Snowflake-issued access and ID tokens include some subset of the following claims:\n\n| **Claim**            | **Description**                                                                                                                                                          | **Required Scopes (in addition to `openid`)** |\n|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|\n| `iss`                | The URL at which the client accessed Snowflake.                                                                                                                          | None                                          |\n| `sub`                | The ID of the user's Discord account.                                                                                                                                    | None                                          |\n| `aud`                | For access tokens, the URL of Snowflake's `/userinfo` endpoint; for ID tokens, the client ID of your Discord application.                                                | None                                          |\n| `iat`                | The [Unix time](https://en.wikipedia.org/wiki/Unix_time) at which the token was issued.                                                                                  | None                                          |\n| `exp`                | The [Unix time](https://en.wikipedia.org/wiki/Unix_time) past which the token should be considered expired and thus no longer valid.                                     | None                                          |\n| `preferred_username` | The username of the user's Discord account.                                                                                                                              | `profile`                                     |\n| `name`               | The [display name](https://support.discord.com/hc/en-us/articles/12620128861463-New-Usernames-Display-Names#h_01GXPQABMYGEHGPRJJXJMPHF5C) of the user's Discord account. | `profile`                                     |\n| `nickname`           | Same as `name`.                                                                                                                                                          | `profile`                                     |\n| `locale`             | The locale of the user's Discord account. See all possible locales [here](https://discord.com/developers/docs/reference#locales).                                        | `profile`                                     |\n| `picture`            | The URL of the avatar of the user's Discord account.                                                                                                                     | `profile`                                     |\n| `email`              | The email address associated with the user's Discord account.                                                                                                            | `email`                                       |\n| `email_verified`     | Whether the email address associated with the user's Discord account is verified.                                                                                        | `email`                                       |\n| `groups`             | A list of IDs of guilds the user is a member of.                                                                                                                         | `groups`                                      |\n| `nonce`              | If the `nonce` parameter was sent to the authorization endpoint, this claim will contain its value. It only appears in ID tokens.                                        | None                                          |\n\n\n#### User Info\n\nThe `/userinfo` endpoint returns the same claims as access tokens but does not include `iss`, `aud`,\n`iat`, or `exp`.\n\n#### Refresh Tokens\n\nSuccessful responses from Snowflake's token endpoint also include a refresh token. After the access and ID tokens \nexpire, the refresh token can be sent to the token endpoint to obtain a new set of access, ID, and refresh tokens \nwithout having to make the user reauthorize.\n\nSee [OpenID Connect Core 1.0 § 12](https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens) \nfor additional details.\n\n\u003e [!caution]\n\u003e **Public clients must keep their refresh tokens secure!** If an attacker steals a public client's refresh token,\n\u003e Discord doesn't provide any means to keep the attacker from using it and obtaining new access and ID tokens\n\u003e indefinitely.\n\u003e \n\u003e Public clients may opt out of recieving refresh tokens by sending `include_refresh_token=false` to the `/token`\n\u003e endpoint.\n\n### PKCE Support\n\nFor applications that cannot securely store a client secret, Snowflake supports the\n[PKCE-enhanced authorization code flow](https://datatracker.ietf.org/doc/html/rfc7636).\nMake sure the `Public Client` option is enabled in your Discord application's OAuth2 settings.\n\n### WebFinger Support\n\nSnowflake provides a [WebFinger](https://en.wikipedia.org/wiki/WebFinger) endpoint at `/.well-known/webfinger`\nto enable the discovery of Snowflake as the OIDC provider for email addresses at domains permitted by the\n`SNOWFLAKE_ALLOWED_WEBFINGER_HOSTS` environment variable (see [Configuration](#configuration)). The endpoint\nonly supports `acct:` URIs containing email addresses and does not support any link relations other than OpenID Connnect.\n\nThe endpoint will return an HTTP 404 error for email addresses at non-whitelisted domains.\n\n## HTTPS and Reverse Proxies\n\nAs previously mentioned, Snowflake requires HTTPS for external connections. If you're serving Snowflake\nbehind a reverse proxy and connecting to the reverse proxy over HTTPS, you will likely need to configure\n[Uvicorn](https://www.uvicorn.org) — which Snowflake uses under the hood — to trust the IP address\nof your reverse proxy.\n\nYou can do this by setting the `UVICORN_FORWARDED_ALLOW_IPS` environment variable to a comma-separated list of IP\naddresses or networks, at least one of which must match the IP of your reverse proxy. You can also set it to `*` to\ntrust all IP addresses, but this is generally not recommended.\n\nFor more information, see [Uvicorn's documentation](https://www.uvicorn.org/deployment/#proxies-and-forwarded-headers).\n\n## Custom Private Keys\n\n\u003e [!note]\n\u003e This is an advanced feature most users won't need.\n\nBy default, Snowflake signs its JWTs with a private key that it generates and writes to `/app/snowflake/data`,\nwhich you are instructed to mount on your host machine (see [Installation](#installation)). As an alternative to this,\nSnowflake allows you to provide your own private key via the `SNOWFLAKE_PRIVATE_KEY` environment variable. This may\nbe useful, for example, in environments where mounting `/app/snowflake/data` isn't possible, or if you'd just prefer\nto keep the private key in an environment variable rather than have it persisted to a file.\n\nThe value of `SNOWFLAKE_PRIVATE_KEY` must be an RS256 JSON Web Key. There are two recommended ways to generate one:\n\n1. Use the online tool mkjwk via [this link](https://mkjwk.org/?kty=rsa\u0026size=2048\u0026use=sig\u0026alg=RS256). Using that link \nwill prefill the configuration options; you only need to click `Generate` and then `Copy to Clipboard` underneath \n`Public and Private Keypair`.\n2. Use the following command:\n\n    ```shell\n    docker run ghcr.io/celsiusnarhwal/snowflake keygen\n    ```\n\n\u003cdetails\u003e\n\u003csummary\u003eEither way, the result should look similar to this (click to expand):\u003c/summary\u003e\n\u003cbr/\u003e\n\n```json5\n// For demonstration purposes only, do not actually use this private key. Obviously.\n{\n    \"p\": \"4AGfVeTcxkgbvqf0WP5c270L-p_WQyNwMmtn4pXPazhmfwVPW6j3f2n2_Ober4xObaD5KOJIR3ah3Wu9LCoYp2HNdxsddyBXYh7nZhYP21uq1MphX9jvw1l422qAEbPraISKfkPv71sJxnXMG1cm7SaUtkj4P6Lg7bTv8PxapQ0\",\n    \"kty\": \"RSA\",\n    \"q\": \"2ues113yqdjCdx9O_1piyYeWQhYbM-VZy_TTKmc3JqARj68wx8lUoggr_ybcN5dJ8JKPKh93SN5TnqbmscqYllEaXtSQPw6aDq5OkF5Z5M7J-kDtfVcHU-Z02NFa40ViU25seIDmejbJi442ox2yChTd9gbp_0Rfkhv9EuWdnaU\",\n    \"d\": \"GMJcHduhQEp1EYSU7MGuA6RWUHFYWhuwxPorrY09E5PrAPmPJxFmrPls_2hSfJSSJ-TnnKKcHQpcNFt7BiZ6Th2D_qH5DH9FUKSRkl6kvb9gEI5bNDF_1lYZxnivG94OEtkqprVXURMaza5Hbz57Gl0iBpV28BmnZAg6Llb7AUUNONmZgtzhPYpwH9JxJOHCzQHbc4u9ZF1XfbW-iINHenJW34pN8jdWPlv_DYKt9SDd9qPQq4eCGkOU9uQFL4KeoPlGaDXA_7ps4i62klEtb-rdQFQD-gg8-nc2trMt9oMmqVl0XFdG4KN9_N4Qid4HgiaiMwjNsdkNKk2e8aZWvQ\",\n    \"e\": \"AQAB\",\n    \"use\": \"sig\",\n    \"qi\": \"2vWPtbeCUETj7ZgqrOxUqtO_yD5I86tY_zoMK_woQ389VLg--fwXcY9amWo1FViHm1KmuA0nqxc0Sdbl5N1ibxZPqYglX_YnGH5AQ9HTOCmrPeAOTCOdUtUgBD0biG2y63VfiGKnrJz1QGVLIkEFub6V0JraUNDxE7nUJlxb3Lk\",\n    \"dp\": \"YLISl79dVfJWl6xkm-3hI7GtdBh_IygvDHS0uWi1yrDj_bzLDuQXQlb5mR4Hznugd05ff7h-PusE4FHbrS7WyZo8WUfJJl09m0t_099-JNCjI4vhEMDSbt82fnCwq_OgkNN1_R9SeV4xEAxVeQ_b688VrsI89ytWMQZD9SDZ-Bk\",\n    \"alg\": \"RS256\",\n    \"dq\": \"JmN8jyQ9mwWVTNijvOo36smpUxuXV6l_7uGXapdBN7fYfI8nidHH0saGGK_S7LjOUa8SBjwQain7FhaE3GcADVRZwImcZkKER9DPnEe_kf2ltApQ26s4cME4epF0U-jmDmWOBi_su0ACZkPhVwetIlF4f13FCWwPKotX_UlhM7U\",\n    \"n\": \"v4waY3YE-AFuYoVy_T7fgC48LRujLaQNaFb-GGZnZEbiFi7rkVJF_EVajmu3Ksz1TwTrIHhrJijKAuBg_p4UKNJVZATqjPCilIrOajbWWJ-OISYXqeUHmlaoqML3Qq1x8ti05G6DyUjZTfZRabqrx7UggB3nOL-Eog69FnNf7tf1XmEIKEvwfB9NFAQWG2Jiksts8jzU2PVDnmR5cpsAeOK2hwZnp0BKcezAnILGrVbt_NPvp4J2ldD6eV8_YMZ9YenZaTw6LuVAE0k4buPv7mNoP-QhDhhg2UrmY3xElhhk0VNxbNV7b0AAm07bfuPfEb-y8V0amzYLKb48F55aYQ\"\n}\n```\n\n\u003c/details\u003e\n\nIf `SNOWFLAKE_PRIVATE_KEY` is set, there's no need to mount `/app/snowflake/data`. On startup, Snowflake\nwill log a message affirming that a custom private key is in use.\n\n## Configuration\n\nSnowflake is configurable through the following environment variables (all optional):\n\n| **Environment Variable**             | **Type** | **Description**                                                                                                                                                                                                                                                                                                                                                                                       | **Default**               |\n|--------------------------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------|\n| `SNOWFLAKE_ALLOWED_HOSTS`            | String   | A comma-separated list of hostnames at which Snowflake may be accessed. Wildcard domains (e.g., `*.example.com`) and IP addresses are supported. You can also set this to `*` to allow all hostnames, but this is not recommended.\u003cbr/\u003e\u003cbr/\u003eLoopback addresses (e.g., `localhost`) are always included.                                                                                               | `localhost,127.0.0.1,::1` |\n| `SNOWFLAKE_ALLOWED_CLIENTS`          | String   | A comma-separated list of Discord application client IDs. Snowflake will only fulfill authorization requests for client IDs in this list.\u003cbr/\u003e\u003cbr/\u003eThis can be set to `*` to allow all client IDs.                                                                                                                                                                                                    | `*`                       |\n| `SNOWFLAKE_BASE_PATH`                | String   | The URL path at which Snowflake is being served. This may be useful if you're serving Snowflake behind a reverse proxy.                                                                                                                                                                                                                                                                               | `/`                       |\n| `SNOWFLAKE_FIX_REDIRECT_URIS`        | Boolean  | Whether to automatically correct redirect URIs to subpaths of Snowflake's `/r` endpoint as necessary. This may be useful for OIDC clients that don't allow you to set the redirect URI they use.\u003cbr/\u003e\u003cbr/\u003eThe redirect URIs you set in the Discord Developer Portal must always be subpaths of `/r` regardless of this setting.                                                                       | `false`                   |                                                                                                                                                                                                                                                                                                                                   |               |              |\n| `SNOWFLAKE_TOKEN_LIFETIME`           | String   | A [Go duration string](https://pkg.go.dev/time#ParseDuration) representing the amount of time after which Snowflake-issued tokens should expire. In addition to the standard Go units, you can use `d` for day, `w` for week, `mm` for month, and `y` for year.[^1]\u003cbr/\u003e\u003cbr/\u003eMust be greater than or equal to 60 seconds.                                                                             | `1h`                      |\n| `SNOWFLAKE_ROOT_REDIRECT`            | String   | Where Snowflake's root path redirects to. Must be `repo`, `settings`, `docs`, or `off`.\u003cbr/\u003e\u003cbr/\u003e`repo` redirects to Snowflake's GitHub repository; `settings` redirects to the user's Discord account settings; `docs` redirects to Snowflake's interactive API documentation; `off` responds with an HTTP 404 error.\u003cbr/\u003e\u003cbr/\u003eSetting this to `docs` will force `SNOWFLAKE_ENABLE_DOCS` to be true. | `repo`                    |\n| `SNOWFLAKE_TREAT_LOOPBACK_AS_SECURE` | Boolean  | Whether Snowflake will consider loopback addresses (e.g., `localhost`) to be secure even if they don't use HTTPS.                                                                                                                                                                                                                                                                                     | `true`                    |\n| `SNOWFLAKE_RETURN_TO_REFERRER`       | Boolean  | If this is `true` and the user denies an authorization request, Snowflake will redirect the user back to the initiating URL.[^3] Otherwise, Snowflake behaves according to [OpenID Connect Core 1.0 § 3.1.2.6](https://openid.net/specs/openid-connect-core-1_0.html#AuthError).                                                                                                                      | `false`                   |\n| `SNOWFLAKE_ALLOWED_WEBFINGER_HOSTS`  | String   | A comma-separated lists of domains allowed in `acct:` URIs sent to Snowflake's WebFinger endpoint. The endpoint will return an HTTP 404 error for URIs with domains not permitted by this setting.\u003cbr/\u003e\u003cbr/\u003e Wildcard domains (e.g., `*.example.com`) are supported, but the unqualified wildcard (`*`) is not.                                                                                       | N/A                       |\n| `SNOWFLAKE_PRIVATE_KEY`              | String   | A private RS256 JSON Web Key. If provided, Snowflake will use it instead of generating its own. See [Custom Private Keys](#custom-private-keys).                                                                                                                                                                                                                                                      |                           |\n| `SNOWFLAKE_ENABLE_DOCS`              | Boolean  | Whether to serve Snowflake's interactive API documentation at `/docs`. This also controls whether Snowflake's [OpenAPI](https://spec.openapis.org/oas/latest.html) schema is served at `/openapi.json`.\u003cbr/\u003e\u003cbr/\u003eThis is forced to be `true` if `SNOWFLAKE_ROOT_REDIRECT` is set to `docs`.                                                                                                           | `false`                   |\n\n\u003cbr\u003e\n\nUvicorn will respect most[^2] of [its own environment variables](https://www.uvicorn.org/settings/) if they are set, but `UVICORN_FORWARDED_ALLOW_IPS` is the only one supported by Snowflake. Please don't open an issue if you set any of the others and something breaks.\n\n[^1]: 1 day = 24 hours, 1 week = 7 days, 1 month = 30 days, and 1 year = 365 days.\n\n[^2]: With the exceptions of `UVICORN_HOST` and `UVICORN_PORT`.\n\n[^3]: Specifically, if the \n[`Referer` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Referer) was sent to the \nauthorization endpoint and the callback endpoint recieves an `error` parameter with a value of `access_denied`, \nSnowflake will redirect to the URL that was given by `Referer` at the authorization endpoint.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcelsiusnarhwal%2Fsnowflake","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcelsiusnarhwal%2Fsnowflake","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcelsiusnarhwal%2Fsnowflake/lists"}