Why Two Implementations
Having two independent implementations provides critical benefits:
- Protocol credibility — If two implementations written in different languages produce the same output for the same input, the protocol is well-specified enough to be trusted.
- Specification validation — Divergences between implementations surface ambiguities in the spec that need resolution.
- Ecosystem flexibility — Go services can evaluate consequences without spawning Node.js processes.
- Attestation interoperability — Attestations signed by Go can be verified by TypeScript and vice versa.
The Go implementation passes 18/19 differential tests against TypeScript. The single divergence is a documented spec ambiguity that will be resolved in a future protocol version.
Installation
Install from source:
git clone https://github.com/recourseOS/recourse.git
cd recourse/recourse-go
go build -o recourse-go ./cmd/recourseOr use as a library:
go get github.com/recourseOS/recourse-goCLI Usage
Evaluate a Terraform plan:
terraform show -json plan.out > plan.json
./recourse-go plan plan.jsonOutput formats:
# Human-readable (default)
./recourse-go plan plan.json --format human
# JSON for programmatic use
./recourse-go plan plan.json --format jsonEnvironment-specific policy:
# Production policy (stricter thresholds)
./recourse-go plan plan.json --env production
# Development (default, more permissive)
./recourse-go plan plan.json --env developmentLibrary Usage
Use the Go packages directly in your application:
package main
import (
"fmt"
"github.com/recourseOS/recourse-go/pkg/evaluator"
"github.com/recourseOS/recourse-go/pkg/parser"
"github.com/recourseOS/recourse-go/pkg/policy"
)
func main() {
// Parse a Terraform plan
plan, err := parser.ParsePlanFile("plan.json")
if err != nil {
panic(err)
}
// Evaluate consequences
eval := evaluator.New()
report := eval.EvaluatePlan(plan, plan.PriorState)
// Apply policy
pol := policy.ProductionPolicy()
verdict := pol.Evaluate(report)
fmt.Printf("Risk: %s\n", verdict.RiskAssessment)
fmt.Printf("Tier: %s\n", report.OverallTier)
}Cross-Action Pattern Detection
The evaluator automatically detects dangerous action combinations:
report := eval.EvaluatePlan(plan, state)
for _, risk := range report.CrossActionRisks {
fmt.Printf("Pattern: %s\n", risk.PatternName)
fmt.Printf("Explanation: %s\n", risk.Explanation)
fmt.Printf("Affected: %v\n", risk.AffectedResources)
}Detected patterns:
backup_and_protected_both_deleted— Database and its backup/snapshot deleted togetherreplica_and_primary_both_deleted— Primary and replica deleted togetherprotection_disabled_then_deleted— Protection removed and resource deleted in same plan
Attestation
The Go SDK includes full cryptographic attestation support using Ed25519 signatures.
Signing Attestations
import "github.com/recourseOS/recourse-go/pkg/attestation"
// Create a signer with instance base URL
signer, err := attestation.NewSigner(
"recourse-go/v1", // evaluator identifier
"https://recourse.example", // instance base URL
)
// Sign an evaluation
attest, err := signer.Sign(input, output)
// attestation includes:
// - attestation_uri: unique identifier
// - signature: Ed25519 base64url
// - key_id: derived from public key
// - timestamp: RFC3339Verifying Attestations
// Verify with a known public key
err := attestation.VerifyWithPublicKey(attest, publicKeyBytes)
if err != nil {
// Invalid signature or tampered content
}
// Or use a verifier with multiple keys
verifier := attestation.NewVerifier()
verifier.AddPublicKey(keyID, publicKeyBytes)
err := verifier.Verify(attest)Cross-Implementation Verification
Attestations are fully interoperable between Go and TypeScript:
- PASSGo signs, TypeScript verifies
- PASSTypeScript signs, Go verifies
- PASSTampered attestations rejected
Running cross-implementation tests:
cd recourse-go
npx tsx tests/cross-impl/run-test.tsAPI Reference
Package: types
Core types for consequence evaluation.
| Type | Description |
|---|---|
RecoverabilityTier | 1=Reversible, 2=RecoverableWithEffort, 3=RecoverableFromBackup, 4=Unrecoverable, 5=NeedsReview |
RiskAssessment | allow, warn, escalate, block |
TerraformPlan | Parsed Terraform plan JSON |
ConsequenceReport | Full evaluation output with resource results and cross-action risks |
Package: evaluator
Main evaluation logic.
| Function | Description |
|---|---|
New() | Create evaluator with default handler registry |
EvaluatePlan(plan, state) | Evaluate a Terraform plan, returns ConsequenceReport |
Package: attestation
Cryptographic signing and verification.
| Function | Description |
|---|---|
NewSigner(evaluator, baseURL) | Create signer with fresh Ed25519 keypair |
Signer.Sign(input, output) | Sign an evaluation, returns Attestation |
NewVerifier() | Create verifier for checking signatures |
Verifier.Verify(attestation) | Verify an attestation signature |
VerifyWithPublicKey(attestation, key) | One-shot verification without pre-registration |
Package: policy
Policy evaluation and thresholds.
| Function | Description |
|---|---|
DefaultPolicy() | Development-friendly policy |
ProductionPolicy() | Stricter production thresholds |
Policy.Evaluate(report) | Apply policy to report, returns Verdict |