Policy Enforcement Guide

Overview

This guide explains how APort policy enforcement works, what users need to set in their passports, and how the GitHub Actions showcase the full scope of policy features.

How Policy Enforcement Works

1. Policy Definition (policies/code.repository.merge.v1/policy.json)

{
  "enforcement": {
    "allowed_repos_enforced": true,
    "allowed_base_branches_enforced": true,
    "path_allowlist_enforced": true,
    "size_limits_enforced": true,
    "review_requirements_enforced": false,
    "github_actor_enforced": true,
    "github_app_enforced": true

  }
}

2. Enforcement Logic (functions/api/verify/policy/[pack_id].ts)

The enforcement is OPTIONAL and GRACEFUL:

  • If a limit is NOT set in passport → NO CHECK PERFORMED āœ…
  • If a limit IS set in passport → CHECK IS PERFORMED āœ…
  • If enforcement rule is false → CHECK IS SKIPPED āœ…

Review counts and required labels are handled by GitHub branch protection or
repository rules today. APort hosted verification enforces passport-scoped
repository, branch, path, size, actor/app/workflow allowlist, and evidence
checks, then records a signed decision.

3. User Passport Requirements

Users do NOT need to set all options. The system is designed to be flexible:

Minimal Passport (works fine):

{
  "agent_id": "agt_123",
  "limits": {
    "max_prs_per_day": 10,
    "max_merges_per_day": 5
  }
}

Result: Only PR count limits are enforced. Repository/branch/path restrictions are ignored.

Full Passport (all restrictions):

{
  "agent_id": "agt_123", 
  "limits": {
    "max_prs_per_day": 10,
    "max_merges_per_day": 5,
    "max_pr_size_kb": 1000,
    "allowed_repos": ["owner/repo1", "owner/repo2"],
    "allowed_base_branches": ["main", "develop"],
    "allowed_paths": ["src/", "docs/"]
  },
  "integrations": {
    "github": {
      "allowed_actors": ["my-bot[bot]", "acme-ci"],
      "allowed_apps": ["my-github-app"]
    }
  }
}

Result: All APort-supported restrictions are enforced. Review counts and
required labels still belong in GitHub branch protection or repository rules.

TypedLimits Interface

The TypedLimits interface now includes all policy enforcement fields:

export interface TypedLimits {
  // Numeric limits
  max_prs_per_day?: number;
  max_merges_per_day?: number;
  max_pr_size_kb?: number;
  
  // Array limits (for allowlists)
  allowed_repos?: string[];
  allowed_base_branches?: string[];
  allowed_paths?: string[];
  
  // Other existing limits...
  refund_amount_max_per_tx?: number;
  max_export_rows?: number;
  allow_pii?: boolean;
  // ... etc
}

GitHub Action Context Mapping

The GitHub Action now maps comprehensive context to enable full policy enforcement:

GitHub Context APort Context Policy Enforcement
github.repository repo Repository allowlist
github.event.pull_request.base.ref base_branch Base branch allowlist
github.actor github_actor GitHub actor allowlist
github.app github_app GitHub app allowlist
Computed diff stats files_changed, lines_added Change statistics
PR size calculation pr_size_kb Size limits
Changed file paths file_paths Path allowlist
PR labels labels Evidence context only
Review count reviews Evidence context only

Policy Enforcement Examples

Example 1: Repository Allowlist

// Passport
{
  "limits": {
    "allowed_repos": ["owner/repo1", "owner/repo2"]
  }
}

// Context
{
  "repo": "owner/repo3"  // āŒ Not in allowlist
}

// Result: BLOCKED - "Agent does not have access to repository owner/repo3"

Example 2: Path Allowlist

// Passport
{
  "limits": {
    "allowed_paths": ["src/", "docs/"]
  }
}

// Context
{
  "file_paths": ["src/main.js", "config/secrets.json"]  // āŒ secrets.json not allowed
}

// Result: BLOCKED - "Agent not authorized to access paths: config/secrets.json"

Example 3: Size Limits

// Passport
{
  "limits": {
    "max_pr_size_kb": 1000
  }
}

// Context
{
  "pr_size_kb": 1500  // āŒ Exceeds limit
}

// Result: BLOCKED - "PR size 1500KB exceeds limit of 1000KB"

Example 4: No Restrictions (Minimal Passport)

// Passport
{
  "limits": {
    "max_prs_per_day": 10
    // No other limits set
  }
}

// Context
{
  "repo": "any/repo",
  "base_branch": "any-branch",
  "file_paths": ["any/file.js"]
}

// Result: ALLOWED - Only PR count is enforced, other restrictions ignored

Passport Path Overrides for Command Validation

The system.command.execute.v1 policy includes built-in security patterns that block access to sensitive paths (e.g. /etc/, /proc/, hidden files). Passport owners can override path-sensitivity heuristics using allowed_paths:

{
  "limits": {
    "allowed_paths": ["/root/", "/home/agent/"],
    "allowed_commands": ["*"]
  }
}

When a command references a path in allowed_paths, overridable rules are skipped (e.g. "Access to sensitive system directories"). Catastrophic protections — fork bombs, rm -rf /, reverse shells, nc/netcat, find -exec rm — can never be overridden by passport config.

Overridable rules include: sensitive system directories, sensitive hidden files, credential files, secrets files, network exfiltration heuristics, permission manipulation, password manager databases, log files, and clipboard access.

Key Benefits

  1. Flexible: Users can set as many or as few restrictions as needed
  2. Type Safe: All limits are properly typed in TypeScript
  3. Comprehensive: GitHub Action maps all relevant context
  4. Graceful: Missing limits don't cause errors, they're simply ignored
  5. Extensible: Easy to add new enforcement rules
  6. Overridable: Path-sensitivity heuristics can be customized per passport without weakening catastrophic protections

Testing

The system has been tested with real API calls and works correctly:

  • āœ… Policy verification endpoint responds properly
  • āœ… Context mapping works for all enforcement rules
  • āœ… Type safety is maintained
  • āœ… Graceful handling of missing limits
  • āœ… Comprehensive error messages

Conclusion

The policy enforcement system is now complete and showcases the full scope of the code.repository.merge.v1 policy. Users can create minimal passports for basic functionality or comprehensive passports for full security, and the system will enforce only the restrictions they've configured.