Releases: craigamcw/raucle
Release list
v0.13.0 — Security fail-loud + strict proof-enforced mint mode
Security minor release. Two P1 fixes addressing structural-correctness gaps surfaced by an internal security review. No public-API breaks — every new behaviour is opt-in. Existing deployments see no surprise.
FIX 1 — Fail-loud cryptographic configuration
Six places in the codebase used silent try / except: pass patterns around signer initialisation. The behaviour is now:
- Explicit config + broken = REFUSE. Operator misconfigured; raise
ConfigurationError, exit non-zero. - No config + safe default exists = WARN loudly. Continue in explicitly-marked unsigned mode.
- Never silent.
Affected paths:
raucle_detect/errors.py— new module:ConfigurationError,PolicyUnproven.raucle_detect.server._init_compliance()— extracted from import-time init;RAUCLE_DETECT_VERDICT_KEY_PEMorRAUCLE_DETECT_AUDIT_PRIVATE_KEY_PEMset but unparseable now refuses to start.VerdictSigner.__init__/Ed25519Signer.__init__— a signer whose public key cannot be extracted raisesConfigurationErrorat construction (was: silently produced unverifiable receipts).audit.sink_from_env()— invalidRAUCLE_DETECT_AUDIT_PRIVATE_KEY_PEMraises instead of silently producing an unsigned sink.HashChainSink— every newly-created chain emits a self-describingchain_metaheader on line 1, signed when a signer is supplied.AuditVerifiersurfacessigned_mode ∈ {signed, unsigned, unknown}and rejects splice attempts (signed checkpoint in unsigned chain, mismatchedkey_idbetween header and checkpoint).
FIX 2 — Strict proof-enforced mint mode
Previously, cap mint --policy-proof-hash was advisory: any string could be passed. Tokens cited proofs they had no structural relationship to. The new strict mode makes the relationship enforceable.
from raucle_detect.capability import CapabilityIssuer
from raucle_detect.prove import JSONSchemaProver
# 1. Prove the policy
result = JSONSchemaProver().prove(schema=tool_schema, policy=tool_policy)
assert result.status == "PROVEN"
# 2. Strict-mint binds proof + grammar + policy hashes into the token
issuer = CapabilityIssuer.generate(issuer="acme.bank.kyc", require_proof=True)
token = issuer.mint(
agent_id="agent:kyc-prod",
tool="lookup_customer",
proof_result=result, # required
)
# 3. The token now carries:
# token.policy_proof_hash == result.hash
# token.grammar_hash == result.grammar_hash
# token.policy_hash == result.policy_hash
# All three covered by token_id and the Ed25519 signature.Defence-in-depth at the gate too:
from raucle_detect.capability import CapabilityGate
gate = CapabilityGate(
trusted_issuers={...},
proof_enforcement_mode=\"strict\",
trusted_proofs={result.hash: result}, # pre-loaded cache
)
# Every call now denied unless:
# * token has policy_proof_hash, AND
# * proof in trusted_proofs cache, AND
# * proof.status == 'PROVEN', AND
# * token.grammar_hash matches proof.grammar_hash, AND
# * token.policy_hash matches proof.policy_hashCLI:
# Strict mint:
raucle-detect cap mint \\
--key issuer.key.pem --issuer acme.bank.kyc \\
--agent-id agent:kyc-prod --tool lookup_customer \\
--require-proof --proof-result proof.json \\
--out token.jsonraucle-detect prove json|url|sql already returned exit-code 2 on REFUTED and 1 on UNDECIDED — both pipeline-failing under set -e. Now covered by tests so CI never silently regresses.
Backward compatibility
| Default | Opt-in via | |
|---|---|---|
| Strict mint mode | OFF | CapabilityIssuer(require_proof=True) or RAUCLE_REQUIRE_PROOF=1 |
| Gate-time proof enforcement | OFF | `CapabilityGate(proof_enforcement_mode='lenient' |
Chain chain_meta header |
always emitted on new chains | n/a — additive on-wire format; legacy chains remain verifiable |
| Fail-loud crypto errors | always loud | n/a — replaces silent except-pass with ConfigurationError |
The two Capability field additions (grammar_hash, policy_hash) are nullable; absent in pre-0.13.0 tokens. Round-tripped through to_dict() / from_dict() cleanly.
Tests
70 new tests across tests/test_audit.py, tests/test_verdicts.py, tests/test_capability.py, tests/test_server_init.py, tests/test_cli_exit_codes.py. Full suite: 429 passed, 4 skipped. No regressions.
What's not in this release
- Hosted policy-registry fetcher (gate consults a published registry at runtime with TTL caching).
[DECIDE: gate-time proof enforcement]comment inCapabilityGate.__init__flags this as future scope; current gate-time enforcement uses a caller-supplied in-memory cache. - Argon2id password hashes server-side. Out of scope for this fix.
🤖 Generated with Claude Code
v0.12.0 — Microsoft AGT integration first-class (PR #2610 merged)
Microsoft's Agent Governance Toolkit just landed our PR.
microsoft/agent-governance-toolkit#2610 — adding proof_artefact and verification_pointers carry-through on AGT's BackendDecision so high-assurance external policy backends can attach offline-verifiable evidence to the AGT audit chain — merged upstream at 25abf72 on 2026-05-27 by Microsoft maintainer Imran Siddique.
raucle-detect v0.12.0 ships the first-class integration that consumes the new contract.
What's new
RauclePolicyBackend
from agent_os.policies.evaluator import PolicyEvaluator
from raucle_detect.integrations.agt_backend import RauclePolicyBackend
from raucle_detect.capability import CapabilityGate, CapabilityIssuer
issuer = CapabilityIssuer.generate(issuer="acme.bank.kyc-platform")
gate = CapabilityGate(trusted_issuers={issuer.key_id: issuer.public_key_pem})
evaluator = PolicyEvaluator()
evaluator.add_backend(RauclePolicyBackend(
gate=gate,
verification_base_url="https://acme.bank",
))Every BackendDecision raucle returns now carries:
proof_artefact— the cited policy-proof hash (SMT-verified, content-addressed)verification_pointers—{issuer_pubkey, policy_registry, lean_development}URLs where an external auditor can fetch the deploying organisation's published material and re-verify the decision offline
AGT's PolicyEvaluator propagates both into PolicyDecision.audit_entry, so any AGT audit-chain consumer gets offline-verifiable evidence on every raucle-rendered decision automatically.
Graceful degradation
The backend detects at construction whether the installed AGT carries the merged fields. On pre-merge AGT installs, verdicts remain correct; the evidence fields are silently dropped. No code changes required for users straddling the upgrade.
Tests
7 new tests in tests/test_agt_backend.py. Skipped automatically when agent_os is not installed; passing 7/7 against microsoft/agent-governance-toolkit@main post-merge.
Deprecation
The pre-merge raucle_detect.integrations.agt stub module is deprecated; remove in v0.13.0. New consumers use raucle_detect.integrations.agt_backend.RauclePolicyBackend.
Where this sits
This is the second of three Microsoft-stack integrations.
- v0.11.0 — Agent Framework
FunctionMiddleware. ✅ - v0.12.0 — AGT
ExternalPolicyBackend. ✅ shipped here. - v0.13.0 — Azure AI Foundry MCP Gateway sidecar (recorded walkthrough in progress).
🤖 Generated with Claude Code