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

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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

Table of Contents


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 with DaisyUI components integrated for consistent theme application
  • Local timezone support
  • Multilingual interface with automatic translation via GPT-PO Translator
  • Status endpoint for healthcheck and version
  • Integrated version check with GitHub release comparison and 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
  • Table/Card view preference is saved per module via localStorage for persistent view selection (e.g., Messages, Emails, Reminders, & Users)
  • Modular partial layout: all list views (emails, messages, reminders, Apprise, webhooks) use shared table_view.html, card_view.html, actions.html, and help_panel.html partials for maintainability
  • Context-sensitive help panels for each major module
  • Dashboard with equal-height cards showing reminders, emails, messages, Apprise, webhooks, and SMTP at a glance
  • Dedicated Schedule tab showing all enabled items and their configured run times
  • Activity tab displaying filtered logs of recent user actions and system events
  • Shared UI components and actions ensure consistency across table and card views
  • Progressive Web App (PWA) support: installable manifest, service worker registration, offline metadata caching, and mobile/desktop home screen integration. Requires HTTPS and a public certificate.
  • Seamless navigation and interaction using HTMX:
    • All sidebar and profile dropdown links use HTMX for dynamic content loading
    • Add/edit/delete/cancel actions update only affected content via HTMX
    • Buttons for test/send/enable/disable are handled dynamically via HTMX and fully CSP-compliant

Accessibility & Inclusive Design

⬆ Back to Table of Contents

  • 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

Messages

⬆ Back to Table of Contents

  • Configurable notification and check-in system
  • Deliver Messages using Apprise, with support for dozens of services
  • Execute webhooks when notification grace period for checkin has expired
  • Customizable emails with optional attachments
  • Attach multiple files to emails
  • Files are loaded from /uploads at send time (edit outside Grylli)

Reminder System

⬆ Back to Table of Contents

  • 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

⬆ Back to Table of Contents

  • 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

⬆ Back to Table of Contents

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

Logging & Diagnostics

⬆ Back to Table of Contents

  • All application events are logged with context, including:
    • check-in attempts, enable/disable actions, task execution, test runs, and validation errors
    • internal exceptions are captured with full tracebacks and categorized by severity
  • Logs are written to both stdout and data/grylli.log by default
  • Admin panel includes a filterable and sortable log viewer:
    • Filter by log level, text content, and timestamp (before/after)
    • Sort by timestamp or severity column
    • HTMX-powered for live interaction without full page reload
  • Dedicated Activity tab shows recent user-facing log events tied to current user
  • CSP violation reports are captured, parsed, and logged for debugging front-end policy violations
  • Debug layout view captures DOM structure, controller bindings, loaded styles/scripts, and page metadata
  • All logging is structured for human readability and system integration
  • Debug-friendly logging helpers (log_info_message, log_exception_with_traceback) used across all routes for consistent traceability

Admin Tasks

⬆ Back to Table of Contents

  • Admin-only UI available under Tasks for executing one-time system actions
  • First task available: Manual Version Check
    • Triggers the same logic used in the scheduled update check
    • Confirms if a new Grylli release is available on GitHub
  • Fully CSP-compliant task execution and feedback via flash messages

Admin Reports

⬆ Back to Table of Contents

  • Admin-only dashboard with real-time reports and usage summaries
  • Tabbed UI with HTMX-based dynamic content loading (no full page reloads)
  • Currently available reports:
    • Accounts: Overview of all users, roles, MFA status, activity flags, and lockouts
    • Scheduler Activity: Displays execution history for scheduled items (reminders, emails, messages)
  • Uses modular partial templates and consistent DaisyUI styling
  • Reports are automatically updated with the latest activity and user status changes
  • Table views support sortable and accessible column headers

Security & Production Readiness

⬆ Back to Table of Contents

  • Email integrity is enforced on login: only users can change their own email address, preventing backend tampering
  • Sensitive credentials (e.g., SMTP passwords, Apprise tokens) and user-defined data (e.g., message subjects, email recipients, reminder text, etc.) 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

File Integrity Verification

⬆ Back to Table of Contents

  • Grylli performs a secure file integrity check on startup to ensure application files have not been tampered with.
  • A file_hashes.sha256 manifest is generated at build time, containing SHA-256 hashes for all .py, .html, and .js files in the source tree.
  • At runtime, a built-in Python script verifies these hashes against the actual files on disk.
  • If any file has been modified or added, startup is aborted, and the failure is logged.
  • This ensures administrators or malicious actors cannot modify core logic or templates without detection.
  • A scheduler task re-validates file integrity and exits if any tampering is detected.

Application Trust Model

⬆ Back to Table of Contents

  • 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

⬆ Back to Table of Contents

  • 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

⬆ Back to Table of Contents 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 was validated using Lighthouse PWA audits.


Testing & Quality Assurance

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

Test Coverage Breakdown

⬆ Back to Table of Contents

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

Total Coverage: 81%
(4977 statements, 933 currently not covered)

Test Framework

⬆ Back to Table of Contents

  • 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

Backups & Maintenance

⬆ Back to Table of Contents

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

Screenshots

⬆ Back to Table of Contents

Show Screenshots Config Tab Schedule Tab Activity Tab Linked Items Tab Admin Overview Backups Application Logs Accounts Scheduler System Settings SMTP Settings Admin Tasks User Management Messages Apprise Destinations Webhook Destinations Emails User SMTP Config Reminders

Docker Compose Configuration

⬆ Back to Table of Contents 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 protected] \
  -e [email protected] \
  -e SMTP_PASS=your_password_or_app_token \
  --restart unless-stopped \
  ghcr.io/samcro1967/grylli

Environment Variables

⬆ Back to Table of Contents

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 [email protected]
SMTP_USER SMTP authentication username [email protected]
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

⬆ Back to Table of Contents

Frontend & UI

⬆ Back to Table of Contents

  • 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
  • DaisyUI — Plugin for TailwindCSS that provides pre-designed components
  • SVGBackgrounds — Open-source SVG background patterns used in the theme-aware background selector
  • PostCSS — CSS transformation engine used in Tailwind’s build pipeline
  • Autoprefixer — Adds vendor prefixes to CSS rules automatically

Integrations & Features

⬆ Back to Table of Contents

  • 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

⬆ Back to Table of Contents

  • 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

⬆ Back to Table of Contents

  • 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

⬆ Back to Table of Contents