|
2 | 2 |
|
3 | 3 | This is a TypeScript library that implements the provider side of the OAuth 2.1 protocol with PKCE support. The library is intended to be used on Cloudflare Workers.
|
4 | 4 |
|
| 5 | +## EXPERIMENTAL |
| 6 | + |
| 7 | +As of March, 2025, this library is very new. Please use with caution as additional security reviews are still in progress. |
| 8 | + |
5 | 9 | ## Benefits of this library
|
6 | 10 |
|
7 | 11 | * The library acts as a wrapper around your Worker code, which adds authorization for your API endpoints.
|
@@ -66,16 +70,16 @@ export default new OAuthProvider({
|
66 | 70 | // If provided, this will be included in the RFC 8414 metadata as 'scopes_supported'.
|
67 | 71 | // If not provided, the 'scopes_supported' field will be omitted from the metadata.
|
68 | 72 | scopesSupported: ["document.read", "document.write", "profile"],
|
69 |
| - |
| 73 | + |
70 | 74 | // Optional: Controls whether the OAuth implicit flow is allowed.
|
71 | 75 | // The implicit flow is discouraged in OAuth 2.1 but may be needed for some clients.
|
72 | 76 | // Defaults to false.
|
73 | 77 | allowImplicitFlow: false,
|
74 |
| - |
75 |
| - // Optional: Controls whether public clients (clients without a secret, like SPAs) |
| 78 | + |
| 79 | + // Optional: Controls whether public clients (clients without a secret, like SPAs) |
76 | 80 | // can register via the dynamic client registration endpoint.
|
77 | 81 | // When true, only confidential clients can register.
|
78 |
| - // Note: Creating public clients via the OAuthHelpers.createClient() method |
| 82 | + // Note: Creating public clients via the OAuthHelpers.createClient() method |
79 | 83 | // is always allowed regardless of this setting.
|
80 | 84 | // Defaults to false.
|
81 | 85 | disallowPublicClientRegistration: false
|
@@ -194,10 +198,21 @@ See the `OAuthHelpers` interface definition for full API details.
|
194 | 198 |
|
195 | 199 | ## Written by Claude
|
196 | 200 |
|
197 |
| -This library (including the schema documentation) was largely written by Claude, the AI model by Anthropic. Check out the commit history to see how Claude was prompted and what code it produced. |
| 201 | +This library (including the schema documentation) was largely written by [Claude](https://claude.ai), the AI model by Anthropic. Claude's output was thoroughly reviewed by Cloudflare engineers with careful attention paid to security and compliance with standards. Many improvements were made on the initial output, mostly again by prompting Claude (and reviewing the results). Check out the commit history to see how Claude was prompted and what code it produced. |
| 202 | + |
| 203 | +(@kentonv, the lead engineer, was actually an AI skeptic, and started this project with the intent to prove that LLMs cannot code. He ended up deciding he had proven himself wrong.) |
198 | 204 |
|
199 | 205 | ## Implementation Notes
|
200 | 206 |
|
| 207 | +### End-to-end encryption |
| 208 | + |
| 209 | +This library stores records about authorization tokens in KV. The storage schema is carefully designed such that a complete leak of the storage only reveals mundane metadata about what has been granted. In particular: |
| 210 | + |
| 211 | +* Secrets (including access tokens, refresh tokens, authorization codes, and client secrets) are stored only by hash. Hence, such secrets cannot be derived from the storage alone. |
| 212 | +* The `props` associated with a grant (which are passed back to the application when API requests are performed) are stored encrypted with the secret token as key material. Hence, the contents of `props` are impossible to derive from storage unless a valid token is provided. |
| 213 | + |
| 214 | +Note that the `userId` and the `metadata` associated with each grant are not encrypted, because the purpose of these values is to allow grants to be enumerated for audit and revocation purposes. However, these values are completely opaque to the library. An application is free to omit them or apply its own encryption to them before passing them into the library, if it desires. |
| 215 | + |
201 | 216 | ### Single-use refresh tokens?
|
202 | 217 |
|
203 | 218 | OAuth 2.1 requires that refresh tokens are either "cryptographically bound" to the client, or are single-use. This library currently does not implement any cryptographic binding, thus seemingly requiring single-use tokens. Under this requirement, every token refresh request invalidates the old refresh token and issues a new one.
|
|
0 commit comments