Generating a token with JWT authod from Hashicorp Vault (enterprise)

Hi All,

I’m struggling with using the module community.hashi_vault.vault_token_create with a JW to generate a Hashicorp Vault token. I’m able to use the ansible.builtin.uri successfully with the same input values to generate a token.

My code

This works and successully generates a functional token.

      ansible.builtin.uri:
        url: '{{ vault_addr }}/v1/auth/jwt-aap/login'
        method: POST
        headers:
          X-Vault-Namespace: '{{ vault_namespace }}'
        body: '{{ {"jwt": jwt, "role": vault_role} | to_json }}'
        validate_certs: false
        return_content: true
      environment:
        PYTHONWARNINGS: "ignore:Unverified HTTPS request"
      register: _vault_token_result

However this …

    - name: 'Get token from Hashicorp Vault with vault_token_create'
      community.hashi_vault.vault_token_create:
        auth_method: 'jwt'
        jwt: '{{ jwt }}'
        role_id: '{{ vault_role }}'
        namespace: '{{ vault_namespace }}'
        url: '{{ vault_addr }}'
        validate_certs: false
      environment:
        PYTHONWARNINGS: "ignore:Unverified HTTPS request"
      register: _vault_token_result

produces an error like this “An exception occurred during task execution. To see the full traceback, use -vvv. The error was: hvac.exceptions.Forbidden: permission denied, on post https://s1vault.lab-us …”

The error suggests that Hashicorp Vault denied the request. Given that I use the same JWT, URL, namespace in both tasks, it seems that something may be missing in the second task rather than permissions on the Vault side.

Software set up:
Hashicorp Vault (Enterprise): 1.5.5
hvac: 2.3.0 (I also tried with 2.1.0 and got the same error)
community.hashi_vault: 6.2.0 (I tried with 5.0.1 & 6.1.0 and got the same error)
ansible-core: 2.16.14 (I also tried with 2.18.3 with the same error)

In the uri version, you’re hitting the auth method mounted as jwt-aap.

In the vault_token_create version, you’re not specifying a mount path so it’s defaulting to the name of the method (jwt), see the mount_point parameter: community.hashi_vault.vault_token_create module – Create a HashiCorp Vault token — Ansible Community Documentation

    - name: 'Get token from Hashicorp Vault with vault_token_create'
      community.hashi_vault.vault_token_create:
        auth_method: 'jwt'
        mount_point: jwt-aap
        jwt: '{{ jwt }}'
        role_id: '{{ vault_role }}'
        namespace: '{{ vault_namespace }}'
        url: '{{ vault_addr }}'
        validate_certs: false
      environment:
        PYTHONWARNINGS: "ignore:Unverified HTTPS request"
      register: _vault_token_result

However, I think you may prefer using the vault_login module: community.hashi_vault.vault_login module – Perform a login operation against HashiCorp Vault — Ansible Community Documentation

Using vault_token_create is going to create a child token, so when you use it with an auth method you’re performing a login (creating a token based on that auth method) and then creating another child token from that token, which is probably not what you really want.

    - name: 'Get token from Hashicorp Vault with vault_login'
      community.hashi_vault.vault_login:
        auth_method: 'jwt'
        mount_point: jwt-aap
        jwt: '{{ jwt }}'
        role_id: '{{ vault_role }}'
        namespace: '{{ vault_namespace }}'
        url: '{{ vault_addr }}'
        validate_certs: false
      environment:
        PYTHONWARNINGS: "ignore:Unverified HTTPS request"
      register: _vault_token_result

This on the other hand would not create the child token and would return the login token.

1 Like

Thank you very much for the answer. This is exactly what I need!

1 Like