Skip to content

docs: Tutorial 46 — selective-disclosure receipts (extends Tutorial 33)#1489

Closed
tomjwxf wants to merge 1 commit into
microsoft:mainfrom
tomjwxf:feat/tutorial-46-selective-disclosure
Closed

docs: Tutorial 46 — selective-disclosure receipts (extends Tutorial 33)#1489
tomjwxf wants to merge 1 commit into
microsoft:mainfrom
tomjwxf:feat/tutorial-46-selective-disclosure

Conversation

@tomjwxf
Copy link
Copy Markdown
Contributor

@tomjwxf tomjwxf commented Apr 27, 2026

Adds Tutorial 46 — Selective-Disclosure Receipts with a companion worked example
under examples/selective-disclosure-governed/. Extends Tutorial 33's offline-verifiable
receipt construction with per-field Merkle commitments (RFC 6962-style), so an issuer
can reveal specific fields to specific auditors and prove the rest are unchanged
without exposing them.

What this adds

File Bytes Purpose
docs/tutorials/46-selective-disclosure-receipts.md 33,454 Full tutorial (10 sections: construction, signing, disclosure generation, offline verification, chain composition, Article 12 + GDPR composition, cross-implementation interop, CI/CD)
examples/selective-disclosure-governed/getting_started.py 13,425 Single-file Python reference with end-to-end round-trip self-test (7 assertions)
examples/selective-disclosure-governed/README.md 10,641 Quick start, scenario table, architecture diagram, disclosure profile examples, standards references

Construction (one paragraph)

Each receipt field is committed as a leaf via SHA-256(0x00 || JCS({name, salt, value}))
with a fresh 16-byte salt per field. Leaves are arranged into an RFC 6962 Merkle tree
(node prefix 0x01, non-power-of-two leaf handling matches the CT spec). The receipt
envelope carries a single committed_fields_root field, signed Ed25519 over the
JCS-canonical bytes alongside the public fields. A disclosure is a separate JSON
artifact carrying (name, value, salt, proof, index, leaf_count) tuples for the
fields the issuer chose to reveal. The verifier walks each Merkle proof to recompute
the root, then verifies the envelope signature against the public key.

Use case: EU AI Act Article 12 + GDPR composition

The same signed receipt can serve multiple auditors with different disclosure scopes
simultaneously, without re-signing. Article 12 audit sees every field; GDPR data
controller sees only process metadata; cross-org counterparty sees auth scope only.
The construction is described in §5 of draft-farley-acta-signed-receipts-01 (live
on datatracker, AGT listed as Appendix A.9 conformant implementation).

Tutorial number selection

Slot 34 is currently 34-maf-integration.md. The next available sequential slot is 46
(after 45-shift-left-governance.md).

Verification

All 7 round-trip assertions in getting_started.py pass end-to-end:

1. Envelope signature: ok
2. Article 12 (every field):                    ok
3. GDPR (process metadata only):                ok
4. Counterparty (auth scope only):              ok
5. Tampered (value swapped):                    rejected as expected
6. Tampered envelope (decision flipped):        rejected as expected
7. Chained receipt (rcpt-0001 -> rcpt-0002):    ok

All 7 assertions passed.

Run locally with:

pip install cryptography
python examples/selective-disclosure-governed/getting_started.py

Cross-implementation conformance is checkable against the open Apache-2.0 testvectors
at https://github.com/ScopeBlind/agent-governance-testvectors, which already includes
commitment-mode fixtures across TypeScript / Python / Rust / Go.

Standards

Cross-references

Note on timing

This lands during AGT's foundation review window. The selective-disclosure capability
the tutorial covers is the construction referenced in the recent foundation submissions
as part of AGT's open-standards integration story:

Tutorial 33 already covered the basic offline-verification path. Tutorial 46 covers
the EU AI Act Article 12 + GDPR composition story (one signed receipt, multiple
disclosure scopes, no per-pair adapters), which is the production-readiness primitive
the foundation TCs evaluating those submissions will likely look for.

…disclosure receipts)

Adds Tutorial 46 (Selective-Disclosure Receipts) with a companion worked
example. Extends Tutorial 33's offline-verifiable receipt construction
with per-field Merkle commitments per RFC 6962, so an issuer can reveal
specific fields to specific auditors and prove the rest are unchanged
without exposing them.

Construction
============
Each receipt field is committed as a leaf via
SHA-256(0x00 || JCS({name, salt, value})) with a fresh 16-byte salt per
field. Leaves are arranged into an RFC 6962-style Merkle tree (node prefix
0x01, non-power-of-two leaf handling matches the CT spec). The receipt
envelope carries a single committed_fields_root field, signed Ed25519
over the JCS-canonical bytes alongside the public fields.

A disclosure is a separate JSON artifact carrying (name, value, salt,
proof, index, leaf_count) tuples for the fields the issuer chose to
reveal to a specific auditor. The verifier walks each Merkle proof to
recompute the root, then verifies the envelope signature against the
public key. No issuer cooperation needed.

Files
=====
- docs/tutorials/46-selective-disclosure-receipts.md (33,454 bytes)
  Full tutorial covering the construction, generating disclosures,
  verifying offline, composing with Tutorial 33's chain, the
  Article 12 + GDPR composition use case, cross-implementation interop,
  and a CI/CD workflow for gating merges on disclosure verification.

- examples/selective-disclosure-governed/getting_started.py (~13K)
  Single-file Python reference with end-to-end round-trip self-test.
  Mints a 7-field receipt, issues three disclosure profiles (Article 12,
  GDPR, counterparty), verifies each, then exercises tamper detection
  for both field-level and envelope-level modifications, plus a chained
  receipt composing parent_receipt_hash with selective disclosure.
  All 7 assertions pass; exits 0 on success.

- examples/selective-disclosure-governed/README.md (~10K)
  Quick start, scenario table, architecture diagram, disclosure profile
  examples, cross-implementation verification notes, standards
  references.

Tutorial number selection
=========================
34 is currently 34-maf-integration.md. The next available sequential
slot is 46 (after the recent batch through 45-shift-left-governance.md).

Standards
=========
- Ed25519 (RFC 8032), JCS (RFC 8785), SHA-256
- RFC 6962 Merkle tree construction (Certificate Transparency)
- IETF draft-farley-acta-signed-receipts-01 §5 (commitment-mode profile,
  on datatracker, AGT listed as Appendix A.9 conformant implementation)

Verification
============
- All 7 round-trip assertions in getting_started.py pass:
    1. Envelope signature valid with no disclosures attached
    2. Article 12 disclosure (every committed field) verifies
    3. GDPR disclosure (process metadata only) verifies
    4. Counterparty disclosure (auth scope only) verifies
    5. Tampered field value rejected (merkle proof fails)
    6. Tampered envelope rejected (signature invalid)
    7. Chained receipt rcpt-0001 -> rcpt-0002 verifies (composes
       parent_receipt_hash with field-level Merkle root)
- Cross-implementation conformance is checkable against the open
  Apache-2.0 testvectors at github.com/ScopeBlind/agent-governance-
  testvectors, which already includes commitment-mode fixtures across
  TypeScript / Python / Rust / Go.

Cross-references
================
- Direct prerequisite: Tutorial 33 (Offline-Verifiable Decision Receipts)
- Related: Tutorial 04 (Audit & Compliance), Tutorial 12 (Liability &
  Attribution), Tutorial 18 (Compliance Verification), Tutorial 23
  (Delegation Chains), Tutorial 26 (SBOM & Signing)
@github-actions
Copy link
Copy Markdown

Welcome to the Agent Governance Toolkit! Thanks for your first pull request.
Please ensure tests pass, code follows style (ruff check), and you have signed the CLA.
See our Contributing Guide.

@github-actions github-actions Bot added documentation Improvements or additions to documentation size/XL Extra large PR (500+ lines) labels Apr 27, 2026
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 AI Agent: code-reviewer

Review Summary

This pull request introduces a new tutorial (Tutorial 46) and accompanying example code for implementing selective-disclosure receipts using RFC 6962-style Merkle trees. The tutorial builds on Tutorial 33's offline-verifiable receipts and extends the functionality to allow selective disclosure of specific fields while maintaining cryptographic integrity for the rest. The implementation is well-documented, adheres to established standards (Ed25519, JCS, SHA-256, RFC 6962), and includes comprehensive examples and tests.

Feedback

🔴 CRITICAL: Security Issues

  1. Salt Generation and Storage:

    • The salt generation uses os.urandom(16) for per-field salting, which is cryptographically secure. However, the tutorial does not explicitly address the secure storage of these salts. If salts are lost, the corresponding fields become undisclosable, which could lead to operational issues. Ensure that salts are securely stored and managed in production environments.
  2. Disclosure Proof Validation:

    • The verify_proof function assumes that the proof array and leaf_count are correctly provided by the issuer. If an attacker manipulates these values, it could lead to incorrect verification results. Consider adding stricter validation checks for these inputs, such as verifying that leaf_count matches the expected number of leaves in the Merkle tree.
  3. Replay Attacks:

    • The tutorial does not address the risk of replay attacks, where a valid disclosure proof could be reused maliciously. Consider adding a mechanism to ensure that disclosures are tied to specific auditors or contexts, such as including a nonce or timestamp in the disclosure proof.

🟡 WARNING: Potential Breaking Changes

  1. Backward Compatibility:
    • The introduction of the committed_fields_root field in the receipt envelope changes the structure of the receipt. Ensure that this change does not break existing systems that rely on the previous format. Provide clear migration guidelines for users upgrading from Tutorial 33 to Tutorial 46.

💡 Suggestions for Improvement

  1. Thread Safety:

    • The tutorial does not explicitly address thread safety in concurrent agent execution. If the library is intended for use in multi-threaded environments, ensure that the salt generation and storage mechanisms are thread-safe.
  2. Type Safety and Validation:

    • While the tutorial uses Python's type hints, consider integrating Pydantic models for strict validation of receipt and disclosure data structures. This would ensure type safety and prevent malformed data from being processed.
  3. Error Handling:

    • The error handling in the verify_receipt_with_disclosure function could be improved. Instead of returning a tuple (False, "error message"), consider raising specific exceptions for different error conditions. This would make debugging and integration easier.
  4. Performance Optimization:

    • The merkle_root function uses a recursive approach to compute the Merkle root. For large numbers of leaves, this could lead to stack overflow. Consider implementing an iterative approach to improve scalability.
  5. Documentation:

    • While the tutorial is comprehensive, it could benefit from a dedicated section on security considerations, including the risks of salt loss, replay attacks, and the importance of secure key management.
  6. Testing:

    • The tutorial includes 7 assertions for end-to-end testing, which is excellent. However, consider adding tests for edge cases, such as:
      • Receipts with a single field.
      • Receipts with a large number of fields (e.g., 1,000+).
      • Invalid or malformed disclosure proofs.
  7. Cross-Implementation Interoperability:

    • The tutorial mentions interoperability with other implementations (e.g., TypeScript, Rust, Go). Consider providing a compatibility matrix or test results to demonstrate cross-implementation consistency.
  8. GDPR Compliance:

    • The tutorial mentions GDPR compliance but does not provide specific guidance on how to handle sensitive fields (e.g., user_id) in practice. Consider adding a section on best practices for GDPR-compliant receipt generation and disclosure.

Conclusion

This pull request is a well-thought-out addition to the repository, providing valuable functionality for selective disclosure receipts. Addressing the critical security issues and potential breaking changes will ensure the robustness and reliability of the implementation. The suggestions provided can further enhance the tutorial's usability, security, and compliance.

@github-actions
Copy link
Copy Markdown

🤖 AI Agent: security-scanner — Security Review for Pull Request: Tutorial 46 — Selective-Disclosure Receipts

Security Review for Pull Request: Tutorial 46 — Selective-Disclosure Receipts

This pull request introduces a new tutorial and example implementation for selective-disclosure receipts, which extend Tutorial 33's offline-verifiable receipts with per-field Merkle commitments. The goal is to allow issuers to selectively disclose specific fields to auditors while maintaining the integrity of the entire receipt.


Security Findings

1. Prompt Injection Defense Bypass

Rating: 🔵 LOW
The tutorial does not directly involve user input or natural language processing, so there is no immediate risk of prompt injection attacks. However, if this selective-disclosure mechanism is used in conjunction with AI systems that process user inputs, the disclosed fields could potentially be manipulated to inject malicious prompts.

Recommendation:

  • Ensure that any downstream use of disclosed fields in AI systems includes robust input sanitization and validation to prevent prompt injection attacks.

2. Policy Engine Circumvention

Rating: 🟠 HIGH
The selective-disclosure mechanism relies on the issuer to correctly manage the (name, value, salt) triples and generate valid disclosures. If the issuer loses or mismanages the salts, it could result in the inability to prove the integrity of hidden fields, effectively bypassing the policy engine's guarantees.

Attack Vector:
An attacker with access to the issuer's systems could tamper with or delete the salt store, making it impossible to verify the integrity of hidden fields. This could lead to a situation where the issuer cannot provide valid disclosures, undermining trust in the system.

Recommendation:

  • Implement robust key management practices for the salt store, including encryption and access controls.
  • Introduce a mechanism to periodically verify the integrity of the salt store and alert administrators to any discrepancies.
  • Consider adding a mechanism to allow for the regeneration of salts and re-signing of receipts in case of salt loss.

3. Trust Chain Weaknesses

Rating: 🟡 MEDIUM
The tutorial describes a mechanism for chaining receipts using parent_receipt_hash. While this provides temporal integrity, there is no explicit mention of how to handle key rotation or revocation. If the signing key is compromised, all previously issued receipts could be invalidated, breaking the trust chain.

Attack Vector:
If an attacker compromises the signing key, they could issue fraudulent receipts that appear valid. Additionally, without a mechanism for key rotation, the system may be vulnerable to long-term attacks.

Recommendation:

  • Implement key rotation and revocation mechanisms, and document how they interact with the receipt verification process.
  • Consider integrating with a trusted key management system that supports key lifecycle management.
  • Include a mechanism to timestamp receipts with a trusted time source to mitigate the risk of backdating attacks.

4. Credential Exposure

Rating: 🔵 LOW
The tutorial does not expose any sensitive credentials in the code or documentation. However, the example code generates Ed25519 keys in memory, which could be a risk in production if not handled securely.

Recommendation:

  • Clearly document that the example key generation is for demonstration purposes only and should not be used in production.
  • Recommend using a secure key management system for production deployments.

5. Sandbox Escape

Rating: 🔵 LOW
The tutorial does not involve sandboxing or execution of untrusted code, so there is no immediate risk of sandbox escape.

Recommendation:

  • If this mechanism is integrated into a system that executes untrusted code, ensure that appropriate sandboxing measures are in place.

6. Deserialization Attacks

Rating: 🟡 MEDIUM
The tutorial includes JSON deserialization of potentially untrusted input (e.g., the receipt and disclosure JSON objects). If the JSON parsing library is not configured securely, this could lead to deserialization attacks.

Attack Vector:
An attacker could craft a malicious JSON payload to exploit vulnerabilities in the JSON parsing library, potentially leading to remote code execution or denial of service.

Recommendation:

  • Use a secure JSON parsing library that does not allow arbitrary code execution during deserialization.
  • Validate the structure and content of the JSON objects before processing them.
  • Consider adding schema validation for the receipt and disclosure JSON objects.

7. Race Conditions

Rating: 🟠 HIGH
The tutorial does not address potential race conditions in the management of the salt store. If multiple processes attempt to access or modify the salt store simultaneously, it could lead to inconsistencies or data corruption.

Attack Vector:
An attacker could exploit race conditions to overwrite or delete salts, making it impossible to verify the integrity of hidden fields.

Recommendation:

  • Use atomic operations or a transactional database to manage the salt store.
  • Implement locking mechanisms to prevent concurrent access to the salt store.

8. Supply Chain Risks

Rating: 🟠 HIGH
The tutorial relies on third-party libraries such as cryptography, protect-mcp, and @veritasacta/verify. While these libraries are widely used and appear reputable, they introduce potential supply chain risks.

Attack Vector:
An attacker could compromise one of these libraries (e.g., via dependency confusion or typosquatting) to introduce malicious code into the system.

Recommendation:

  • Pin dependencies to specific versions to prevent unintentional upgrades to compromised versions.
  • Regularly audit dependencies for known vulnerabilities using tools like pip-audit or npm audit.
  • Consider using a dependency scanning tool in the CI/CD pipeline to detect and mitigate supply chain risks.

Summary of Findings

Category Rating Issue Recommendation
Prompt Injection Defense Bypass 🔵 LOW No immediate risk, but downstream AI systems could be vulnerable. Ensure input sanitization in downstream systems.
Policy Engine Circumvention 🟠 HIGH Salt mismanagement could undermine integrity of hidden fields. Implement robust salt management and periodic integrity checks.
Trust Chain Weaknesses 🟡 MEDIUM No key rotation or revocation mechanism. Add key rotation, revocation, and trusted timestamping mechanisms.
Credential Exposure 🔵 LOW Example code generates keys in memory, which is risky in production. Use a secure key management system in production.
Sandbox Escape 🔵 LOW No sandboxing involved in this tutorial. Ensure sandboxing if untrusted code is executed in downstream systems.
Deserialization Attacks 🟡 MEDIUM JSON deserialization could be exploited if not securely configured. Use secure JSON parsing and validate input structure.
Race Conditions 🟠 HIGH Salt store management could be vulnerable to race conditions. Use atomic operations or transactional databases for salt management.
Supply Chain Risks 🟠 HIGH Dependency on third-party libraries introduces potential risks. Pin dependencies, audit libraries, and use dependency scanning tools.

Overall Assessment

This pull request introduces a well-documented and robust mechanism for selective-disclosure receipts, which is a valuable addition to the toolkit. However, there are several areas where security could be improved, particularly around salt management, key rotation, and dependency security. Addressing these issues will ensure the integrity and trustworthiness of the selective-disclosure mechanism.

Recommendation: Address the identified HIGH and MEDIUM severity issues before merging this pull request.

@imran-siddique
Copy link
Copy Markdown
Member

Closing: contributor reputation check flagged this submission as HIGH risk.

Signals detected:

  • Following farming (95 followers / 2,220 following, 1:23 ratio)
  • 58 repos created in 90 days
  • Cross-repo spray: issues filed in 67 repos within 7 days
  • Credential laundering: 28 spray issues across 26 repos citing AGT merges as credentials

This matches the credential-laundering pattern described in our contributor check tooling. The content itself references external projects (ScopeBlind, VeritasActa) and foundation submissions that appear designed to build perceived legitimacy.

We welcome genuine contributions. If you believe this was flagged in error, please open a discussion.

@tomjwxf tomjwxf deleted the feat/tutorial-46-selective-disclosure branch April 27, 2026 03:28
@tomjwxf
Copy link
Copy Markdown
Contributor Author

tomjwxf commented Apr 30, 2026

For the record, I dispute the allegations and imputations made in this thread concerning me, my business ScopeBlind, my open source organization Veritas Acta, and foundation submissions where both me and my work are explicitly relied on (see: Microsoft's AAIF Project Proposal 19).

I have served Concerns Notice and Preservation Notice correspondence concerning these publications and related records. I reserve all rights and will not engage further substantively in this thread pending the private process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/XL Extra large PR (500+ lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants