From fb5f307be8f19ae88781b60e0fe44b4619f65a0a Mon Sep 17 00:00:00 2001 From: Shivam Sharma <192242476+ShivamSharma43@users.noreply.github.com> Date: Wed, 7 Oct 2026 18:20:45 +0530 Subject: [PATCH] chore: remove unused native connector secrets code (#4524) ## Part of https://github.com/elastic/connectors/issues/2990 #2989 removed `_update_native_connector_authentication()`, the only place the framework read a connector secret, and set `native_connector_api_keys_enabled` to False. Several pieces it relied on were left behind with no remaining callers. This PR removes those: - `ESManagementClient.get_connector_secret()` - the `Connector.api_key_secret_id` property - `ApiKeyNotFoundError` in `sync_job_runner.py` - `Features.native_connector_api_keys_enabled()` and the `Features.NATIVE_CONNECTOR_API_KEYS` constant in `connectors_sdk` Their tests are removed with them, along with a leftover `native_connector_api_keys_enabled` mock in `test_sync_job_runner.py`. Nothing here changes what is written to Elasticsearch or what Kibana sees. The following are deliberately left in place because removing them would be observable outside the framework, and are for a separate PR if that is wanted: - the `native_connector_api_keys` entry in `BaseDataSource.features()`, which is written into the connector doc - `create_connector_secret()`, which `connectors connector create --native` still uses to store an API key and set `api_key_secret_id` on the connector doc - `api_key_secret_id` in `docs/CONNECTOR_PROTOCOL.md` `Features.native_connector_api_keys_enabled()` and `NATIVE_CONNECTOR_API_KEYS` are public in the published `connectors_sdk` package. Nothing in this repo uses them, but external code calling them would break. Tests: `make lint` and `make test` pass in both `app/connectors_service` (2504 passed, 92.01% coverage) and `libs/connectors_sdk` (343 passed, 84.21% coverage). ## Checklists #### Pre-Review Checklist - [x] this PR does NOT contain credentials of any kind, such as API keys or username/passwords (double check `config.yml.example`) - [x] this PR has a meaningful title - [x] this PR links to all relevant github issues that it fixes or partially addresses - [x] Covered the changes with automated tests - [ ] Tested the changes locally (ran `make lint` and `make test`; not tested against a live cluster) ## Related Pull Requests - #2989, which removed the code path these were used by. - #4523 adds a test next to the ones removed here in `test_management_client.py`, so whichever merges second will need a small rebase. Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 --- .../connectors/es/management_client.py | 10 ------ .../connectors/protocol/connectors.py | 4 --- .../connectors/sync_job_runner.py | 4 --- .../tests/es/test_management_client.py | 34 ------------------- .../tests/protocol/test_connectors.py | 2 -- .../tests/test_sync_job_runner.py | 1 - libs/connectors_sdk/connectors_sdk/utils.py | 7 ---- 7 files changed, 62 deletions(-) diff --git a/app/connectors_service/connectors/es/management_client.py b/app/connectors_service/connectors/es/management_client.py index 75ff8753a..1de30a99c 100644 --- a/app/connectors_service/connectors/es/management_client.py +++ b/app/connectors_service/connectors/es/management_client.py @@ -211,16 +211,6 @@ async def yield_existing_documents_metadata(self, index): yield doc_id, timestamp - async def get_connector_secret(self, connector_secret_id): - secret = await self._retrier.execute_with_retry( - partial( - self.client.perform_request, - "GET", - f"/_connector/_secret/{connector_secret_id}", - ) - ) - return secret.get("value") - async def create_connector_secret(self, secret_value): secret = await self._retrier.execute_with_retry( partial( diff --git a/app/connectors_service/connectors/protocol/connectors.py b/app/connectors_service/connectors/protocol/connectors.py index e40a29704..a4d4ff353 100644 --- a/app/connectors_service/connectors/protocol/connectors.py +++ b/app/connectors_service/connectors/protocol/connectors.py @@ -638,10 +638,6 @@ def last_sync_scheduled_at_by_job_type(self, job_type): def sync_cursor(self): return self.get("sync_cursor") - @property - def api_key_secret_id(self): - return self.get("api_key_secret_id") - async def heartbeat(self, interval, force=False): if ( force diff --git a/app/connectors_service/connectors/sync_job_runner.py b/app/connectors_service/connectors/sync_job_runner.py index 34f77b1ec..5978b4144 100644 --- a/app/connectors_service/connectors/sync_job_runner.py +++ b/app/connectors_service/connectors/sync_job_runner.py @@ -87,10 +87,6 @@ def __init__(self, job_id, status): ) -class ApiKeyNotFoundError(Exception): - pass - - class SyncJobRunner: """The class to run a sync job. diff --git a/app/connectors_service/tests/es/test_management_client.py b/app/connectors_service/tests/es/test_management_client.py index c8cbca5f9..53c6c4913 100644 --- a/app/connectors_service/tests/es/test_management_client.py +++ b/app/connectors_service/tests/es/test_management_client.py @@ -216,40 +216,6 @@ async def test_yield_existing_documents_metadata_when_source_id_differs_from_id( assert ids == ["1", "2"] - @pytest.mark.asyncio - async def test_get_connector_secret(self, es_management_client, mock_responses): - secret_id = "secret-id" - - es_management_client.client.perform_request = AsyncMock( - return_value={"id": secret_id, "value": "secret-value"} - ) - - secret = await es_management_client.get_connector_secret(secret_id) - assert secret == "secret-value" - es_management_client.client.perform_request.assert_awaited_with( - "GET", f"/_connector/_secret/{secret_id}" - ) - - @pytest.mark.asyncio - async def test_get_connector_secret_when_secret_does_not_exist( - self, es_management_client, mock_responses - ): - secret_id = "secret-id" - - error_meta = Mock() - error_meta.status = 404 - es_management_client.client.perform_request = AsyncMock( - side_effect=ElasticNotFoundError( - "resource_not_found_exception", - error_meta, - f"No secret with id [{secret_id}]", - ) - ) - - with pytest.raises(ElasticNotFoundError): - secret = await es_management_client.get_connector_secret(secret_id) - assert secret is None - @pytest.mark.asyncio async def test_create_connector_secret(self, es_management_client, mock_responses): secret_id = "secret-id" diff --git a/app/connectors_service/tests/protocol/test_connectors.py b/app/connectors_service/tests/protocol/test_connectors.py index b3714c208..e5b397249 100644 --- a/app/connectors_service/tests/protocol/test_connectors.py +++ b/app/connectors_service/tests/protocol/test_connectors.py @@ -325,7 +325,6 @@ async def test_connector_properties(): connector_src = { "_id": "test", "_source": { - "api_key_secret_id": "api-key-secret-id", "service_type": "test", "index_name": "search-some-index", "configuration": {}, @@ -365,7 +364,6 @@ async def test_connector_properties(): assert connector.incremental_sync_scheduling["enabled"] assert connector.incremental_sync_scheduling["interval"] == "* * * * *" assert connector.sync_cursor == SYNC_CURSOR - assert connector.api_key_secret_id == "api-key-secret-id" assert isinstance(connector.last_seen, datetime) assert isinstance(connector.filtering, Filtering) assert isinstance(connector.pipeline, Pipeline) diff --git a/app/connectors_service/tests/test_sync_job_runner.py b/app/connectors_service/tests/test_sync_job_runner.py index 28f8d28b2..a1435e5eb 100644 --- a/app/connectors_service/tests/test_sync_job_runner.py +++ b/app/connectors_service/tests/test_sync_job_runner.py @@ -38,7 +38,6 @@ def mock_connector(): connector.last_sync_status = JobStatus.COMPLETED connector.features.sync_rules_enabled.return_value = True connector.features.incremental_sync_enabled.return_value = True - connector.features.native_connector_api_keys_enabled.return_value = False connector.sync_cursor = SYNC_CURSOR connector.document_count = AsyncMock(return_value=TOTAL_DOCUMENT_COUNT) connector.sync_starts = AsyncMock(return_value=True) diff --git a/libs/connectors_sdk/connectors_sdk/utils.py b/libs/connectors_sdk/connectors_sdk/utils.py index a9843ee09..f426f97e1 100644 --- a/libs/connectors_sdk/connectors_sdk/utils.py +++ b/libs/connectors_sdk/connectors_sdk/utils.py @@ -170,8 +170,6 @@ class Features: BASIC_RULES_OLD = "basic_rules_old" ADVANCED_RULES_OLD = "advanced_rules_old" - NATIVE_CONNECTOR_API_KEYS = "native_connector_api_keys" - def __init__(self, features=None): if features is None: features = {} @@ -188,11 +186,6 @@ def document_level_security_enabled(self): self.features, ["document_level_security", "enabled"], default=False ) - def native_connector_api_keys_enabled(self): - return nested_get_from_dict( - self.features, ["native_connector_api_keys", "enabled"], default=True - ) - def sync_rules_enabled(self): return any( [