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

Passing k8s secret to a workflow as input #5506

Open
roitalpaz opened this issue Mar 25, 2021 · 29 comments · May be fixed by #13899
Open

Passing k8s secret to a workflow as input #5506

roitalpaz opened this issue Mar 25, 2021 · 29 comments · May be fixed by #13899
Labels
area/spec Changes to the workflow specification. solution/workaround There's a workaround, might not be great, but exists type/feature Feature request type/security Security related

Comments

@roitalpaz
Copy link

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 👍.

@roitalpaz roitalpaz added the type/feature Feature request label Mar 25, 2021
@alexec
Copy link
Contributor

alexec commented Mar 25, 2021

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.

@roitalpaz
Copy link
Author

roitalpaz commented Mar 29, 2021

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

@alexec
Copy link
Contributor

alexec commented Mar 29, 2021

That looks good. Would you like to submit a PR?

@shuheiktgw
Copy link

Hi, may I work on this issue if no one does right now?

@StepanKuksenko
Copy link

@shuheiktgw hi, do you have any progress regarding this?

@terrytangyuan
Copy link
Member

terrytangyuan commented Oct 19, 2021

We've recently added support for loading parameters from ConfigMaps in #6662 so it should be pretty straightforward to support secret as well following that reference implementation.

@alexec
Copy link
Contributor

alexec commented Oct 19, 2021

If anyone would like to commit the changes, the core team will provide support.

@shadiramadan
Copy link

shadiramadan commented Feb 2, 2022

So for functionality is this basically a clone of #6982 #6662 @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:
image

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.

@alexec
Copy link
Contributor

alexec commented Feb 3, 2022

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?

@alexec alexec added area/spec Changes to the workflow specification. and removed help wanted labels Feb 7, 2022
@alexec alexec added the good first issue Good for newcomers label Apr 11, 2022
@sarabala1979
Copy link
Member

@roitalpaz you can mount the secret on pods. this is a more secure way to access the secret in container

@panakour
Copy link

any update on this?

@jamesgoodhouse
Copy link

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.

@beejiujitsu
Copy link
Contributor

Related to OP:

When using Templates directly (e.g., the HTTP Template), it isn't possible to read a k8s secret into it.

@jamesgoodhouse
Copy link

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.

@beejiujitsu
Copy link
Contributor

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/

@kevinpauli
Copy link

I too am attempting to use http template, and would like to set the authorization header using a value from a secret.

@beejiujitsu
Copy link
Contributor

beejiujitsu commented Aug 31, 2022

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 

@johnlinp
Copy link
Contributor

johnlinp commented Oct 4, 2022

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

@Igor992
Copy link

Igor992 commented Oct 17, 2022

@johnlinp Thanks for this, works perfectly! 👍🏼

@Sajiyah-Salat

This comment was marked as duplicate.

@tooptoop4
Copy link
Contributor

tooptoop4 commented Feb 13, 2023

i have similar issue with resources.requests....getting "Failed to parse workflow template: quantities must match the regular expression '^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$'" with:

        resources:
          requests:
            memory: "{{inputs.parameters.ram}}Gi"
            cpu: "{{inputs.parameters.cpu}}"

@xmsanchez
Copy link

xmsanchez commented Apr 27, 2023

@beejiujitsu suggested solution works perfectly and is the most efficient and secure from this thread IMO.

         args:
           - $(WEBHOOK_URL)
           - '--include'
           - '--json'
           - '{"content": "{{inputs.parameters.content_prefix}} {{inputs.parameters.forked_subgraph_name}}: {{inputs.parameters.forked_subgraph_url}}"}'
         env:
           - name: WEBHOOK_URL
             valueFrom:
               secretKeyRef:
                 key: forked-subgraph
                 name: discord-webhooks

@joebowbeer
Copy link
Contributor

With support for resource action: get another workaround is:

apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
  name: secret-extractor
spec:
  entrypoint: main
  templates:
  - name: main
    inputs:
      parameters:
      - name: secretNamespace
        value: default
      - name: secretName
      - name: secretKey
    outputs:
      parameters:
      - name: secretValue
        valueFrom:
          jsonPath: '{.data.{{inputs.parameters.secretKey}}}'
    resource:
      action: get
      manifest: |
        apiVersion: v1
        kind: Secret
        metadata:
          name: {{inputs.parameters.secretName}}
          namespace: {{inputs.parameters.secretNamespace}}

@umi0410
Copy link
Contributor

umi0410 commented Jul 23, 2023

@terrytangyuan I'm interested in this issue. Could I investigate this?

@terrytangyuan
Copy link
Member

@umi0410 Sure go ahead

@umi0410
Copy link
Contributor

umi0410 commented Jul 25, 2023

@terrytangyuan I wrote a PR for the initial implementation. Could you take a look at it?

@artemklevtsov
Copy link

artemklevtsov commented Dec 12, 2023

You're welcome to modify this WorkFlowTemplate to suit your needs. [...]

But pass env to the args not works for me:

# yaml-language-server: $schema=https://raw.githubusercontent.com/argoproj/argo-workflows/master/api/jsonschema/schema.json
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: curl-test-
spec:
  entrypoint: main
  templates:
    - name: main
      container:
        image: quay.io/curl/curl:latest
        env:
          - name: URL
            value: https://ifconfig.co
        command:
          - curl
        args:
          - ${URL}

What am I doing wrong?

Work only with shell:

        command:
          - sh
        args:
          - -c
          - curl -s ${URL}

@beejiujitsu
Copy link
Contributor

beejiujitsu commented Jan 13, 2024

But pass env to the args not works for me: [...]

What am I doing wrong?

Work only with shell: [...]

You're using curly braces for the arg env var; use parentheses. See my example again.

@agilgur5 agilgur5 added solution/workaround There's a workaround, might not be great, but exists solution/suggested A solution to the bug has been suggested. Someone needs to implement it. and removed good first issue Good for newcomers hacktoberfest labels Feb 12, 2024
@agilgur5 agilgur5 added the type/security Security related label Apr 4, 2024
@agilgur5 agilgur5 removed the solution/suggested A solution to the bug has been suggested. Someone needs to implement it. label Aug 4, 2024
@rossigee
Copy link

Security issues aside, the workarounds so far all depend on containers and shell substitution, so aren't very efficient.

It would be great to be able to pull a secret into an HTTP template without needing an intermediate container step. For example, pull a variable 'discord_url' in and use it as the 'url' for a POST request.

shuangkun added a commit to shuangkun/argo-workflows that referenced this issue Nov 12, 2024
shuangkun added a commit to shuangkun/argo-workflows that referenced this issue Nov 14, 2024
shuangkun added a commit to shuangkun/argo-workflows that referenced this issue Jan 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/spec Changes to the workflow specification. solution/workaround There's a workaround, might not be great, but exists type/feature Feature request type/security Security related
Projects
None yet
Development

Successfully merging a pull request may close this issue.