Flutter Policy Engine

Pub Version License: MIT Flutter

A lightweight, extensible policy engine for Flutter applications. Define, manage, and evaluate access control rules declaratively using ABAC (Attribute-Based Access Control) or RBAC (Role-Based Access Control) models with a clean, intuitive API.

✨ Features

  • πŸ” Dual Access Control Models: Support for both Role-Based (RBAC) and Attribute-Based (ABAC) access control
  • 🎯 Declarative Policy Definitions: Define access rules using simple, readable configurations
  • πŸ“ JSON Asset Loading: Load policies from external JSON files bundled with your app
  • πŸ—οΈ Modular Architecture: Extensible design with clear separation of concerns
  • ⚑ Lightweight & Fast: Minimal overhead with efficient policy evaluation
  • πŸ”„ Real-time Updates: Dynamic policy updates without app restarts
  • 🎨 Flutter-Native: Built specifically for Flutter with widget integration
  • πŸ“± Easy Integration: Simple setup with minimal boilerplate code
  • πŸ§ͺ Comprehensive Testing: Full test coverage with examples
  • πŸ›‘οΈ Robust Error Handling: Structured exception handling with detailed context

πŸš€ Quick Start

Installation

Add the package to your pubspec.yaml:

dependencies:
  flutter_policy_engine: ^1.1.0

Run the installation:

flutter pub get

Basic Usage

import 'package:flutter/material.dart';
import 'package:flutter_policy_engine/flutter_policy_engine.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize policy manager
  final policyManager = PolicyManager();
  await policyManager.initialize({
    "admin": ["dashboard", "users", "settings", "reports"],
    "manager": ["dashboard", "users", "reports"],
    "user": ["dashboard"],
    "guest": ["login"]
  });

  runApp(MyApp(policyManager: policyManager));
}

class MyApp extends StatelessWidget {
  final PolicyManager policyManager;

  const MyApp({super.key, required this.policyManager});

  @override
  Widget build(BuildContext context) {
    return PolicyProvider(
      policyManager: policyManager,
      child: MaterialApp(
        title: 'Policy Engine Demo',
        home: HomePage(),
      ),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Dashboard')),
      body: Column(
        children: [
          // Only show for admin and manager roles
          PolicyWidget(
            role: "admin",
            content: "users",
            child: UserManagementCard(),
            fallback: AccessDeniedWidget(),
          ),

          // Show for all authenticated users
          PolicyWidget(
            role: "user",
            content: "dashboard",
            child: DashboardCard(),
          ),
        ],
      ),
    );
  }
}

Loading Policies from JSON Assets

You can also load policies from JSON files bundled with your app:

// Add to pubspec.yaml
flutter:
  assets:
    - assets/policies/

// Create assets/policies/user_roles.json
{
  "admin": {
    "allowedContent": ["dashboard", "users", "settings", "reports"]
  },
  "manager": {
    "allowedContent": ["dashboard", "users", "reports"]
  },
  "user": {
    "allowedContent": ["dashboard"]
  }
}

// Initialize from JSON asset
final policyManager = PolicyManager();
await policyManager.initializeFromJsonAssets('assets/policies/user_roles.json');

πŸ“š Core Concepts

Policy Manager

The central orchestrator that manages all access control logic:

final policyManager = PolicyManager();

// Initialize with role definitions
await policyManager.initialize({
  "admin": ["dashboard", "users", "settings"],
  "user": ["dashboard"],
});

// Check access programmatically
bool hasAccess = policyManager.evaluateAccess("admin", "users"); // true
bool canAccess = policyManager.evaluateAccess("user", "settings"); // false

Policy Widget

Conditionally render content based on user roles:

PolicyWidget(
  role: "admin",
  content: "settings",
  child: SettingsPage(),
  fallback: AccessDeniedWidget(),
)

Role Management

Create and manage roles dynamically:

// Add a new role
await policyManager.addRole("moderator", ["dashboard", "comments"]);

// Update existing role
await policyManager.updateRole("user", ["dashboard", "profile"]);

// Remove a role
await policyManager.removeRole("guest");

πŸ§ͺ Testing

Local Testing

Run tests with coverage:

# Using the provided script (recommended)
./scripts/test_with_coverage.sh

# Or manually
fvm flutter test --coverage
lcov --summary coverage/lcov.info
genhtml coverage/lcov.info -o coverage/html
open coverage/html/index.html

GitHub Actions Testing

Test GitHub Actions workflows locally before pushing to GitHub:

# Install dependencies (first time only)
./scripts/install_dependencies.sh

# Test a specific workflow
./scripts/test_github_actions.sh -w .github/workflows/check-commits.yml --dry-run

# List available workflows
./scripts/test_github_actions.sh --list-workflows

# Test with verbose output
./scripts/test_github_actions.sh -w .github/workflows/main-branch-pipeline.yml -v

Features:

  • 🐳 Docker-based local testing with act
  • πŸ” Workflow validation and syntax checking
  • πŸ§ͺ Dry-run mode for safe testing
  • πŸ“‹ Comprehensive workflow coverage
  • πŸ› οΈ Automatic dependency management

For detailed usage, see GitHub Actions Testing Guide.

Example App

Explore the interactive example app with multiple demos:

cd example
flutter run

The example includes:

🎯 Basic Policy Demo

  • Core policy evaluation demonstrations
  • Real-time access control testing
  • Widget-based permission checking

πŸ‘₯ Role Management Demo

  • Dynamic role creation and modification
  • Interactive role testing interface
  • Real-time policy updates

πŸ“ JSON Assets Demo

  • Loading policies from external JSON files
  • Asset-based configuration management
  • Comprehensive permission testing

πŸ“š Documentation

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/aspicas/flutter_policy_engine.git
cd flutter_policy_engine

# Run the setup script
./setup.sh

# Run tests
./scripts/test_with_coverage.sh

Code Style

  • Follow the existing code patterns and style
  • Write clear commit messages (Commitlint enabled)
  • Add tests for new features
  • Ensure all tests pass before submitting PRs

πŸ“„ License

MIT Β© 2025 David Alejandro Garcia Ruiz


πŸ’‘ Tip: If you use VSCode, restart your terminal after setup to ensure FVM is properly detected.