Install GuardSpine in 10 Minutes
Three commands. Ten minutes. Audit-grade evidence for every AI-assisted change in your codebase. No vendor dependency. No telemetry. Apache 2.0.
Three commands. Ten minutes. Audit-grade evidence for every AI-assisted change in your codebase. No vendor dependency. No telemetry. Apache 2.0.
I built GuardSpine because the governance tools I evaluated all had the same problem: they took longer to set up than the sprint they were supposed to govern. Configuration wizards, vendor onboarding calls, SSO integration prerequisites, mandatory training sessions. By the time you finished setup, the compliance deadline had passed.
So I made a rule: if someone cannot go from zero to producing evidence bundles in 10 minutes, the onboarding is broken.
Here are three entry points. Pick the one that matches how you work.
Entry Point 1: The GitHub Action (Recommended)
This is the fastest path if your code lives on GitHub. One file addition, one commit, done.
Create .github/workflows/guardspine.yml in your repository:
name: GuardSpine Review
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
guardspine:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: DNYoussef/codeguard-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
Commit that file. Open a pull request. Watch the Action run.
What just happened: CodeGuard extracted the diff from your PR, classified each change unit into a risk tier (L0 through L4), ran the review, and produced an evidence bundle. The bundle is attached to the PR as a comment with the review summary and stored as a workflow artifact.
No API keys for GuardSpine itself. No account creation. No telemetry phone-home. The Action runs in your GitHub Actions environment using your compute.
If you want AI council review (multiple models reviewing the diff), add your model API keys as repository secrets:
- uses: DNYoussef/codeguard-action@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
Without API keys, CodeGuard still runs — it performs deterministic risk classification and policy evaluation. The AI council adds multi-model review on top.
Entry Point 2: The Node.js Package
If you want to create evidence bundles programmatically — in a CI pipeline, a custom tool, or a server-side application — use the kernel directly.
npm install @guardspine/kernel
Create your first evidence bundle:
import { createBundle, sealBundle } from '@guardspine/kernel';
// Define the evidence items
const items = [
{
content_type: 'guardspine/diff',
content: {
file: 'src/auth/middleware.ts',
changes: [
{ line: 42, type: 'modified', before: 'const maxAttempts = 5;', after: 'const maxAttempts = 10;' }
]
}
},
{
content_type: 'guardspine/policy-eval',
content: {
policy: 'auth-modification-review',
result: 'flagged',
risk_tier: 'L3',
reason: 'Authentication parameter modified'
}
},
{
content_type: 'guardspine/approval',
content: {
reviewer: 'claude-sonnet-4',
decision: 'approved_with_comments',
comments: 'Rate limit increase from 5 to 10 is within acceptable range for this endpoint.'
}
}
];
// Create and seal the bundle
const bundle = createBundle(items);
const sealed = sealBundle(bundle);
console.log(JSON.stringify(sealed, null, 2));
Run it:
npx tsx create-bundle.ts
You now have a sealed evidence bundle. The output contains:
bundle_id: A UUID identifying this bundle.items[]: Your evidence items, each with acontent_hash(SHA-256 of the canonical JSON content).immutability_proof: The hash chain linking all items, plus theroot_hashthat commits the entire bundle.signatures[]: Cryptographic signatures over the root hash.
Save that JSON. Hand it to anyone. They can verify it offline.
Entry Point 3: The Python CLI
For teams that work primarily in Python, or for quick verification of existing bundles:
pip install guardspine-verify
Verify an existing bundle:
guardspine-verify bundle.json
The CLI reads the bundle, recomputes every content hash, rebuilds the hash chain, checks the root hash, and validates all signatures. The output tells you exactly what passed and what failed.
Bundle: a3f8c2d1-...
Items: 3
Hash chain: VALID
Root hash: VALID
Signatures: 1/1 VALID (ed25519)
Result: VERIFIED
You can also use guardspine-verify in a Python script:
from guardspine_verify import verify_bundle
import json
with open('bundle.json') as f:
bundle = json.load(f)
result = verify_bundle(bundle)
print(f"Valid: {result.valid}")
print(f"Errors: {result.errors}")
Your First Evidence Bundle: What to Look At
Whichever entry point you chose, you now have a bundle. Here is what to inspect.
The Items Array
Each item in the bundle has three fields that matter:
content_type: What kind of evidence this is.guardspine/difffor change diffs,guardspine/policy-evalfor policy evaluation results,guardspine/approvalfor review decisions.content: The actual evidence payload. The diff, the policy result, the reviewer’s decision.content_hash: SHA-256 of the content, serialized using RFC 8785 canonical JSON. This is how you prove the content has not been modified.
The Hash Chain
Open the immutability_proof object. You will see:
hash_chain[]: An array where each entry links to the previous one. The first entry is a genesis sentinel. Each subsequent entry contains the content hash of the corresponding item and a chain hash that incorporates the previous chain hash.root_hash: SHA-256 of the final chain hash concatenated with the item count. This single value commits the entire bundle. Change any item, and the root hash changes.
The Signatures
The signatures[] array contains cryptographic signatures over the root hash. Each signature includes the algorithm used (Ed25519, RSA-SHA256, ECDSA-P256, or HMAC-SHA256), the public key or key identifier, and the signature value.
To verify: recompute the root hash from the items, then check each signature against it. That is exactly what guardspine-verify does.
Zero-Config Defaults vs. Custom Configuration
Out of the box, CodeGuard uses sensible defaults:
- Risk classification: Built-in patterns for auth, crypto, PII, payments, infra config. Auth middleware changes are L3. Payment logic is L4. CSS is L0.
- Review routing: L0-L1 auto-approve. L2+ get AI review if API keys are configured. L4 gets flagged for human attention regardless.
- Policy evaluation: Default policies catch the patterns that matter in most codebases.
When you need to customize, create a .guardspine/config.yml in your repository:
classification:
patterns:
- pattern: "src/billing/**"
risk_tier: L4
reason: "All billing changes require full review"
- pattern: "*.test.*"
risk_tier: L0
reason: "Test files are low risk"
review:
blockTier: L4
gateType: review-required
policies:
- name: no-direct-sql
description: "No raw SQL strings in application code"
pattern: "(?:SELECT|INSERT|UPDATE|DELETE)\\s+(?:FROM|INTO|SET)"
exclude: ["**/migrations/**", "**/*.sql"]
risk_tier: L3
The config file is optional. Everything works without it. But when your security team says “all changes to the billing module must be L4 regardless of content,” you add three lines instead of filing a ticket.
What Happens Next
You have evidence bundles. Now what?
If you are a developer, you keep working. The GitHub Action runs on every PR. Evidence bundles accumulate automatically. When someone asks “was this change reviewed?” you point them to the bundle.
If you are a security engineer, you pull bundles from the workflow artifacts and feed them into your SIEM or compliance tool. Each bundle is a JSON file. Parse it, index it, query it.
If you are an auditor, you use guardspine-verify to validate bundles offline. You do not need access to our systems, our API, or our dashboard. The bundle contains everything needed for independent verification.
If you want to extend GuardSpine to other systems — Jira, Slack, your internal tools — the connector SDK lets you build custom integrations. That is covered in the connectors post later in this series.
The 10-Minute Test
Here is how to verify this actually took 10 minutes or less:
- Minute 0-2: Copy the GitHub Action YAML into your repo. Commit and push.
- Minute 2-4: Create a branch, make a change to any file, open a PR.
- Minute 4-8: Watch the Action run. Read the PR comment it produces.
- Minute 8-10: Download the evidence bundle from workflow artifacts. Run
guardspine-verifyon it.
If you hit 10 minutes and you are not done, something is wrong with my onboarding, and I want to know about it.
Book a call and tell me where you got stuck. I will fix it before the next person tries.