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

Proposal for re-introducing SecretGenerators using Exec. #892

Merged
merged 1 commit into from
Mar 27, 2019

Conversation

pwittrock
Copy link
Member

@pwittrock pwittrock commented Mar 12, 2019

Follow up to #811

@k8s-ci-robot k8s-ci-robot added approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Mar 12, 2019
@k8s-ci-robot k8s-ci-robot requested review from seans3 and soltysh March 12, 2019 18:25
@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Mar 12, 2019
@pwittrock pwittrock requested review from anguslees and removed request for soltysh and seans3 March 12, 2019 18:25
@k8s-ci-robot k8s-ci-robot added kind/kep Categorizes KEP tracking issues and PRs modifying the KEP directory sig/cli Categorizes an issue or PR as relevant to SIG CLI. labels Mar 12, 2019
@pwittrock
Copy link
Member Author

cc @akutz

@donbowman
Copy link

It seems like another way to achieve the goal is exec path prefix.

the other kep is about ~/.config/... for the hard-coded path.
if that were added here then I could simply soft-link the 'exposed' executables into there, rather than renaming them from /usr/bin.

e.g. ln -s /usr/bin/sops ~/.config/kustomize/sops

and then --exec-path-prefix ~/.config/kustomize

Copy link
Member

@anguslees anguslees left a comment

Choose a reason for hiding this comment

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

lgtm. In particular, this is effectively a whitelist of allowed commands explicitly configured on the client-side - which addresses the concerns I had with the original SecretGenerators (remote file could specify arbitrary local commands).

It would be nice to clarify in the doc whether the commands are executed when using --dry-run or not.

- Command is executed from the `PATH` variable, it cannot be an absolute or relative path
- This is to prevent Carl from publishing a malicious generator with the kustomization.yaml and invoking it
- Users can override the prefix with a string value with `len(value) > 2` - e.g. `sg-`
- Min length is to prevent users from providing an empty value, which would allow arbitrary command execution
Copy link
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 nanny-state imo. If I have gone out of my way to overridde an option, then the tool should do-what-i-said (don't introduce an arms race with the user).

Copy link
Contributor

Choose a reason for hiding this comment

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

@anguslees sorry to see that you aren't the author on this KEP. Feel free to write a different one - there's no limit.
@pwittrock can we leave some of the more obvious KEP opportunities to new community members?

Copy link
Member Author

Choose a reason for hiding this comment

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

I am fine with removing this.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, maybe I'll start writing KEPs for KEPs :)

Copy link
Contributor

Choose a reason for hiding this comment

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

@anguslees A colleague suggested my previous comment was inappropriate, and I apologize. I meant it literally. You made some great points on #811, which strongly influenced its final form, and i hoped you or someone else who was interested in exec would contribute something along these lines.

Re-introduce `exec` Secret generators, but require the executables to have a whitelisted prefix
and require a flag.

- Introduce a flag `--secret-generator-exec-prefix` defaulted to `kustomize-sg-`
Copy link
Member

@anguslees anguslees Mar 13, 2019

Choose a reason for hiding this comment

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

What is a use-case where someone would vary this? (Is it ok to just always use that specific prefix?)

Copy link
Member Author

Choose a reason for hiding this comment

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

I could imagine this for if they wanted to use kubectl or git plugins for instance.

Copy link
Member Author

Choose a reason for hiding this comment

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

Or, in the case of using a directory containing the binaries, to disable it altogether.

@pwittrock
Copy link
Member Author

@donbowman

It seems like another way to achieve the goal is exec path prefix.

Good point. Something I had considered but didn't put in the alternatives. This isn't mutually exclusive and I could add it as another flag. Then users could do

  • Use anything on the user's path
    • --secret-generator-exec-prefix="" ----exec-path-prefix=""
  • Executables from a dir
    • --secret-generator-exec-prefix="" ----exec-path-prefix="~/.kube/config"
  • Executables with a prefix
    • --secret-generator-exec-prefix="kustomize-sg-" ----exec-path-prefix=""
  • Executables with a prefix that are in a dir
    • --secret-generator-exec-prefix="kustomize-sg-" ----exec-path-prefix="~/.kube/config"

Thoughts?

Copy link

@donbowman donbowman left a comment

Choose a reason for hiding this comment

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

@donbowman

It seems like another way to achieve the goal is exec path prefix.

Good point. Something I had considered but didn't put in the alternatives. This isn't mutually exclusive and I could add it as another flag. Then users could do

  • Use anything on the user's path

    • --secret-generator-exec-prefix="" ----exec-path-prefix=""
  • Executables from a dir

    • --secret-generator-exec-prefix="" ----exec-path-prefix="~/.kube/config"
  • Executables with a prefix

    • --secret-generator-exec-prefix="kustomize-sg-" ----exec-path-prefix=""
  • Executables with a prefix that are in a dir

    • --secret-generator-exec-prefix="kustomize-sg-" ----exec-path-prefix="~/.kube/config"

Thoughts?

its more convenient for me to have a prefix dir and call it a day, than to rename the tools to have a prefix in their exec.

e.g. I'd rather ln -s sops somewhere and just type sops when doing it interactively, than rename sops to kustomize-prefix-sops and try and remember that.

Re-introduce `exec` Secret generators, but require the executables to have a whitelisted prefix
and require a flag.

- Introduce a flag `--secret-generator-exec-prefix` defaulted to `kustomize-sg-`
Copy link

@donbowman donbowman Mar 13, 2019

Choose a reason for hiding this comment

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

suggest also/instead --secret-generator-path.
this allows an admin to softlink the exposed tools into a directory, rather than searching the path.
simpler for the end user and more secure

e.g. I would allow this ---exec-path-prefix="~/.kube/config" concept to be a path.
then I would just 'setenv('PATH', that)' in main(). this would allow me to have >1 spot for curated plugins, w/o exposing them randomly to kubectl apply http://blah/ random bad users, and leave the rest of the code intact.

Choose a reason for hiding this comment

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

also i think the 'with a prefix in a dir' is not needed.
IMHO simply the dir is sufficient, and would have been the solution I would have intro when this whole convo started that lead to the removal of the command. But certainly i don't have an issue w/ also having a prefix on the name.

Copy link
Member Author

Choose a reason for hiding this comment

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

WDYT of the current proposal? Specifically w.r.t. the defaults chosen. e.g. we default to prefix based rather than dir based, but support both.

Copy link
Member Author

Choose a reason for hiding this comment

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

Defaulting the path to an absolute path would make it simpler to produce a kustomize container with generators pre-installed. Maybe default it to (os agnostic version of) /usr/local/kustomize/bin/ ?

Choose a reason for hiding this comment

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

TBH I'm ok w/ anything that works since its unlikely that the defaults are perfect and its not hard to set.

So sure. prefix default is ok, support path/dir optional is ok. default to /usr/local/k/bin? sure, seems fine to me too.

Copy link
Member Author

Choose a reason for hiding this comment

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

SG. I'll sleep on it and finalize the defaults tomorrow. Sounds like we are good to more forward though.

@pwittrock
Copy link
Member Author

PTAL. I believe I have addressed all comments.

@pwittrock
Copy link
Member Author

I think the defaults for the values is the only thing up in the air. I think we can move forward with this, and revisit the defaults as a follow up.

@sethpollack
Copy link
Contributor

@pwittrock It will be possible to have many different types of KV plugins in a single kustomization file. Rather than having flags for overriding each type, would it make more sense for them all to share path/filename conventions and then allow users to override with either flags or env vars?

- Alice wants to run a whitebox mysql instance on a test cluster
- Carl publishes a whitebox mysql `kustomization.yaml` on GitHub, with a SecretGenerator
that will read Alice's ~/.kube/config and send it to Carl's server by executing `sh`
will a script to generate some Secret
Copy link
Member

Choose a reason for hiding this comment

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

nit: sentence is incorrect I suspect

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed

Copy link
Member

@apelisse apelisse left a comment

Choose a reason for hiding this comment

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

I think this proposal is better than the previous one.

My main goal is:

  1. In an organization where bases are shared across teams, I don't want to have to standardize a convention for the prefix name, which made the prefix option hard to manage
  2. I don't want to have to copy scripts to a specific location every time I run kustomize
  3. Ideally, I think I'd want the scripts to be committed next to my kustomization.yaml file
  4. I want to be able to declarative whitelist the scripts that I've vetted

At least with this solution, I see we could do:

  • When I update my bases, I copy (possibly rename to have a common prefix) and inspect all these bases scripts into my top-level dir and commit them
  • Code reviews help catch problematic constructs
  • I always run kustomize with --sg-exec-path=. --sg-prefix-path=vetted-

Hope this makes sense,

- (default) the empty string - disable exec secrets altogether
- `$PATH` - any executable in the user's path matching the prefix
- an absolute directory path - only executables matching the prefix in that directory
- a relative directory - only executables matching the prefix in that directory
Copy link
Member

Choose a reason for hiding this comment

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

I'm assuming it's relative to the kustomization.yaml file that was command-line specified, and by "in that directory" you're saying "that doesn't contain ..". Does it follow symlinks outside "that directory"?

Copy link
Member Author

Choose a reason for hiding this comment

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

changed this. lmk what you think

@pwittrock
Copy link
Member Author

@apelisse

IIUC, I agree with your assessment. Users have enough flexibility w.r.t. how they provide plugins to be able to things that might work really well for their environment / organization, but wouldn't be appropriate for all organizations or as defaults.

@pwittrock pwittrock force-pushed the secret-gen branch 2 times, most recently from de26f3e to 2338bda Compare March 14, 2019 18:19
@pwittrock
Copy link
Member Author

pwittrock commented Mar 14, 2019

@anguslees @donbowman @apelisse @sethpollack @monopole

PTAL. Refined the UX and updated the defaults based on the feedback from y'all.

Notable changes:

  • Require --sg-exec-enabled to enable the secret generation
  • Use "/usr/local/kustomize/sg"as the default search location. Remove support for using the PATH rather than explicitly defined dirs.
  • Use "" as the default prefix. Rely on the paths as the primary mechanism for restriction.

Also added some items as possible features for GA.

@pwittrock
Copy link
Member Author

PTAL

@pwittrock pwittrock force-pushed the secret-gen branch 10 times, most recently from 68fc805 to 8e3a5ef Compare March 27, 2019 03:13
@donbowman
Copy link

lgtm

Copy link
Contributor

@soltysh soltysh left a comment

Choose a reason for hiding this comment

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

I'm slightly concerned about this returning... but I see it's part of today's SIG-CLI call, so that's good 👍


```sh
# User enables the plugin and allows it to exec sh
$ kubectl apply -k https://github.com/chuck/maliciousapp --enable-plugins --plugin-path=/bin
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm... my only concert is that this will confuse users, when he reads --enable-plugins the first thing he might think of is kubectl plugins, but that's not the case here.

Copy link
Contributor

Choose a reason for hiding this comment

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

The plugin is enabled by installing it.

or another location she provided with `--plugin-path=<path-including-exploitable-binary>`
- The specified SecretGenerator must be exploitable
- Simple transformation functions would not be exploitable.
- e.g. A command like `cat` would not be possible for Chuck to exploit in a meaningful way.
Copy link
Contributor

Choose a reason for hiding this comment

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

Additional risk is that --enable-plugins is specified as part of alias, thus invoking kustomize will always have that enabled.

Copy link
Contributor

@monopole monopole Mar 27, 2019

Choose a reason for hiding this comment

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

These flags will be aliased or encoded in scripts. The true opt-in point is installing the plugin. If a bad actor can install the plugin, none of these flags help.

The real issue here is the assumption that someone is blindly obtaining instructions from the web and blindly using them when applying to their cluster.

In this spirit of helping people to avoid hurting themselves, one could help here by failing on any attempt to obtain a kustomization target from the web unless the user specified

  --enable_download_of_unverified_instructions_from_the_internet

or some such. But people can already curl | apply so...

Someone who's blindly installing resources found on the web to their cluster is putting their cluster at risk. I understand that local exec is a new twist here, but arguably that's only a threat to the system which is running kustomize, and the user has already opted in by installing the plugin.

Copy link
Member Author

Choose a reason for hiding this comment

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

This only addresses malicious plugins, not exploitable plugins. They are 2 different things.


#### Enable Plugins with Environment Variables

Allow users to specify `export KUSTOMIZE_ENABLE_PLUGINS=true` instead of providing the flag.
Copy link
Contributor

Choose a reason for hiding this comment

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

Although it's convenient, env vars usually hide stuff. For this particular usecase I'd prefer we do not have env var. Although the alias problem (see my other comment) is still a thing.

Copy link
Contributor

Choose a reason for hiding this comment

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

The env var acknowledges that the flag is merely a source of annoyance.

@apelisse
Copy link
Member

I think I agree with @monopole that most of this is unnecessary. Having the plugins prefixed with kustomize- in $PATH should be good enough. no need for environment variable, customize prefix, specific bin path, etc ...

@monopole
Copy link
Contributor

monopole commented Mar 27, 2019

i like plugins as an extension point, but don't think this proposal establishes that these extra flags solve a problem that isn't already solved.

The plugins are here:

$XDG_CONFIG_HOME/kustomize/plugins/kvSources

This allows them to be installed and virtually relocated with whatever security your local filesystem has.

The convention here is that followed by chrome, gcloud, etc. The path makes it unambiguous that these are kustomize plugins. It's already implemented for goplugins - exec plugins can be added trivially.

@pwittrock
Copy link
Member Author

pwittrock commented Mar 27, 2019

I think I agree with @monopole that most of this is unnecessary. Having the plugins prefixed with kustomize- in $PATH should be good enough. no need for environment variable, customize prefix, specific bin path, etc ...

Why is kustomize- prefix better than a dir? At least 1 user has expressed they prefer the dir approach.

@donbowman
Copy link

I think I agree with @monopole that most of this is unnecessary. Having the plugins prefixed with kustomize- in $PATH should be good enough. no need for environment variable, customize prefix, specific bin path, etc ...

Why is kustomize- prefix better than a dir?

can we please not make the mistake kubectl did and require a prefix of kustomise-? It breaks the tab-completion in bash. kubectl<tab> now needs more letters, unlike the rest of the shell, when plugins are installed.

If you want a prefix for some reason, please don't make it the same as the base command :)

-- signed a sad bash completion fan

@vreon
Copy link

vreon commented Mar 27, 2019

Just speaking as an interested user here. Either approach is acceptable to me, but I don't see a compelling reason to deviate from the path that git and kubectl have taken.

I'm looking at KEP 24 and it notes that "[forcing] plugin scripts and executables to exist in a pre-determined location" was undesirable but doesn't explain why. Anyone know the story there?

@apelisse
Copy link
Member

Why is kustomize- prefix better than a dir? At least 1 user has expressed they prefer the dir approach

Either way would work, as long as you don't have to explicitely specify that path everytime. If we have a default path, it should probably be something simple enough that I don't have to create a specific hierarchy to satisfy the tool (If I want to configure $XDG_CONFIG_HOME/kustomize/plugins/kvSources, I still have to create kustomize/plugins/kvSources). PATH is pretty conventional, if they want to use a dir, they can add it to their path, etc ... No strong opinion, I just think it's convenient.

@pwittrock
Copy link
Member Author

pwittrock commented Mar 27, 2019

Prefix vs Path

No argument has been given to justify one of these as strictly better than the other. They have slightly different UX each of which appeals to different users. Everyone has their own opinion without a lot of data beside personal preference (including myself).

We need to choose:

  • Support both
  • Pick one and support that
    • Consider also adding the other later
  • Bike shed endlessly

Explicit flag to enable

Organizations are likely to provide their own kustomize distributions with their own plugins. IMHO, It is more likely that the distributed plugins will be Exploitable (e.g. gcloud) than Malicious (e.g. carls-bad-plugin). The users running Kustomize on their dev station would be different than the users installing the plugins in their dev station. A simple kustomize build to see what a public MySQL kustomization.yaml could then invoke commonly installed exploitable plugins.

The big points are:

  • Will users be trained to use the flag always, in which case it isn't that useful? Some users might, other users might not.
  • For environments where a different user installs kustomize + plugin than runs kustomize, both must opt-in to running them.

What is the worst case scenario with requiring the flag?

@vreon
Copy link

vreon commented Mar 27, 2019

Have we also considered an exec-less implementation?

kustomize build --external-secret-generator | my-custom-secret-fetcher > secrets.yaml
kustomize edit add resource secrets.yaml
kustomize build | kubectl apply -f -

Edit: Also, lmk if it'd be more appropriate to propose that ^ elsewhere. Like if this discussion is "how to" exec plugins rather than "should we", that's totally fair.

@donbowman
Copy link

Have we also considered an exec-less implementation?

kustomize build --external-secret-generator | my-custom-secret-fetcher > secrets.yaml
kustomize edit add resource secrets.yaml
kustomize build | kubectl apply -f -

Edit: Also, lmk if it'd be more appropriate to propose that ^ elsewhere. Like if this discussion is "how to" exec plugins rather than "should we", that's totally fair.

I'm trying to achieve a secrets don't end up on disk unencrypted solution. If the approach is build > file, then the secrets get decrypted and placed on disk. I'm looking for a pipeline.

@monopole
Copy link
Contributor

withdrawn, lets go.

@monopole
Copy link
Contributor

Phil has already merged https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/20190318-kustomize-generators-transformers.md, which arguably includes secret generation via plugin as a subset, so we can accept this or just drop it

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Mar 27, 2019
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: monopole, pwittrock

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot merged commit b28bf26 into kubernetes:master Mar 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/kep Categorizes KEP tracking issues and PRs modifying the KEP directory lgtm "Looks good to me", indicates that a PR is ready to be merged. sig/cli Categorizes an issue or PR as relevant to SIG CLI. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants