Skip to main content
Back to Journal
AI SafetySecurity

18 Platforms, 170 Rules: Building a Security Pattern Registry

When I started building theGuard's rule engine, I had about twenty rules covering the most obvious dangerous operations: deleting databases, force-pushing to main, removing production deployments. Within a week, I realized twenty rules was not even close to enough.

Modern development environments touch dozens of platforms. A single project might use AWS for infrastructure, Docker for containers, Terraform for provisioning, GitHub for source control, Supabase for the database, and Vercel for deployments. Each platform has its own set of destructive operations that an AI agent could trigger. Covering them all required a systematic approach.

The PatternRule Type

Every rule in theGuard follows the same structure. A PatternRule has an id (like AWS-001), a human-readable description, a severity level (info, warning, critical), an impact statement explaining what would happen if the action succeeded, a remediation suggestion, and the actual matching pattern.

The id convention is deliberate. The platform prefix (AWS, K8S, TF, GH) tells you instantly which platform the rule covers. The number is sequential within that platform. When a rule triggers, the audit log shows "Blocked by AWS-014" and anyone on the team can look up exactly what that means without digging through code.

I chose this structure because the rules need to serve two audiences. The matching engine needs patterns and severity levels to make enforcement decisions. Humans need descriptions, impact statements, and remediation advice to understand what happened and what to do instead.

One File Per Platform

The registry is organized as one TypeScript file per platform. There is aws.ts, azure.ts, gcp.ts, kubernetes.ts, docker.ts, terraform.ts, github.ts, supabase.ts, vercel.ts, and so on, eighteen files in total as of today.

Each file exports an array of PatternRule objects. The rules within each file are organized by risk level, with critical rules first. This makes code review straightforward: when someone submits a new rule, you can see exactly which platform it affects and how it ranks against existing rules.

The one-file-per-platform structure also makes it easy for teams to customize theGuard for their stack. If you do not use Azure, you can disable the entire azure rules file in configuration. If you have a custom internal platform, you can add a new file with your own rules. The registry is additive by design.

Rule Examples Across Platforms

To give a sense of the coverage, here are representative rules from different platforms:

AWS rules catch operations like deleting S3 buckets, terminating EC2 instances, dropping RDS databases, modifying IAM policies, and disabling CloudTrail logging. Each of these is an action that an AI agent might consider "cleaning up" or "optimizing."

Kubernetes rules cover kubectl delete namespace, helm uninstall on production releases, scaling deployments to zero replicas, and modifying cluster-level RBAC. These are operations that seem reasonable in development but are catastrophic in production.

Terraform rules flag terraform destroy, removing resource blocks from state files, and modifying backend configurations. An AI agent that decides to "simplify" your infrastructure code by removing resources it deems unnecessary could trigger a real infrastructure teardown on the next apply.

Docker rules catch attempts to remove running containers, prune volumes with active mounts, and modify Docker daemon configurations. GitHub rules cover force pushes, branch deletion, repository visibility changes, and webhook modifications.

Environment Auto-Detection

One of the trickier problems was figuring out which rules to activate. Loading all 170 rules for every project wastes memory and adds noise to audit logs. A project that only uses Supabase and Vercel does not need Kubernetes rules cluttering up its output.

theGuard solves this with environment auto-detection. During initialization, it scans the project for signals that indicate which platforms are in use. It checks for CLI tools in the PATH (aws, kubectl, az, gcloud, terraform). It reads environment variables (AWS_REGION, KUBECONFIG, GOOGLE_CLOUD_PROJECT). It parses package.json for platform-specific dependencies. It examines configured MCP servers for platform indicators.

The result is a list of detected platforms. theGuard activates rules only for detected platforms, keeping the active rule set lean and relevant. You can override auto-detection in configuration if needed, either to force-enable rules for a platform the scanner missed or to disable rules for a platform you want to leave unguarded.

Config V2: Simplifying Everything

The first version of theGuard's configuration required users to specify patterns inline. You had to write regex patterns, set severity levels, and provide descriptions for every custom rule. It was powerful but tedious, and most users just wanted to toggle built-in rules on and off.

Config v2 replaced inline patterns with boolean toggles. The configuration file now looks like a simple map of platform names to true or false. Enable AWS protection? Set aws: true. Disable Kubernetes rules because you do not use it? Set kubernetes: false. The built-in rules handle the rest.

For teams that need custom rules, v2 still supports a customRules array where you can add PatternRule objects. But the common case, using the defaults with platform-level toggles, went from twenty lines of configuration to three.

The Build Pipeline

Rules are authored in TypeScript for type safety and IDE support. When you write a new rule, the compiler catches typos in field names, missing required fields, and type mismatches. This matters when you have 170 rules; a typo in a regex pattern that silently fails to match is a security hole.

At build time, a compilation step reads all platform files, validates every rule, resolves cross-references, and emits a single platforms.json artifact. This is the file that ships with the npm package. At runtime, theGuard loads platforms.json once during initialization and indexes it for fast lookups.

The compilation step also runs a test suite that verifies every rule against known-good and known-bad inputs. Each rule has at least two test cases: one that should match and one that should not. This prevents regressions when rules are modified and ensures new rules actually catch what they claim to catch.

The registry is never finished. Every week, I find new operations that should be guarded. The pattern-based architecture makes it easy to add them: write the rule, add test cases, rebuild, and ship. The platform count will keep growing as AI agents gain access to more tools.

AI SafetySecurityPatternsTypeScript