How to Customize the Minimal Admin Panel Provided by CRUDAdmin in FastAPI Boilerplate
Customize the CRUDAdmin panel in benavlabs/fastapi-boilerplate by editing CRUDAdminSettings in src/app/core/config.py for global behavior and modifying register_admin_views in src/app/admin/views.py to control which models appear and how they behave.
The benavlabs/fastapi-boilerplate repository ships with a lightweight, production-ready admin interface powered by the CRUDAdmin library. This minimal admin panel provides instant CRUD capabilities for your SQLAlchemy models without requiring a separate frontend build step. Understanding how to customize the minimal admin panel provided by CRUDAdmin allows you to tailor the interface to your security requirements, data models, and deployment environment.
Understanding the CRUDAdmin Architecture
The admin interface is constructed through three primary files that handle configuration, instantiation, and model registration.
In src/app/core/config.py, the CRUDAdminSettings class defines global toggles such as CRUD_ADMIN_ENABLED, CRUD_ADMIN_MOUNT_PATH, and security policies including IP restrictions and session limits.
The create_admin_interface() function in src/app/admin/initialize.py reads these settings and constructs the CRUDAdmin instance, wiring it to the async database session and optional Redis backend.
Finally, src/app/admin/views.py contains the register_admin_views() function, which calls admin.add_view() for each SQLAlchemy model you want to expose, specifying Pydantic schemas for create and update operations, allowed actions, and optional password handling.
Customizing Global Settings
All global configuration lives in the CRUDAdminSettings section of src/app/core/config.py. Changes take effect immediately on the next application startup.
Enable or Disable the Admin Panel
Set CRUD_ADMIN_ENABLED to False to completely disable the admin interface without removing any code:
class CRUDAdminSettings(BaseSettings):
CRUD_ADMIN_ENABLED: bool = False
Change the Mount Path and URL
By default, the panel mounts at /admin. Modify CRUD_ADMIN_MOUNT_PATH to relocate it:
CRUD_ADMIN_MOUNT_PATH: str = "/dashboard"
Configure Redis-Backed Sessions
By default, CRUDAdmin uses in-memory sessions. For production deployments with multiple replicas, enable Redis:
CRUD_ADMIN_REDIS_ENABLED: bool = True
CRUD_ADMIN_REDIS_HOST: str = "redis.example.com"
CRUD_ADMIN_REDIS_PORT: int = 6379
Restrict Access by IP and Network
Limit admin access to specific addresses using CIDR notation or individual IPs:
CRUD_ADMIN_ALLOWED_IPS_LIST: list[str] = ["127.0.0.1", "10.0.0.5"]
CRUD_ADMIN_ALLOWED_NETWORKS_LIST: list[str] = ["192.168.1.0/24", "10.0.0.0/8"]
Registering and Configuring Models
The register_admin_views function in src/app/admin/views.py controls which SQLAlchemy models appear in the admin interface and what operations are permitted.
Adding New Models to the Admin Panel
To expose a new model, import it along with its Pydantic schemas and call admin.add_view():
from ..models.comment import Comment
from ..schemas.comment import CommentCreate, CommentUpdate
admin.add_view(
model=Comment,
create_schema=CommentCreate,
update_schema=CommentUpdate,
allowed_actions={"view", "create", "update", "delete"},
)
Customizing Allowed Actions
Restrict operations by passing a subset of actions to allowed_actions. For read-only access, use only "view":
admin.add_view(
model=Tag,
create_schema=TagRead,
update_schema=TagRead,
allowed_actions={"view"},
)
Configuring Password Hashing with PasswordTransformer
For models storing passwords, use PasswordTransformer to automatically hash plain text before persistence. In src/app/admin/views.py, the transformer is configured as:
password_transformer = PasswordTransformer(
password_field="password",
hashed_field="hashed_password",
hash_function=get_password_hash,
required_fields=["name", "username", "email"],
)
To require additional fields during user creation, append them to required_fields:
required_fields=["name", "username", "email", "phone"],
Securing the Admin Interface
Security configurations are split between CRUDAdminSettings in config.py and the initialization logic in initialize.py.
Session Limits and Timeouts
Control concurrent access and idle timeouts:
CRUD_ADMIN_MAX_SESSIONS: int = 3 # Max concurrent sessions per user
CRUD_ADMIN_SESSION_TIMEOUT: int = 3600 # Seconds until logout (1 hour)
HTTPS Enforcement and Secure Cookies
In production, enforce HTTPS and secure cookie flags:
SESSION_SECURE_COOKIES: bool = True
The initialize.py file automatically sets enforce_https=True when ENVIRONMENT is PRODUCTION:
enforce_https=settings.ENVIRONMENT == EnvironmentOption.PRODUCTION,
Setting Initial Admin Credentials
The first admin user is created automatically when the panel is first accessed. Configure credentials via FirstUserSettings in config.py or environment variables:
ADMIN_USERNAME: str = "admin"
ADMIN_PASSWORD: str = "changeme"
These values populate the initial_admin argument in CRUDAdmin construction within initialize.py.
Summary
- Global behavior is controlled through
CRUDAdminSettingsinsrc/app/core/config.py, including enable/disable toggles, mount paths, Redis sessions, and IP restrictions. - Model exposure is managed in
src/app/admin/views.pyviaadmin.add_view(), where you specify SQLAlchemy models, Pydantic schemas, allowed actions, and password transformers. - Security hardening involves setting session limits, HTTPS enforcement, and initial admin credentials in
config.py, whichinitialize.pyapplies duringCRUDAdmininstantiation.
Frequently Asked Questions
How do I completely disable the CRUDAdmin panel?
Set CRUD_ADMIN_ENABLED = False in the CRUDAdminSettings class within src/app/core/config.py. This prevents the admin interface from mounting without requiring any code changes to the view registrations.
Can I use a different Pydantic schema for creating versus updating a model?
Yes. When calling admin.add_view() in src/app/admin/views.py, pass distinct schemas to the create_schema and update_schema parameters. This allows you to require additional fields during creation while keeping update operations flexible.
Where do I configure Redis for session persistence?
Enable Redis in src/app/core/config.py by setting CRUD_ADMIN_REDIS_ENABLED = True and providing CRUD_ADMIN_REDIS_HOST and CRUD_ADMIN_REDIS_PORT. The create_admin_interface() function in src/app/admin/initialize.py automatically wires the Redis backend to the CRUDAdmin instance.
How do I restrict admin access to specific IP addresses?
Use the CRUD_ADMIN_ALLOWED_IPS_LIST and CRUD_ADMIN_ALLOWED_NETWORKS_LIST settings in src/app/core/config.py. These accept lists of IP addresses or CIDR notation networks, which initialize.py passes to the CRUDAdmin constructor to enforce access control at the middleware level.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →