Skip to content

Secure, CSP-compliant Flask web app for managing reminders, email alerts, notifications, and user accounts.

License

Notifications You must be signed in to change notification settings

samcro1967/grylli

Repository files navigation

Grylli Logo

Grylli

Grylli is a secure, self-hosted message delivery platform that automatically sends pre-configured notifications if a user fails to check in within a defined time period.


Container Image Version License

Features

πŸš€ Core Application

  • Self-hosted Flask web application with user authentication
  • Responsive UI built with Tailwind CSS
  • Frontend interactivity powered by Stimulus.js for minimal, CSP-compliant JavaScript
  • Light and dark mode support
  • Local timezone support
  • Multilingual interface
  • Automatic translation support using GPT-PO Translator for rapid language expansion
  • Status endpoint for healthcheck and version
  • Integrated version check with GitHub release comparison with automated scheduler updates
  • Language selection toggle with per-user preference and locale-aware interface
  • Fixed sidebar and header layout with scrollable main content for consistent UX
  • Extensive internal logging for traceable execution and graceful failure handling
  • Detects and applies browser language on first visit before user login
  • Context-sensitive help panels for each major module
  • Shared UI components and actions for consistent interactions across modules
  • Progressive Web App (PWA) support with installable manifest, service worker registration, offline metadata caching, and home screen integration on mobile and desktop
  • Seamless Navigation with HTMX. All sidebar and profile dropdown links now use HTMX for dynamic navigation. Prevents full-page reloads and avoids sidebar collapse/reflow

β™Ώ Accessibility & Inclusive Design

  • Grylli has undergone a thorough accessibility audit using pa11y and manual contrast verification.
  • Main pages (login, signup, dashboard, reminders, emails, messages, settings) have been remediated for WCAG 2.1 AA compliance
  • All forms include semantic labels, ARIA feedback, and keyboard-accessible controls
  • High-contrast themes and visible focus styles are built-in
  • No inline JavaScript or event handlers (CSP-compliant)
  • No CAPTCHAs or visual-only barriers; public routes are rate-limited instead
  • ⚠️ Minor, non-blocking color contrast issues (e.g. emoji/icons) are acknowledged

πŸ”” Notifications & Messaging

  • Configurable notification and check-in system
  • Send notifications via apprise Apprise destinations
  • Execute webhooks when notification grace period for checkin has expired
  • Customizable emails with optional attachments
  • Attach multiple files to emails
  • Files are loaded from disk at send time (edit outside Grylli)

⏰ Reminder System

  • Create reminders with labels, subjects, and rich scheduling options
  • Assign email, webhook, and Apprise destinations to each reminder
  • Optional test-send for validation of all linked services
  • Schedule single or recurring reminders (daily, weekly, monthly, etc.)
  • Toggle reminders on/off dynamically from the UI

πŸ‘€ User Management & Access Control

  • Multi-admin and multi-user support
  • Role-based access control (RBAC) with user/admin privileges
  • MFA using TOTP apps (e.g. Google Authenticator) with recovery codes
  • MFA reset and recovery options for both users and admins
  • Admin protection from self-demotion and critical privilege changes
  • Sign-up with registration code
  • Forgot username and password recovery flows
  • User actions to export their data and delete their account

πŸ“§ Email & Integrations

  • Global SMTP settings for system-level notifications
  • User-specific SMTP settings for personalized delivery

πŸ›‘οΈ Security & Production Readiness

  • Sensitive credentials (e.g., SMTP passwords, Apprise tokens) are encrypted at rest using Fernet symmetric encryption
  • Fully Content Security Policy (CSP) compliant: dynamic nonces, no inline scripts or handlers, no .innerHTML
  • Frontend entirely refactored to use Stimulus.js controllers instead of Alpine.js or inline JavaScript
  • Password and token reveal functionality is CSP-safe with strict event handling
  • Admin routes are tightly permission-controlled with automatic role enforcement
  • All public forms and inputs validated server-side using secure WTForms
  • App-level logging captures all sensitive operations, errors, and admin events without exposing secrets
  • Enforces complex passwords
  • Runs as non-root using PUID/PGID
  • Reverse proxy ready (base_url support)
  • Runs in a minimal distroless container for production, reducing attack surface and image size
  • Python sources are precompiled to .pyc files for faster startup and to reduce accidental code exposure in the image
  • Rate limiting on failed logins and sign up
  • Additional HTTP security headers: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, frame-ancestors: 'none' to mitigate common web vulnerabilities
  • Account lockout enforced after repeated failed login attempts, with automatic unlock after a delay
  • Modular view architecture using partials for cleaner maintenance and CSP compliance
  • CAPTCHA-free signup flow with soft rate limiting for better UX and accessibility

πŸ›‘οΈ Application Trust Model

  • Grylli is designed with privacy and control in mind.
  • Users retain full control over their check-in schedules, messages, and delivery methods.
  • All sensitive user data β€” including email passwords, Apprise tokens, and webhook URLs β€” is encrypted before being stored.
  • Administrators cannot view stored credentials or plaintext tokens.
  • No external telemetry, analytics, or phone-home behavior is present.
  • Users can export or delete their data at any time.

βœ… Security Checklist

  • Passwords and secrets encrypted at rest
  • CSP-compliant templates and JavaScript (no inline scripts or handlers)
  • Rate-limited login, signup, and reset flows
  • MFA with TOTP and recovery support
  • Role-based route protections (admin vs. user)
  • Admin safeguards (no self-demotion)
  • Secure form validation with CSRF and ARIA feedback
  • Optional backup and deletion workflows
  • Automatic account lockout after repeated failed logins
  • CSP Violation Reporting: Server now captures and logs CSP violations

🌟 Lighthouse Audit Results

Grylli has been tested with Google Lighthouse across all major modules, achieving:

Metric Average Score
Performance 96
Accessibility 99
Best Practices 93
SEO 100

All primary user-facing and administrative pages meet or exceed Lighthouse guidelines.
Installability and offline support were validated using Lighthouse PWA audits.

βœ… Minor performance warnings on public login and signup pages are acknowledged (e.g. layout shift, unauthenticated CSS/JS) and do not affect core UX.


βœ… Testing & Quality Assurance

Grylli has a comprehensive test suite covering the platform's core features, ensuring the stability, security, and functionality of all workflows.

πŸ“Š Test Coverage Breakdown

βœ… Test Coverage Summary

Module Coverage
Auth Routes 65%
Admin Panels 68%
Reminder Logic 83%
Email Workflows 68%
Apprise & Webhooks 76%
Backup & Restore 78%
MFA Setup & Reset 80%
Account Management 74%
CSP Compliance 100%
Public Pages 100%
Version Metadata 100%
Route Permissions 100%

Total Coverage: 78% (4017 statements, 893 currently not covered)

πŸ§ͺ Test Framework

  • Written using pytest
  • Uses SQLAlchemy 2.x-style db.session.get() methods
  • Mocks all external calls (email, encryption, login state) for safe, fast test runs
  • Enforces role-based access control through simulated admin/user scenarios
  • Coverage includes flash messages, status codes, and failure paths

What's Next:

  • Increase coverage for email workflows, scheduler logic, and admin panels to ensure complete reliability across the application.
  • Expand tests for webhooks and Apprise notifications, which are vital for communication flows.

πŸ’Ύ Backups & Maintenance

  • Automated daily database backups (7-day retention)
  • On-demand backup option

Screenshots

Show Screenshots My Screenshot My Screenshot My Screenshot My Screenshot My Screenshot My Screenshot

Docker Compose Configuration

docker-compose.sample.yml

If you prefer not to use Docker Compose, you can run Grylli with a single command:

Show Docker Run Command
docker run -d \
  --name grylli \
  -p 5069:5069 \
  -v $(pwd)/grylli/data:/data \
  -v $(pwd)/grylli/uploads:/uploads \
  -e TZ=America/Chicago \
  -e PUID=1000 \
  -e PGID=1000 \
  -e GRYLLI_DATA_DIR=/data \
  -e DEBUG=False \
  -e FQDN=http://your.domain.com:5069 \
  -e BASE_URL=/grylli \
  -e FLASK_APP_PORT=5069 \
  -e FLASK_APP_KEY=changeme-supersecret-key \
  -e FERRET_KEY=changeme-fernet-key \
  -e SIGNUP_CODE=YourSuperSecretCode123! \
  -e DEFAULT_LANGUAGE=en \
  -e SMTP_HOST=smtp.example.com \
  -e SMTP_PORT=587 \
  -e SMTP_USE_TLS=1 \
  -e EMAIL_FROM=you@example.com \
  -e SMTP_USER=you@example.com \
  -e SMTP_PASS=your_password_or_app_token \
  --restart unless-stopped \
  ghcr.io/samcro1967/grylli

Environment Variables

Show Environment Variables
Variable Description Example/Notes
TZ Timezone for the container America/Chicago
PUID User ID for container process (for volume permissions) 1000
PGID Group ID for container process 1000
GRYLLI_DATA_DIR Directory for persistent data inside the container /data
DEBUG Enable or disable debug mode False (use True for debugging)
FQDN Public base URL of your Grylli instance http://your.domain.com:5069
BASE_URL Base URL path for Grylli (use /grylli or /) /grylli
FLASK_APP_PORT Port Grylli listens on inside the container 5069
FLASK_APP_KEY Secret key for Flask session security (generate a secure random string)
FERRET_KEY Encryption key for sensitive data (Fernet, 32-byte base64 string) (generate with Fernet)
SIGNUP_CODE Registration code required for new sign-ups YourSuperSecretCode123!
DEFAULT_LANGUAGE Default language code en
SMTP_HOST SMTP server hostname smtp.example.com
SMTP_PORT SMTP server port 587 (for TLS), 465 (for SSL)
SMTP_USE_TLS Use TLS for SMTP connection (1 for yes, 0 for no) 1
EMAIL_FROM Default sender email address you@example.com
SMTP_USER SMTP authentication username you@example.com
SMTP_PASS SMTP authentication password or app token your_password_or_app_token

Note: See docker-compose.sample.yml for instructions on how to generate your own FLASK_APP_KEY and FERRET_KEY.


Credits & Key Dependencies

🧠 Core Backend

  • Flask β€” Python web framework
  • Flask-WTF β€” Secure web forms with CSRF protection
  • Flask-Login β€” User session and authentication management
  • Flask-Migrate β€” Database migrations powered by Alembic
  • Flask-Babel β€” Internationalization (i18n) and localization
  • APScheduler β€” Advanced Python scheduling
  • email-validator β€” Email address validation
  • cryptography β€” Secure encryption for sensitive data at rest
  • PyOTP β€” Time-based one-time passwords for MFA
  • python-dateutil β€” Advanced datetime parsing and timezone handling
  • polib β€” PO file management for localization workflows
  • GPT-PO Translator β€” Automated PO file translation with GPT

🎨 Frontend & UI

  • Stimulus β€” Lightweight JavaScript framework for CSP-compliant interactivity
  • HTMX β€” Dynamic HTML-over-the-wire interactivity without custom JavaScript
  • Tailwind CSS β€” Utility-first CSS framework for responsive, accessible UI
  • PostCSS β€” CSS transformation engine used in Tailwind’s build pipeline
  • Autoprefixer β€” Adds vendor prefixes to CSS rules automatically

πŸ“¦ Integrations & Features

  • Apprise β€” Notification delivery to dozens of services
  • htmx-extensions: safe-nonce β€” HTMX extension for CSP nonce propagation
  • Critical β€” Extracts and inlines critical-path CSS for faster first paint
  • Pa11y β€” Automated accessibility testing and validation

βš™οΈ Runtime & Deployment

  • gunicorn β€” Production Python WSGI server
  • Docker β€” Containerized application deployment (distroless)
  • Clean-CSS CLI β€” CSS minifier for optimized production output
  • Terser β€” JavaScript minifier used in production builds

πŸ§ͺ Testing, Auditing & Code Quality

  • pytest β€” Python test framework
  • pytest-cov β€” Coverage reporting plugin for pytest
  • black β€” Opinionated Python code formatter
  • isort β€” Python import sorter
  • pylint β€” Static code analysis for Python
  • djlint β€” Linter and formatter for Jinja2 templates
  • Lighthouse β€” Performance, accessibility, and SEO auditing for web apps
  • OWASP ZAP β€” Automated security scanning and penetration testing

Special thanks to these libraries and their maintainers for powering Grylli.


Recommended Third-Party Services

Releases

No releases published

Packages