Skip to content

polish medium audit items: bearer case, require_role fallback, bcrypt limit, column type, passkey config#16

Merged
mdfarhankc merged 1 commit into
mainfrom
fix/polish-medium-audit-items
Apr 23, 2026
Merged

polish medium audit items: bearer case, require_role fallback, bcrypt limit, column type, passkey config#16
mdfarhankc merged 1 commit into
mainfrom
fix/polish-medium-audit-items

Conversation

@mdfarhankc
Copy link
Copy Markdown
Owner

@mdfarhankc mdfarhankc commented Apr 23, 2026

Summary

Five small fixes from the medium-severity audit list, batched because each is a few lines.

  • BearerBackend accepts any case of the Bearer scheme. RFC 7235 says auth schemes are case-insensitive; we were rejecting bearer abc / BEARER abc. Now handled via auth[:7].lower() == "bearer ".
  • require_role tolerates a UserSchema with no roles field. Default UserSchema ships without roles — apps that don't use RBAC would get an AttributeError (500) from require_role instead of a clean 403. Uses getattr(user, "roles", []) or [] now.
  • bcrypt 72-byte limit enforced at hash time. hash_password(..., algorithm="bcrypt") with a password over 72 UTF-8 bytes now raises InvalidPasswordError instead of silently truncating. Prevents a subtle lockout if someone ever migrates a bcrypt-hashed DB to argon2id (argon2 doesn't truncate). Length check happens before import bcrypt so it still validates cleanly in environments without the bcrypt extra installed.
  • SQLModel UserBase.hashed_password is explicit Text. Matches the SQLAlchemy adapter. Argon2id output is ~97 chars, so the implicit VARCHAR(255) default on MySQL/MSSQL was fine — but now the intent is obvious from the model, and any future hash-length creep is safe.
  • FullAuthConfig validates passkey settings at construction time. When PASSKEY_ENABLED=True, the config now rejects empty PASSKEY_RP_ID, PASSKEY_RP_ID with a scheme or path, empty PASSKEY_ORIGINS, origins without a scheme, and PASSKEY_CHALLENGE_BACKEND="redis" without REDIS_URL. All of these used to surface as a 500 on the first passkey request; now they fail fast at app startup.

Test plan

  • uv run ruff format --check . clean
  • uv run ruff check . clean
  • uv run pytest tests/ — 188 passing, 1 skipped (bcrypt install-dependent test). 12 new tests in tests/test_polish.py cover every fix.
  • Manual: deploy with a typo in PASSKEY_RP_ID (e.g. https://example.com) — confirm the app refuses to start instead of crashing on the first register/begin request.
  • Manual: send a request with Authorization: bearer <token> — confirm it authenticates.

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Bearer authentication now accepts case-insensitive scheme matching
    • Role-based access control returns proper 403 status when roles attribute is undefined
    • Password hashing now enforces 72-byte UTF-8 input limit, rejecting longer passwords
    • Passkey configuration validation now occurs at startup to prevent runtime errors
  • Documentation

    • Updated changelog with recent fixes

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a727c294-6573-471e-860a-a1ac484efcfc

📥 Commits

Reviewing files that changed from the base of the PR and between 9a59232 and 1296bea.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • fastapi_fullauth/adapters/sqlmodel/models/base.py
  • fastapi_fullauth/backends/bearer.py
  • fastapi_fullauth/config.py
  • fastapi_fullauth/core/crypto.py
  • fastapi_fullauth/dependencies/require_role.py
  • tests/test_polish.py

📝 Walkthrough

Walkthrough

This PR implements several behavioral improvements across authentication and configuration: Bearer token scheme matching is now case-insensitive, role-based authorization returns a clean 403 when roles are missing instead of erroring, bcrypt password hashing validates the 72-byte UTF-8 limit, SQLModel's hashed_password field is explicitly mapped to Text column type, and FullAuthConfig validates passkey settings at instantiation time.

Changes

Cohort / File(s) Summary
Authentication & Authorization
fastapi_fullauth/backends/bearer.py, fastapi_fullauth/dependencies/require_role.py
Bearer scheme matching now case-insensitive; require_role safely returns 403 when roles attribute missing instead of raising AttributeError.
Cryptographic Security
fastapi_fullauth/core/crypto.py
Bcrypt password hashing enforces 72-byte UTF-8 limit via InvalidPasswordError instead of silent truncation.
Configuration Validation
fastapi_fullauth/config.py
FullAuthConfig validates passkey settings at instantiation: requires RP_ID and ORIGINS when enabled, validates format (bare domain for RP_ID, full origins with scheme), and checks Redis URL when Redis backend is used.
Data Models
fastapi_fullauth/adapters/sqlmodel/models/base.py
User.hashed_password explicitly mapped to SQLAlchemy Text column with nullable=False.
Documentation & Tests
CHANGELOG.md, tests/test_polish.py
Changelog documents all fixes; test suite validates Bearer casing, role handling, password limits, field types, and config validation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~40 minutes

Possibly related PRs

  • add passkey/webauthn authentication #11 — Both PRs modify passkey configuration behavior in FullAuthConfig, with this PR adding post-initialization validation that directly complements passkey settings work.

Poem

🐰 With whiskers twitched and paws so keen,
I've polished the auth, made things pristine—
Cases now match, roles softly fall,
Passwords bounded, config checks all! ✨🔐

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/polish-medium-audit-items

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mdfarhankc mdfarhankc merged commit 975ba71 into main Apr 23, 2026
6 of 7 checks passed
@mdfarhankc mdfarhankc deleted the fix/polish-medium-audit-items branch April 23, 2026 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant