argo-workflows
argo-workflows copied to clipboard
Passing k8s secret to a workflow as input
Summary
I know it is possible to pass a secret to a container via ENV or FILE. but it is not possible to pass it as an argument of a workflow.
Use Cases
I have a few tools which accept values as command line args. These args are values which I'm not convenient in putting in YAMLs as plaintext and would like to store as k8s secrets.
Message from the maintainers:
Impacted by this bug? Give it a 👍. We prioritize the issues with the most 👍.
Could you propose the syntax? Where would the secrets be? In the user namespace? The controller would need RBAC access. Might not pass security audit for some users.
Thanks for the quick comment!
Syntax
Regarding the syntax I though something along the lines:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: arguments-parameters-
spec:
entrypoint: whalesay
arguments:
parameters:
- name: message
valueFrom:
secretKeyRef:
name: my-secret
key: mypassword
templates:
- name: whalesay
inputs:
parameters:
- name: message
container:
image: docker/whalesay:latest
command: [cowsay]
args: ["{{inputs.parameters.message}}"]
The valueFrom idea is taken from here: https://argoproj.github.io/argo-workflows/examples/#secrets
Secrets location
regarding the location of the secrets, I think placing the secret in the user namespace and giving permissions to the controller to this specific secret only will pass most security audits.
using the resourceNames
https://kubernetes.io/docs/reference/access-authn-authz/rbac/#referring-to-resources
That looks good. Would you like to submit a PR?
Hi, may I work on this issue if no one does right now?
@shuheiktgw hi, do you have any progress regarding this?
We've recently added support for loading parameters from ConfigMaps in https://github.com/argoproj/argo-workflows/pull/6662 so it should be pretty straightforward to support secret as well following that reference implementation.
If anyone would like to commit the changes, the core team will provide support.
So for functionality is this basically a clone of #6982 @alexec @terrytangyuan ?
Should we also sanitize the display of such parameters as 'secret' ?
Should you be able to mark a parameter as secret at all?
- name: my-pass
value: "{{some-output-val}}"
secret: "true"
Which could subsequently not display the raw value anywhere? Same with outputs I guess... or is this overkill?
ArgoCD displays secrets like this:
I'm having an issue right now where I'm using the http template and I have an API key. Right now it is passed in as a param but it renders in the UI. The alternative is to make a container running curl and pass it as an env value.... but I felt that was a little too much.
I think you mean it is a clone of #6662. I think it might be more difficult. I think we store parameters in the workflows status. But, we should not do this with secrets. I might be wrong. Could you investigate?
@roitalpaz you can mount the secret on pods. this is a more secure way to access the secret in container
any update on this?
I'm unsure the reason Argo can't load secrets like this, but I suspect it was an intentional decision to limit Argo from accessing secrets directly. I just load the secret name into my workflows and pass it down to the container that needs it, and have it be "responsible" for getting the value from the secret.
Related to OP:
When using Templates directly (e.g., the HTTP Template), it isn't possible to read a k8s secret into it.
why not just pass the secret name in and have the container load the secret? there's no need for argo to load the secret, nor do i think it should.
why not just pass the secret name in and have the container load the secret? there's no need for argo to load the secret, nor do i think it should.
The HTTP Template is a built-in template that doesn't offer container parameters, so what you're suggesting isn't possible.
https://argoproj.github.io/argo-workflows/http-template/
I too am attempting to use http template, and would like to set the authorization header using a value from a secret.
I too am attempting to use http template, and would like to set the authorization header using a value from a secret.
I wrote this workflow to work-around the httpTemplate secrets limitation.
You're welcome to modify this WorkFlowTemplate
to suit your needs.
---
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
annotations:
workflows.argoproj.io/description: 'Forked subgraph: notify Discord'
workflows.argoproj.io/maintainer: '@beejiujitsu'
workflows.argoproj.io/version: '>= v3.3.6'
name: forked-subgraph-notify-discord
spec:
activeDeadlineSeconds: 172800
arguments:
parameters:
- name: content_prefix
- name: forked_subgraph_name
- name: forked_subgraph_url
entrypoint: main
podGC:
strategy: OnWorkflowSuccess
podMetadata:
labels:
app: forked-subgraph
templates:
- container:
args:
- $(WEBHOOK_URL)
- '--include'
- '--json'
- '{"content": "{{inputs.parameters.content_prefix}} {{inputs.parameters.forked_subgraph_name}}: {{inputs.parameters.forked_subgraph_url}}"}'
command:
- curl
env:
- name: WEBHOOK_URL
valueFrom:
secretKeyRef:
key: forked-subgraph
name: discord-webhooks
image: curlimages/curl:7.84.0
name: curl
resources:
limits:
memory: 100Mi
requests:
memory: 50Mi
securityContext:
allowPrivilegeEscalation: false
runAsGroup: 1000
runAsUser: 1000
inputs:
parameters:
- name: content_prefix
- name: forked_subgraph_name
- name: forked_subgraph_url
name: main
Hi, I created a workaround for the secret parameter: a template that extracts secret as a output parameter.
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: secret-extractor
spec:
templates:
- name: main
inputs:
parameters:
- name: secretName
- name: secretKey
outputs:
parameters:
- name: secretValue
valueFrom:
path: /tmp/secret-value
container:
image: docker-registry.netbase.com/alpine:latest
command:
- sh
- '-c'
args:
- echo -n "$SECRET_VALUE" > /tmp/secret-value
env:
- name: SECRET_VALUE
valueFrom:
secretKeyRef:
name: "{{inputs.parameters.secretName}}"
key: "{{inputs.parameters.secretKey}}"
entrypoint: main
One can use it in steps, for example:
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: demo
spec:
templates:
- name: main
steps:
- - name: extract-secret
templateRef:
name: secret-extractor
template: main
arguments:
parameters:
- name: secretName
value: demo-secret
- name: secretKey
value: password
- - name: print-msg
template: msg-printer
arguments:
parameters:
- name: msg
value: "{{steps.extract-secret.outputs.parameters.secretValue}}"
- name: msg-printer
inputs:
parameters:
- name: msg
container:
image: docker-registry.netbase.com/alpine:latest
command:
- echo
- "{{inputs.parameters.msg}}"
entrypoint: main
@johnlinp Thanks for this, works perfectly! 👍🏼