Opening Hook

I spent six months rewriting security rules in Babashka, convinced the industry was missing something. Then I discovered Rego. Turns out, I’d been reinventing Open Policy Agent without knowing it had a name.

If you’ve ever thought “why aren’t there more functional languages in security automation?” — you’re not alone. The answer is: there are. We just call them “policy engines” now.


The Core Insight (3-minute read)

Every Clojure concept you love has a direct analog in modern policy infrastructure:

Clojure/Babashka Concept Policy Engine Equivalent
EDN data structures Rego evaluates structured JSON-like input data
Code = data (homoiconicity) Rego rules are data-driven and inspectable through OPA tooling
Immutability Policy evaluation reads input and produces a decision value
Concurrency and orchestration Policy evaluation plus host-pipeline scheduling
rewrite-clj (AST manipulation) opa eval --explain evaluation tracing
REPL-driven development opa repl, conftest repl

Most Clojure devs skip OPA/Rego jobs because they sound unrelated. But they’re not. Rego is not Clojure, but its declarative, data-oriented style can feel familiar to functional programmers.


Real Tools Doing This

1. Open Policy Agent (OPA) / Rego

package iam.pam

import rego.v1

required_clearance := 3

allow if {
    input.user.clearance >= required_clearance
    input.resource.classification <= input.user.max_class
}

allowed_actions contains action if {
    some role in input.user.roles
    some action in role.permissions
}

OPA is used for authorization and policy enforcement in production systems. Cloudflare has publicly documented using OPA, Rego, Terraform, and Conftest to enforce infrastructure baselines across internal accounts. That is evidence for the pattern, not a claim that every company using authorization uses OPA. OPA policy language · Cloudflare engineering write-up

2. Conftest — Checkov’s Functional Cousin

Provides an executable policy workflow that can complement or replace selected custom checks:

# A conceptual equivalent of a custom infrastructure check:

# You write:
conftest test lambda.json --policy lambda.rego
# lambda.rego
package terraform.aws.lambda

import rego.v1

deny contains msg if {
    resource := input.resource.aws_lambda_function
    not resource.environment.variables.PROMETHEUS_ENDPOINT
    msg := sprintf("Lambda %v missing metrics endpoint", [resource.name])
}

3. CUE Lang (configuration validation)

package iam

#Role: {
  name: string
  assume_role_policy: #Policy
}

#Policy: {
  Version: "2012-10-17"
  Statement: [...{
    Effect: "Allow" | "Deny"
    Action: [...string]
  }]
}

CUE is a configuration language and validation tool with a different constraint model from Rego; the useful comparison is that both make configuration requirements executable.


Your Career Bridge

Diagram

Strategic Repositioning (Resume Translation)

❌ Old (too niche):

✅ New (hireable):


Action Plan (2026 Edition)

  1. brew install conftest — drops into your existing workflow
  2. Rewrite one Checkov rule as Rego — compare outputs
  3. Add to LinkedIn headline: Senior SecOps Engineer — Policy-as-Code & IAM Governance
  4. Search jobs for: “OPA”, “Rego”, “Policy Engineer”, “Infrastructure Governance”

Takeaway

You didn’t need to abandon Clojure. You needed to translate it into hireable terms.

The functional programming revolution in security is already here. It just ships under different packaging.

Related post: Replacing Babashka IAM checks with Rego — the practical migration from imperative checks to declarative policy.

Stay functional.