[JIRA] (JENKINS-60764) Allow configuration per folder rather than globally

1 view
Skip to first unread message

rittneje@gmail.com (JIRA)

unread,
Jan 14, 2020, 10:20:06 AM1/14/20
to jenkinsc...@googlegroups.com
Jesse Rittner updated an issue
 
Jenkins / Story JENKINS-60764
Allow configuration per folder rather than globally
Change By: Jesse Rittner
Summary: Allows Allow configuration per folder rather than globally
Add Comment Add Comment
 
This message was sent by Atlassian Jira (v7.13.6#713006-sha1:cc4451f)
Atlassian logo

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 14, 2020, 11:18:07 AM1/14/20
to jenkinsc...@googlegroups.com
Chris Kilding commented on Story JENKINS-60764
 
Re: Allow configuration per folder rather than globally

Great suggestion, and indeed something we are starting to think about.

Do you happen to have any examples of plugins that take folder-scoped configuration? This would help to get started.

rittneje@gmail.com (JIRA)

unread,
Jan 14, 2020, 6:25:02 PM1/14/20
to jenkinsc...@googlegroups.com

We are currently just using the CloudBees folder plugin, which allows you to scope credentials to a folder. But afaik it only works for secrets that are stored in Jenkins itself (i.e., the standard credentials provider). https://plugins.jenkins.io/cloudbees-folder

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 20, 2020, 7:34:06 AM1/20/20
to jenkinsc...@googlegroups.com

I had a poke around in the folder plugin - source code diving results below.

The classes of interest are FolderCredentialsProvider, AbstractFolder, and FolderCredentialsProperty.

When the provider is asked for credentials, it tests if the itemGroup is an AbstractFolder (or walks up the tree till it finds the nearest parent that is an AbstractFolder). Then it gets the credentials from the AbstractFolder's FolderCredentialsProperty (which just seems to be a holder class). The credentials are a plain old in-memory Map<domain, credentials>. Then it returns the credentials list, optionally filtered by domain.

It looks like the AbstractFolder is responsible for persistence of its components, on the Jenkins master's disk. The persistence structure looks like

  • jobs/
    • foo/ (a normal job) 
    • <folder>
      • config.xml (folder-scoped config, including the serialized credentials)
      • jobs/
        • bar/ (a folder-scoped job)

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 20, 2020, 7:47:08 AM1/20/20
to jenkinsc...@googlegroups.com

This means that the folder plugin is not just an access control layer on top of the standard local disk credentials provider. Instead it has taken over credentials handling and persistence within folders, to the extent that it is its own credentials provider.

This design makes it harder for any third party credentials provider - not just this one - to integrate with the folders plugin.

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 20, 2020, 8:07:07 AM1/20/20
to jenkinsc...@googlegroups.com

There is a way to do it within the constraints of the current design, but it's not good.

AbstractFolder is public, and we do have access to the itemGroup in our own providers, so we could potentially do the same test on the itemGroup / walk up the tree, get the folder name, check that against something we can store in our credentials provider, and return a scoped list, and otherwise return the unscoped global credentials.

This is bad because:

  • We would have to duplicate large amounts of folders plugin logic in every credentials provider that wanted to support folder-scoped credentials. (Possibility for bugs to creep in, behaviour updates applied erratically across all providers etc.)
  • We would be overloading credentials providers with responsibilities they shouldn't have. A provider should really have 1 purpose - store and retrieve a list of credentials - because this is already complex enough, especially with the retry/failure handling for remote providers.
  • We would need the provider's data store to hold extra ACL metadata, which could make its storage schema more complicated, or could be a poor fit for some data stores.

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 20, 2020, 8:09:07 AM1/20/20
to jenkinsc...@googlegroups.com
Chris Kilding edited a comment on Story JENKINS-60764
There is a way to do it within the constraints of the current design, but it's not good.

AbstractFolder is public, and we do have access to the itemGroup in our own providers, so we could potentially do the same test on the itemGroup / walk up the tree, get the folder name, check that against something we can store in our credentials provider, and return a scoped list, and otherwise return the unscoped global credentials.

This is bad because:
* We would have to duplicate large amounts of folders plugin logic (and tests) in every credentials provider that wanted to support folder-scoped credentials. (Possibility for bugs to creep in, behaviour updates applied erratically across all providers etc.)
* We would be overloading credentials providers with responsibilities they shouldn't have. A provider should really have 1 purpose - store and retrieve a list of credentials - because this is already complex enough, especially with the retry/failure handling for remote providers.
* We would need the provider's data store to hold extra ACL metadata, which could make its storage schema more complicated, or could be a poor fit for some data stores.

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 20, 2020, 8:19:07 AM1/20/20
to jenkinsc...@googlegroups.com

I believe we are looking at some wider design changes like the following:

  • The folders plugin stores and manages the ACL matrix (an association of credentials to folders).
  • JCasC support to let the folders plugin read its ACL matrix from CasC YAML.
  • FolderCredentialsProvider is either removed, or becomes a simple filtering proxy for other credential providers.
  • (Optional) Remove ACL-related parameters like itemGroup from the CredentialsProvider getCredentials API.

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 28, 2020, 12:45:03 PM1/28/20
to jenkinsc...@googlegroups.com
Chris Kilding edited a comment on Story JENKINS-60764
Have written up the work that would need to be done on the folders plugin in this issue JENKINS-60897 .

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 28, 2020, 12:45:03 PM1/28/20
to jenkinsc...@googlegroups.com

Have written up the work that would need to be done on the folders plugin in this issue.

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 28, 2020, 1:11:03 PM1/28/20
to jenkinsc...@googlegroups.com
Chris Kilding edited a comment on Story JENKINS-60764
Have written up I have started writing an epic for the work that would need to be done on the folders - plugin in JENKINS-60897. [~rittneje] Could you take a look and comment with the kind of functionality you'd like to see?

rittneje@gmail.com (JIRA)

unread,
Jan 28, 2020, 11:08:03 PM1/28/20
to jenkinsc...@googlegroups.com

Chris Kilding Thanks so much for looking into this! Can you clarify what information you are looking for? At a high level, this is what we'd like:

  1. Create a folder-scoped secret for the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. These could either be two string credentials, or a single AWS credentials (https://github.com/jenkinsci/aws-credentials-plugin/blob/master/src/main/java/com/cloudbees/jenkins/plugins/awscredentials/AWSCredentialsImpl.java).
  2. Configure the aws-secrets-manager-credentials-provider-plugin for that folder. We can configure it with the settings for our specific account. It should use the folder-scoped credentials from (1) to authenticate. Bonus points if we can pull settings from the folder properties plugins. https://wiki.jenkins.io/display/JENKINS/Folder+Properties+Plugin and/or https://docs.cloudbees.com/docs/cloudbees-core/latest/cloud-secure-guide/folders-plus

Also, if possible we would prefer to be able to configure all of this via Job DSL, not the GUI. https://wiki.jenkins.io/display/JENKINS/Job+DSL+Plugin

 

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 29, 2020, 6:39:02 AM1/29/20
to jenkinsc...@googlegroups.com

I believe the JENKINS-60897 proposal can do what you ultimately are trying to achieve (having some credentials restricted to jobs in folder A, some restricted to jobs in folder B, some restricted to jobs in folders A and B, and some global credentials with no folder restrictions).

But there is a fundamental constraint in the way: a plugin has only one instance in Jenkins. You couldn't run multiple instances of a plugin (e.g. to apply different configurations) on the same Jenkins server.

So under the proposal, you'd achieve it like this instead:

  • Install credential provider plugin.
  • Install folders plugin.
  • Configure the credentials access control layer (ACL) on the folders plugin. 

Example:

If I have 4 secrets in Secrets Manager that I want to use in Jenkins like this:

  • foo (visible to jobs in folders A and B)
  • bar (visible to jobs in folder A)
  • baz (visible to jobs in folder B)
  • qux (global, visible to all jobs)

I would configure the ACL like this in JCasC (I suppose you could also use Job DSL or the GUI):

folders:
  a:
    someUnrelatedProperty: 'hello'
    credentials:
    - 'foo'
    - 'bar'
  b:
    someUnrelatedProperty: 'world'
    credentials:
    - 'foo'
    - 'baz'

(The implication in this particular design is that if you access a credential like qux which has no folder restrictions, it is treated as global.)

Does that sound like what you're after?

rittneje@gmail.com (JIRA)

unread,
Jan 29, 2020, 6:35:02 PM1/29/20
to jenkinsc...@googlegroups.com

We have different accounts for dev vs. QA vs. production. If we can only configure the plugin once globally, that implies we would actually need a separate Jenkins installation for each account, which we definitely do not want to do.

chris+jenkins@chriskilding.com (JIRA)

unread,
Jan 30, 2020, 6:44:02 AM1/30/20
to jenkinsc...@googlegroups.com

Could you let me know a bit more about your Jenkins setup?

  • Is it On premises / hosted in AWS / hosted in another cloud provider?
  • Are you using plain folders, or something else that's folder-like e.g. GitHub organization folders?
  • Is this Jenkins for one team in your organization with 3 different deployment environments (dev, QA, prod)? Or do multiple teams use it?
  • What other plugins do you use which interact with AWS services?
  • Which credential providers are you using (apart from the folders plugin, and potentially the Secrets Manager one)?

rittneje@gmail.com (JIRA)

unread,
Jan 30, 2020, 9:19:02 PM1/30/20
to jenkinsc...@googlegroups.com
  1. Our Jenkins master is currently on premise with some Azure agents, and is shared with the rest of the organization. We plan to get a team-specific Jenkins installation in the near future, likely hosted on AWS. We were not planning to have multiple installations for our team. We also have a single on-premise Bitbucket server that is shared with the rest of the organization; builds can also be triggered from Bitbucket via a webhook to Jenkins.
  2. We are currently just using folders from that CloudBees plugin. We are considering switching to their Folders Plus plugin in the near future.
  3. See above. Our team has three different deployment environments: dev, QA, and prod.
  4. We are not currently using any other credential providers.

chris+jenkins@chriskilding.com (JIRA)

unread,
Feb 3, 2020, 10:42:03 AM2/3/20
to jenkinsc...@googlegroups.com

Since your environments are deployed as separate AWS accounts, but you've got only one (environment-independent) Jenkins, it sounds like your intended setup is that Jenkins will run in a shared AWS tools account (not dev, QA, or prod).

The options I can see are something like the following:

  1. Put the secrets for each environment in the tooling account. Use the JEP-225 folder-based credentials ACL to restrict jobs so they can only access the right credentials.
  2. Store the secrets in their respective environment accounts. We implement JENKINS-59670 (cross-account secret retrieval) so the plugin can fetch secrets from multiple accounts. You give Jenkins IAM cross-account roles to let it call Secrets Manager in those accounts (this is far preferable to supplying 3 access key pairs). Then use the JEP-225 folder-based credentials ACL as in solution 1.

Option 2 is considerably more work, and also increases the number of HTTP requests (and therefore lag, and the possibility for network failures) to list secrets.

But in both cases, the JEP-225 credentials ACL should do what you're asking for.

chris+jenkins@chriskilding.com (JIRA)

unread,
Feb 3, 2020, 12:03:52 PM2/3/20
to jenkinsc...@googlegroups.com
Chris Kilding edited a comment on Story JENKINS-60764
Since your environments are deployed as separate AWS accounts, but you've got only one (environment-independent) Jenkins, it sounds like your intended setup is that Jenkins will run in a shared AWS tools account (not dev, QA, or prod).

The options I can see are something like the following:
# Put the secrets for each environment in the tooling account. Use the JEP-225 folder-based credentials ACL to restrict jobs so they can only access the right credentials.
# Store the secrets in their respective environment accounts. We implement JENKINS-59670 (cross-account secret retrieval) so the plugin can fetch secrets from multiple accounts.
* You give Jenkins IAM cross-account roles * to let so it can call Secrets Manager in those accounts *(this is far preferable to supplying 3 access key pairs)*. Then use the JEP-225 folder-based credentials ACL as in solution 1.


Option 2 is considerably more work, and also increases the number of HTTP requests (and therefore lag, and the possibility for network failures) to list secrets.

But in both cases, the JEP-225 credentials ACL should do what you're asking for.

chris+jenkins@chriskilding.com (JIRA)

unread,
Mar 2, 2020, 6:44:03 AM3/2/20
to jenkinsc...@googlegroups.com
Change By: Chris Kilding
Status: Fixed but Unreleased Closed
This message was sent by Atlassian Jira (v7.13.12#713012-sha1:6e07c38)
Atlassian logo

chris+jenkins@chriskilding.com (JIRA)

unread,
Mar 2, 2020, 6:44:03 AM3/2/20
to jenkinsc...@googlegroups.com
 

Closing in favour of JENKINS-60897 (add a notion of folders and credentials to the Jenkins access control plugins).

Additionally, don't forget JENKINS-59670 (support multi-account credentials lookup) which is a prerequisite to any of this work. Jesse Rittner I'd appreciate your feedback on GitHub PR #25 to indicate if the feature design will work for your setup.

Change By: Chris Kilding
Status: Open Fixed but Unreleased
Resolution: Fixed

chris+jenkins@chriskilding.com (JIRA)

unread,
Mar 2, 2020, 6:45:02 AM3/2/20
to jenkinsc...@googlegroups.com
Chris Kilding edited a comment on Story JENKINS-60764
 
Re: Allow configuration per folder rather than globally
Closing in favour of a combination of JENKINS-60897 for authZ (add a notion of folders and credentials to the Jenkins access control plugins) .

Additionally, don't forget
and JENKINS-59670 for authN (support multi-account credentials lookup) which is a prerequisite to any of this work .

[~rittneje] I'd appreciate your feedback on [GitHub PR #25|https://github.com/jenkinsci/aws-secrets-manager-credentials-provider-plugin/pull/25] to indicate if the cross-account feature design will work for your setup.

rittneje@gmail.com (JIRA)

unread,
Mar 2, 2020, 10:02:02 PM3/2/20
to jenkinsc...@googlegroups.com

Chris Kilding I'm not terribly familiar with cross-account credentials, but I have some concerns. What specifically will stop a malicious developer from accessing the production secrets from their feature branch job and printing them out?

Also, I noticed a comment that says "The secret name must be unique across all AWS accounts that Jenkins uses." We require that secret names be identical across the three accounts to maintain consistency.

To clarify, we are not interested in pulling secrets from multiple accounts within a given multibranch pipeline. Rather, each pipeline should only have access to one of the three accounts.

it sounds like your intended setup is that Jenkins will run in a shared AWS tools account

Can you clarify what you mean by this?

chris+jenkins@chriskilding.com (JIRA)

unread,
Mar 5, 2020, 6:18:03 AM3/5/20
to jenkinsc...@googlegroups.com

How secret names are treated is still up for discussion, at the moment the draft implementation rejects them, but we could potentially support a namespacing feature for this. Eg your Jenkins job would ask for credential ID "<aws-account-id>/<secret-name>" and it would be fetched from the relevant account. This would allow the secret names in each AWS account to be identical. But it leaks an implementation detail - the AWS account ID - into the Jenkins job definition, which is not ideal for credential portability.

When I say Jenkins running in a shared tools account, basically this is a pattern where you have a number of environment-specific accounts (staging, prod) and you want a single Jenkins to manage them. It's not appropriate for that Jenkins to run in any of the environment-specific accounts, because by definition it exists outside those environments to manage them. As a result it is often put in an environment-independent account (sometimes called 'tools') with any other shared infrastructure (e.g. Artifactory), and given cross-account access to manage the relevant AWS resources in each environment. Even if a particular job only gets secrets from, say, the production account, under the hood Jenkins would make cross-account requests to get them. When you said you want to have a single Jenkins managing all three environments, I assumed you had a setup like this in mind.

chris+jenkins@chriskilding.com (JIRA)

unread,
Mar 5, 2020, 6:33:02 AM3/5/20
to jenkinsc...@googlegroups.com

Regarding the question of access control... a new approach has just come up, which might be more appropriate for your use case.

This approach would involve defining credentials for the folders plugin in JCasC YAML - basically what you have already done with the folders plugin, but codified in YAML. You would interpolate the actual values of those credentials using JCasC interpolation key syntax. The upcoming SecretSource support in the AWS secrets manager credentials provider (JENKINS-61291) would then resolve the values from Secrets Manager, and save them into the on-disk copy of those credentials. JCasC would then fetch the values from Secrets Manager each time it runs, to keep them up to date.

As far as your jobs are concerned, the credentials will still come from the folders plugin like they do today. So the folders plugin would still be responsible for access control.

chris+jenkins@chriskilding.com (JIRA)

unread,
Mar 5, 2020, 6:34:02 AM3/5/20
to jenkinsc...@googlegroups.com
Chris Kilding edited a comment on Story JENKINS-60764
Regarding the question of access control... a new approach has just come up, which might be more appropriate for your use case.

This approach would involve defining credentials for the folders plugin in JCasC YAML - basically what you have already done with the folders plugin, but codified in YAML. You would interpolate the actual values of those credentials using JCasC interpolation key syntax. The upcoming SecretSource support in the AWS secrets manager credentials provider (JENKINS-61291) would then resolve the values from Secrets Manager, and hand them back to JCasC, which would save them into the on-disk copy of those credentials. JCasC would then fetch the values from Secrets Manager each time it runs, to keep them up to date.


As far as your jobs are concerned, the credentials will still come from the folders plugin like they do today. So the folders plugin would still be responsible for access control.

chris+jenkins@chriskilding.com (JIRA)

unread,
Mar 5, 2020, 6:36:02 AM3/5/20
to jenkinsc...@googlegroups.com
Chris Kilding edited a comment on Story JENKINS-60764
Regarding the question of access control... a new approach has just come up, which might be more appropriate for your use case.

This approach would involve defining credentials for the folders plugin in JCasC YAML - basically what you have already done with the folders plugin, but codified in YAML. You would interpolate the actual values of those credentials using JCasC interpolation key syntax. The upcoming SecretSource support in the AWS secrets manager credentials provider (JENKINS-61291) would then resolve the values from Secrets Manager, and hand them back to JCasC, which would save them into the on-disk copy of those credentials.


JCasC would then fetch the values from Secrets Manager consults its interpolation sources each time it runs, to keep them which should ensure that your credentials stay up to date on a frequency of however often you run JCasC .


As far as your jobs are concerned, the credentials will still come from the folders plugin like they do today. So the folders plugin would still be responsible for access control.
Reply all
Reply to author
Forward
0 new messages