Getting Started
Set up your first PolicyFlow project
Welcome to PolicyFlow! This guide will help you set up your first project and write your first authorization policy.
Project Structure
A typical PolicyFlow project has the following structure:
my-project/
├── .env # Environment variables (optional)
├── schemas/ # Schema definitions
│ ├── auth.pfs
│ └── resources.pfs
├── policies/ # Policy files
│ ├── document-access.pf
│ └── admin-access.pf
└── tests/ # Test files
├── document-access.pftest
└── admin-access.pftest
Your First Schema
Let's start by defining a simple schema for users and documents:
schema BasicSchema {
// Define a User type
User type AppUser {
id: UUID
email: Email
name: String
roles: String[]
isActive: Boolean = true
}
// Define a Resource type
Resource type Document {
id: UUID
title: String
ownerId: UUID
classification: String
createdAt: DateTime
}
// Define a Context type
Context type RequestContext {
ipAddress: IPAddress
timestamp: DateTime = DateTime.Now()
}
}
Your First Policy
Now let's create a simple policy that uses this schema:
import * as Basic from "@/schemas/basic.pfs:BasicSchema";
policy DocumentAccess {
description: "Controls access to documents based on ownership and classification"
version: "1.0.0"
// Specify which types this policy applies to
schemas {
User from Basic.AppUser
Resource from Basic.Document
Context from Basic.RequestContext
}
// Define the authorization rules
rules {
// Rule 1: Owners can always access their documents
rule OwnerAccess {
when user.id == resource.ownerId
then ALLOW
reason: "Document owner has full access"
}
// Rule 2: Active users can read public documents
rule PublicDocumentAccess {
when user.isActive
AND resource.classification == "Public"
AND action == "read"
then ALLOW
reason: "Active users can read public documents"
}
// Rule 3: Users with admin role can access everything
rule AdminAccess {
when "admin" in user.roles
then ALLOW
priority: 1000
reason: "Administrators have full access"
}
}
}
Testing Your Policy
Let's write tests to ensure our policy works correctly:
import * as DocPolicy from "@/policies/document-access.pf";
test DocumentAccessTests for DocPolicy {
// Test Case 1: Owner can access their document
case "Document owner should have access" {
given {
user: {
id: "user-123",
email: "owner@example.com",
name: "Document Owner",
roles: ["user"],
isActive: true
}
resource: {
id: "doc-456",
title: "My Document",
ownerId: "user-123",
classification: "Confidential",
createdAt: DateTime.Parse("2025-06-01T00:00:00Z")
}
context: {
ipAddress: "192.168.1.1"
}
action: "read"
}
expect: ALLOW
reason: "Document owner has full access"
}
// Test Case 2: Non-owner cannot access confidential document
case "Non-owner should be denied access to confidential document" {
given {
user: {
id: "user-789",
email: "other@example.com",
name: "Other User",
roles: ["user"],
isActive: true
}
resource: {
id: "doc-456",
title: "Confidential Document",
ownerId: "user-123",
classification: "Confidential",
createdAt: DateTime.Parse("2025-06-01T00:00:00Z")
}
context: {
ipAddress: "192.168.1.2"
}
action: "read"
}
expect: DENY
}
// Property-based test
property "Inactive users should never have access" {
for User where !(user?.isActive ?? false)
for Resource
for Context
for Action
expect: DENY
}
}
Running Your Policies
Once you've written your schemas, policies, and tests, you can:
- Validate your policies for syntax errors
- Run tests to ensure your logic is correct
- Deploy your policies to your authorization service
What's Next?
Now that you've created your first PolicyFlow project, explore these topics: