Sigstore Interop — Exporting Diogenes Manifests for cosign¶
This guide is for publishers — people running CI pipelines or admin
tooling who already maintain Diogenes attestations and need to hand them
to downstream consumers running cosign, sigstore-policy-controller,
or other in-toto / DSSE-aware tooling.
If you are a developer working on the in-toto/DSSE output layer
itself (adapters, the serializer, the _diogenes_extensions envelope),
see the developer reference at
docs/developers/sigstore-interop.md.
When to use this¶
You should reach for the manifest-level export when:
- Your CI pipeline produces a Diogenes Manifest carrying one or more
signed
Attestations (e.g., authorship + review + publication on a release artifact). - Your downstream consumer's policy verifier speaks
cosign verify-blob-attestation(orcosign verify-attestation) and you do not want to change that. - You can afford to have the publisher's signing key online at export time. The DSSE export re-signs the in-toto Statement bytes with the publisher's key; it cannot be done by a third party who only has the manifest.
Use the single-artifact diogenes sign command when you have just one
file to attest and emit (no pre-existing manifest). Use this guide's
diogenes export-dsse command when you already have a manifest and want
to fan out one DSSE envelope per attestation.
End-to-end example¶
Given a Diogenes Manifest JSON file manifest.json and a publisher key
publisher.pem:
# 1. Export — one DSSE envelope per attestation in the manifest
diogenes export-dsse \
--manifest ./manifest.json \
--key-file ./publisher.pem \
--out ./release.intoto.jsonl
# 2. Inspect — each line is a DSSE envelope
wc -l release.intoto.jsonl # one line per attestation
head -n1 release.intoto.jsonl | jq '.payloadType' # "application/vnd.in-toto+json"
# 3. Verify each envelope under cosign
PUB_KEY=./publisher-pub.pem # extract via `openssl pkey -in publisher.pem -pubout`
ARTIFACT=./release.tar.gz
PREDICATE_TYPE=https://trustdiogenes.com/attestation/v1
while read envelope_line; do
echo "$envelope_line" > /tmp/env.json
cosign verify-blob-attestation \
--key "$PUB_KEY" \
--type "$PREDICATE_TYPE" \
--payload "$ARTIFACT" \
/tmp/env.json
done < release.intoto.jsonl
Each cosign verify-blob-attestation invocation prints a verification-success
line and exits 0 when the envelope is valid.
The publisher-online caveat¶
Diogenes' native signature covers the deterministic JSON payload of the attestation. DSSE's signature covers the DSSE Pre-Authentication Encoding (PAE) of the in-toto Statement bytes. These are two different byte strings, so they require two distinct signatures.
diogenes export-dsse produces the DSSE signature at export time using
the --key-file you supply. This means:
- You can export your own attestations at any time.
- You cannot export someone else's attestation as a Sigstore-verifiable bundle — you do not have their private key. The native Diogenes signature is still valid in their attestation, but it does not satisfy cosign on its own.
- For "I want anyone to be able to convert this Diogenes attestation into a Sigstore-verifiable form" you need a different design — likely a transparency export where the verifier re-fetches the original Diogenes manifest and re-checks the native signature against the Diogenes Key Registry. That work is not in scope for this release (see issue #308 "Out of scope").
The native signature is preserved verbatim inside the DSSE envelope,
under the predicate's _diogenes_extensions block. Diogenes-aware
verifiers can recover it and check it against the Diogenes Key Registry;
sigstore-aware verifiers ignore the extension and check the DSSE
signature against the supplied --key.
What goes in the predicate¶
By default, the manifest-level export uses the Diogenes-native
passthrough adapter (predicateType:
https://trustdiogenes.com/attestation/v1) and parks the entire native
attestation under _diogenes_extensions. The typed predicate body is
empty {}.
If you need to emit a typed predicate — for example, SLSA Provenance v1 — call the SDK function directly with a custom resolver:
from diogenes.interop.sigstore.output import serialize_manifest_to_intoto_jsonl
result = serialize_manifest_to_intoto_jsonl(
manifest,
private_key=publisher_key,
predicate_type_resolver=lambda att: "https://slsa.dev/provenance/v1",
predicate_body_resolver=lambda manifest, att: {
"buildType": "https://example.com/my-build-type/v1",
# ...
},
)
Path("release.intoto.jsonl").write_text(result.jsonl_text)
See the developer reference for the full adapter list.
Limitations vs. native Diogenes verification¶
Cosign / sigstore tooling cannot do everything a Diogenes verifier can:
| Feature | DSSE export (cosign) | Native Diogenes verify |
|---|---|---|
| Cryptographic signature covering the content hash | Yes (DSSE signs canonical Statement bytes, which embed the digest) | Yes (deterministic payload) |
| Web-of-trust resolution | No — single key check only | Yes — full trust-config graph |
| Endorsement DAG traversal | No | Yes |
| OpenTimestamps / Bitcoin anchoring | Not exposed via the DSSE envelope | Yes — ots_proofs in the manifest |
| Per-attestation type semantics | Surfaced as predicateType |
Surfaced as attestation.type + adapter logic |
| Verifier-side public key discovery | Caller provides --key or uses certificate-identity |
Diogenes Key Registry transparency log |
The export gives you "this artifact has a signature by this key" — the same answer Sigstore gives. It does not give you "this signature is trusted under the project's policy graph"; for that you still need the native Diogenes pipeline.
Output format details¶
release.intoto.jsonl is a newline-delimited JSON file. Each line is
one DSSE envelope:
{"payloadType":"application/vnd.in-toto+json","payload":"<base64>","signatures":[{"sig":"<base64>","keyid":"<fingerprint>"}]}
The payload field is the base64-encoded canonical (JCS) bytes of an
in-toto Statement. The Statement's predicate._diogenes_extensions
sub-object carries the full native Diogenes attestation.
Reserved formats¶
--format sigstore-bundle is reserved for a future release. Today,
selecting it exits non-zero with an "install extras" message. The
Sigstore Bundle protobuf form (bundle.sigstore.json) is tracked as a
follow-up to #308
and will ship when there is a real consumer asking for it.
Cosign installation¶
The export itself does not depend on cosign — you only need cosign to verify the output. Install per the cosign install guide:
# macOS / Linux
go install github.com/sigstore/cosign/v2/cmd/cosign@latest
# or download a release binary
curl -L https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -o cosign
chmod +x cosign && sudo mv cosign /usr/local/bin/
See also¶
- Developer reference for the in-toto/DSSE output layer:
docs/developers/sigstore-interop.md - DSSE specification: secure-systems-lab/dsse
- in-toto Statement v1: in-toto/attestation/spec/v1/statement.md
- Sigstore Bundle protobuf-specs: sigstore/protobuf-specs
- Companion concept: Diogenes Vault