Skip to content

v0.3.0

Choose a tag to compare

@rameerez rameerez released this 09 Feb 05:08
· 24 commits to main since this release

Highlights

Major release adding Stripe-style key types with permission ceilings, environment isolation (test/live), and a security fix for scope enforcement.

New Features

  • Stripe-style key types β€” publishable (pk_*) and secret (sk_*) keys with per-type permission ceilings
  • Environment isolation β€” test/live key prefixes (pk_test_, sk_live_) with strict environment enforcement
  • Public key token storage β€” non-revocable publishable keys can be viewed again in the dashboard
  • Headless helpers β€” for apps with custom dashboard integrations
  • Usage analytics scopes β€” admin dashboard query helpers

Fixes

  • Fix PostgreSQL FOR UPDATE with COUNT aggregate error
  • Security: Fix blank scopes bypass in key_types mode β€” empty scopes no longer grant unrestricted access when permission ceilings are configured

What's Changed

  • Ensure comprehensive testing and production readiness by @rameerez in #5
  • Add Stripe-style key types and environments (publishable/secret keys with test/live isolation) by @rameerez in #6
  • Fix PostgreSQL FOR UPDATE with COUNT aggregate error by @rameerez in #7
  • Add public key token storage for non-revocable publishable keys by @rameerez in #8
  • Add headless helpers for custom dashboard integrations by @rameerez in #9
  • Add usage analytics scopes for admin dashboards by @rameerez in #10
  • Fix blank scopes bypass in key_types mode by @rameerez in #11

Full Changelog: v0.2.1...v0.3.0


Production-readiness review (2026-07-07)

Full release review ahead of the RubyGems push and the RailsFast v1.0.0 integration β€” verdict: GO. (At review time 0.3.0 was tagged but not yet on RubyGems, so Bundler still resolved 0.2.1.) Everything below was verified empirically inside a fresh RailsFast app β€” Ruby 4.0.5 / Rails 8.1.3 / PostgreSQL with uuid primary keys β€” not just the gem's own suite:

  • Install path: rails generate api_keys:install correctly picks up the host app's primary_key_type (uuid) for both the table and the polymorphic owner FK, and jsonb on PostgreSQL.
  • Auth matrix (integration-tested): missing/garbage/truncated tokens β†’ missing_token/invalid_token; revoked β†’ revoked_key; expired β†’ expired_key; Bearer and raw Authorization header forms both accepted; authenticate_api_key!(scope:) gates enforced (missing_scope); simple mode's "no scopes = unrestricted" default confirmed. The documented ActionController::API + include ApiKeys::Controller pattern works as advertised on Rails 8.1.
  • Security spot-checks: plaintext is never persisted (stored digest == SHA256(token), #token nil after reload); publishable-key plaintext storage is correctly double-gated on public: true and revocable: false; the dashboard is fully owner-scoped (a cross-user access probe was rejected); revocation lag is bounded by the 5-second default cache_ttl; token entropy is 24 random bytes (~192 bits) with the default :sha256 strategy giving O(1) indexed lookup.
  • Dashboard: Devise-authenticated mount, key minting through the UI (blank form scopes cleaned), show-once plaintext, revoke flow β€” all green.
  • Boot/deploy gates: host-app suite green with the gem enabled (235 runs, 0 failures), zeitwerk production-parity eager load clean, assets:precompile with no reachable database exits 0 (Docker image builds are safe), and a full RAILS_ENV=production eager-loaded boot verified end to end.
  • Package: gem build produces a clean package β€” 61 files, zero test/dummy leakage.
  • CI: matrix green on Ruby 3.3 / 3.4 / 4.0 Γ— Rails 7.2 / 8.1.

Non-blocking hardening and polish follow-ups from the review are tracked in #12.