Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 31 additions & 2 deletions sigstore-cli/src/main/java/dev/sigstore/cli/Sign.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
import dev.sigstore.KeylessSigner;
import dev.sigstore.SigningConfigProvider;
import dev.sigstore.TrustedRootProvider;
import dev.sigstore.bundle.Bundle;
import dev.sigstore.oidc.client.OidcClients;
import dev.sigstore.oidc.client.TokenStringOidcClient;
import dev.sigstore.trustroot.ImmutableSigstoreSigningConfig;
import dev.sigstore.trustroot.Service;
import dev.sigstore.tuf.RootProvider;
import dev.sigstore.tuf.SigstoreTufClient;
import java.net.URI;
Expand Down Expand Up @@ -89,6 +92,12 @@ static class Target {
required = false)
Path workingDirectory;

@Option(
names = {"--in-toto"},
description = "treat the artifact as an in-toto statement payload",
required = false)
boolean inToto;

@Override
public Integer call() throws Exception {
if (workingDirectory != null) {
Expand All @@ -102,7 +111,22 @@ public Integer call() throws Exception {
}
}
KeylessSigner.Builder signerBuilder;
if (target == null) {
// TODO(#1033): Get Rekor v2 service from TUF signing config when in prod
if (inToto) { // Attestation signing requires Rekor v2
var prodTufClient = SigstoreTufClient.builder().usePublicGoodInstance().build();
Copy link
Member

Choose a reason for hiding this comment

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

we already have --signing-config as an option, should the conformance test just inject the signing config in instead of us doing this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This seems relevant to sigstore/sigstore-conformance#279. Any thoughts, @jku?

Copy link
Member

@jku jku Feb 6, 2026

Choose a reason for hiding this comment

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

I 'm not 100% sure what happens here but this is what it looks like to me:

  • conformance is currently trying to test rekor v1 dsse signing (we could test rekor2 with a custom signingconfig as @loosebazooka says but currently don't)
  • sigstore-java does not support this combo (right?) so sneakily changes the signingconfig to use rekor v2 instead
  • This happens to pass the test because rekor2 is already in the trusted root so the verification succeeds and the test doesn't happen to explicitly check the entry kind version

I do not think sigstore-java should change the test parameters like that, even if that means the test starts passing. It feels like gaming the test.

However, there is something we can do :

  • we should be able to run test_sign_verify_dsse in staging as well as prod -- this should give sigstore-java different results in the two environments I think
  • Deprecate "environment: staging" sigstore-conformance#279 is related in that I'd like this to eventually happen in a single test run...
  • but I believe right now we can add @pytest.mark.staging marker to the test and it will be included in the staging test run without issues

Copy link
Member

Choose a reason for hiding this comment

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

sigstore/sigstore-conformance#334 -- I think that's correct but you could test with that to check that you get expected results with it if you remove the signinconfig change here (succeeds on staging but fails on prod)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've tested locally using sigstore/sigstore-conformance#334 and removing the signing config, and can confirm that this succeeds in staging and fails in prod.

prodTufClient.update();
var prodSigningConfig = prodTufClient.getSigstoreSigningConfig();
var signingConfig =
ImmutableSigstoreSigningConfig.builder()
.from(prodSigningConfig)
.addTLogs(Service.of(URI.create("https://log2025-1.rekor.sigstore.dev"), 2))
.build();
signerBuilder =
KeylessSigner.builder()
.sigstorePublicDefaults()
.signingConfigProvider(() -> signingConfig)
.enableRekorV2(true);
} else if (target == null) {
signerBuilder = new KeylessSigner.Builder().sigstorePublicDefaults().enableRekorV2(true);
} else if ((target.trustedRoot != null && signingConfig == null)
|| (target.trustedRoot == null && signingConfig != null)) {
Expand Down Expand Up @@ -151,7 +175,12 @@ public Integer call() throws Exception {
OidcClients.of(TokenStringOidcClient.from(identityToken)));
}
var signer = signerBuilder.build();
var bundle = signer.signFile(artifact);
Bundle bundle;
if (inToto) {
bundle = signer.attest(Files.readString(artifact, StandardCharsets.UTF_8));
} else {
bundle = signer.signFile(artifact);
}
Files.write(bundleFile, bundle.toJson().getBytes(StandardCharsets.UTF_8));
return 0;
}
Expand Down
Loading