[stable/concourse] Refactor values and make secrets optional #3254
[stable/concourse] Refactor values and make secrets optional #3254
Conversation
4a5bf24
to
a8a3cc1
Compare
/assign @viglesiasce @nexeck @mattfarina |
@william-tran: GitHub didn't allow me to assign the following users: nexeck. Note that only kubernetes members can be assigned. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/assign |
stable/concourse/README.md
Outdated
|
||
To run Concourse securely you'll need [3 private keys](https://concourse.ci/binaries.html#generating-keys). For your convenience, this chart provides some [default keys](concourse-keys), but it is recommended that you generate your own keys by running: | ||
For your convenience, this chart provides some default values for secrets, but it is recommended that you generate and manage these secrets outside the Helm chart. To do this, set `secrets.create` to `false`, create files for each secret value, and turn it all into a k8s secret. First, perform the following to create the manditory secret values: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@viglesiasce any idea how we run automated testing on this if mandatory secret values need to be manually created?
It would be nice if you could pass in a secret to use that was created outside the chart. If that didn't happen the chart could generate a secret.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now automated testing would only cover the case where secrets.create: true,
as in the values defaults, see https://github.com/kubernetes/charts/pull/3254/files#diff-95cc28250f44d26990fee96ad2fbd63dR465 and below (diff not rendered automatically by github)
FS4HAoGAGy+56+zvdROjJy9A2Mn/4BvWrsu4RSQILBJ6Hb4TpF46p2fn0rwqyhOj | ||
Occs+xkdEsI9w5phXzIEeOq2LqvWHDPxtdLpxOrrmx4AftAWdM8S1+OqTpzHihK1 | ||
y1ZOrWfvON+XjWFFAEej/CpQZkNUkTzjTtSC0dnfAveZlasQHdI= | ||
-----END RSA PRIVATE KEY----- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, templates can generate keys like this. See https://masterminds.github.io/sprig/crypto.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, though I don't see a function that can generate both the public key and private key, or extract a public key given a private key.
/ok-to-test |
Not sure why but in the test run and when running this locally the pods stayed in |
/test all |
I think that was a blip, reran tests and it was ready in 30 seconds |
You should definitely add a notice to README that manually created secrets must NOT have a trailing newline ( Otherwise, running Just spend a few hours debugging this and wouldn't wish it upon anyone :) |
I'm so sorry @ilyasotkov, I hope f748073 addresses that. |
013c591
to
ce0404a
Compare
Also noticed, this block in templates/secrets.yaml should have {{ if .Values.postgresql.enabled }}
postgresql-user: {{ .Values.postgresql.postgresUser | b64enc | quote }}
{{ else }}
postgresql-uri: {{ .Values.secrets.postgresql.uri | b64enc | quote }}
{{ end }} |
@william-tran do you have a sec to look at the isse that @ilyasotkov found wrt |
@ilyasotkov I don't think the postgres-password should be in these secrets as it needs to end up in the secrets for the postgres chart dependency as well, see https://github.com/autonomic-ai/charts/blob/ce0404a6a87c738baad46794c3ea630a93288429/stable/concourse/templates/web-deployment.yaml#L49 If you are using the postgres chart dependency, there's no way to keep that password out of your helm values. But now I question whether the postgres username needs to be a secret, or whether that can just go into the values. This was the way it was set up before I added the conditional postgres dependency and kept this structure, with the username in these secrets and the password in the postgres chart's secrets. But the postgres chart doesn't treat the username as a secret: https://github.com/kubernetes/charts/blob/master/stable/postgresql/templates/deployment.yaml#L34 So I'll further simplify this. |
@viglesiasce I've addressed @ilyasotkov's concern in the latest commit e8a9a96 |
@william-tran you are right about Also I think some massive confusion happened on my end there as I recommended you add the I believe this line in the README confused me
as it lead me to believe both Now that you removed |
Thanks for proofreading, now that I'm looking through the README there's lots of table entries that need updating. I'll try to get around to this in the next few days. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there may be some lifecycle issues with how Vault periodic tokens are being used right now.
Also using client certs is independent of other auth backends and can actually have separate pairs used for the TCP connection and identity verification. (Which has valid use cases.)
Some of my suggestions may fall outside of the scope of this PR so please let me know if you would like me to create separate issues. See my other comments for details.
|
||
## initial periodic token issued for concourse | ||
## ref: https://www.vaultproject.io/docs/concepts/tokens.html#periodic-tokens |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be best to leave this comment as it specifies the kind of token needed. For example if you configured it with a non renewable token it would fail after a period of time and if you use (gasp) a root token it would be a security horror.
{{- end }} | ||
{{- if .Values.credentialManager.vault.enabled }} | ||
vault-ca-cert: {{ default "" .Values.secrets.credentialManager.vault.caCert | b64enc | quote }} | ||
vault-client-token: {{ default "" .Values.secrets.credentialManager.vault.clientToken | b64enc | quote }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it may be incorrect to persist the client token in this way as concourse will need to periodically renew it and redeploying a stale token would cause a failure. (Same for a pod failure or scaling) I haven't verified this so maybe Concourse is smart enough to deal with it and has the latest token stored elsewhere. Vault best practice is to either use an App Role or even better a service account with the Vault Kubernetes auth backend. That has the downside of longer lived credentials, but the advantage of being able to deal with long periods of downtime without requiring manually created tokens. I'm not sure if concourse has a way to save the refreshed tokens but a persistent volume might make more sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe Concourse is smart enough to deal with it and has the latest token stored elsewhere.
@madmod I'm not a vault user, but from my reading of https://www.vaultproject.io/docs/concepts/tokens.html#periodic-tokens as long as there isn't downtime longer than the token period, the token value provided would still be valid. So maybe the word initial
should be dropped from the comment
## initial periodic token issued for concourse
Because this value shouldn't change, unless you have enough downtime that the token expires.
configMapKeyRef: | ||
name: {{ template "concourse.concourse.fullname" . }} | ||
key: vault-auth-backend | ||
value: {{ default "" .Values.credentialManager.vault.authBackend | quote }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be required instead of an empty default to avoid undefined behavior?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the comments for credentialManager.vault.authBackend
:
## vault authentication backend, leave this blank if using an initial periodic token
## currently supported backends: token, approle, cert.
##
# authBackend:
Concourse seems to deal with env vars that are set as empty strings for other features, so unless we can demonstrate otherwise, I'd be hesitant to start wrapping everything in if statements. See also https://concourse.ci/creds.html#vault
stable/concourse/values.yaml
Outdated
## provide the client key for authenticating with the [TLS](https://www.vaultproject.io/docs/auth/cert.html) backend | ||
## the value will be written to /concourse-vault/client.key | ||
## make sure to also set authBackend to `cert` | ||
# clientKey: |- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some Vault deployments may have the TCP listener configured to require a client cert and client key alongside any other form of authentication so it is incorrect to make this a choice between the three. It must be client token or app role and/or client cert and client key. Source
It is also possible to use one cert/key pair for the initial connection and another for the auth backend. (Untested but I'm pretty certain based on the documentation.)
An example use case could be having few shared client key pairs granting permission to talk with Vault at all (TCP listener) and a separate client key pair claiming the identity of the client. (TLS auth backend) This would allow for auditing of traffic with TLS decryption but securely prove the identity of the client in a way that could have a chain of trust subject to certificate revocation lists. (A common use case is for short lived ssh certs given to engineers by other engineers. Each engineer is an intermediate CA provided by Vault so provenance of credentials is easy to track.)
Maybe it would be better to treat this like caCert instead by having it be independent from the auth settings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whenever possible, please add defaults to values.yaml
instead of using the default
function.
@unguiculus I'll address the use of @madmod The documentation for the vault initial periodic token has moved to the bottom of values.yaml as I've separated out values stored as secrets into their own section. @viglesiasce How can I become at least a reviewer for this chart? I have a close relationship with the Concourse team so I'd probably be a good candidate to help drive adoption via this chart. Would you sponsor my membership? |
Provide a way to opt out of managing secrets in helm values. The configmap introduced needless repetition, mapping values directly to environment variables is a simpler approach.
Also fix encryption key values key in secrets, and rename credentialManager.vault.caCert to credentialManager.vault.useCaCert for clarity
Use a helper to produce more informative errors when secret values are required
Add rbac support for secret access from web pods to to team specific namespaces. Upgrade to Concourse 3.9.0
If the worker runs out of disk space, logs will stop tee-ing to /concourse-work-dir/.liveness_probe because it's on the same persistent volume, and the condition won't be detected.
Contributors, reviewers and approvers of PRs to this chart who are also kubernetes github org members.
5eff1f3
to
d5e35e3
Compare
@unguiculus have I addressed your concerns around the use of |
The maintainers have OWNER on the top level of the repo already
/lgtm Thanks @william-tran! |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: viglesiasce, william-tran 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 |
* Make secrets optional, eliminate configmap. Provide a way to opt out of managing secrets in helm values. The configmap introduced needless repetition, mapping values directly to environment variables is a simpler approach. * Don't store postgresql user as a secret * Add missing documentation for values introduced in this and previous PRs Also fix encryption key values key in secrets, and rename credentialManager.vault.caCert to credentialManager.vault.useCaCert for clarity * [stable/concourse] bump postgresql dependency to v0.8.11 * Remove redundant default template function calls * Flatten secret values Use a helper to produce more informative errors when secret values are required * Add support for using k8s secrets as a credential manager. Add rbac support for secret access from web pods to to team specific namespaces. Upgrade to Concourse 3.9.0 * Write the liveness probe log to /tmp instead of /concourse-work-dir If the worker runs out of disk space, logs will stop tee-ing to /concourse-work-dir/.liveness_probe because it's on the same persistent volume, and the condition won't be detected. * Add OWNERS file Contributors, reviewers and approvers of PRs to this chart who are also kubernetes github org members. * fix typos * see if btrfs works in e2e test * Stick with naive FS driver since its the most compatible * Fix helm#3407, make docs reflect actual value * Remove core maintainers from local OWNERS The maintainers have OWNER on the top level of the repo already
* Make secrets optional, eliminate configmap. Provide a way to opt out of managing secrets in helm values. The configmap introduced needless repetition, mapping values directly to environment variables is a simpler approach. * Don't store postgresql user as a secret * Add missing documentation for values introduced in this and previous PRs Also fix encryption key values key in secrets, and rename credentialManager.vault.caCert to credentialManager.vault.useCaCert for clarity * [stable/concourse] bump postgresql dependency to v0.8.11 * Remove redundant default template function calls * Flatten secret values Use a helper to produce more informative errors when secret values are required * Add support for using k8s secrets as a credential manager. Add rbac support for secret access from web pods to to team specific namespaces. Upgrade to Concourse 3.9.0 * Write the liveness probe log to /tmp instead of /concourse-work-dir If the worker runs out of disk space, logs will stop tee-ing to /concourse-work-dir/.liveness_probe because it's on the same persistent volume, and the condition won't be detected. * Add OWNERS file Contributors, reviewers and approvers of PRs to this chart who are also kubernetes github org members. * fix typos * see if btrfs works in e2e test * Stick with naive FS driver since its the most compatible * Fix helm#3407, make docs reflect actual value * Remove core maintainers from local OWNERS The maintainers have OWNER on the top level of the repo already Signed-off-by: voron <av@arilot.com>
Addresses #3208 with the original intent of the issue, to eliminate config map as a source of duplication and make secrets in helm values optional. I could take another stab at it using configmap and secrets supplying an envFrom, but I find this approach simpler.
This PR includes the commits in #3203 assuming that'll be merged first. Only the latest commit in this PR needs to be considered.