API Key

Create and verify user API keys.

This page documents the current Ruby port behavior. Ruby uses snake_case option names and auth.api method names; HTTP paths and JSON keys keep the upstream wire shape where implemented.

Configure

config/auth.rb
require "better_auth"
require "better_auth/api_key"

auth = BetterAuth.auth(
  secret: ENV.fetch("BETTER_AUTH_SECRET"),
  base_url: ENV.fetch("BETTER_AUTH_URL", "http://localhost:3000"),
  plugins: [
    BetterAuth::Plugins.api_key(enable_session_for_api_keys: true)
  ]
)

Usage

server.rb
created = auth.api.create_api_key(headers: { "cookie" => request.env["HTTP_COOKIE"] }, body: { name: "CLI" })
verified = auth.api.verify_api_key(body: { key: created[:key] })
keys = auth.api.list_api_keys(headers: { "cookie" => request.env["HTTP_COOKIE"] })
cleanup = auth.api.delete_all_expired_api_keys

Routes

MethodPathRuby API method
POST/api-key/createauth.api.create_api_key
POST/api-key/verifyauth.api.verify_api_key
GET/api-key/getauth.api.get_api_key
GET/api-key/listauth.api.list_api_keys
POST/api-key/updateauth.api.update_api_key
POST/api-key/deleteauth.api.delete_api_key
POST/api-key/delete-all-expired-api-keysauth.api.delete_all_expired_api_keys

Options

Current Ruby options accepted by BetterAuth::Plugins.api_key:

  • enable_session_for_api_keys
  • config_id
  • rate_limit
  • starting_characters_config
  • default_key_length
  • default_prefix
  • custom_api_key_validator
  • require_name
  • minimum_name_length
  • maximum_name_length
  • minimum_prefix_length
  • maximum_prefix_length
  • enable_metadata
  • key_expiration
  • custom_key_generator
  • disable_key_hashing
  • storage
  • fallback_to_database
  • custom_storage
  • custom_api_key_getter
  • api_key_headers
  • permissions
  • references ("user" or "organization")
  • defer_updates

For default permissions, pass permissions: { default_permissions: ... } to match the upstream permissions.defaultPermissions option while keeping Ruby snake_case keys.

When enable_session_for_api_keys is enabled, Ruby creates an in-memory session for user-owned API keys but does not place the raw API key in session["token"]. The session includes tokenFingerprint, an irreversible SHA-256 fingerprint of the presented key, for correlation without persisting the secret.

Plugin metadata

The plugin object exposes the gem version, mirroring upstream @better-auth/api-key@1.6.0+:

auth.options.plugins.find { |plugin| plugin.id == "api-key" }.version
# => BetterAuth::APIKey::VERSION

Organization-owned API keys

When a configuration sets references: "organization", the plugin requires BetterAuth::Plugins.organization to also be installed. The organization's access-control bundle must define the apiKey resource with the create, read, update, and delete actions. The configured creator_role (default "owner") bypasses the per-action permission check and can perform any apiKey mutation; other roles must be explicitly granted the relevant apiKey:* permission.

Browser client and OpenAPI

The browser-only @better-auth/api-key/client helpers from upstream are not ported. Server endpoints accept and return upstream JSON so frontend applications using the upstream JavaScript client interoperate without configuration changes; Ruby applications should call the JSON endpoints directly.

The OpenAPI metadata blocks embedded in upstream endpoint definitions are intentionally not ported either — OpenAPI generation lives outside the gem's scope.

Support Notes

  • Install gem "better_auth-api-key" before requiring better_auth/api_key.
  • The examples above are based on Ruby plugin source and tests in packages/better_auth-api-key.
  • The Ruby gem reads legacy secondary-storage keys (api-key:key:*, api-key:id:*, api-key:user:*) for backward compatibility but always writes to the upstream layout (api-key:*, api-key:by-id:*, api-key:by-ref:*).
  • If an upstream section is not represented here, treat it as not yet documented or not yet supported by the Ruby port until the matching Ruby implementation exists.

On this page