✓ Human-authored analysis; AI used for formatting and proofreading.
The cloud security industry has a tool for every case. An S3 scanner. An IAM analyzer. A Lambda checker. A VPC auditor. A Kubernetes admission controller. A Terraform linter. A CloudFormation validator.
Each tool is specialized for its local domain. Each tool has its own engine, its own rule format, its own output schema, its own dashboard. The specialization is in the code. A different mechanism for every case.
The result: tool sprawl. Fifteen tools in the average organization. Hundreds of thousands of lines of mechanism across them. Adding support for a new AWS service means adding a new tool or a new module with its own parser, its own rules, its own integration.
There's a principle from innovation theory that says this is backwards. Specialize the outcomes, not the mechanisms. The mechanism stays uniform. The data varies by case. One kernel. 109 cloud services. The kernel doesn't grow when the catalog does.
The principle: Local Quality
Different parts of a system should not behave in a uniform way. Each part should adapt to its local purpose, conditions, and constraints — instead of enforcing global uniform behavior.
The principle seems to endorse the industry's approach: specialize each part. But there's a constraint that changes everything:
Local Quality must never introduce local MECHANISMS, only local OUTCOMES. Mechanisms remain generic. Only invariants and policies specialize.
The constraint separates scalable specialization from sprawl:
| Localizing... | What grows | Result |
|---|---|---|
| Mechanisms (code per case) | Code. Every new cloud service, compliance regime, or control type adds a new engine, parser, or module. | Tool sprawl. Mechanism complexity grows linearly with cases. |
| Outcomes (data per case) | Data. Every new cloud service, compliance regime, or control type adds a YAML file. | One kernel. Data complexity grows. Mechanism doesn't. |
The industry localizes mechanisms. The architecture localizes outcomes. Same specialization. Different place. Opposite scaling properties.
The industry's design vs the alternative
| Dimension | Industry default (local mechanisms) | Local Quality (local outcomes) |
|---|---|---|
| Cloud service coverage | Per-service scanner (S3 scanner, IAM scanner, Lambda scanner, ...) | One kernel + 109 asset-type schemas |
| Compliance regime | Per-regime engine (HIPAA tool, SOC 2 tool, PCI-DSS tool, ...) | One kernel + 10 compliance profiles |
| Control time semantics | One check type. Every condition treated the same. | Two types: unsafe_state (instant) and unsafe_duration (threshold-based) |
| Compound risk scoping | Uniform grouping (or none at all) | Per-chain scope_field — each chain declares its own local scope |
| Threat taxonomy | Per-taxonomy product | Same catalog projected through different mappings (compliance OR threat taxonomy) |
| Observation contract | Generic JSON for all cloud services | 109 specialized schemas, each capturing its service's unique properties |
| Adding a new AWS service | Add a new module: new parser, new rules, new tests, new integration | Add a YAML file: new schema + new controls. Same kernel. Same tests. Same integration. |
Every row on the right is the result of specializing outcomes while keeping the mechanism uniform. The left column grows mechanism complexity with every case. The right column grows data. Data is cheaper to maintain, cheaper to review, cheaper to test, and cheaper to add than mechanism.
Seven layers of specialization — all in data
1. 109 asset-type schemas — local observation contracts
An S3 bucket has properties IAM roles don't: encryption settings, public access blocks, lifecycle policies. An IAM role has properties S3 buckets don't: trust policies, attached policies, MFA requirements. Forcing them into one uniform schema wastes most fields on most assets.
Each of the 109 schemas captures exactly the properties its cloud service exposes. An S3 schema has 81 field paths. An IAM role schema has 64. A Bedrock agent schema has 31. Each is tuned to its local domain.
The kernel reads any of the 109 schemas through the same generic parser. One mechanism. 109 locally-specialized observation contracts.
2. 3,000+ controls — local security judgments
Each control is tuned to a specific unsafe state in a specific domain:
# S3-specific: public read access
id: CTL.S3.PUBLIC.001
unsafe_predicate:
any:
- field: properties.storage.access.public_read
op: eq
value: true
# IAM-specific: overprivileged role
id: CTL.IAM.ROLE.SCOPE.001
unsafe_predicate:
any:
- field: properties.identity.unused_services_pct
op: gt
value: 20
# Bedrock-specific: agent with broad Lambda invoke
id: CTL.BEDROCK.AGENT.ROLE.001
unsafe_predicate:
any:
- field: properties.agent.role.policies.statements.actions
op: contains
value: "lambda:InvokeFunction"
Three different domains, unsafe states and predicates. Same kernel evaluating all three. The specialization is in the YAML. The mechanism is uniform.
3. Two control types — local time semantics
Some conditions are unsafe instantly. A public S3 bucket is dangerous the moment it's created. Other conditions are unsafe only if they persist. An overprivileged role might be acceptable during a migration window but dangerous after 90 days.
# Instant: unsafe the moment it's observed
type: unsafe_state
predicate: properties.storage.access.public_read == true
# Durational: unsafe only after threshold exceeded
type: unsafe_duration
predicate: properties.identity.access_key_age_days > 90
max_unsafe: 168h
A uniform control type would either flag every transient condition (false positives) or miss every durational violation (low coverage). Two types let each control declare its local time semantics. The kernel handles both with the same evaluation loop.
4. 10 compliance profiles — local regulatory priorities
HIPAA prioritizes PHI protection and encryption. PCI-DSS prioritizes cardholder data protection. SOC 2 prioritizes availability and confidentiality. Each regime has different priorities with different subsets of the same controls.
stave apply --profile hipaa --observations ./snapshots # HIPAA subset
stave apply --profile pci-dss --observations ./snapshots # PCI-DSS subset
stave apply --profile nist-800-53 --observations ./snapshots # NIST subset
Same 3,000+ controls. Ten different projections. The operator names the regime. The profile selects the local invariant family. The mechanism doesn't change.
5. 700+ compound chains — local scope keys
A naive compound chain groups findings by some uniform criterion (asset type, or account). Stave's scope_field lets each chain declare its own local grouping:
- An AI-agent chain groups by agent ID (which agent is the risk?)
- A PHI-data chain groups by data-classification tag (which data is exposed?)
- An IAM chain groups by role ARN (which identity is overprivileged?)
Each chain specifies what "this composition" means for THIS chain. The chain engine is uniform. It groups and evaluates. The scope key varies per chain.
6. OWASP NHI mapping — local threat taxonomy
The same 3,000+ controls projected through a threat-taxonomy lens (235 controls mapped to OWASP Non-Human Identity Top 10) vs a compliance lens (10 regulatory profiles). Two different axes of specialization. Same controls and kernel. Different local concerns.
7. The asymmetric interface — local granularity per audience
Each layer of the system has a different audience with different cognitive capacity:
| Layer | Granularity | Audience |
|---|---|---|
| Operator interface | Macro — one compliance profile name | Humans |
| Control catalog | Mid — predicate definitions in YAML | Control authors |
| Observation schemas | Micro — 81 field paths per S3 bucket | Kernel |
| SIR export | Sub-micro — raw Policy / ACL / IAM vectors | External solvers (Z3, Soufflé) |
Each layer is at the granularity appropriate to its local consumer. The operator doesn't see the 81 field paths. The solver doesn't see the compliance profile name. Each interface specializes its granularity. The mechanism connecting them is uniform.
Why this matters for scaling
The scaling property of data-local vs mechanism-local:
Day 1: 1,030-line kernel + 100 controls + 20 schemas
Day 180: 1,030-line kernel + 2,650 controls + 109 schemas
Day 360: 1,030-line kernel + 5,000 controls + 200 schemas
Year 2: 1,030-line kernel + 10,000 controls + 300+ schemas
Kernel: unchanged
Data: 100× growth
Operator cognitive load: unchanged (one command, one profile)
Maintainability: unchanged (one engine to test, debug, verify)
Compare to the industry's mechanism-local scaling:
Day 1: 50,000 lines across 5 tools
Day 180: 120,000 lines across 10 tools
Day 360: 200,000 lines across 15 tools
Year 2: 500,000 lines across 20+ tools
Mechanism: grows with every case
Data: scattered across tool-specific formats
Operator cognitive load: grows with every new tool
Maintainability: degrades with every new tool
The mechanism-local approach can't escape linear growth. Every new cloud service, compliance regime, or control type adds mechanism. The data-local approach has constant mechanism cost. Every new case adds a YAML file.
This is the complexity-curve difference from the prior articles made concrete. The post-peak shape (function grows, complexity flat) is the Local Quality result. The pre-peak shape (function grows, complexity grows) is the Local Quality violation.
The pair that produces the architecture
Local Quality has a partner principle: Prior Action. Together they answer two questions:
| Principle | Question | Answer |
|---|---|---|
| Prior Action | WHEN should the work happen? | Before the change ships — in the control author's YAML, the schema definition, the profile selection |
| Local Quality | WHERE should specialization live? | In the data, not the mechanism — controls, chains, profiles, schemas |
Together they produce one commitment:
All cleverness happens earlier, in data appropriate to its local case.
Prior Action says: don't reason at runtime. Local Quality says: specialize via data, not via code. The combination produces a kernel that is both simple (no runtime derivation) AND generic (no per-case logic). 1,030 lines. 3,000+ controls. The literal result of applying both principles simultaneously.
Without Local Quality, Prior Action produces a uniform pre-bound system. Same controls for every case, no localization. Wrong for S3, IAM and Lambda. A universal tool that's universally mediocre.
Without Prior Action, Local Quality produces specialized runtime reasoning. Per-case logic running at decision time. Complex, non-deterministic, impossible to audit. A locally-correct tool that's globally unmaintainable.
Both principles together: a uniform kernel that runs locally-specialized data, all pre-bound before the runtime moment. Simple mechanism. Rich outcomes. Deterministic. Scalable.
The diagnostic for founders
When you add support for a new case in your product (a new customer type, a new cloud service, a new compliance regime, a new data format):
Are you adding code or data?
If code: you're localizing the mechanism. Your kernel grows with every case. Your test surface grows. Your maintenance cost grows. Your complexity curve is still ascending.
If data: you're localizing the outcome. Your kernel stays the same. A new case is a new file. Your test surface stays constant (the kernel tests cover every new file automatically). Your complexity curve is past the peak and descending.
The question is WHERE the specialization lives: in the mechanism (code) or in the outcome (data). The first produces sprawl. The second produces scale.
One kernel for 109 cloud services. Because the specialization is in the right place.
How this relates to existing compliance mods
Specialization in the right place cuts a specific way through the framework-mod ecosystem. turbot/steampipe-mod-aws-compliance
specializes along a different axis: per-framework benchmark hierarchies (CIS controls under CIS section IDs, PCI controls under PCI requirement numbers, HIPAA controls under HIPAA Security Rule citations). That specialization is in the data layer each control is a SQL query and a section ID and the mod's kernel is the Powerpipe runtime that renders the hierarchy. The specialization-in-data principle applies: Powerpipe stays small, framework content grows. Stave applies the same principle to a different specialization axis (asset types and compound shapes). Two specialization axes (framework-section + compound-shape), one specialization principle (data not code), both render in the same Powerpipe dashboard. Comparison: aws-compliance-mod.
Local Quality in 109 specialized schemas, 3,000+ specialized controls, 585 specialized chains, 10 specialized profiles, two control types, per-chain scope keys, asymmetric granularity per audience are all evaluated by one 1,030-line kernel that doesn't grow when the catalog does. Implemented in Stave, an open-source Risk Reasoner. Try it: bash examples/demo-ai-security/run.sh
Top comments (0)