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()
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)
print(decision.remaining)
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")
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
| Sandbox mode | 10 free evaluations/day, no signup required |
| 6 Bayesian gates | Risk, profit, novelty, complexity, quality, utility |
| KL divergence drift | Detects when your risk baseline shifts |
| Shadow mode | Evaluate without enforcing (calibration) |
| Typed responses | Full dataclass types with IDE autocomplete |
| Async support | AsyncAegis with identical API surface |
| Retry + backoff | Automatic retry on transient failures (429, 5xx) |
| Idempotency | Safe 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 enforced | HTTPS 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")
result = client.risk_check(
risk_score=0.15,
threshold=0.3,
action_description="Deploy to production",
)
print(result.safe)
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:
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)
print(decision.gates.novelty)
print(decision.gates.complexity)
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",
base_url="https://...",
timeout=60.0,
max_retries=3,
)
Customer Management
client = Aegis(api_key="uk_live_xxx")
profile = client.get_profile()
print(profile.tier)
usage = client.get_usage()
print(usage.total_evaluations)
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_...")
result = client.attestations.attest(
decision_id="12345678-1234-1234-1234-123456789abc",
subject_digest_sha256="<sha256 hex>",
environment="production",
risk_class="medium",
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)
print(len(result.envelope.signatures))
print(result.idempotent_replayed)
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}")
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:
...
except aegis.AttestationCollisionError:
...
except aegis.AttestationProviderUnavailableError:
...
except aegis.AttestationSchemaDriftError:
...
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
keys = AttestationVerifyKey(
ed25519_public=b"...32 bytes raw...",
mldsa65_public=b"...1952 bytes raw...",
)
valid, error_class = verify_attestation_locally(
envelope=envelope,
expected_digest="<sha256 lowercase hex 64>",
expected_environment="production",
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
| Sandbox | Free | 10/day | No signup |
| Community | Free | 100/month | 60/min |
| Professional | $3,500 | 10,000/month | 100/min |
| Enterprise | $18,000 | 100,000/month | 1,000/min |
Full pricing details
Links
License
Apache 2.0 - see LICENSE for details.