Skip to content

Update SigningConfig to specify API version and validity periods#539

Merged
Hayden-IO merged 2 commits intosigstore:mainfrom
Hayden-IO:sc-updates
Mar 13, 2025
Merged

Update SigningConfig to specify API version and validity periods#539
Hayden-IO merged 2 commits intosigstore:mainfrom
Hayden-IO:sc-updates

Conversation

@Hayden-IO
Copy link
Copy Markdown
Collaborator

In order to faciliate clients gracefully handling breaking API changes, the SigningConfig will now include API versions for each of the service URLs so that clients can determine what services they are compatible with. Additionally, we've included validity periods which will be used to faciliate Rekor log sharding, when we spin up new log shards and distribute new key material.

Fixes #474

Summary

Release Note

Documentation

@Hayden-IO
Copy link
Copy Markdown
Collaborator Author

Hayden-IO commented Feb 14, 2025

A few things to note:

  • I kept the old url fields because I'm not sure if that will break sigstore-python, which supports ClientTrustConfig. Edit: The old fields have been removed.
  • That also means we need a new media type version, which I added.
  • I've included comments for the selection process. For CA and OIDC URLs, the client must select one URL that matches its criteria. For Rekor and TSA URLs, the client must select all URLs that match its criteria. If this is confusing, lemme know and we can think about grouping things differently. Edit: The Rekor and TSA URLs are now selected based on an explicitly provided selector.
  • Naming is hard because we've already used the abbreviated names I would have used for the pluralized fields....so the names are a bit verbose. Edit: No longer an issue with removal of old fields.

Copy link
Copy Markdown
Member

@kommendorkapten kommendorkapten left a comment

Choose a reason for hiding this comment

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

Looks good!

Comment on lines +210 to +213
// Clients must select only Service with the highest API version
// that the client is compatible with and that is within its
// validity period. Clients should select the first Service
// that meets this requirement.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If the sort order is the same as for TrustedRoot

// All the listed instances SHOULD be sorted by the 'valid_for' in ascending
// order, that is, the oldest instance first. Only the last instance is
then this could result in a client choosing a service that is valid but about to expire, when a later service in the list would be valid for longer.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Good call out. I've added the following:

     // All listed Services SHOULD be sorted by the `valid_for` window in
     // descending order, with the newest instance first.

With the newest instance first, this should limit how far into the list clients need to search to find a valid instance. Typically a client will just select the first from the list. With a sharding, a client will select the second (old shard) until the first in the list (new shard) becomes valid. For API changes, a client may have to search further into the list, but major API changes will be infrequent.

// These URL **MUST** be the "base" URLs for the transparency logs,
// which clients should construct appropriate API endpoints on top of.
//
// Clients must select ALL Services with the highest API version
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This seems like a big change, as clients don't currently upload entries to multiple logs at once, and may not always want to. Could this be changed to ANY?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Originally, I was going to say that since this is for signing, I would expect that a user provide all the logs that they want to contact. Thinking more on this, Certificate Transparency has a similar concept with log lists, and doesn't require its clients to write to all logs, only a subset.

I'm proposing now that we include a configuration for how clients should select Rekor and TSA instances (we don't need a configuration for Fulcio and the OIDC provider because the bundle only supports one certificate). The config will specify a selection of ANY, ALL, or EXACT, with another field count when EXACT is specified (like CAs writing to 2 logs based on browser requirements).

We need to decide on what we as the PGI operator will set. I think ANY is fine since I expect we'll only ship one log for now.

Thanks for this idea!

// that the client is compatible with and that is within its
// validity period. Clients should select the first Service
// that meets this requirement.
repeated Service certificate_authority_urls = 6;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wish the new field names were more meaningfully different from the old names but I don't have a great suggestion.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

With the removal of the old fields, I've renamed them to the abbreviated service names

Comment on lines +151 to +152
// MUST be application/vnd.dev.sigstore.signingconfig.v0.1+json or
// application/vnd.dev.sigstore.signingconfig.v0.2+json
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This seems a bit unclear: after this PR this message documents v0.2 only but that's not said anywhere. Do we allow v0.1 to be used in future as well?

Bundle uses this language:

    // MUST be application/vnd.dev.sigstore.bundle.v0.3+json when encoded as JSON.
    // Clients must to be able to accept media type using the previously defined formats:
    // [list follows]

Of course situation here is a bit different: we should document

  • what we expect the instance to serve
    • I'd like to say "MUST serve v0.2" but obviously there's a migration period here
  • what we expect clients to handle
    • MUST handle v0.2, SHOULD handle v0.1

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Updated to serve only v0.2, and say clients can optionally handle v0.1. In practice, I assume all will drop support.

// application/vnd.dev.sigstore.signingconfig.v0.2+json
string media_type = 5;

// Deprecated: Use certificate_authority_urls
Copy link
Copy Markdown
Member

@jku jku Feb 18, 2025

Choose a reason for hiding this comment

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

Can you explain the way these deprecations are useful (compared to just removing the fields):

  • if a service does not want to support the new fields, I would expect them to just keep serving signingconfig v0.1?
  • if a client supports signingvonfig v0.2 then they need to support the new fields so won't need these

Maybe I'm missing a case?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

is the idea that clients have an easier time supporting v0.2 if they can just update version number and keep doing what they are doing now?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I was aiming to concurrently support both to avoid a breaking change, but you're right, this isn't necessary.

Also, only sigstore-python and -go support signing configs and I'm fairly certain no one is using them for the Go client, so making this breaking change is likely to have no impact.

@jku
Copy link
Copy Markdown
Member

jku commented Feb 18, 2025

I guess one option to make the transition to new SigningConfig as easy as possible is to not replace the old one but just offer a new one:

  • a new TUF artifact signing_config2.json is added alongside the existing signing_config.json
  • the clients can implement support on their schedule: instead of parsing signing_config.json they start download/parse signing_config2.json
  • at some point in future when enough clients have transitioned, signing_config.json artifact is removed from TUF repository

This would be a way to avoid a flag day for SigningConfig

@jku
Copy link
Copy Markdown
Member

jku commented Feb 18, 2025

  • I kept the old url fields because I'm not sure if that will break sigstore-python, which supports ClientTrustConfig.

pretty sure sigstore-python will not parse the new data without code changes since the signingconfig version number changes

@jku
Copy link
Copy Markdown
Member

jku commented Feb 18, 2025

I guess one option to make the transition to new SigningConfig as easy as possible is to not replace the old one but just offer a new one:

I'll have a better look at this again this week as I feel there is something to this idea -- we may be mistakenly combining the two problem cases (backwards incompatible service migration and plain log instance rotation), the right solutions to each might actually be different

@jku
Copy link
Copy Markdown
Member

jku commented Feb 25, 2025

Okay, I couldn't actually make experiments with sigstore-python because of an ongoing protobuf-specs incompatibility, but I have tried to fully understand this and here's my current thinking:

On versioning SigningConfig itself

  • technically this PR makes only "compatible" changes to SigningConfig so we could update signing_config.json in root-signing without major issues. root-signing artifacts should be considered API and changes should avoid flag days when possible so this seems good... however:
  • the moment we switch on a rekor v2 log and add it to the config in root-signing, this compatibility is shown to be fake: some clients seem to be compatible with the new signingconfig but that's only because they rely on the deprecated fields that won't contain the new log

Let's consider this approach:

  • this pr actually makes incompatible SigningConfig changes (in other words the deprecated fields are removed)
  • we add a new artifact into root-signing: "signing_config_N.json" (where N is the version), the old config remains as "signing_config.json"
  • at this point clients can be updated to handle the new artifact (if we have already added the new artifact to both root-signing-staging and root-signing, they can remove the old signingconfig handling at the same time)
  • at some point in future we fully deprecate old signing_config by removing the old artifact from root-signing

I think that might be best of both worlds: avoids a flag day but still makes it clear the API actually changes (and allows us to see from CDN logs how much the old signing_config.json is still used). The counter argument could be that only sigstore-python is using signing_config.json so there's no point in considering this a real API change... but in that case I guess we can just remove the deprecated fields and not care about compatibility? comments @haydentherapper?

On Service.major_api_version

It's really hard to say if this will actually be a mechanism that works in cases that are not this specific upgrade (rekor v1->v2) but I can't figure out anything smarter. LGTM

@Hayden-IO
Copy link
Copy Markdown
Collaborator Author

@jku Thanks for the review and suggestions. I've updated this PR to remove the old fields. This is cleaner, it likely doesn't affect any clients or users, and for all the reasons you've stated, this should be fine if we version the signing config.

Given that no clients are using the public-good-instance-provided signing config at the moment, I would suggest we simply update the existing signing config. I like this idea for versioning configs and so we should document this to use this in the future for the next time we make a breaking change that removes fields.

In order to faciliate clients gracefully handling breaking API
changes, the SigningConfig will now include API versions for each
of the service URLs so that clients can determine what services
they are compatible with. Additionally, we've included validity periods
which will be used to faciliate Rekor log sharding, when we spin up new
log shards and distribute new key material.

Fixes sigstore#474

Signed-off-by: Hayden B <8418760+haydentherapper@users.noreply.github.com>
Copy link
Copy Markdown
Member

@kommendorkapten kommendorkapten left a comment

Choose a reason for hiding this comment

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

Nice work!

Signed-off-by: Hayden B <8418760+haydentherapper@users.noreply.github.com>
Copy link
Copy Markdown
Member

@kommendorkapten kommendorkapten left a comment

Choose a reason for hiding this comment

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

Thank you!

@Hayden-IO Hayden-IO merged commit 4752ba2 into sigstore:main Mar 13, 2025
22 checks passed
@Hayden-IO Hayden-IO deleted the sc-updates branch March 13, 2025 18:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SigningConfig proto to have start dates?

4 participants