🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

aegis-governance

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

aegis-governance

Quantitative AI governance — works immediately, no signup required. 10 free evaluations/day.

pipPyPI
Version
1.4.0
Weekly downloads
543
Maintainers
1

AEGIS Python SDK

Quantitative AI governance — works immediately, no signup required.

AEGIS evaluates engineering proposals through 6 mathematical gates — risk, profit, novelty, complexity, quality, and utility — using Bayesian posterior analysis and KL divergence drift detection.

Quick Start (no signup needed)

pip install aegis-governance
from aegis import Aegis

client = Aegis()  # Works immediately — 10 free evaluations/day

decision = client.evaluate(
    proposal_summary="Add Redis caching layer to reduce API latency",
    risk_baseline=0.02,
    risk_proposed=0.05,
    novelty_score=0.75,
    complexity_score=0.8,
    quality_score=0.9,
)

print(decision.status)      # "proceed"
print(decision.remaining)   # 9 sandbox evaluations left today

No API key, no signup, no configuration. The gate engine runs server-side — your code hits the same evaluation engine used in production.

For Production Use

Get a free API key at portal.undercurrentholdings.com for 100 evaluations/month:

client = Aegis(api_key="uk_live_xxx")  # or set AEGIS_API_KEY env var

MCP Server (Claude Code, Cursor, Windsurf, VS Code)

Give your AI agent a governance gate it can call before it acts:

pip install "aegis-governance[mcp]"

Claude Code:

claude mcp add aegis -- aegis-mcp-server

Cursor / Windsurf (.cursor/mcp.json):

{
  "mcpServers": {
    "aegis": { "command": "aegis-mcp-server" }
  }
}

Works immediately in sandbox mode (10 evaluations/day, no signup). Set AEGIS_API_KEY in the server's environment for the full authenticated surface — decision history, usage reports, and risk checks. Six tools: aegis_evaluate_proposal, aegis_quick_risk_check, aegis_health, aegis_list_decisions, aegis_get_decision, aegis_get_usage.

A hosted streamable-http endpoint is also available — see aegis-mcp for connection configs.

Features

FeatureDescription
Sandbox mode10 free evaluations/day, no signup required
6 Bayesian gatesRisk, profit, novelty, complexity, quality, utility
KL divergence driftDetects when your risk baseline shifts
Shadow modeEvaluate without enforcing (calibration)
Typed responsesFull dataclass types with IDE autocomplete
Async supportAsyncAegis with identical API surface
Retry + backoffAutomatic retry on transient failures (429, 5xx)
IdempotencySafe retries — SDK auto-sends Idempotency-Key on every /evaluate; server honors it with a 24h dedup window (AEGIS v4.6.137+, IETF draft-07). Pass idempotency_key="..." for cross-process dedup. decision_id stable across replays; request_id fresh per HTTP call — use decision_id for log correlation.
TLS enforcedHTTPS always on, no opt-out

Quick Risk Check

Requires an API key. Unlike evaluate(), risk_check() has no sandbox path — it always calls the authenticated /risk-check endpoint. Get a free key at portal.undercurrentholdings.com.

client = Aegis(api_key="uk_live_xxx")  # or set the AEGIS_API_KEY env var

result = client.risk_check(
    risk_score=0.15,
    threshold=0.3,
    action_description="Deploy to production",
)
print(result.safe)  # True

Calling risk_check() on a sandbox client (Aegis() with no key) raises aegis.AuthenticationError.

Async Usage

from aegis import AsyncAegis

async with AsyncAegis() as client:  # sandbox mode works here too
    decision = await client.evaluate(
        proposal_summary="Migrate database to Postgres 17",
        estimated_impact="high",
    )

Gate Results

Access individual gate evaluations:

decision = client.evaluate(proposal_summary="...")

if decision.gates:
    print(decision.gates.risk)        # GateResult(passed=True, value=0.05, ...)
    print(decision.gates.novelty)     # GateResult(passed=True, value=0.75, ...)
    print(decision.gates.complexity)  # GateResult(passed=True, value=0.80, ...)

Error Handling

import aegis

try:
    decision = client.evaluate(proposal_summary="...")
except aegis.SandboxLimitError as e:
    print(f"Sandbox limit reached. Sign up at {e.upgrade_url}")
except aegis.AuthenticationError:
    print("Invalid API key")
except aegis.RateLimitError as e:
    print(f"Rate limited. Retry after {e.retry_after}s")
except aegis.ConflictError as e:
    print(f"Concurrent in-flight request — retry shortly: {e.message}")
except aegis.IdempotencyBodyMismatchError as e:
    print(f"Idempotency-Key reused with a different body: {e.message}")
except aegis.ValidationError as e:
    print(f"Bad request: {e.message}")
except aegis.AegisError as e:
    print(f"API error: {e.message} (request_id={e.request_id})")

Configuration

client = Aegis(
    api_key="uk_live_xxx",       # omit for sandbox mode
    base_url="https://...",      # or AEGIS_BASE_URL env var
    timeout=60.0,                # seconds (default: 30)
    max_retries=3,               # retry attempts (default: 2)
)

Customer Management

client = Aegis(api_key="uk_live_xxx")

profile = client.get_profile()
print(profile.tier)              # "professional"

usage = client.get_usage()
print(usage.total_evaluations)   # 847

keys = client.list_keys()
new_key = client.create_key("CI Pipeline")

Attestations

Issue, verify, and retrieve artifact-bound AEGIS attestations (in-toto Statement v1 wrapped in DSSE v1 envelope, signed with hybrid Ed25519 + ML-DSA-65 per ADR-011).

from aegis import Aegis

client = Aegis(api_key="uk_live_...")  # auth required (no sandbox mode)

# Issue an attestation binding decision_id → artifact digest
result = client.attestations.attest(
    decision_id="12345678-1234-1234-1234-123456789abc",
    subject_digest_sha256="<sha256 hex>",
    environment="production",            # "production" | "staging" | "preview"
    risk_class="medium",                 # "low" | "medium" | "high" | "critical"
    policy_version="1.2.0",
    repository="undercurrentai/your-repo",
    workflow_ref=".github/workflows/deploy.yml@refs/heads/main",
    run_id="25579660561",
    run_attempt=1,
    gate_pass_states={"risk":"pass","profit":"pass","novelty":"pass",
                      "complexity":"pass","quality":"pass","utility":"pass"},
    builder_id="https://github.com/undercurrentai/your-repo/actions",
    expires_at="2026-05-10T12:00:00+00:00",
)
print(result.envelope.payload_type)        # "application/vnd.in-toto+json"
print(len(result.envelope.signatures))      # 2 (ed25519 + ml-dsa-65)
print(result.idempotent_replayed)           # False on fresh issue, True on cache replay

# Server-side reference verification (HTTP 200 always; check `valid` field)
verify = client.attestations.verify(
    envelope=result.envelope,
    expected_digest="<sha256 hex>",
    expected_environment="production",
)
if not verify.valid:
    print(f"verification failed: {verify.error_class}")

# Retrieve persisted attestation (tenant-isolated to caller's customer_id)
record = client.attestations.get(decision_id=result.decision_id)
print(record.predicate.governance.artifact_digest)

Idempotency

Pass idempotency_key="..." for cross-process dedup; the server honors it with a 24h dedup window per ADR-010. The same Idempotency-Key + same body → 200 with result.idempotent_replayed=True (cached envelope returned, NOT freshly issued). Different body with same key → IdempotencyBodyMismatchError (HTTP 422; since 1.4.0 — earlier releases raised the generic AegisError). A concurrent request still in flight with the same key → ConflictError (HTTP 409) — back off briefly and retry with the same key to receive the cached decision (this remedy requires an explicit idempotency_key; auto-generated keys are per-call). If omitted, the SDK auto-generates a UUID per call.

Async

from aegis import AsyncAegis

async with AsyncAegis(api_key="uk_live_...") as client:
    result = await client.attestations.attest(...)
    record = await client.attestations.get(decision_id=result.decision_id)

Attestation error handling

import aegis

try:
    record = client.attestations.get(decision_id="...")
except aegis.AttestationNotFoundError:
    # 404 — absent OR cross-customer (same shape; tenant-isolation invariant)
    ...
except aegis.AttestationCollisionError:
    # 409 (only on attest) — decision_id exists for foreign customer
    ...
except aegis.AttestationProviderUnavailableError:
    # 503 — server crypto provider unavailable; retryable
    ...
except aegis.AttestationSchemaDriftError:
    # 410 — post-migration predicate drift; not retryable, operator action required
    ...

Offline Verification (Sprint 4 / D2)

Verify an AEGIS attestation envelope without a network round-trip to the API server. Useful for air-gapped CI, latency-sensitive paths, AEGIS-API-outage tolerance, and stronger trust topology (pinned consumer-side public keys).

Install with the [verify] extra (adds cryptography, liboqs-python, rfc8785):

pip install aegis-governance[verify]
from aegis import verify_attestation_locally, AttestationVerifyKey

# Pin public keys at SDK init (consumers fetch out-of-band — Sprint 5/E2 verifier-kit
# ships canonical keys; or fetch from a project KMS / config)
keys = AttestationVerifyKey(
    ed25519_public=b"...32 bytes raw...",
    mldsa65_public=b"...1952 bytes raw...",
)

# Verify locally — pure crypto, no HTTP
valid, error_class = verify_attestation_locally(
    envelope=envelope,                      # DSSEEnvelope from client.attestations.attest(...)
    expected_digest="<sha256 lowercase hex 64>",
    expected_environment="production",      # "production" | "staging" | "preview"
    keys=keys,
)
if not valid:
    raise RuntimeError(f"local verification failed: {error_class}")

Error-class parity with server: verify_attestation_locally returns the SAME error_class strings the server's POST /attestations/verify emits, so consumer code is identical whether using HTTP verify (D1) or offline verify (D2). Examples: AttestationDigestMismatch, AttestationEnvironmentMismatch, AttestationExpired, AttestationEd25519VerifyFailed, AttestationMLDSAVerifyFailed.

Crypto details (per ADR-011):

  • in-toto Statement v1 wrapped in DSSE v1 envelope
  • AND-of-2 hybrid signatures: Ed25519 (classical) + ML-DSA-65 (post-quantum, FIPS 204 final)
  • RFC 8785 JSON Canonicalization with NFC Unicode normalization
  • DSSE PAE byte-exact format match with server-side AttestationProvider.verify()

Pricing

TierMonthlyEvaluationsRate Limit
SandboxFree10/dayNo signup
CommunityFree100/month60/min
Professional$3,50010,000/month100/min
Enterprise$18,000100,000/month1,000/min

Full pricing details

License

Apache 2.0 - see LICENSE for details.

Keywords

ai

FAQs

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts