Skip to main content

Three-Tier Policy Hierarchy

AxonFlow's policy architecture uses a three-tier hierarchy that balances security defaults with customization flexibility.

Tier Overview

┌────────────────────────────────────────────────────────────────────┐
│ SYSTEM TIER │
│ • 63 policies (53 static + 10 dynamic) │
│ • Managed by AxonFlow │
│ • Cannot modify patterns/conditions │
│ • Can override action (Enterprise only) │
├────────────────────────────────────────────────────────────────────┤
│ ORGANIZATION TIER │
│ • Enterprise only │
│ • Applies to all tenants in the organization │
│ • Full CRUD operations │
│ • Can disable system policies for the org │
├────────────────────────────────────────────────────────────────────┤
│ TENANT TIER │
│ • Available in all editions │
│ • Team-specific customizations │
│ • Full CRUD operations │
│ • Inherits from org and system │
└────────────────────────────────────────────────────────────────────┘

Policy Resolution

When evaluating a request, AxonFlow merges policies from all tiers into an effective policy set:

  1. System policies are loaded first
  2. Organization policies are merged (can override system)
  3. Tenant policies are merged (can override org)
  4. Policies are sorted by priority (higher first)
  5. First matching policy determines the action

Resolution Rules

ScenarioResult
Same pattern at different tiersLower tier wins (tenant > org > system)
System policy disabled at org levelPolicy is excluded for all org tenants
Org policy disabled at tenant levelPolicy is excluded for that tenant only
Conflicting actionsLower tier's action is used

System Tier

System policies provide security and compliance coverage out-of-the-box. They are immutable - you cannot modify the detection patterns.

Categories

CategoryTypeCountDescription
security-sqliStatic37SQL injection patterns
security-adminStatic4Admin access control
pii-globalStatic7Universal PII detection
pii-usStatic2US-specific PII (SSN, bank accounts)
pii-euStatic1EU-specific PII (IBAN)
pii-indiaStatic2India-specific PII (PAN, Aadhaar)
dynamic-riskDynamic2Risk-based policies
dynamic-complianceDynamic3HIPAA, GDPR, PCI-DSS
dynamic-securityDynamic2Tenant isolation
dynamic-costDynamic2Cost optimization
dynamic-accessDynamic1Data access control

Viewing System Policies

// List all system policies
const systemPolicies = await client.listStaticPolicies({
tier: 'system'
});

// Filter by category
const sqliPolicies = await client.listStaticPolicies({
tier: 'system',
category: 'security-sqli'
});
# REST API
curl -X GET "http://localhost:8080/api/v1/static-policies?tier=system" \
-H "X-Tenant-ID: my-tenant"

Organization Tier (Enterprise)

Enterprise Feature

Organization-tier policies require an Enterprise license.

Organization policies apply to all tenants within your organization. Use them for:

  • Company-wide security standards
  • Compliance requirements that apply to all teams
  • Disabling system policies that don't apply to your industry

Creating Organization Policies

// Use an existing category that best fits your use case
const policy = await client.createStaticPolicy({
name: 'Company Email Pattern',
description: 'Detect company email addresses',
tier: 'organization',
category: 'pii-global', // security-sqli, security-admin, pii-global, pii-us, pii-eu, pii-india
pattern: '@mycompany\\.com\\b',
action: 'log',
severity: 'low',
enabled: true,
});

Disabling System Policies

To disable a system policy for your entire organization, create an organization override:

await client.createPolicyOverride({
policyId: 'sys_pii_email', // System policy ID
enabledOverride: false,
overrideReason: 'Email detection not required for internal tools',
});

Tenant Tier

Tenant policies are team-specific rules. They inherit from both system and organization tiers.

Use Cases

  • Team-specific PII patterns
  • Project-specific blocking rules
  • Custom validation patterns
  • Department compliance requirements

Creating Tenant Policies

// Use an existing category that best fits your use case
const policy = await client.createStaticPolicy({
name: 'Block Test Data',
description: 'Prevent test data patterns in production',
tier: 'tenant', // Default if not specified
category: 'security-admin', // security-sqli, security-admin, pii-global, pii-us, pii-eu, pii-india
pattern: '\\b(test_|demo_|fake_)\\w+\\b',
action: 'block',
severity: 'medium',
enabled: true,
});

Effective Policies

The getEffectiveStaticPolicies method returns the merged policy set for a tenant:

const effective = await client.getEffectiveStaticPolicies();

console.log(`Total policies: ${effective.length}`);

// Group by tier
const byTier = {
system: effective.filter(p => p.tier === 'system'),
organization: effective.filter(p => p.tier === 'organization'),
tenant: effective.filter(p => p.tier === 'tenant'),
};

Response Structure

{
"policies": [
{
"id": "sys_sqli_union_select",
"name": "UNION SELECT Detection",
"tier": "system",
"category": "security-sqli",
"pattern": "(?i)\\bUNION\\s+(ALL\\s+)?SELECT\\b",
"action": "block",
"severity": "critical",
"enabled": true,
"has_override": false
},
{
"id": "org_pii_email",
"name": "Company Email Pattern",
"tier": "organization",
"category": "pii-global",
"pattern": "@mycompany\\.com\\b",
"action": "log",
"severity": "low",
"enabled": true
}
]
}

Policy Actions

ActionDescriptionUse Case
blockReject the requestSecurity threats, policy violations
redactMask matched contentPII protection
warnAllow but log warningMonitoring, soft rollout
logAllow and log for auditCompliance tracking

Action Restrictiveness

Actions have a restrictiveness hierarchy: block > redact > warn > log

When overriding system policies (Enterprise), you can only make policies more restrictive or disable them - you cannot make a block policy into a log policy.

Best Practices

1. Don't Fight System Policies

System policies exist for security. Instead of trying to work around them:

  • Use overrides to adjust actions (Enterprise)
  • Create tenant policies with higher priority for exceptions
  • Disable policies that truly don't apply to your use case

2. Use Organization for Shared Rules

If multiple teams need the same policy, create it at the organization level rather than duplicating across tenants.

3. Test Before Enabling

Always test new policies in warn or log mode before switching to block:

// Create in log mode first
await client.createStaticPolicy({
// ...
action: 'log', // Monitor before blocking
});

// After validation, update to block
await client.updateStaticPolicy(policyId, {
action: 'block',
});

4. Use Descriptive Names

Policy names should clearly indicate what they detect:

  • Block SQL UNION Injection
  • Policy 1

5. Document Override Reasons

When creating overrides, always provide a clear reason for audit trails:

await client.createPolicyOverride({
policyId: 'sys_pii_email',
enabledOverride: false,
overrideReason: 'Internal tooling - no customer data exposure',
expiresAt: new Date('2025-06-01'), // Optional: auto-revert
});