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:
- System policies are loaded first
- Organization policies are merged (can override system)
- Tenant policies are merged (can override org)
- Policies are sorted by priority (higher first)
- First matching policy determines the action
Resolution Rules
| Scenario | Result |
|---|---|
| Same pattern at different tiers | Lower tier wins (tenant > org > system) |
| System policy disabled at org level | Policy is excluded for all org tenants |
| Org policy disabled at tenant level | Policy is excluded for that tenant only |
| Conflicting actions | Lower 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
| Category | Type | Count | Description |
|---|---|---|---|
security-sqli | Static | 37 | SQL injection patterns |
security-admin | Static | 4 | Admin access control |
pii-global | Static | 7 | Universal PII detection |
pii-us | Static | 2 | US-specific PII (SSN, bank accounts) |
pii-eu | Static | 1 | EU-specific PII (IBAN) |
pii-india | Static | 2 | India-specific PII (PAN, Aadhaar) |
dynamic-risk | Dynamic | 2 | Risk-based policies |
dynamic-compliance | Dynamic | 3 | HIPAA, GDPR, PCI-DSS |
dynamic-security | Dynamic | 2 | Tenant isolation |
dynamic-cost | Dynamic | 2 | Cost optimization |
dynamic-access | Dynamic | 1 | Data 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-Org-ID: my-tenant"
Organization Tier (Enterprise)
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
| Action | Description | Use Case |
|---|---|---|
block | Reject the request | Security threats, policy violations |
redact | Mask matched content | PII protection |
warn | Allow but log warning | Monitoring, soft rollout |
log | Allow and log for audit | Compliance 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
});
Real-World Multi-Tier Examples
These examples show how the three-tier hierarchy works in practice across different industries.
Example 1: Banking — 12 Lines of Business
A bank has 12 LOB tenants (retail, corporate, wealth management, fraud investigation, etc.). PAN card detection must be enforced org-wide, but the fraud team needs a targeted exception.
System tier: PAN card detection (sys_pii_pan) — action: block
Applied globally to all organizations
Org tier: No override — inherits system-level block
All 12 LOB tenants block PAN by default
Tenant tier: Fraud Investigation overrides sys_pii_pan:
→ action_request = warn (query by PAN is allowed, audit-logged)
→ action_response = redact (PAN never appears in response)
Result:
- 11 tenants: PAN is blocked on both input and output
- Fraud team: Can search by PAN (logged), but PAN is redacted in results
- New LOB tenants auto-inherit the org-level block — no manual config needed
Example 2: Healthcare — HIPAA PHI Redaction
A healthcare platform must redact Protected Health Information in all LLM outputs. The research team adds a stricter restriction.
System tier: PHI detection (SSN, MRN, DOB patterns) — action: redact
Ensures baseline HIPAA compliance for all organizations
Org tier: No override (system tier is sufficient for HIPAA)
All tenants inherit system-level redaction
Tenant tier: Research team adds ADDITIONAL policy:
→ Block ALL PHI entirely (not just redact)
Clinical team: no tenant override, inherits redaction
Result:
- Clinical team: PHI patterns are redacted in responses (system tier)
- Research team: PHI patterns cause request to be blocked entirely
- Most-restrictive-wins: block > redact, so research team's policy takes effect
- Neither team can weaken the system-tier redaction baseline
Example 3: Multi-Team SaaS — Cost and Model Governance
An enterprise SaaS company uses tenant policies for budget caps and model restrictions across teams.
System tier: No default cost limits
Org tier: Budget cap: $500/day across all tenants
Model restriction: block GPT-4-turbo (deprecated model)
Tenant tier: Engineering: $200/day sub-cap, GPT-4o allowed
Marketing: $50/day sub-cap, GPT-4o-mini only
Sales: $100/day sub-cap
Support: $50/day sub-cap
Result:
- Tenant caps cannot exceed org cap ($500/day total)
- Engineering's $200 counts toward the org's $500
- If Engineering hits $200, their requests are blocked — even if org total is only $300
- If org total hits $500, ALL tenants are blocked — even if individual caps aren't reached
- No tenant can use GPT-4-turbo (org-level block inherited by all)
- Marketing is additionally restricted to GPT-4o-mini (tenant-level)
Related
- OAuth vs Governance — Why governance policies exist alongside OAuth
- System Policies - Complete list of 63 system policies
- SDK Methods - Full API reference
- Enterprise Features - Override capabilities
