Add Akeyless Vault Platform provider#64754
Conversation
|
Congratulations on your first Pull Request and welcome to the Apache Airflow community! If you have any issues or are unsure about any anything please check our Contributors' Guide (https://github.com/apache/airflow/blob/main/contributing-docs/README.rst)
|
|
Please follow Accepting New Community Providers for adding a new provider. Once this is checked we can start review proccess |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a new community Apache Airflow provider for Akeyless Vault Platform, including a Hook, a custom akeyless connection type (with UI fields), and a Secrets Backend implementation.
Changes:
- Introduces
AkeylessHookfor authenticating and interacting with Akeyless (static/dynamic/rotated secrets, item CRUD). - Adds
AkeylessBackendto source Airflow Connections/Variables/Config from Akeyless paths. - Wires the provider into the Airflow monorepo (extras, workspace membership, docs, ownership/labels, spelling list, example DAG, unit/system tests scaffolding).
Reviewed changes
Copilot reviewed 39 out of 39 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| pyproject.toml | Registers the akeyless extra, adds provider to “all” extras, mypy paths, and workspace members. |
| providers/akeyless/pyproject.toml | Defines the provider package metadata and dependencies. |
| providers/akeyless/provider.yaml | Declares provider metadata (for provider tooling/release generation). |
| providers/akeyless/src/airflow/providers/akeyless/init.py | Sets provider version and enforces minimum Airflow version. |
| providers/akeyless/src/airflow/providers/akeyless/get_provider_info.py | Exposes provider info for Airflow’s provider discovery. |
| providers/akeyless/src/airflow/providers/akeyless/hooks/akeyless.py | Implements AkeylessHook, auth handling, secret operations, and UI fields/behavior. |
| providers/akeyless/src/airflow/providers/akeyless/secrets/akeyless.py | Implements AkeylessBackend secrets backend. |
| providers/akeyless/src/airflow/init.py | Sets up namespace package for provider build layout. |
| providers/akeyless/src/airflow/providers/init.py | Sets up namespace package for provider build layout. |
| providers/akeyless/src/airflow/providers/akeyless/hooks/init.py | Package marker for hooks. |
| providers/akeyless/src/airflow/providers/akeyless/secrets/init.py | Package marker for secrets backend module. |
| providers/akeyless/tests/conftest.py | Enables common pytest plugin for provider tests. |
| providers/akeyless/tests/unit/init.py | Namespace package marker for unit tests. |
| providers/akeyless/tests/unit/akeyless/init.py | Package marker for unit tests. |
| providers/akeyless/tests/unit/akeyless/hooks/init.py | Package marker for hook tests. |
| providers/akeyless/tests/unit/akeyless/hooks/test_akeyless.py | Unit tests for AkeylessHook. |
| providers/akeyless/tests/unit/akeyless/secrets/init.py | Package marker for secrets backend tests. |
| providers/akeyless/tests/unit/akeyless/secrets/test_akeyless.py | Unit tests for AkeylessBackend. |
| providers/akeyless/tests/system/init.py | Namespace package marker for system tests. |
| providers/akeyless/tests/system/akeyless/init.py | Package marker for system tests. |
| providers/akeyless/tests/system/akeyless/example_dag_akeyless.py | Example DAG demonstrating provider usage. |
| providers/akeyless/docs/index.rst | Provider documentation index and generated content scaffold. |
| providers/akeyless/docs/connections.rst | Documentation for the akeyless connection type and auth extras. |
| providers/akeyless/docs/secrets-backend.rst | Documentation for AkeylessBackend configuration and naming conventions. |
| providers/akeyless/docs/changelog.rst | Provider changelog initial release entry. |
| providers/akeyless/docs/commits.rst | Placeholder for commit list generation at release time. |
| providers/akeyless/docs/security.rst | Security docs include scaffold. |
| providers/akeyless/docs/installing-providers-from-sources.rst | Include scaffold for provider source install docs. |
| providers/akeyless/docs/conf.py | Sphinx config for provider docs build. |
| providers/akeyless/docs/.latest-doc-only-change.txt | Marks last doc-only change version. |
| providers/akeyless/README.rst | Provider README with installation and features overview. |
| providers/akeyless/LICENSE | Provider package license file. |
| providers/akeyless/NOTICE | Provider package notice file. |
| providers/akeyless/.gitignore | Provider-local ignore rules. |
| docs/spelling_wordlist.txt | Adds “Akeyless/akeyless” to spelling allowlist. |
| airflow-core/docs/extra-packages-ref.rst | Documents the new apache-airflow[akeyless] extra. |
| .github/boring-cyborg.yml | Adds automated label mapping for provider path. |
| .github/ISSUE_TEMPLATE/1-airflow_bug_report.yml | Adds akeyless to provider selection options. |
| .github/CODEOWNERS | Adds ownership for /providers/akeyless/. |
Comments suppressed due to low confidence (1)
providers/akeyless/tests/unit/akeyless/hooks/test_akeyless.py:1
- The rotated-secret test validates only the returned shape, but it does not assert the request sent to the SDK. Given the implementation currently passes
names=name(string) intoGetRotatedSecretValue, add an assertion thatapi.get_rotated_secret_valuewas called with the expected request object/fields (in particular, thatnamesis a list containing the secret name). This will prevent request-shape regressions.
|
fixed the relevant files, and added some more tests |
|
Fixed unit test and documentation |
f5d9720 to
84d0019
Compare
7efb2bd to
21197bb
Compare
21197bb to
8dee5d1
Compare
8dee5d1 to
d557f65
Compare
eladkal
left a comment
There was a problem hiding this comment.
LGTM
will merge when CI is green
|
HEllo @baraka-akeyless -> I see you keep on having conflicts with uv.lock - and while it's expected to see it in a pr that changes dependencies, you can avoid a lot of problems by When you are choosing Could you please rebase your PR once again (it might be that due to merge commits you already have you will have to solve commits few times during the rebase - but then next rebase should be way simpler. |
|
Look at our PR guidelines or https://stackoverflow.com/questions/7244321/how-do-i-update-or-sync-a-forked-repository-on-github/7244456#7244456 |
07b0a03 to
8e2f1bc
Compare
Introduces a new community provider for Akeyless (https://www.akeyless.io/) with the following components: - AkeylessHook: Hook for interacting with Akeyless Vault Platform supporting static, dynamic, and rotated secrets with 8 auth methods (API Key, AWS IAM, GCP, Azure AD, UID, JWT, Kubernetes, Certificate) - AkeylessBackend: Secrets backend for sourcing Airflow Connections, Variables, and Configuration directly from Akeyless - Custom 'akeyless' connection type with dedicated UI fields Includes full RST documentation, unit tests, and example DAG. Made-with: Cursor
The _internal_client layer was an unnecessary abstraction. The akeyless Python SDK already provides clean Auth() and V2Api methods that handle authentication and CRUD in single calls. - AkeylessHook now holds a cached akeyless.V2Api and calls SDK methods directly (idiomatic Airflow pattern). - AkeylessBackend likewise creates its own V2Api + Auth inline. - Tests updated to mock the akeyless SDK directly. Made-with: Cursor
- Import BaseHook from airflow.providers.common.compat.sdk (not airflow.hooks.base) — required compatibility layer for providers - Add apache-airflow-providers-common-compat>=1.8.0 to dependencies - Rewrite example DAG to use classic DAG/PythonOperator pattern (airflow.decorators not visible to provider mypy config) - Add [tool.uv.sources] for workspace resolution - Add Python 3.14 classifier Made-with: Cursor
- Change integration tag from [security, secrets] to [software] (matching hashicorp provider; 'secrets' not in allowed tag list) - Fix test assertions: check conn.host/login instead of conn_type (URI scheme normalization varies across Airflow versions) Made-with: Cursor
…extra-packages-ref - Add providers/akeyless/docs/conf.py for Sphinx documentation build - Restructure index.rst to match Airflow provider conventions (commits section, Python API reference, proper toctree structure) - Register akeyless in airflow-core/docs/extra-packages-ref.rst for static check-extra-packages-references validation Made-with: Cursor
…o conventions - Replace all short-form Apache license headers with full ASF license format across all Python, RST, and YAML files (25+ files) - Fix docs/conf.py Sphinx configuration (already added) - Restructure docs/index.rst with auto-generated sections (separator, description, cross-provider deps, download links) - Add System Tests toctree section to index.rst - Fix RST include paths to use devel-common sphinx_exts - Rename .latest-doc-only-changes.txt to .latest-doc-only-change.txt (matches .rat-excludes pattern) - Fix NOTICE copyright year: 2017 -> 2016 - Fix .gitignore to only contain *.iml (matches other providers) - Add __path__ extensions to tests/unit/__init__.py and tests/system/__init__.py - Add akeyless to bug report provider list - Fix spelling wordlist sort order for Akeyless/akeyless entries - Run ruff check --fix and ruff format for code style compliance Made-with: Cursor
- Fix GetRotatedSecretValue to pass names as list, not string - Add access_type validation in AkeylessHook.authenticate() with clear error message listing valid auth types - Catch ImportError for akeyless_cloud_id with helpful install message - Restrict AkeylessBackend auth to api_key/uid types only (cloud-based auth methods require AkeylessHook directly) - Add token caching with configurable TTL in AkeylessBackend to avoid repeated auth calls during DAG parsing - Align get_provider_info.py tags with provider.yaml ([software]) - Add tests for invalid access_type validation, rotated secret list parameter, unsupported backend auth type, and token caching Made-with: Cursor
The test_get_rotated_secret_passes_list was checking .names on a MagicMock object instead of verifying the SDK constructor call args. The commits.rst file was missing a proper RST title, causing 48 documentation build errors. Made-with: Cursor
Co-authored-by: Elad Kalif <45845474+eladkal@users.noreply.github.com>
When core.multi_team is enabled, the secrets backend now looks up
secrets under {base_path}/{team_name}/{key} first, falling back to
a global path. Supports use_team_secrets_path and global_secrets_path
configuration options, matching the VaultBackend pattern from apache#65493.
Made-with: Cursor
Co-authored-by: Elad Kalif <45845474+eladkal@users.noreply.github.com>
…space member Made-with: Cursor
…rovider Run update_airflow_pyproject_toml.py to add required comments and exclude-newer-package entries for the akeyless provider. Made-with: Cursor
Reset file to upstream main and re-add only Akeyless/akeyless entries. Made-with: Cursor
…o example DAG - Replace short Apache license header with full ASF boilerplate in providers/akeyless/pyproject.toml to pass insert-license pre-commit hook - Add required get_test_run(dag) pytest function to example_dag_akeyless.py as required by check-system-tests-present pre-commit hook Made-with: Cursor
Accept changes generated by the update-providers-build-files prek hook: - pyproject.toml: use canonical template format with proper comments - get_provider_info.py: regenerated from provider.yaml - __init__.py: add auto-generated file notice - docs/conf.py: add flake8 disable comment - LICENSE: use full Apache License 2.0 text - docker-compose: add akeyless provider volume mounts Made-with: Cursor
…utput The breeze CLI commands that list providers (publish-docs, prepare-provider-distributions, etc.) now include akeyless in their output. Regenerated all affected SVG/text documentation files. Made-with: Cursor
…ollution In Airflow 2.11.1 (before min_length_to_mask was introduced), short password values like "p" get added to the secrets masker regex patterns. This caused the cncf/kubernetes test_get_k8s_pod_yaml to fail because "p" in "pod" was being replaced with "***". Use longer, realistic passwords (secret123) in test connection URIs to prevent polluting the global secrets masker in compat test environments. Made-with: Cursor
be52fd6 to
6d4c695
Compare
|
Awesome work, congrats on your first merged pull request! You are invited to check our Issue Tracker for additional contributions. |
Summary
Add a new community provider for Akeyless Vault Platform — a SaaS-based secrets management and zero-trust access platform.
Components
AkeylessHookakeylessAkeylessBackendAuthentication methods supported
API Key, AWS IAM, GCP, Azure AD, Universal Identity (UID), JWT/OIDC, Kubernetes, Certificate
Hook capabilities
get_secret_value/get_secret_values— static secretsget_dynamic_secret_value— just-in-time credentials (databases, cloud, K8s)get_rotated_secret_value— auto-rotated credentialscreate_secret/update_secret_value/delete_itemlist_items/describe_itemSecrets Backend
Drop-in replacement pattern identical to the HashiCorp Vault backend — stores Connections (URI or JSON), Variables, and Config under configurable Akeyless paths.
Dependencies
akeyless>=5.0.0(Apache 2.0, ~350K monthly PyPI downloads)akeyless_cloud_idfor AWS/GCP/Azure cloud-based authChanges outside
providers/akeyless/pyproject.toml: addedakeylessextra, workspace member, uv source, mypy paths, all-providers dep.github/boring-cyborg.yml:provider:akeylesslabel mapping.github/CODEOWNERS:/providers/akeyless/ownershipdocs/spelling_wordlist.txt: addedAkeyless/akeylessTest plan
tests/unit/akeyless/hooks/test_akeyless.py— 10 tests)tests/unit/akeyless/secrets/test_akeyless.py— 19 tests)prek run --from-ref main)prek --stage manual mypy-providers --all-files)Made with Cursor