- Add PolicySourceStore for tracking where policies come from - Implement claim extraction skill and API endpoints - Add community UI text selection extractor component - Create Go SDK aphoria client for policy operations - Document patent specifications and legal disclosures - Add guides: golden path loop, policy audit trails, pre-flight checks - Expand Unreal Engine config extractor with source tracking - Add UAT reports for policy source tracking validation - Refactor tests.rs into modular test files Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
278 lines
8.6 KiB
Markdown
278 lines
8.6 KiB
Markdown
# Guide: Multi-Team Policy Governance — Scaling Standards Across the Org
|
|
|
|
**Target Audience:** Platform Engineers, Security Leads, Engineering Directors
|
|
**Prerequisite:** [Policy Audit Trails](./policy-audit-trails.md)
|
|
|
|
---
|
|
|
|
## The Problem: Too Many Cooks
|
|
|
|
Your organization has grown. Now you have:
|
|
- **Security Team** — owns cryptography and authentication policies
|
|
- **Platform Team** — owns infrastructure and observability policies
|
|
- **Compliance Team** — owns data handling and PII policies
|
|
- **Game Team** — owns performance and asset loading policies
|
|
|
|
Each team publishes policies. A developer violates something and sees:
|
|
|
|
```
|
|
BLOCK code://go/auth/jwt/expiry
|
|
```
|
|
|
|
They ask: *"Who do I talk to about this? Is this Security or Platform?"*
|
|
|
|
Without policy source tracking, they're stuck playing email roulette.
|
|
|
|
---
|
|
|
|
## The Solution: Federated Policy with Clear Ownership
|
|
|
|
With policy source tracking, every violation shows exactly which team's policy caused it:
|
|
|
|
```
|
|
BLOCK code://go/auth/jwt/expiry
|
|
Source: Security Team Standards v3.2 (sec-team: a1b2c3d4)
|
|
↑ Pack name ↑ Team ↑ Key
|
|
```
|
|
|
|
Now the developer knows: *"This is a Security Team policy. I'll ask them for an exception."*
|
|
|
|
---
|
|
|
|
## Architecture: One Project, Many Policies
|
|
|
|
```
|
|
Developer's Project
|
|
├── aphoria.toml
|
|
│ policies = [
|
|
│ "https://policies.acme.com/security-v3.2.pack",
|
|
│ "https://policies.acme.com/platform-v2.1.pack",
|
|
│ "https://policies.acme.com/compliance-v1.0.pack"
|
|
│ ]
|
|
└── src/
|
|
└── ...
|
|
```
|
|
|
|
Each pack is owned by a different team. When conflicts arise, the source attribution tells you who to escalate to.
|
|
|
|
---
|
|
|
|
## Step 1: Each Team Creates Their Domain Policy
|
|
|
|
### Security Team
|
|
|
|
```bash
|
|
cd security-team-policies/
|
|
aphoria init
|
|
|
|
# Security-specific rules
|
|
aphoria bless "code://*/tls/min_version" value "TLS1.3" \
|
|
--reason "Only TLS 1.3+ allowed per security policy"
|
|
|
|
aphoria bless "code://*/jwt/expiry" max_seconds 900 \
|
|
--reason "Access tokens expire in 15 minutes"
|
|
|
|
aphoria bless "code://*/crypto/hash" algorithm "sha256" \
|
|
--reason "MD5 and SHA1 banned for cryptographic use"
|
|
|
|
aphoria export --name "Security Team Standards" --output security-v3.2.pack
|
|
```
|
|
|
|
### Platform Team
|
|
|
|
```bash
|
|
cd platform-team-policies/
|
|
aphoria init
|
|
|
|
# Platform-specific rules
|
|
aphoria bless "code://*/grpc/timeout" max_seconds 30 \
|
|
--reason "gRPC calls must timeout within 30s"
|
|
|
|
aphoria bless "code://*/logging/level" default "info" \
|
|
--reason "Default log level is INFO, not DEBUG"
|
|
|
|
aphoria bless "code://*/metrics/enabled" value true \
|
|
--reason "All services must export Prometheus metrics"
|
|
|
|
aphoria export --name "Platform Team Standards" --output platform-v2.1.pack
|
|
```
|
|
|
|
### Compliance Team
|
|
|
|
```bash
|
|
cd compliance-team-policies/
|
|
aphoria init
|
|
|
|
# Compliance-specific rules
|
|
aphoria bless "code://*/pii/logging" masked true \
|
|
--reason "GDPR: PII must never appear in logs"
|
|
|
|
aphoria bless "code://*/data/retention" max_days 90 \
|
|
--reason "Data retention policy: 90 days max"
|
|
|
|
aphoria export --name "Compliance Standards" --output compliance-v1.0.pack
|
|
```
|
|
|
|
---
|
|
|
|
## Step 2: Centralized Policy Registry
|
|
|
|
Host all packs in a central location with a manifest:
|
|
|
|
```yaml
|
|
# https://policies.acme.com/manifest.yaml
|
|
policies:
|
|
security:
|
|
url: https://policies.acme.com/security-v3.2.pack
|
|
owner: security-team@acme.com
|
|
slack: "#security-policy"
|
|
|
|
platform:
|
|
url: https://policies.acme.com/platform-v2.1.pack
|
|
owner: platform-team@acme.com
|
|
slack: "#platform-support"
|
|
|
|
compliance:
|
|
url: https://policies.acme.com/compliance-v1.0.pack
|
|
owner: compliance@acme.com
|
|
slack: "#compliance-questions"
|
|
```
|
|
|
|
---
|
|
|
|
## Step 3: Developer Experience
|
|
|
|
A developer working on `payment-service` configures their project:
|
|
|
|
```toml
|
|
# aphoria.toml
|
|
policies = [
|
|
"https://policies.acme.com/security-v3.2.pack",
|
|
"https://policies.acme.com/platform-v2.1.pack",
|
|
"https://policies.acme.com/compliance-v1.0.pack"
|
|
]
|
|
```
|
|
|
|
They run a scan and see multiple violations:
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────────────┐
|
|
│ SCAN RESULTS: payment-service │
|
|
├──────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ BLOCK code://go/payment/tls/min_version │
|
|
│ Your Code: TLS1.2 │
|
|
│ Policy: TLS1.3 │
|
|
│ Source: Security Team Standards v3.2 (a1b2c3d4) │
|
|
│ Contact: #security-policy │
|
|
│ │
|
|
│ FLAG code://go/payment/grpc/timeout │
|
|
│ Your Code: 60s │
|
|
│ Policy: 30s max │
|
|
│ Source: Platform Team Standards v2.1 (e5f6g7h8) │
|
|
│ Contact: #platform-support │
|
|
│ │
|
|
│ BLOCK code://go/payment/pii/logging │
|
|
│ Your Code: logging full request body │
|
|
│ Policy: PII must be masked │
|
|
│ Source: Compliance Standards v1.0 (c9d0e1f2) │
|
|
│ Contact: #compliance-questions │
|
|
│ │
|
|
└──────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
The developer now knows:
|
|
- TLS issue → Ask **Security Team** in `#security-policy`
|
|
- Timeout issue → Ask **Platform Team** in `#platform-support`
|
|
- PII issue → Ask **Compliance** in `#compliance-questions`
|
|
|
|
---
|
|
|
|
## Handling Policy Conflicts Between Teams
|
|
|
|
What if Security says "log everything for forensics" but Compliance says "mask all PII"?
|
|
|
|
### Option 1: Policy Hierarchy
|
|
|
|
Configure policy precedence in your project:
|
|
|
|
```toml
|
|
# aphoria.toml
|
|
policies = [
|
|
"https://policies.acme.com/compliance-v1.0.pack", # Highest priority
|
|
"https://policies.acme.com/security-v3.2.pack",
|
|
"https://policies.acme.com/platform-v2.1.pack" # Lowest priority
|
|
]
|
|
```
|
|
|
|
Later policies can override earlier ones. Compliance wins.
|
|
|
|
### Option 2: Domain Scoping
|
|
|
|
Teams scope their policies to avoid overlap:
|
|
|
|
```bash
|
|
# Security Team: only auth/* and crypto/* paths
|
|
aphoria bless "code://*/auth/..." ...
|
|
aphoria bless "code://*/crypto/..." ...
|
|
|
|
# Compliance Team: only pii/* and data/* paths
|
|
aphoria bless "code://*/pii/..." ...
|
|
aphoria bless "code://*/data/..." ...
|
|
```
|
|
|
|
### Option 3: Joint Resolution Pack
|
|
|
|
Create a "Resolved Conflicts" pack signed by both teams:
|
|
|
|
```bash
|
|
# After Security + Compliance agree
|
|
aphoria bless "code://*/logging/pii" \
|
|
masked true \
|
|
--reason "Joint resolution: Mask PII, log metadata for forensics"
|
|
|
|
aphoria export --name "Security-Compliance Resolution" --output resolved-v1.pack
|
|
```
|
|
|
|
---
|
|
|
|
## Reporting Across Teams
|
|
|
|
Generate a policy coverage report showing which teams govern which areas:
|
|
|
|
```bash
|
|
aphoria scan . --mode persistent --format json | jq '
|
|
.findings | group_by(.conflicting_sources[0].policy_source.pack_name) |
|
|
map({
|
|
team: .[0].conflicting_sources[0].policy_source.pack_name,
|
|
violations: length
|
|
})
|
|
'
|
|
```
|
|
|
|
**Output:**
|
|
```json
|
|
[
|
|
{ "team": "Security Team Standards v3.2", "violations": 3 },
|
|
{ "team": "Platform Team Standards v2.1", "violations": 1 },
|
|
{ "team": "Compliance Standards v1.0", "violations": 2 }
|
|
]
|
|
```
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
| Without Policy Source Tracking | With Policy Source Tracking |
|
|
|--------------------------------|-----------------------------|
|
|
| "Who owns this rule?" | "Security Team Standards v3.2" |
|
|
| "Where do I escalate?" | "#security-policy Slack channel" |
|
|
| "Can I get an exception?" | "Ask the signing team (a1b2c3d4)" |
|
|
| "Which team approved this?" | Cryptographic proof in pack signature |
|
|
|
|
**The Result:** Decentralized policy authorship with centralized enforcement and clear accountability.
|
|
|
|
---
|
|
|
|
**Next:** Learn how to integrate Aphoria into your CI/CD pipeline in [Pre-flight Checks](./pre-flight-checks.md).
|