Skip to content

Incorrect implementation of GCP auth type in VaultBackend? #17500

Description

@pbetkier

Short

I'm pretty sure the authentication flow for GCP in the airflow.providers.hashicorp.secrets.vault.VaultBackend is incorrect and not usable. The Vault API used /auth/gcp/config has a different purpose, /auth/gcp/login should be used instead.

I've seen the /auth/<type>/config API being used in a couple other auth types, e.g. RADIUS and Azure, so the problem is probably broader than just GCP.

It's a bold statement as it means nobody has really used VaultBackend with these auth types. I may be wrong, but I would be surprised.

Details

I've analysed Airflow's VaultBackend code while researching how to integrate Vault with GCP for a different project. Here's the discrepancy I found between the current implementation and the Vault's design.

Current implementation

GCP auth is implemented in vault_client.py#L277. The implementation delegates to official Vault client's method that calls /auth/gcp/config while providing the Airflow's GCP credentials to the call.

This is however an administrative API to configure Vault's capability to verify JWT tokens via GCP API. The credentials expected are credentials for Vault to use when communicating with GCP IAM API, not application's credentials. This is explained in /auth/gcp/config API docs. The API doesn't respond with any data, so from the point of view of VaultBackend this call is basically just a no-op.

/auth/gcp/config call requires X-Vault-Token header with a token that has proper permissions. I'm guessing either this auth method was not tested at all or some administrative (root?) Vault token was passed (by mistake?) during manual tests? I haven't seen any integration tests for the auth methods, I understand they would be difficult/costly.

Expected implementation

The proper API to use is /auth/gcp/login. It requires a signed JWT token issued by IAM's signJwt based on application's GCP credentials. It returns a Vault token to be passed in subsequent requests.

This is described in the Vault docs on GCP auth and on Google blog along with an implementation example Authenticating to HashiCorp Vault using Google Cloud IAM.


Am I missing something? What do you think about this?

Activity

  1. boring-cyborg commented on Aug 9, 2021

    @boring-cyborg

    Thanks for opening your first issue here! Be sure to follow the issue template!

  2. mik-laj commented on Aug 9, 2021

    @mik-laj
    Member
  3. dlampa commented on Nov 24, 2021

    @dlampa
    Contributor

    Unfortunately I ran into this very issue trying to configure Vault as secrets backend using GCP Auth. The "credentials" returned by the /auth/gcp/config call cannot be serialized into JSON , triggering the following:

    [2021-11-24 07:45:00,858] {taskinstance.py:1463} ERROR - Task failed with exception
    Traceback (most recent call last):
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/models/taskinstance.py", line 1165, in _run_raw_task
        self._prepare_and_execute_task_with_callbacks(context, task)
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/models/taskinstance.py", line 1283, in _prepare_and_execute_task_with_callbacks
        result = self._execute_task(context, task_copy)
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/models/taskinstance.py", line 1313, in _execute_task
        result = task_copy.execute(context=context)
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/operators/python.py", line 150, in execute
        return_value = self.execute_callable()
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/operators/python.py", line 161, in execute_callable
        return self.python_callable(*self.op_args, **self.op_kwargs)
      File "/opt/airflow/dags/fa43208e955dbded1f92788fdabc5945cc1cabfb/vault_test.py", line 8, in get_secrets
        conn = BaseHook.get_connection(kwargs['my_conn_id'])
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/hooks/base.py", line 68, in get_connection
        conn = Connection.get_connection_from_secrets(conn_id)
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/models/connection.py", line 376, in get_connection_from_secrets
        conn = secrets_backend.get_connection(conn_id=conn_id)
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/providers/hashicorp/secrets/vault.py", line 226, in get_connection
        response = self.get_response(conn_id)
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/providers/hashicorp/secrets/vault.py", line 193, in get_response
        return self.vault_client.get_secret(secret_path=secret_path)
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/providers/hashicorp/_internal_client/vault_client.py", line 375, in get_secret
        response = self.client.secrets.kv.v2.read_secret_version(
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/providers/hashicorp/_internal_client/vault_client.py", line 205, in client
        if not self._client.is_authenticated():
      File "/usr/local/lib/python3.8/functools.py", line 967, in __get__
        val = self.func(instance)
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/providers/hashicorp/_internal_client/vault_client.py", line 228, in _client
        self._auth_gcp(_client)
      File "/home/airflow/.local/lib/python3.8/site-packages/airflow/providers/hashicorp/_internal_client/vault_client.py", line 307, in _auth_gcp
        _client.auth.gcp.configure(credentials=credentials)
      File "/home/airflow/.local/lib/python3.8/site-packages/hvac/api/auth_methods/gcp.py", line 59, in configure
        return self._adapter.post(
      File "/home/airflow/.local/lib/python3.8/site-packages/hvac/adapters.py", line 121, in post
        return self.request("post", url, **kwargs)
      File "/home/airflow/.local/lib/python3.8/site-packages/hvac/adapters.py", line 356, in request
        response = super(JSONAdapter, self).request(*args, **kwargs)
      File "/home/airflow/.local/lib/python3.8/site-packages/hvac/adapters.py", line 305, in request
        response = self.session.request(
      File "/home/airflow/.local/lib/python3.8/site-packages/requests/sessions.py", line 528, in request
        prep = self.prepare_request(req)
      File "/home/airflow/.local/lib/python3.8/site-packages/requests/sessions.py", line 456, in prepare_request
        p.prepare(
      File "/home/airflow/.local/lib/python3.8/site-packages/requests/models.py", line 319, in prepare
        self.prepare_body(data, files, json)
      File "/home/airflow/.local/lib/python3.8/site-packages/requests/models.py", line 471, in prepare_body
        body = complexjson.dumps(json, allow_nan=False)
      File "/usr/local/lib/python3.8/json/__init__.py", line 234, in dumps
        return cls(
      File "/usr/local/lib/python3.8/json/encoder.py", line 199, in encode
        chunks = self.iterencode(o, _one_shot=True)
      File "/usr/local/lib/python3.8/json/encoder.py", line 257, in iterencode
        return _iterencode(o, 0)
      File "/usr/local/lib/python3.8/json/encoder.py", line 179, in default
        raise TypeError(f'Object of type {o.__class__.__name__} '
    TypeError: Object of type Credentials is not JSON serializable
    
    
  4. github-actions commented on Apr 28, 2023

    @github-actions
    Contributor

    This issue has been automatically marked as stale because it has been open for 365 days without any activity. There has been several Airflow releases since last activity on this issue. Kindly asking to recheck the report against latest Airflow version and let us know if the issue is reproducible. The issue will be closed in next 30 days if no further activity occurs from the issue author.

  5. github-actions commented on May 29, 2023

    @github-actions
    Contributor

    This issue has been closed because it has not received response from the issue author.

  6. fpopic commented on Jul 22, 2023

    @fpopic
    Contributor

    Please reopen.

  7. potiuk commented on Jul 22, 2023

    @potiuk
    Member

    Why? Can you confirm it is still open in the latest version of Google Provider @fpopic ? Can you then open a new issue with new stack trace showing the problem ? Otherwise (if there is no new data on latest versions ) there is no way anyone is able to take any action on it since it's open for 2 years.

    But if you still have the issue, really the best way from your side to get attention is to provide more fresh information - ideally in a new issue.

  8. fpopic commented on Jul 22, 2023

    @fpopic
    Contributor

    I will try with the latest provider and write my outcome here. ~ 6 months ago I was getting the same error as @pbetkier.

  9. fpopic commented on Dec 15, 2024

    @fpopic
    Contributor
  10. potiuk commented on Dec 16, 2024

    @potiuk
    Member

    Not sure what you are asking for @fpopic -> but a) this issue is closed, b) we cannot assign anyone who is not a contributor or has not commented themselves on the issue.

  11. fpopic commented on Jan 7, 2025

    @fpopic
    Contributor

    @potiuk @mik-laj can you reopen the issue, please? I wrote update here #35855 (comment). Not sure how to proceed with Closed Issue and Closed PR by bot.

  12. aaabramov commented on Feb 4, 2025

    @aaabramov
    Contributor

    @potiuk I can confirm that this issue still exists.

    Instead of login (auth/{gcp}/login), airflow calls configure (auth/{gcp}/config).
    References:

    It should be changed to _client.auth.gcp.login(...).

    @fpopic thanks for opening #35855, this is a good start.

    Moreover, for the same reason, azure and radius authn won't work as well.

  13. potiuk commented on Feb 5, 2025

    @potiuk
    Member

    @aaabramov -> I suggest to open a new issue about it. Ass I already commented above - tt makes very little sense to comment on an issue opened 3 years ago. Quite likely it's related- but different issue and many of the things that were valid 3 years ago are not valid any more. And there is no point in tagging me again - I might or might not be involved in any way in diagnosing and solving the issue. Possibly people from google will get interested when you open a new issue (and link to that one marking it as imilar) and they migh help with it. Or other people might get interest and implement it.

    By commenting on a closed issue you are limiting your visibility and a chance that someone will look at it. Highly recommend to open a new issue.

  14. fpopic commented on Feb 6, 2025

    @fpopic
    Contributor

    @pbetkier can you create a clone issue and I will make a new PR?

  15. potiuk commented on Feb 6, 2025

    @potiuk
    Member

    @pbetkier can you create a clone issue and I will make a new PR?

    @fpopic -> if you have a fix, you can create PR regardless from having an issue. We do not need issues in Airflow. We need PRs solving them and we are perfectly fine to have PRs just solving issues describing issues the are solving. We do not need double-accounting for that.

  16. fpopic commented on Feb 6, 2025

    @fpopic
    Contributor

    @potiuk Here it is #35855 just I don't have authorisation to reopen it.

  17. potiuk commented on Feb 6, 2025

    @potiuk
    Member

    I can't reopen it either. You need to recreate it by pushing a new branch and creating new PR.

  18. added and removed
    provider:googleGoogle (including GCP) related issues
    on Jun 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions