Safeguard.sh Documentation Center

SDKs

Official SDKs for Python, TypeScript/JavaScript, Go, Java, and Rust — typed, versioned, and signature-verifying by default.

SDKs

Safeguard maintains official SDKs in five languages. Each wraps the REST API, handles authentication (API keys and workload identity), and verifies webhook signatures. They're versioned against the API version, not the Safeguard version.

Quick Matrix

LanguagePackageInstall
Pythonsafeguard-shpip install safeguard-sh
TypeScript / JavaScript@safeguard-sh/sdknpm install @safeguard-sh/sdk
Gogithub.com/safeguard-sh/sdk-gogo get github.com/safeguard-sh/sdk-go
Java (JVM)sh.safeguard:sdkMaven / Gradle
Rustsafeguard-shcargo add safeguard-sh

All SDKs follow the same shape — the examples below mirror each other.

Authentication

API Key

from safeguard_sh import Safeguard
sg = Safeguard(api_key="sg_api_...")
import { Safeguard } from "@safeguard-sh/sdk";
const sg = new Safeguard({ apiKey: process.env.SG_API_KEY });
import "github.com/safeguard-sh/sdk-go"
sg := safeguard.New(safeguard.WithAPIKey(os.Getenv("SG_API_KEY")))

Workload Identity (OIDC Federation)

sg = Safeguard.from_workload_identity(
    provider="github-actions",  # or aws, azure, gcp, gitlab, etc.
)
const sg = await Safeguard.fromWorkloadIdentity({ provider: "github-actions" });

No long-lived key to rotate. The SDK exchanges the workload token for a short-lived Safeguard token automatically.

Common Examples

Find critical, KEV-listed, reachable vulnerabilities

findings = sg.findings.list(
    severity=["critical", "high"],
    kev=True,
    reachable=True,
    env="production",
)
for f in findings:
    print(f.id, f.cve, f.asset.name)
const findings = await sg.findings.list({
  severity: ["critical", "high"],
  kev: true,
  reachable: true,
  env: "production",
});
findings.forEach((f) => console.log(f.id, f.cve, f.asset.name));
findings, err := sg.Findings.List(ctx, &safeguard.FindingsListParams{
    Severity:    []string{"critical", "high"},
    KEV:         safeguard.Bool(true),
    Reachable:   safeguard.Bool(true),
    Environment: safeguard.String("production"),
})

Open an auto-fix PR

plan = sg.griffin.remediate(
    vulnerability="CVE-2024-3094",
    repository="acme/app",
)
pr = sg.pull_requests.create(plan.id)
print(pr.url)
const plan = await sg.griffin.remediate({
  vulnerability: "CVE-2024-3094",
  repository: "acme/app",
});
const pr = await sg.pullRequests.create(plan.id);
console.log(pr.url);

Classify a package with Eagle

result = sg.eagle.classify(ecosystem="npm", package="react", version="19.0.0")
if result.classification == "malicious":
    raise RuntimeError(f"blocked: {result.indicators}")

Generate a policy with Lino

policy = sg.lino.generate_policy(
    intent="Block production images without an SBOM less than 7 days old"
)
sg.policies.create(policy.yaml)

Upload and verify an SBOM

sbom = sg.sboms.upload("./sbom.cdx.json")
report = sg.sboms.quality(sbom.id)
print(report.score, report.missing_fields)

Subscribe to events (server-side)

sg.webhooks.create(
    url="https://example.com/sg",
    events=["findings.vulnerability.created", "remediation.pr_merged"],
    filter={"severity": ["critical", "high"], "env": "production"},
)

Verify webhook signatures

from safeguard_sh.webhooks import verify_signature

@app.post("/sg")
async def hook(request: Request):
    body = await request.body()
    sig = request.headers["X-Safeguard-Signature"]
    if not verify_signature(os.getenv("SG_SECRET"), sig, body):
        return Response(status=400)
    event = json.loads(body)
    # handle event
import { verifySignature } from "@safeguard-sh/sdk/webhooks";

app.post("/sg", express.raw({ type: "application/json" }), (req, res) => {
  const sig = req.header("x-safeguard-signature")!;
  if (!verifySignature(process.env.SG_SECRET!, sig, req.body)) {
    return res.sendStatus(400);
  }
  const event = JSON.parse(req.body);
  // handle event
});

Streaming

for event in sg.events.stream(types=["findings.vulnerability.created"]):
    print(event.type, event.data.finding.cve)
for await (const event of sg.events.stream({ types: ["findings.vulnerability.created"] })) {
  console.log(event.type, event.data.finding.cve);
}

Pagination

All list endpoints return async iterators that paginate transparently:

for finding in sg.findings.iter_all(severity="critical"):
    ...
for await (const finding of sg.findings.iterAll({ severity: "critical" })) {
  ...
}

Retries and Rate Limits

  • Automatic retry with exponential backoff on 429 / 502 / 503 / 504.
  • Respects Retry-After header.
  • Per-client connection pooling.

Tune:

const sg = new Safeguard({
  apiKey: process.env.SG_API_KEY,
  maxRetries: 5,
  timeoutMs: 30_000,
});

Typed Responses

Every response type is generated from the Safeguard OpenAPI spec. The SDK ships the types:

from safeguard_sh.types import VulnerabilityFinding, Asset, WorkflowRun
import type { VulnerabilityFinding, Asset, WorkflowRun } from "@safeguard-sh/sdk";

Self-Hosted / Custom Base URL

sg = Safeguard(api_key="...", base_url="https://api.safeguard.internal.acme.com")

Useful for:

  • Self-hosted Enterprise deployments.
  • Air-gapped environments (point at the on-prem control plane).
  • Staging / test tenants.

Open Source Extras

In the safeguard-sh/sdk-* repos:

  • Example applications (GitHub Action, Jira webhook handler, Slack bot).
  • Pytest fixtures (safeguard_sh.testing) for stubbing the API in tests.
  • A drop-in MCP server built on the Python SDK for self-hosting.

Version Compatibility

SDKs pin to an API version:

SDK versionMinimum API version
1.x2026-01-01
0.x2025-06-01

Set an explicit API version to prevent breaking changes rolling in silently:

sg = Safeguard(api_key="...", api_version="2026-01-01")

On this page