Sign vs. Attest: When to Use Which

This guide helps you choose the right JACS API for your use case.

Decision Tree

Start here: What do you need to prove?

  1. "This data hasn't been tampered with"

    • Use sign_message() / signMessage()
    • This gives you a cryptographic signature and integrity hash.
  2. "This data hasn't been tampered with AND here's why it should be trusted"

    • Use create_attestation() / createAttestation()
    • This gives you signature + integrity + claims + evidence + derivation chain.
  3. "I have an existing signed document and want to add trust context"

    • Use lift_to_attestation() / liftToAttestation()
    • This wraps an existing JACS-signed document into a new attestation.
  4. "I need to export a trust proof for external systems"

    • Use export_attestation_dsse() / exportAttestationDsse()
    • This creates an in-toto DSSE envelope compatible with SLSA and Sigstore.
  5. "I need to send signed data to another agent or service"

Quick Reference

ScenarioAPIOutput
Log an AI actionsign_message()Signed document
Record a human review decisioncreate_attestation()Attestation with claims
Attach evidence from another systemcreate_attestation() with evidenceAttestation with evidence refs
Wrap an existing signed doc with trust contextlift_to_attestation()New attestation referencing original
Export for SLSA/Sigstoreexport_attestation_dsse()DSSE envelope
Verify signature onlyverify()Valid/invalid + signer
Verify signature + claims + evidenceverify_attestation(full=True)Full verification result
Exchange artifact with another agentsign_artifact() / A2ASigned wrapped artifact

Examples

Just need integrity? Use signing.

signed = client.sign_message({"action": "approve"})
result = client.verify(signed.raw_json)
# result["valid"] == True

Need trust context? Use attestation.

att = client.create_attestation(
    subject={"type": "artifact", "id": "doc-001", "digests": {"sha256": "..."}},
    claims=[{"name": "reviewed", "value": True, "confidence": 0.95}],
)
result = client.verify_attestation(att.raw_json, full=True)
# result["valid"] == True, result["evidence"] == [...]

Already signed? Lift to attestation.

signed = client.sign_message({"content": "original"})
att = client.lift_to_attestation(signed, [{"name": "approved", "value": True}])
# att now has attestation metadata referencing the original document

Common Patterns

AI Agent Action Logging

Use sign_message() for each tool call or action. The signature proves the agent took the action and the data hasn't been modified.

Human Review Attestation

Use create_attestation() with claims like reviewed_by: human and confidence: 0.95. This creates an auditable record that a human reviewed and approved the output.

Multi-step Pipeline

Use create_attestation() with a derivation field to capture input/output relationships. Each step attests to its own transformation with references to upstream attestations.

Cross-system Verification

Use export_attestation_dsse() to generate an in-toto DSSE envelope that external systems (SLSA verifiers, Sigstore) can validate independently.