ansible / awx

AWX provides a web-based user interface, REST API, and task engine built on top of Ansible. It is one of the upstream projects for Red Hat Ansible Automation Platform.
Other
13.89k stars 3.4k forks source link

Conjur credential retrieval differs between Conjur OSS and Conjur Enterprise #14377

Open Zektono opened 1 year ago

Zektono commented 1 year ago

Please confirm the following

Bug Summary

When attempting to retrieve credentials using Ansible AWX 22.7.x from Conjur Enterprise 13, I consistently encounter a 401 error. After thorough investigation, I've identified that the root of the issue lies within the conjur_backend function, which executes two requests to Conjur in order to fetch the necessary credential information:

  1. Initial authentication is performed through the endpoint api/authn/<account>/<username>/authenticate/. The response from this request includes a signature.
  2. The actual credential retrieval takes place using the endpoint api/secrets/<account>/variable/<path_to_secret>/, where users provide the relevant variable or secret.

Upon closer inspection, it becomes clear that the authentication response (as described in point 1) differs between Conjur OSS and Conjur Enterprise. To illustrate these differences, I wrote a test script, and the subsequent output from the console is documented in the provided images (Image 1: Test Code, Image 2: Console Output).

Image 1:

Screenshot 2023-08-24 at 10 48 32

Image 2:

Screenshot 2023-08-24 at 10 46 50

The Conjur Enterprise API returns a response containing the keys signature, payload, and protected. In contrast, the Conjur OSS response presents the same keys, encoded in base64, though. The result is that the plain message from Conjur Enterprise should be encoded to base64 first, before added as a header to the second request (point 2).

An alternative approach involves including the header {"Accept-Encoding": "base64"} within the headers for the second request. This adjustment is performed within the awx/main/credential_plugins/conjur.py file, wherein the modification is as follows:

Original Code:

    lookup_kwargs = {
        'headers': {'Authorization': 'Token token="{}"'.format(token)},
        'allow_redirects': False,
    }

Modified Code:

    lookup_kwargs = {
        'headers': {'Authorization': 'Token token="{}"'.format(token), 'Accept-Encoding': 'base64'},
        'allow_redirects': False,
    }

By incorporating this change, we ensure compatibility with both Conjur OSS and Conjur Enterprise instances, enhancing the credential retrieval process from AWX.


EDIT: Following further investigation into this issue, it appears that my initial solution of adding headers may not be effective. I attempted to rectify this within my local AWX environment, but unfortunately, the issue persisted.

A more viable approach could involve checking whether the authentication response is already in base64 format. This can be accomplished using the following steps:

  1. Begin by importing the necessary modules:

    import base64
    import binascii
  2. Integrate the following function into your codebase:

    def _is_base64(s: str) -> bool:
    try:
        return base64.b64encode(base64.b64decode(s.encode("utf-8"))) == s.encode("utf-8")
    except binascii.Error:
        return False
  3. Adjust the declaration of the lookup_kwargs as shown below. This modification ensures that the authentication token is properly encoded if it's not already in base64 format:

    lookup_kwargs = {
    'headers': {'Authorization': 'Token token="{}"'.format(
        token if _is_base64(token) else base64.b64encode(token.encode('utf-8')).decode('utf-8')
    )},
    'allow_redirects': False,
    }

@infamousjoeg can you help with this? And do you agree with this change?

AWX version

22.7.1

Select the relevant components

Installation method

docker development environment

Modifications

yes

Ansible version

No response

Operating system

MacOS

Web browser

Chrome

Steps to reproduce

Expected results

The retrieval of a secret from OSS will work, but the retrieval of a secret from Enterprise will result in a 401 error.

Actual results

The retrieval of a secret from OSS works, and the retrieval of a secret from Enterprise results in a 401 error.

Additional information

I tested the suggested code change. That was the only change I did in AWX.

campofilone commented 1 year ago

I encounter the same issue with Conjur EE 12.6 / AWX 22.1.0. Conjur OSS seems to work fine.

infamousjoeg commented 1 year ago

@zEktONO I'm looking into this - thanks for submitting!

Nenodema commented 1 year ago

I just tested the Conjur integration with AWX version 21.8.0 and I can confirm that this version is working well with Conjur Enterprise. This AWX version contains the conjur.py version witth base64 code in it.