SDKs

CrowdControl ships native parser + evaluator implementations in six languages. Every SDK passes the same conformance suite and produces identical decisions for identical inputs.

Supported languages

LanguageStatusPathRuntime deps
GoReferencerepo rootstdlib only
PythonStage 2sdks/python/stdlib only
TypeScriptStage 2sdks/typescript/stdlib only
RubyStage 2sdks/ruby/stdlib only
KotlinStage 2sdks/kotlin/stdlib only
PHPStage 2sdks/php/stdlib only

Every SDK uses only its host language's standard library. No external runtime dependencies.

Go (reference)

go get github.com/mikemackintosh/crowdcontrol
package main

import (
    "fmt"
    "github.com/mikemackintosh/crowdcontrol"
)

func main() {
    eng, err := crowdcontrol.New([]string{"./policies"})
    if err != nil { panic(err) }

    results := eng.Evaluate(map[string]any{
        "user":    map[string]any{"name": "alex", "role": "intern"},
        "request": map[string]any{"action": "delete"},
        "resource": map[string]any{"environment": "production"},
    })

    for _, r := range results {
        fmt.Printf("%s [%s] passed=%v: %s\n", r.Rule, r.Kind, r.Passed, r.Message)
    }
}

Python

cd sdks/python && pip install -e .

TypeScript

cd sdks/typescript && npm install && npm run build

Ruby

cd sdks/ruby && bundle install

Kotlin

cd sdks/kotlin && ./gradlew build

PHP

cd sdks/php && composer install

Docker images

Every SDK ships a Dockerfile so you can run its conformance suite without installing its runtime locally. Always build from the repo root — the build context needs both the SDK directory and conformance/.

# build and run one SDK
docker build -f sdks/python/Dockerfile -t crowdcontrol-python .
docker run --rm crowdcontrol-python

# run every SDK via docker compose
docker compose up --build --abort-on-container-exit

# or use the helper script
./sdks/run-conformance.sh              # all of them
./sdks/run-conformance.sh python ruby  # a subset

Each container exits 0 on full pass and non-zero on any failure — drop them straight into CI.

Why native ports?

CrowdControl could have shipped one implementation and bindings for everyone else — that's the usual pattern. But the grammar is small enough (~1500 LOC in the Go reference) that rewriting it idiomatically in each target language is cheaper than maintaining FFI bindings and their quirks.

The upside: every SDK is a zero-dependency, native install. No CGo, no WASM loader, no shared library you have to vendor. The downside: every SDK has to pass the conformance suite, and when the spec changes, every SDK ships an update.