[PR #1515] [MERGED] Feat: API Key plugin (rework) #3839

Closed
opened 2026-03-13 11:16:48 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/1515
Author: @ping-maxwell
Created: 2/20/2025
Status: Merged
Merged: 2/28/2025
Merged by: @Bekacru

Base: mainHead: feat/plugin/api-key-rework


📝 Commits (10+)

  • acb6f02 feat: API-key plugin
  • b761394 add: deleteAllExpiredApiKeys functionality
  • e5e0449 fix: fetching sessions from headers
  • d2f300c update: types & create-api-key now checks for min & max expiresIn values
  • 552c19e tests: Started working on tests
  • 26ec128 add: features
  • 66b8c54 fix: create-api-key's expiration using / instead of *
  • d1a8317 update: schema metadata transforms invalid values as null
  • 6e52d01 fix: create-api-key metadata should go through transformation
  • c33cb34 fix: missing metadata wouldn't have 'null' as value

📊 Changes

21 files changed (+4620 additions, -0 deletions)

View changed files

📝 docs/app/docs/[[...slug]]/page.tsx (+4 -0)
docs/components/divider-text.tsx (+13 -0)
docs/components/endpoint.tsx (+48 -0)
📝 docs/components/sidebar-content.tsx (+7 -0)
docs/content/docs/plugins/api-key.mdx (+934 -0)
📝 packages/better-auth/src/client/plugins/index.ts (+1 -0)
packages/better-auth/src/plugins/api-key/api-key.test.ts (+1603 -0)
packages/better-auth/src/plugins/api-key/client.ts (+12 -0)
packages/better-auth/src/plugins/api-key/index.ts (+228 -0)
packages/better-auth/src/plugins/api-key/rate-limit.ts (+97 -0)
packages/better-auth/src/plugins/api-key/routes/create-api-key.ts (+302 -0)
packages/better-auth/src/plugins/api-key/routes/delete-all-expired-api-keys.ts (+37 -0)
packages/better-auth/src/plugins/api-key/routes/delete-api-key.ts (+87 -0)
packages/better-auth/src/plugins/api-key/routes/get-api-key.ts (+69 -0)
packages/better-auth/src/plugins/api-key/routes/index.ts (+92 -0)
packages/better-auth/src/plugins/api-key/routes/list-api-keys.ts (+55 -0)
packages/better-auth/src/plugins/api-key/routes/update-api-key.ts (+284 -0)
packages/better-auth/src/plugins/api-key/routes/verify-api-key.ts (+280 -0)
packages/better-auth/src/plugins/api-key/schema.ts (+194 -0)
packages/better-auth/src/plugins/api-key/types.ts (+272 -0)

...and 1 more files

📄 Description

API Key Plugin

image

Core features:

  • Allows you to create, update, get, list & delete API keys.
  • Allows you to to pass an API Key in the header of an API call, and it will mock a session out of the user who created that API key. (configurable in plugin options)
  • Rate-limiting built-in.
    • Custom rate-limits can be applied per API key, which only goes into effect when an API key is being verified.
    • Everything else can use the built-in Better Auth rate-limiting functionality to rate-limit endpoints.
  • API Key remaining count for limited (or optionally unlimited) verification usage.
  • API Key refilling functionality to refill the remaining count over a period of time. (useful for subscription use-cases)
  • Optionally enable or disable a key.
  • Allows you to pass additional metadata information for each key.
  • Allows you to pass a prefix for the API key generation.
  • Other stuff that I probably forgot. 😁

Tests

screenshot of it all

Almost 3x more tests than the old PR. 😅

image
Create
  • create api key client without headers (should fail)
  • create api key client with headers
  • create api key server without headers (should fail)
  • create api key server with headers
  • create api key with custom name
  • create api key with custom name that's smaller than allowed minimum (should fail)
  • create api key with custom name that's larger than the allowed maximum (should fail)
  • create api key with custom prefix
  • create api key with custom prefix that's smaller than allowed minimum (should fail)
  • create api key with custom prefix that's larger than the allowed maximum (should fail)
  • create api key with custom expiresIn
  • should fail to create key with custom expiresin when customExpiresTime is enabled
  • create api key with custom expiresIn that's smaller than the allowed minimum (should fail)
  • create api key with custom expiresIn that's larger than the allowed maximum (should fail)
  • create api key with custom refillAndAmount from client auth (should fail because this is a server-only-property)
  • create api key with custom refillInterval (should fail because it requires refillAmount as well)
  • create api key with custom refillAmount (should fail because refillInterval is required)
  • create api key with custom refillInterval & refillAmount
  • create api key with custom remaining
  • create api key with custom remaining that's smaller than allowed minimum (should fail)
  • create api key with custom remaining that's larger than the allowed maximum (should fail)
  • create api key with custom invalid metadata (should fail)
  • create api key with custom valid metadata
  • create api key's returned metadata should be an object
  • create api key with with metadata when metadata is disabled (should fail)
  • created api key's start property should be valid
  • created api key's start property should be null if shouldStore is false
  • created api key's start property should be the first charactersLength characters of the hashed key
  • create api key with custom rate limit options from client auth (should fail because this is a server-only-property)
  • create api key with custom rate limit options should apply successfully
Verify
  • verify api key without headers (should fail)
  • verify api key with headers
  • verify api key with invalid key (should fail)
  • verify api key 10 times in a row (should fail to rate-limits)
  • should allow us to verify api key after rate-limit window has passed
  • should check if verifying an api key's remaining count does go down
  • should fail if the api key has no remaining
  • Api key should fail if it's expired
Update
  • update api key name without headers (should fail)
  • update api key name with headers
  • should fail to update api key name with a length larger than the allowed maximum
  • should fail to update api key name with a length smaller than the allowed minimum
  • should fail to update api key with no values to update
  • update api key expiresIn value
  • should fail to update expiresIn value if disableCustomExpiresTime is enabled
  • update api key expiresIn value that's smaller than allowed minimum (should fail)
  • update api key expiresIn value that's larger than the allowed maximum (should fail)
  • update api key remaining value
  • update api key remaining value that's smaller than allowed minimum (should fail)
  • update api key remaining value that's larger than the allowed maximum (should fail)
  • update api key refillInterval value (should fail since it requires refillAmount as well)
  • update api key refillAmount value (should fail since it requires refillInterval as well)
  • update api key refillInterval & refillAmount value
  • update api key enabled value
  • update api key with invalid metadata value
  • update api key with valid metadata value
  • update api key's returned metadata should be an object
Delete
  • delete api key without headers (should fail)
  • delete api key with headers
  • delete api key that doesn't exist (should fail)
Get
  • get api key by ID without headers (should fail)
  • get api key by ID with headers
  • get api key that doesn't exist (should fail)
  • get api key's returned metadata should be an object
  • get api key's returned key should not be defined
List
  • list api keys without headers (should fail)
  • list api keys with headers
  • list api keys should contain metadata that are either objects or null
Sessions
  • When making any request, if headers include x-api-key, then the the request should generate a mock session object for the user.
  • Custom headers list should still work when calling getSession
  • Custom key getter function should work

Closes

https://github.com/better-auth/better-auth/issues/1112

What's left? (todo)

  • Update documentation: done
  • Update nextjs/demo: Not started
  • Add openAPI metadata: Not started

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/1515 **Author:** [@ping-maxwell](https://github.com/ping-maxwell) **Created:** 2/20/2025 **Status:** ✅ Merged **Merged:** 2/28/2025 **Merged by:** [@Bekacru](https://github.com/Bekacru) **Base:** `main` ← **Head:** `feat/plugin/api-key-rework` --- ### 📝 Commits (10+) - [`acb6f02`](https://github.com/better-auth/better-auth/commit/acb6f0281a86a59856e4781480105134527a6e6b) feat: API-key plugin - [`b761394`](https://github.com/better-auth/better-auth/commit/b7613943c68f5a433c0f23c9f8d478796a51e172) add: `deleteAllExpiredApiKeys` functionality - [`e5e0449`](https://github.com/better-auth/better-auth/commit/e5e04490e405dde9536303c0aa3f46cf4629f6bb) fix: fetching sessions from headers - [`d2f300c`](https://github.com/better-auth/better-auth/commit/d2f300c28e4e486b02c2d7b9e5d2b3b2c551f2ad) update: types & create-api-key now checks for min & max expiresIn values - [`552c19e`](https://github.com/better-auth/better-auth/commit/552c19e5df1a2b13c18e09751075059cfc43a1d9) tests: Started working on tests - [`26ec128`](https://github.com/better-auth/better-auth/commit/26ec128f4795f9a4034086930279035894b9062c) add: features - [`66b8c54`](https://github.com/better-auth/better-auth/commit/66b8c543facf80842d83b44929ab559766f9065f) fix: create-api-key's expiration using `/` instead of `*` - [`d1a8317`](https://github.com/better-auth/better-auth/commit/d1a8317a2279a90fb8505211bc71f1b33150f6f1) update: schema `metadata` transforms invalid values as `null` - [`6e52d01`](https://github.com/better-auth/better-auth/commit/6e52d01b9b7940a090f9340aa331ea7fe0ac1c45) fix: create-api-key metadata should go through transformation - [`c33cb34`](https://github.com/better-auth/better-auth/commit/c33cb34606c0ebb5a1a0313768f274d3c8ef57ff) fix: missing metadata wouldn't have `'null'` as value ### 📊 Changes **21 files changed** (+4620 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `docs/app/docs/[[...slug]]/page.tsx` (+4 -0) ➕ `docs/components/divider-text.tsx` (+13 -0) ➕ `docs/components/endpoint.tsx` (+48 -0) 📝 `docs/components/sidebar-content.tsx` (+7 -0) ➕ `docs/content/docs/plugins/api-key.mdx` (+934 -0) 📝 `packages/better-auth/src/client/plugins/index.ts` (+1 -0) ➕ `packages/better-auth/src/plugins/api-key/api-key.test.ts` (+1603 -0) ➕ `packages/better-auth/src/plugins/api-key/client.ts` (+12 -0) ➕ `packages/better-auth/src/plugins/api-key/index.ts` (+228 -0) ➕ `packages/better-auth/src/plugins/api-key/rate-limit.ts` (+97 -0) ➕ `packages/better-auth/src/plugins/api-key/routes/create-api-key.ts` (+302 -0) ➕ `packages/better-auth/src/plugins/api-key/routes/delete-all-expired-api-keys.ts` (+37 -0) ➕ `packages/better-auth/src/plugins/api-key/routes/delete-api-key.ts` (+87 -0) ➕ `packages/better-auth/src/plugins/api-key/routes/get-api-key.ts` (+69 -0) ➕ `packages/better-auth/src/plugins/api-key/routes/index.ts` (+92 -0) ➕ `packages/better-auth/src/plugins/api-key/routes/list-api-keys.ts` (+55 -0) ➕ `packages/better-auth/src/plugins/api-key/routes/update-api-key.ts` (+284 -0) ➕ `packages/better-auth/src/plugins/api-key/routes/verify-api-key.ts` (+280 -0) ➕ `packages/better-auth/src/plugins/api-key/schema.ts` (+194 -0) ➕ `packages/better-auth/src/plugins/api-key/types.ts` (+272 -0) _...and 1 more files_ </details> ### 📄 Description # API Key Plugin <img width="1066" alt="image" src="https://github.com/user-attachments/assets/bb20aedc-7197-4aec-8046-badf4ee1b6b5" /> ## Core features: - Allows you to create, update, get, list & delete API keys. - Allows you to to pass an API Key in the header of an API call, and it will mock a session out of the user who created that API key. (configurable in plugin options) - Rate-limiting built-in. - Custom rate-limits can be applied per API key, which only goes into effect when an API key is being verified. - Everything else can use the built-in Better Auth rate-limiting functionality to rate-limit endpoints. - API Key `remaining` count for limited (or optionally unlimited) verification usage. - API Key refilling functionality to refill the `remaining` count over a period of time. (useful for subscription use-cases) - Optionally enable or disable a key. - Allows you to pass additional metadata information for each key. - Allows you to pass a prefix for the API key generation. - Other stuff that I probably forgot. 😁 ## Tests <details> <summary>screenshot of it all</summary> Almost 3x more tests than the old PR. 😅 <img width="555" alt="image" src="https://github.com/user-attachments/assets/ed4db425-df56-48fe-bf24-4aa0670fbfd4" /> </details> <details> <summary>Create</summary> - ✅ create api key client without headers (should fail) - ✅ create api key client with headers - ✅ create api key server without headers (should fail) - ✅ create api key server with headers - ✅ create api key with custom name - ✅ create api key with custom name that's smaller than allowed minimum (should fail) - ✅ create api key with custom name that's larger than the allowed maximum (should fail) - ✅ create api key with custom prefix - ✅ create api key with custom prefix that's smaller than allowed minimum (should fail) - ✅ create api key with custom prefix that's larger than the allowed maximum (should fail) - ✅ create api key with custom expiresIn - ✅ should fail to create key with custom expiresin when `customExpiresTime` is enabled - ✅ create api key with custom expiresIn that's smaller than the allowed minimum (should fail) - ✅ create api key with custom expiresIn that's larger than the allowed maximum (should fail) - ✅ create api key with custom refillAndAmount from client auth (should fail because this is a server-only-property) - ✅ create api key with custom refillInterval (should fail because it requires refillAmount as well) - ✅ create api key with custom refillAmount (should fail because refillInterval is required) - ✅ create api key with custom refillInterval & refillAmount - ✅ create api key with custom remaining - ✅ create api key with custom remaining that's smaller than allowed minimum (should fail) - ✅ create api key with custom remaining that's larger than the allowed maximum (should fail) - ✅ create api key with custom invalid metadata (should fail) - ✅ create api key with custom valid metadata - ✅ create api key's returned metadata should be an object - ✅ create api key with with metadata when metadata is disabled (should fail) - ✅ created api key's start property should be valid - ✅ created api key's start property should be null if `shouldStore` is false - ✅ created api key's start property should be the first `charactersLength` characters of the hashed key - ✅ create api key with custom rate limit options from client auth (should fail because this is a server-only-property) - ✅ create api key with custom rate limit options should apply successfully </details> <details> <summary>Verify</summary> - ✅ verify api key without headers (should fail) - ✅ verify api key with headers - ✅ verify api key with invalid key (should fail) - ✅ verify api key 10 times in a row (should fail to rate-limits) - ✅ should allow us to verify api key after rate-limit window has passed - ✅ should check if verifying an api key's remaining count does go down - ✅ should fail if the api key has no remaining - ✅ Api key should fail if it's expired </details> <details> <summary>Update</summary> - ✅ update api key name without headers (should fail) - ✅ update api key name with headers - ✅ should fail to update api key name with a length larger than the allowed maximum - ✅ should fail to update api key name with a length smaller than the allowed minimum - ✅ should fail to update api key with no values to update - ✅ update api key expiresIn value - ✅ should fail to update expiresIn value if `disableCustomExpiresTime` is enabled - ✅ update api key expiresIn value that's smaller than allowed minimum (should fail) - ✅ update api key expiresIn value that's larger than the allowed maximum (should fail) - ✅ update api key remaining value - ✅ update api key remaining value that's smaller than allowed minimum (should fail) - ✅ update api key remaining value that's larger than the allowed maximum (should fail) - ✅ update api key refillInterval value (should fail since it requires refillAmount as well) - ✅ update api key refillAmount value (should fail since it requires refillInterval as well) - ✅ update api key refillInterval & refillAmount value - ✅ update api key enabled value - ✅ update api key with invalid metadata value - ✅ update api key with valid metadata value - ✅ update api key's returned metadata should be an object </details> <details> <summary>Delete</summary> - ✅ delete api key without headers (should fail) - ✅ delete api key with headers - ✅ delete api key that doesn't exist (should fail) </details> <details> <summary>Get</summary> - ✅ get api key by ID without headers (should fail) - ✅ get api key by ID with headers - ✅ get api key that doesn't exist (should fail) - ✅ get api key's returned metadata should be an object - ✅ get api key's returned key should not be defined </details> <details> <summary>List</summary> - ✅ list api keys without headers (should fail) - ✅ list api keys with headers - ✅ list api keys should contain metadata that are either objects or null </details> <details> <summary>Sessions</summary> - ✅ When making any request, if headers include `x-api-key`, then the the request should generate a mock session object for the user. - ✅ Custom headers list should still work when calling getSession - ✅ Custom key getter function should work </details> ## Closes https://github.com/better-auth/better-auth/issues/1112 ## What's left? (todo) - ✅ Update documentation: done - ❌ Update nextjs/demo: Not started - ❌ Add openAPI metadata: Not started --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-03-13 11:16:48 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#3839