You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Version bumps: pyproject, sonar.projectVersion, __version__ -> 0.3.0.
CHANGELOG: [Unreleased] finalized as [0.3.0]; adds the admission-semantics
bullet (VERIFIED admits only with a cryptographically valid bound
attestation; placeholder tokens now BLOCK) and new runtime dependencies
(pyjwt, cryptography).
README: all three stale presence-only attestation statements updated to
the shipped cryptographic reality; NetworkGuard usage example extended
with the full mint flow (verify -> to_diagnostic ->
mint_diagnostic_attestation -> to_verification_context) and verified
runnable end-to-end; roadmap restructured with v0.3.0 as current and the
deferred Docker/K8s/Azure items moved to Next.
513 tests pass; docs+version-only release prep.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+6-2Lines changed: 6 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,16 +1,20 @@
1
1
# Changelog
2
2
3
-
## [Unreleased]
3
+
## [0.3.0] - 2026-08-24
4
4
5
5
### Added
6
6
- Verification Context v1.0 across all four guards (tracker #36) — every guard now exposes `to_verification_context()`, producing a schema-valid, tamper-evident VC document (claim, verifier identity, `sha256`-bound evidence `proof_ref`, ADMIT/DENY admission):
- Shared bridge module `verification_context_bridge` (#37, PR #44): diagnostic → VC document conversion with fail-closed attestation policy and decision-status demotion
9
9
- Conformance suite `tests/test_vc_conformance.py` (#42, PR #52) — bridge + all guards + document validation + malformed-input fail-closed acceptance tests
10
10
- README: "Verification Context v1.0" section — why VC, usage examples, downstream integration guide; VC badge in the header
11
+
-**Attestation trust boundary (#47, PR #54)** — new `qwed_infra/attestation.py`: ES256 (ECDSA P-256) JWT attestation service with ephemeral key lifecycle auditing, revocation registry, and the never-None fail-closed `AttestationResult` contract; `enforce_trust_decision()` in diagnostics.py as the single consumption-side gate validating signature/issuer/expiry/revocation plus claim bindings (status match, `query_hash == sha256(formal_statement)`, `proof_hash == diagnostic proof_ref`)
12
+
-`mint_diagnostic_attestation()` — issues a token bound to a diagnostic's own evidence commitment
11
13
12
14
### Changed
13
-
-**BREAKING (pre-1.0, unreleased API):** guard adapters no longer accept pre-computed result objects. `to_verification_context()` takes **raw verification inputs** and runs the guard's own deterministic solver internally (`NetworkGuard.to_verification_context(resources, source, destination, port, ...)` / `IamGuard.to_verification_context(policy, action, resource, context, ...)` / `CostGuard.to_verification_context(resources, budget_monthly, ...)` / `ArtifactBoundaryGuard.to_verification_context(package_dir, ...)`) — a result-accepting signature is forgeable (a caller could fabricate a positive result and mint ADMIT), so it was removed before any release (PRs #45/#46/#48/#50)
15
+
-**BREAKING (pre-1.0, unreleased API):** guard adapters no longer accept pre-computed result objects. `to_verification_context()` takes **raw verification inputs** and runs the guard's own deterministic solver internally (`NetworkGuard.to_verification_context(resources, source, destination, port, ...)` / `IamGuard.to_verification_context(policy, action, resource, context=None, ...)` / `CostGuard.to_verification_context(resources, budget_monthly, ...)` / `ArtifactBoundaryGuard.to_verification_context(package_dir, ...)`) — a result-accepting signature is forgeable (a caller could fabricate a positive result and mint ADMIT), so it was removed before any release (PRs #45/#46/#48/#50)
16
+
-**ADMISSION SEMANTICS:**`VERIFIED` results now admit **only** with a cryptographically valid attestation bound to the exact claim and evidence. Arbitrary non-empty attestation strings no longer grant ADMIT (they are rejected as forged tokens); a missing token demotes VERIFIED to UNVERIFIABLE/DENY. Callers previously passing placeholder tokens must mint via `create_verification_attestation()` / `mint_diagnostic_attestation()`
17
+
- New runtime dependencies: `pyjwt>=2.8.0,!=2.12.1`, `cryptography>=41.0.0`
14
18
15
19
### Fixed
16
20
- Fail-closed on malformed inputs at every VC boundary: undecimal budgets, extreme Decimal values, non-string build backends, malformed topology/policy/package inputs, symlink escapes/loops, wheel entries outside the scanned boundary — all map to BLOCKED/DENY documents instead of exceptions or guessed approval (#48, #49/PR #51, #50)
Copy file name to clipboardExpand all lines: README.md
+21-8Lines changed: 21 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -203,14 +203,15 @@ A `True/False` return value is enough for one process — but CI/CD pipelines, r
203
203
| Lives only in your process log | JSON-serializable, schema-validated, evidence-bound (`sha256` proof_ref computed over the exact evidence) |
204
204
| No story when someone asks "who verified this?" |`proof.verifier`, `audit_trace`, and rule IDs answer it |
205
205
206
-
The document is **fail-closed by construction**: anything that is not proven is `DENY` — `UNVERIFIABLE` and `BLOCKED` outcomes can never produce `ADMIT`. Note that in v1.0 the attestation token is checked for **presence only** — cryptographic validation (signature/issuer/expiry/claim binding) lands with #47.
206
+
The document is **fail-closed by construction**: anything that is not proven is `DENY` — `UNVERIFIABLE` and `BLOCKED` outcomes can never produce `ADMIT`. Attestations are **cryptographically validated** (ES256 signature, issuer, expiry, revocation) and bound to the exact claim and evidence (`query_hash`, `proof_hash`) — a token minted for one statement can never admit another.
207
207
208
208
### Usage
209
209
210
210
Each guard runs its own verification internally and returns a VC document. You pass raw inputs — never a pre-computed result object:
211
211
212
212
```python
213
213
from qwed_infra import NetworkGuard
214
+
from qwed_infra.attestation import mint_diagnostic_attestation
214
215
215
216
net = NetworkGuard()
216
217
infra = {
@@ -223,15 +224,26 @@ infra = {
223
224
},
224
225
}
225
226
227
+
statement ="Traffic from internet to subnet-web on port 80 is safe"
228
+
229
+
# Mint an attestation bound to THIS claim + evidence (the guard computes the
230
+
# same check internally; the token's proof_hash must match its commitment).
Store or forward `document` anywhere JSON goes — release gates, pipeline artifacts, audit logs. The `proof_ref` binds a VERIFIED decision to the exact evidence that produced it. VC evidence can contain sensitive infrastructure, policy, or cost data — apply your own access control, redaction, and retention rules when storing or forwarding documents downstream.
278
290
279
-
> **Roadmap (#47):**today the attestation token is checked for **presence only**; cryptographic validation and claim binding (signature, issuer, expiry, digest binding à la `enforce_trust_decision`) land with the attestation trust boundary milestone.
291
+
> **Attestation trust model:**attestations are self-signed by the guard process (ES256, ephemeral key) and cryptographically validated at the admission boundary — signature, issuer, expiry, revocation, plus binding to the exact claim and evidence. This is the interim stage on the path to an external witness/transparency log (ADR-005 in qwed-verification); multi-replica deployments require shared signing keys until replica-key resolution exists.
280
292
281
293
---
282
294
@@ -296,8 +308,9 @@ A: We use public On-Demand pricing for "Worst Case" estimation. If you have Ente
296
308
## 🗺️ Roadmap
297
309
298
310
* ✅ **v0.1.0:** IAM Z3 Logic, Basic Network Graph, Static Cost Catalog. (Released Jan 2025)
* ✅ **v0.2.0:** Fail-closed parser + IAM, NetworkGuard CIDR fix, CI fail-open removal, diagnostic port (audit.py/InfraDiagnosticResult), CostGuard Decimal/unknown types, ArtifactBoundaryGuard.
312
+
* ✅ **v0.3.0:** Verification Context v1.0 across all four guards (bridge, `to_verification_context()` adapters, conformance suite) + attestation trust boundary — ES256-signed receipts bound to the exact claim and evidence gate every ADMIT. (Current)
0 commit comments