stemedb/applications/aphoria/docs/guides/policy-audit-trails.md
jordan 1cc453c97b feat: Aphoria policy source tracking + claim extraction pipeline
- 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>
2026-02-04 02:35:02 -07:00

196 lines
6.0 KiB
Markdown

# Guide: Policy Audit Trails — "Who Approved This?"
**Target Audience:** Compliance Officers, Security Auditors, Engineering Managers
**Prerequisite:** [Federating Truth](./federating-truth.md)
---
## The Problem: The Compliance Nightmare
It's audit season. The auditor asks:
> "Show me evidence that your TLS configuration was approved by someone with authority."
You dig through Slack, Jira, and Confluence. You find a thread from 2024 where someone said "LGTM." The auditor is not impressed.
What you need is:
1. **What** was approved (the exact policy)
2. **Who** approved it (cryptographic proof)
3. **When** it was approved (timestamp)
4. **Where** it's enforced (which projects)
Aphoria's policy source tracking gives you all four.
---
## How Policy Provenance Works
When you import a Trust Pack, Aphoria stores metadata for every assertion:
| Field | Description | Example |
|-------|-------------|---------|
| `pack_name` | Human-readable policy name | "Acme Security Standard" |
| `pack_version` | Semver version | "2.1.0" |
| `issuer_hex` | First 8 chars of signer's public key | "a1b2c3d4" |
This metadata appears in every conflict report, creating an unbroken chain from violation → policy → approver.
---
## Step 1: Establish Policy Authority
Your Security team creates the authoritative policy in a dedicated repo.
```bash
cd security-policies/
# Initialize persistent storage
aphoria init
# Define policies through bless commands
aphoria bless "code://*/tls/cert_verification" enabled true \
--reason "SOC2 CC6.1: Encrypt data in transit"
aphoria bless "code://*/secrets/api_key" storage "vault" \
--reason "SOC2 CC6.7: Secrets must use approved vault"
aphoria bless "code://*/logging/pii" masked true \
--reason "GDPR Art.32: PII must not appear in logs"
```
## Step 2: Export with Versioning
Export the policy with a meaningful version that maps to your compliance cycle.
```bash
# Version matches your security policy document
aphoria export \
--name "Acme SOC2 Controls v2.1" \
--output acme-soc2-v2.1.pack
```
The `.pack` file contains:
- All assertions (the "what")
- Ed25519 signature (the "who" — cryptographic proof)
- Timestamp (the "when")
## Step 3: Distribute to Projects
Host the pack and configure projects to use it:
```toml
# Every project's aphoria.toml
policies = ["https://security.internal/policies/acme-soc2-v2.1.pack"]
```
## Step 4: The Audit Trail in Action
When a developer violates policy, the report shows full provenance:
```
┌─────────────────────────────────────────────────────────────────┐
│ BLOCK code://go/payments/tls/cert_verification │
├─────────────────────────────────────────────────────────────────┤
│ Location: src/client.go:45 │
│ Your Code: tls.InsecureSkipVerify = true │
│ Policy: enabled = true │
│ │
│ Source: Acme SOC2 Controls v2.1 (a1b2c3d4) │
│ Reason: SOC2 CC6.1: Encrypt data in transit │
└─────────────────────────────────────────────────────────────────┘
```
The auditor can now verify:
- **What:** TLS verification must be enabled
- **Who:** Key `a1b2c3d4` (maps to Security Team's signing key)
- **When:** Pack creation timestamp in the file
- **Where:** This specific project imported the policy
---
## Generating Compliance Reports
Export scan results as JSON for your compliance dashboard:
```bash
aphoria scan . --mode persistent --format json > compliance-scan.json
```
Extract policy sources for your audit evidence:
```bash
cat compliance-scan.json | jq '
.findings[] |
select(.verdict == "BLOCK" or .verdict == "FLAG") |
{
violation: .claim.concept_path,
policy: .conflicting_sources[0].policy_source.pack_name,
version: .conflicting_sources[0].policy_source.pack_version,
approver: .conflicting_sources[0].policy_source.issuer_hex
}
'
```
**Output:**
```json
{
"violation": "code://go/payments/tls/cert_verification",
"policy": "Acme SOC2 Controls v2.1",
"version": "2.1.0",
"approver": "a1b2c3d4"
}
```
---
## Mapping Issuer Keys to People
The `issuer_hex` is derived from an Ed25519 public key. Map these to real identities in your key registry:
```yaml
# key-registry.yaml (maintained by Security team)
keys:
a1b2c3d4:
owner: "security-team@acme.com"
name: "Security Team Signing Key"
created: "2025-01-15"
e5f6g7h8:
owner: "platform-team@acme.com"
name: "Platform Team Signing Key"
created: "2025-03-20"
```
Now the auditor sees:
> "Violation blocked by **Acme SOC2 Controls v2.1**, approved by **Security Team** (key a1b2c3d4)"
---
## Version History for Compliance
Keep old pack versions for historical audits:
```
policies/
├── acme-soc2-v1.0.pack # 2024 Q1-Q2
├── acme-soc2-v1.1.pack # 2024 Q3-Q4
├── acme-soc2-v2.0.pack # 2025 Q1
└── acme-soc2-v2.1.pack # Current
```
If an auditor asks "What policies were in effect on March 15, 2025?", you can point to the specific pack version and its contents.
---
## Summary
| Audit Question | Aphoria Answer |
|----------------|----------------|
| "Who approved this policy?" | `issuer_hex` → Key Registry → Owner |
| "When was it approved?" | Pack file timestamp |
| "What exactly was approved?" | Assertions in the pack |
| "Is it still enforced?" | Current `aphoria.toml` policies list |
| "Which projects comply?" | Scan results across repos |
**Next:** See how multiple teams can publish non-conflicting policies in [Multi-Team Policy Governance](./multi-team-policy-governance.md).