hashicorp / vault-action

A GitHub Action that simplifies using HashiCorp Vault™ secrets as build variables.
MIT License
442 stars 140 forks source link

[BUG] Response code 400 (Bad Request) when using approle auth #235

Open adamtharani opened 3 years ago

adamtharani commented 3 years ago

Describe the bug When trying to use the approle method to authenticate vault, the action breaks with a Response code 400 (Bad Request)

To Reproduce

- name: Import Secrets from Vault
  uses: hashicorp/vault-action@0451f06f9f705768363122da079f46746e31bfe4
  with:
    url: https://vault.***********:8200
    method: approle
    roleId: ${{ secrets.VAULT_ROLE_ID }}
    secretId: ${{ secrets.VAULT_SECRET_ID }}
    caCertificate: ${{ secrets.CA }}
    secrets: |

Expected behavior The action to return my secrets.

Log Output Error: Response code 400 (Bad Request)

Additional context Add any other context about the problem here.

steveteuber commented 3 years ago

Hey @adamtharani. Are you sure, your secretId that you are using is not expired?

adamtharani commented 3 years ago

Hey @steveteuber, yes I had just generated everything at the time of setup, I also did confirm by manually making an HTTP request with the same credentials and got a token back

nivedita-p commented 3 years ago

I think its more of an issue with the policy associated with the approle you created. I was getting the same error when the policy was not right.

soakes commented 3 years ago

Hi @nivedita-p I am also having the same problem. Using the same policy and even the roleid/secret, using vault agent, works fine, but using your action plugin, its not working.

I can confirm I can pull out the secrets by manually loggin in with the approle info or even by using vault agent.

Is there away to enable debugging on this module as I couldn't find anything in the logs which is helpful.

image

What prilivages do I need to work with your action?

The following are my polices.

Default policy


# Allow tokens to look up their own properties
path "auth/token/lookup-self" {
    capabilities = ["read"]
}

# Allow tokens to renew themselves
path "auth/token/renew-self" {
    capabilities = ["update"]
}

# Allow tokens to revoke themselves
path "auth/token/revoke-self" {
    capabilities = ["update"]
}

# Allow a token to look up its own capabilities on a path
path "sys/capabilities-self" {
    capabilities = ["update"]
}

# Allow a token to look up its own entity by id or name
path "identity/entity/id/{{identity.entity.id}}" {
  capabilities = ["read"]
}
path "identity/entity/name/{{identity.entity.name}}" {
  capabilities = ["read"]
}

# Allow a token to look up its resultant ACL from all policies. This is useful
# for UIs. It is an internal path because the format may change at any time
# based on how the internal ACL features and capabilities change.
path "sys/internal/ui/resultant-acl" {
    capabilities = ["read"]
}

# Allow a token to renew a lease via lease_id in the request body; old path for
# old clients, new path for newer
path "sys/renew" {
    capabilities = ["update"]
}
path "sys/leases/renew" {
    capabilities = ["update"]
}

# Allow looking up lease properties. This requires knowing the lease ID ahead
# of time and does not divulge any sensitive information.
path "sys/leases/lookup" {
    capabilities = ["update"]
}

# Allow a token to manage its own cubbyhole
path "cubbyhole/*" {
    capabilities = ["create", "read", "update", "delete", "list"]
}

# Allow a token to wrap arbitrary values in a response-wrapping token
path "sys/wrapping/wrap" {
    capabilities = ["update"]
}

# Allow a token to look up the creation time and TTL of a given
# response-wrapping token
path "sys/wrapping/lookup" {
    capabilities = ["update"]
}

# Allow a token to unwrap a response-wrapping token. This is a convenience to
# avoid client token swapping since this is also part of the response wrapping
# policy.
path "sys/wrapping/unwrap" {
    capabilities = ["update"]
}

# Allow general purpose tools
path "sys/tools/hash" {
    capabilities = ["update"]
}
path "sys/tools/hash/*" {
    capabilities = ["update"]
}

# Allow checking the status of a Control Group request if the user has the
# accessor
path "sys/control-group/request" {
    capabilities = ["update"]
}

cert-admin policy

# Permits token creation
path "auth/token/create" {
  capabilities = ["update"]
}

path "assets/metadata" {
  capabilities = ["list","read"]
}

path "github/metadata" {
  capabilities = ["list","read"]
}

path "assets/+/acme" {
  capabilities = ["list", "read"]
}

path "assets/+/ssl/*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

path "github/+/vault-cert-updater/*" {
  capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}

Can you spot anything I am missing?

GHA workflow snippet

      - name: "Import secrets"
        uses: hashicorp/vault-action@v2.3.1
        with:
          url: ${{ secrets.VAULT_ADDR }}
          method: approle
          roleId: ${{ secrets.VAULT_APPROLE_ROLE_ID }}
          secretId: ${{ secrets.VAULT_APPROLE_SECRET_ID }}
          exportToken: true
          secrets: |
            assets/acme email | _EMAIL ;
            github/vault-cert-updater/cloudflare token | _CF_AUTH_TOKEN ;
            github/vault-cert-updater/scw/s3 access-key | _ACCESS_KEY_ID ;
            github/vault-cert-updater/scw/s3 secret-key | _SECRET_ACCESS_KEY ;
            github/vault-cert-updater/scw/s3 bucket | _BUCKET ;
            github/vault-cert-updater/scw/s3 endpoint | _ENDPOINT

Personal notes on creating approle

Create approle for dnsrobocert and assign policies

vault write auth/approle/role/dnsrobocert policies="default,cert-admin" display-name="DNSRoboCert" token_num_uses=0 token_ttl=10m token_max_ttl=60m

Replace dynamic secret with static for approle push  (needed for GHA)

vault write auth/approle/role/dnsrobocert/custom-secret-id secret_id=4042ed24-5d5f-449b-**************

Create roleid file

vault read -format=json auth/approle/role/dnsrobocert/role-id \
        | jq  -r '.data.role_id' > role-id

Data entered via CLI

vault secrets enable -version=2 -path=github kv
vault kv put github/vault-cert-updater/scw/s3 access_key=SCWDQ****** secret_key=cccaf52e-a******* bucket=****-vault-cert-updater endpoint=https://s3.nl-ams.scw.cloud
vault kv put github/vault-cert-updater/cloudflare token=SbK465************
vault kv put assets/acme email=noc@**********

I am switching over, or trying to from using vault agent single run in my workflow to using your agent but am strugging in getting it to work. Any ideas?

Thanks in advance.

Kind Regards,

Simon


Update:

Iv'e recreated the roleid using the info I supplied above, whats strange is, im getting a bit further.

I have also found that you can enable debugging on the runners, which I wanst aware of which shows the following info now. Much better :)

So I still think its a permissions issue like you said, but idk what I am missing? can anyone enlighten me?

image

Many thanks


Final Update

This has been resolved.

The solution I have posted https://github.com/hashicorp/vault-action/issues/271#issuecomment-951877818 for completeness.

elfelton commented 2 years ago

I am experiencing the same issue with v2.4.2.

If I use clear-text strings for roleId and secretId authentication works, but if I use ${{secrets.ROLE_ID_TEST}} I get a 400 error.

I have verified that the values stored in GitHub Secrets are 100% correct with no extraneous whitespace or quotes, etc.

Below is an excerpt from my workflow file

  - id: get-secrets
  -   uses: vault-action@v2.4.2
        with:
          url: https://internalvault.foobar.com
          method: approle
          roleId: ${{secrets.ROLE_ID_TEST}}
          secretId: ${{secrets.SECRET_ID_TEST}}
          secrets: iat/data/foobar/hereSecretForTheAppRole abcd

      - id: get-secrets-backup
        if: always()
        uses: vault-action@v2.4.2
        with:
          url: https://internalvault.foobar.com
          method: approle
          roleId: c25e5d29-**********-8364cfd7cf5a
          secretId: 4fb378e5-92ed-*******-d34bb2070047
          secrets: iat/data/foobar/hereSecretForTheAppRole abcd

Here is my debug log from the get-secrets step in the workflow

##[debug]Evaluating condition for step: 'Run vault-action@v2.4.2'
##[debug]Evaluating: success()
##[debug]Evaluating success:
##[debug]=> true
##[debug]Result: true
##[debug]Starting: Run vault-action@v2.4.2
##[debug]Loading inputs
##[debug]Evaluating: secrets.ROLE_ID_TEST
##[debug]Evaluating Index:
##[debug]..Evaluating secrets:
##[debug]..=> Object
##[debug]..Evaluating String:
##[debug]..=> 'ROLE_ID_TEST'
##[debug]=> '***'
##[debug]Result: '***'
##[debug]Evaluating: secrets.SECRET_ID_TEST
##[debug]Evaluating Index:
##[debug]..Evaluating secrets:
##[debug]..=> Object
##[debug]..Evaluating String:
##[debug]..=> 'SECRET_ID_TEST'
##[debug]=> '***'
##[debug]Result: '***'
##[debug]Loading env
Run vault-action@v2.4.2
  with:
    url: https://internalvault.foobar.com
    method: approle
    roleId: ***
    secretId: ***
    tlsSkipVerify: true
    secrets: iat/data/foobar/hereSecretForTheAppRole abcd
    kubernetesTokenPath: /var/run/secrets/kubernetes.io/serviceaccount/token
    exportEnv: true
    exportToken: false
    jwtTtl: 3600
::group::Get Vault Secrets
Get Vault Secrets
  ##[debug]Retrieving Vault Token from v1/auth/approle/login endpoint
  ::endgroup::
Error: Response code 400 (Bad Request)
##[debug]Node Action run completed with exit code 1
##[debug]Finishing: Run vault-action@v2.4.2

And the debug log from the get-secrets-backup

##[debug]Evaluating condition for step: 'Run vault-action@v2.4.2'
##[debug]Evaluating: always()
##[debug]Evaluating always:
##[debug]=> true
##[debug]Result: true
##[debug]Starting: Run vault-action@v2.4.2
##[debug]Loading inputs
##[debug]Loading env
Run vault-action@v2.4.2
  with:
    url: https://internalvault.foobar.com
    method: approle
    roleId: ***
    secretId: ***
    tlsSkipVerify: true
    secrets: iat/data/foobar/hereSecretForTheAppRole abcd
    kubernetesTokenPath: /var/run/secrets/kubernetes.io/serviceaccount/token
    exportEnv: true
    exportToken: false
    jwtTtl: 3600
::group::Get Vault Secrets
Get Vault Secrets
  ##[debug]Retrieving Vault Token from v1/auth/approle/login endpoint
  ##[debug]✔ Vault Token successfully retrieved
  ::group::Token Info
Token Info
  ##[debug]Operating under policies: ["default","iat-*************-view"]
  ##[debug]Token Metadata: {"role_name":"ar-***********"}
  ::endgroup::
::add-mask::***
::set-output name=abcd::***
##[debug]steps.get-secrets-backup.outputs.abcd='***'
##[debug]✔ iat/data/foobar/hereSecretForTheAppRole => outputs.abcd | env.ABCD
::endgroup::
##[debug]Node Action run completed with exit code 0
##[debug]ABCD='***'
##[debug]Finishing: Run vault-action@v2.4.2