# Verification Policy Contract **Contract ID:** `CONTRACT-VERIFICATION-POLICY-006` **Version:** 1.0 **Status:** Published **Last Updated:** 2025-12-05 ## Overview This contract defines the VerificationPolicy schema used to configure attestation verification requirements. It specifies which predicate types are allowed, signer requirements, and tenant-scoped verification rules. ## Implementation References - **Predicate Types:** `src/Signer/StellaOps.Signer/StellaOps.Signer.Core/PredicateTypes.cs` - **Attestor Core:** `src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core/Verification/` - **Schema:** `src/Attestor/StellaOps.Attestor.Types/schemas/verification-policy.v1.schema.json` ## JSON Schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://stellaops.io/schemas/verification-policy.v1.json", "title": "VerificationPolicy", "description": "Attestation verification policy configuration", "type": "object", "required": ["policyId", "version", "predicateTypes", "signerRequirements"], "properties": { "policyId": { "type": "string", "description": "Unique policy identifier", "pattern": "^[a-z0-9-]+$" }, "version": { "type": "string", "description": "Policy version (SemVer)", "pattern": "^\\d+\\.\\d+\\.\\d+$" }, "description": { "type": "string", "description": "Human-readable policy description" }, "tenantScope": { "type": "string", "description": "Tenant ID this policy applies to, or '*' for all tenants" }, "predicateTypes": { "type": "array", "description": "Allowed attestation predicate types", "items": { "type": "string" }, "minItems": 1 }, "signerRequirements": { "$ref": "#/$defs/SignerRequirements" }, "validityWindow": { "$ref": "#/$defs/ValidityWindow" }, "metadata": { "type": "object", "additionalProperties": true } }, "$defs": { "SignerRequirements": { "type": "object", "properties": { "minimumSignatures": { "type": "integer", "minimum": 1, "default": 1, "description": "Minimum number of valid signatures required" }, "trustedKeyFingerprints": { "type": "array", "items": { "type": "string", "pattern": "^sha256:[a-f0-9]{64}$" }, "description": "List of trusted signer key fingerprints" }, "trustedIssuers": { "type": "array", "items": { "type": "string" }, "description": "List of trusted issuer identities" }, "requireRekor": { "type": "boolean", "default": false, "description": "Require Rekor transparency log entry" }, "algorithms": { "type": "array", "items": { "type": "string", "enum": ["ES256", "ES384", "ES512", "RS256", "RS384", "RS512", "EdDSA"] }, "description": "Allowed signing algorithms" } } }, "ValidityWindow": { "type": "object", "properties": { "notBefore": { "type": "string", "format": "date-time", "description": "Policy not valid before this time" }, "notAfter": { "type": "string", "format": "date-time", "description": "Policy not valid after this time" }, "maxAttestationAge": { "type": "integer", "minimum": 0, "description": "Maximum age of attestation in seconds" } } } } } ``` ## Example Policy ```json { "policyId": "default-verification-policy", "version": "1.0.0", "description": "Default verification policy for StellaOps attestations", "tenantScope": "*", "predicateTypes": [ "stella.ops/sbom@v1", "stella.ops/vex@v1", "stella.ops/vexDecision@v1", "stella.ops/policy@v1", "stella.ops/promotion@v1", "stella.ops/evidence@v1", "stella.ops/graph@v1", "stella.ops/replay@v1", "https://slsa.dev/provenance/v1", "https://cyclonedx.org/bom", "https://spdx.dev/Document", "https://openvex.dev/ns" ], "signerRequirements": { "minimumSignatures": 1, "trustedKeyFingerprints": [ "sha256:abc123...", "sha256:def456..." ], "requireRekor": false, "algorithms": ["ES256", "RS256", "EdDSA"] }, "validityWindow": { "maxAttestationAge": 86400 } } ``` ## Predicate Types ### StellaOps Types | Type URI | Description | |----------|-------------| | `stella.ops/promotion@v1` | Promotion attestation | | `stella.ops/sbom@v1` | SBOM attestation | | `stella.ops/vex@v1` | VEX attestation | | `stella.ops/vexDecision@v1` | VEX decision with reachability | | `stella.ops/replay@v1` | Replay manifest attestation | | `stella.ops/policy@v1` | Policy evaluation result | | `stella.ops/evidence@v1` | Evidence chain | | `stella.ops/graph@v1` | Graph/reachability attestation | ### Third-Party Types | Type URI | Description | |----------|-------------| | `https://slsa.dev/provenance/v0.2` | SLSA Provenance v0.2 | | `https://slsa.dev/provenance/v1` | SLSA Provenance v1.0 | | `https://cyclonedx.org/bom` | CycloneDX SBOM | | `https://spdx.dev/Document` | SPDX SBOM | | `https://openvex.dev/ns` | OpenVEX | ## Verification Flow ``` 1. Parse DSSE envelope 2. Extract predicate type from in-toto statement 3. Check predicate type against policy.predicateTypes 4. Verify signature(s) meet policy.signerRequirements a. Check algorithm is allowed b. Verify minimum signature count c. Check key fingerprints against trusted list 5. If requireRekor, verify Rekor log entry 6. Check attestation timestamp against validityWindow 7. Return verification result ``` ## API Endpoints ### Create Policy ``` POST /api/v1/attestor/policies Content-Type: application/json { "policyId": "custom-policy", "version": "1.0.0", ... } Response: 201 Created ``` ### Get Policy ``` GET /api/v1/attestor/policies/{policyId} Response: 200 OK { ... } ``` ### Verify Attestation ``` POST /api/v1/attestor/verify Content-Type: application/json { "envelope": "base64-encoded DSSE envelope", "policyId": "default-verification-policy" } Response: 200 OK { "valid": true, "predicateType": "stella.ops/sbom@v1", "signatureCount": 1, "signers": [ { "keyFingerprint": "sha256:...", "algorithm": "ES256", "verified": true } ], "rekorEntry": null } ``` ## Verification Result ```json { "valid": true, "predicateType": "stella.ops/sbom@v1", "signatureCount": 1, "signers": [ { "keyFingerprint": "sha256:abc123...", "issuer": "https://stellaops.io/signer", "algorithm": "ES256", "verified": true } ], "rekorEntry": { "uuid": "24296fb24b8ad77a...", "logIndex": 12345, "integratedTime": "2025-12-05T10:00:00Z" }, "attestationTimestamp": "2025-12-05T09:59:59Z", "policyId": "default-verification-policy", "policyVersion": "1.0.0" } ``` ## Unblocks This contract unblocks the following tasks: - POLICY-ATTEST-73-001 - POLICY-ATTEST-73-002 - POLICY-ATTEST-74-001 - POLICY-ATTEST-74-002 ## Related Contracts - [Mirror Bundle Contract](./mirror-bundle.md) - Uses verification for bundle import - [Sealed Mode Contract](./sealed-mode.md) - Verification in air-gapped mode