Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make keypair format configurable #17

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

patrickpichler
Copy link

@patrickpichler patrickpichler commented Sep 17, 2022

This PR solves #4 by extending the credentials page with a combobox to select the desired
algorithm to create the key pair.

The base functionality is implemented and I now want to get some feedback from the
maintainers. Tests are currently missing and the existing tests still need some adaption.

It is now possible to choose between six different algorithms used for the keypair. Three
of those are RSA based and the other three EC. I found no easy way to recreate the
public key from the private EC key (I'm no expert on that matter, so if there is an
easy way I missed in my research, please let me know 🙂 ), hence
I introduced a new container object to store both private and public key as Jenkins secrets.
The previous private key secret is still around in order to ensure backwards compatibility
for java object serialization, but it is now marked transient.

As a base for creating key pairs for the different types, I leverage jjwt, since it already
provides a nice enum (SignatureAlgorithm) wrapping this functionality.

  • Make sure you are opening from a topic/feature/bugfix branch (right side) and not your main branch!
  • Ensure that the pull request title represents the desired changelog entry
  • Please describe what you did
  • Link to relevant issues in GitHub or Jira
  • Link to relevant pull requests, esp. upstream and downstream changes
  • Ensure you have provided tests - that demonstrates feature works or fixes the issue

Copy link
Member

@jglick jglick left a comment

Choose a reason for hiding this comment

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

Looks about right from a quick glance. I am afraid I have not had the time to devote any effort to this plugin since its creation (and probably lack a good feel for how it is used in the field) so I would welcome new maintainers.

return new JSONObject().
accumulate("issuer", issuer).
accumulate("jwks_uri", issuer + JWKS).
accumulate("response_types_supported", new JSONArray().element("code")).
accumulate("subject_types_supported", new JSONArray().element("public")).
accumulate("id_token_signing_alg_values_supported", new JSONArray().element("RS256")).
accumulate("id_token_signing_alg_values_supported", algValuesSupported).
Copy link
Member

Choose a reason for hiding this comment

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

I think this is only supposed to include the algorithm these credentials actually use. The spec is not terribly clear on what this is used for.

Copy link
Author

Choose a reason for hiding this comment

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

I am a bit confused by the documentation, since it mentions

The algorithm RS256 MUST be included
Does this mean a RS256 key must be present all the time?

Due to this, I went to listing all supported types by the plugin, but I can change it 🙂

src/main/java/io/jenkins/plugins/oidc_provider/Keys.java Outdated Show resolved Hide resolved
src/main/java/io/jenkins/plugins/oidc_provider/Keys.java Outdated Show resolved Hide resolved
@patrickpichler
Copy link
Author

@jglick I've now also added some tests 🙂

@jglick jglick added the enhancement New feature or request label Sep 19, 2022
@patrickpichler
Copy link
Author

@jglick I think the PR is ready yet, could you have another look? 🙂
I would then proceed to make the git history nice and squash everything into a single commit 😅

@jglick jglick mentioned this pull request Sep 24, 2022
9 tasks
Comment on lines 153 to 189
@DataBoundSetter public void setAlgorithm(SupportedKeyAlgorithm algorithm) {
Objects.requireNonNull(algorithm);
this.algorithm = algorithm;
}

@NonNull public SupportedKeyAlgorithm getAlgorithm() {
return algorithm;
}
Copy link
Member

Choose a reason for hiding this comment

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

Propose doing #18 first, and then moving this option to IdTokenConfiguration, as I doubt there is a legitimate use case for a single controller having tokens with two issuers that use different algorithms; and a Jenkins admin would probably prefer to force use of a sufficiently secure algorithm.

Copy link
Author

Choose a reason for hiding this comment

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

The only reason I could think of to not make the algorithm global would be if certain
providers only support a subset of algorithms. Then it might make sense to keep it.

But then, I am by no means a expert in OIDC so maybe this is an unfounded fear 😄

Copy link
Member

Choose a reason for hiding this comment

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

I think everyone supports RS256 and IIRC it is mandated. Beyond that I am unsure.

Copy link
Author

Choose a reason for hiding this comment

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

What exactly do you mean by that? 🤔
That all keys must be signed by a RS256 key?

Copy link
Member

Choose a reason for hiding this comment

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

No, that all OIDC impls must support this algorithm at a minimum.

Copy link
Member

Choose a reason for hiding this comment

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

Right; #18 provides the global config class for another purpose, so if merged, that would be a place to move this option.

Copy link
Author

@patrickpichler patrickpichler Sep 28, 2022

Choose a reason for hiding this comment

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

As said, I am not 100% sure if it makes sense to force the whole Jenkins instance to use a certain algorithm
for generating the key pair.

My fear is, as mentioned above, that certain OIDC connectors doesn't support elliptic curve key pairs. Instead
of now switching all keys to a non elliptic curve algorithm, it would make sense to me, to have a specialized key
pair for that provider which uses a supported key pair.

Copy link
Member

Choose a reason for hiding this comment

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

[It is possible] that certain OIDC connectors doesn't support elliptic curve key pairs

Right but in such a case why not stick with RS256, which all requesting parties should support? One possible reason is because you are a Jenkins admin who does not consider RS256 sufficiently secure and you want to force use of stronger cryptography. That would be undermined if the algorithm were overridable by developers in charge of some folders.

If there is no admin-vs.-dev distinction—one person or group has full config access to Jenkins—then it would make sense to switch to (say) ES512 to connect to one service that supports it, but stick with RS256 for another service which does not.

Not sure at this point what is best, just trying to think through the implications of letting the algorithm be configurable by people who are not Jenkins administrators. Of course all of the new options are stronger than the currently hard-coded option.

Copy link
Author

Choose a reason for hiding this comment

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

You are right, I guess that behavior will anyway be an edge case 🙂
I'll wait for your PR to be merged then and integrate my changes in the global configuration 🙂

Copy link
Member

Choose a reason for hiding this comment

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

wait for your PR to be merged

Merged (and released).

@jglick
Copy link
Member

jglick commented Nov 18, 2022

@patrickpichler do you still plan to work on this?

@patrickpichler
Copy link
Author

Yes, I am still planning to implement this, but I need to first take a look at the changes in master.

@patrickpichler
Copy link
Author

@jglick I've updated the branch. I am not 100% sure how I would go ahead and update all secrets
once the global plugin config is updated though 🤔
Do you have an idea?
https://github.com/jenkinsci/oidc-provider-plugin/pull/17/files#diff-8dfaabe0385e0b0a1de720d3227c8c8d0fdfd57d2f95426d2ea3eccc31984958R147

@jglick
Copy link
Member

jglick commented Nov 18, 2022

Just delete IdTokenCredentials.algorithm and retrieve the algorithm from global settings on demand. Then there is nothing to update.

@patrickpichler
Copy link
Author

There is, as a update to the global algorithm should probably recreate the keypair used (if the algorithm changed). Otherwise the existing keypairs are out of sync with the global config .

@jglick
Copy link
Member

jglick commented Nov 21, 2022

Pending #3 you can simply resave existing credentials at any time.

@patrickpichler
Copy link
Author

I've implemented the update version. Do you know of a better way of doing this? @jglick

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants