diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 00000000..d01b11af --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,10 @@ +title = "skyflow-python gitleaks config" + +[extend] +useDefault = true + +[allowlist] +description = "Dummy, non-secret fixture values used only by tests" +paths = [ + '''(^|/)dummy-non-secret/.*''', +] diff --git a/flowvault/README.md b/flowvault/README.md index a600926a..e2f92883 100644 --- a/flowvault/README.md +++ b/flowvault/README.md @@ -493,7 +493,7 @@ from skyflow.vault.data import DetokenizeRequest, TokenGroupRedactions vault = skyflow_client.vault('') # skyflow_client from Quickstart request = DetokenizeRequest( - tokens=['5479-4229-4622-1393', 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'], + tokens=['5479-4229-4622-1393', ''], token_group_redactions=[TokenGroupRedactions(token_group_name='card_number_cg', redaction='MASKED')], ) response = vault.detokenize(request) @@ -516,7 +516,7 @@ Sample response: "request_id": null }, { - "token": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", + "token": "", "value": null, "token_group_name": null, "metadata": null, @@ -650,7 +650,7 @@ Sample response: "table_name": "table1", "skyflow_id": "9fac9201-7b8a-4446-93f8-5244e1213bd1", "tokens": { - "cardholder_name": [ { "token": "f1a2b3c4-d5e6-7890-abcd-ef1234567890", "token_group_name": "deterministic_string", "path": null } ] + "cardholder_name": [ { "token": "", "token_group_name": "deterministic_string", "path": null } ] }, "data": { "cardholder_name": "Jane Doe" }, "hashed_data": null, diff --git a/skyvault/skyflow/generated/rest/authentication/client.py b/skyvault/skyflow/generated/rest/authentication/client.py index 2f1e804e..99ff6aef 100644 --- a/skyvault/skyflow/generated/rest/authentication/client.py +++ b/skyvault/skyflow/generated/rest/authentication/client.py @@ -73,11 +73,11 @@ def authentication_service_get_auth_token( from skyflow import Skyflow client = Skyflow( - token="YOUR_TOKEN", + token="", ) client.authentication.authentication_service_get_auth_token( grant_type="urn:ietf:params:oauth:grant-type:jwt-bearer", - assertion="eyLhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNzIjoiY29tcGFueSIsImV4cCI6MTYxNTE5MzgwNywiaWF0IjoxNjE1MTY1MDQwLCJhdWQiOiKzb21lYXVkaWVuY2UifQ.4pcPyMDQ9o1PSyXnrXCjTwXyr4BSezdI1AVTmud2fU3", + assertion="", ) """ _response = self._raw_client.authentication_service_get_auth_token( @@ -156,14 +156,14 @@ async def authentication_service_get_auth_token( from skyflow import AsyncSkyflow client = AsyncSkyflow( - token="YOUR_TOKEN", + token="", ) async def main() -> None: await client.authentication.authentication_service_get_auth_token( grant_type="urn:ietf:params:oauth:grant-type:jwt-bearer", - assertion="eyLhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNzIjoiY29tcGFueSIsImV4cCI6MTYxNTE5MzgwNywiaWF0IjoxNjE1MTY1MDQwLCJhdWQiOiKzb21lYXVkaWVuY2UifQ.4pcPyMDQ9o1PSyXnrXCjTwXyr4BSezdI1AVTmud2fU3", + assertion="", ) diff --git a/skyvault/skyflow/generated/rest/tokens/client.py b/skyvault/skyflow/generated/rest/tokens/client.py index 5518932c..a5c35064 100644 --- a/skyvault/skyflow/generated/rest/tokens/client.py +++ b/skyvault/skyflow/generated/rest/tokens/client.py @@ -74,11 +74,11 @@ def record_service_detokenize( vault_id="vaultID", detokenization_parameters=[ V1DetokenizeRecordRequest( - token="afbd1074-51c1-4a16-9eee-e2c0ecb52125", + token="", redaction="PLAIN_TEXT", ), V1DetokenizeRecordRequest( - token="05383487-fcae-42e5-a48e-5bd62a51af12", + token="", redaction="DEFAULT", ), ], @@ -202,11 +202,11 @@ async def main() -> None: vault_id="vaultID", detokenization_parameters=[ V1DetokenizeRecordRequest( - token="afbd1074-51c1-4a16-9eee-e2c0ecb52125", + token="", redaction="PLAIN_TEXT", ), V1DetokenizeRecordRequest( - token="05383487-fcae-42e5-a48e-5bd62a51af12", + token="", redaction="DEFAULT", ), ], diff --git a/skyvault/tests/dummy-non-secret/api_keys.json b/skyvault/tests/dummy-non-secret/api_keys.json new file mode 100644 index 00000000..97c78f25 --- /dev/null +++ b/skyvault/tests/dummy-non-secret/api_keys.json @@ -0,0 +1,8 @@ +{ + "validations_valid_api_key": "sky-test-000000000000000000000000000000000", + "validations_invalid_prefix_api_key": "invalid-test-000000000000000000000000000000000", + "validations_invalid_length_api_key": "sky-test-000000", + "utils_valid_api_key": "sky-00000-00000000000000000000000000000000", + "utils_invalid_length_api_key": "sky-00000-000", + "utils_invalid_pattern_api_key": "sky-00000-0000000000GHIJKL0000000000000000" +} diff --git a/skyvault/tests/utils/test__utils.py b/skyvault/tests/utils/test__utils.py index 1363ad7d..c29f57f3 100644 --- a/skyvault/tests/utils/test__utils.py +++ b/skyvault/tests/utils/test__utils.py @@ -43,6 +43,14 @@ with open(creds_path, "r") as file: credentials = json.load(file) +dummy_api_keys_path = os.path.join(os.path.dirname(__file__), "..", "dummy-non-secret", "api_keys.json") +with open(dummy_api_keys_path, "r") as dummy_api_keys_file: + dummy_api_keys = json.load(dummy_api_keys_file) + +DUMMY_VALID_API_KEY = dummy_api_keys["utils_valid_api_key"] +DUMMY_INVALID_LENGTH_API_KEY = dummy_api_keys["utils_invalid_length_api_key"] +DUMMY_INVALID_PATTERN_API_KEY = dummy_api_keys["utils_invalid_pattern_api_key"] + TEST_ERROR_MESSAGE = "Test error message." VALID_ENV_CREDENTIALS = credentials @@ -556,15 +564,15 @@ def test_handle_exception_json_error(self, mock_log_and_reject_error): ) def test_validate_api_key_valid_key(self): - valid_key = "sky-ABCDE-1234567890abcdef1234567890abcdef" + valid_key = DUMMY_VALID_API_KEY self.assertTrue(validate_api_key(valid_key)) def test_validate_api_key_invalid_length(self): - invalid_key = "sky-ABCDE-123" + invalid_key = DUMMY_INVALID_LENGTH_API_KEY self.assertFalse(validate_api_key(invalid_key)) def test_validate_api_key_invalid_pattern(self): - invalid_key = "sky-ABCDE-1234567890GHIJKL7890abcdef" + invalid_key = DUMMY_INVALID_PATTERN_API_KEY self.assertFalse(validate_api_key(invalid_key)) def test_encode_column_values(self): diff --git a/skyvault/tests/utils/validations/test__validations.py b/skyvault/tests/utils/validations/test__validations.py index 0cab26ca..f55d1a4f 100644 --- a/skyvault/tests/utils/validations/test__validations.py +++ b/skyvault/tests/utils/validations/test__validations.py @@ -2,6 +2,7 @@ from unittest.mock import Mock, patch, MagicMock import tempfile import os +import json from skyflow.error import SkyflowError from skyflow.utils.validations._validations import ( @@ -24,6 +25,16 @@ from skyflow.vault.tokens import DetokenizeRequest from skyflow.vault.connection._invoke_connection_request import InvokeConnectionRequest +_dummy_api_keys_path = os.path.join( + os.path.dirname(__file__), "..", "..", "dummy-non-secret", "api_keys.json" +) +with open(_dummy_api_keys_path, "r") as _dummy_api_keys_file: + _dummy_api_keys = json.load(_dummy_api_keys_file) + +DUMMY_VALID_API_KEY = _dummy_api_keys["validations_valid_api_key"] +DUMMY_INVALID_PREFIX_API_KEY = _dummy_api_keys["validations_invalid_prefix_api_key"] +DUMMY_INVALID_LENGTH_API_KEY = _dummy_api_keys["validations_invalid_length_api_key"] + class TestValidations(unittest.TestCase): @classmethod def setUpClass(cls): @@ -94,20 +105,20 @@ def test_validate_required_field_wrong_type(self): self.assertEqual(context.exception.message, "Invalid error") def test_validate_api_key_valid(self): - valid_key = "sky-abc12-1234567890abcdef1234567890abcdef" + valid_key = DUMMY_VALID_API_KEY self.assertTrue(validate_api_key(valid_key, self.logger)) def test_validate_api_key_invalid_prefix(self): - invalid_key = "invalid-abc12-1234567890abcdef1234567890abcdef" + invalid_key = DUMMY_INVALID_PREFIX_API_KEY self.assertFalse(validate_api_key(invalid_key, self.logger)) def test_validate_api_key_invalid_length(self): - invalid_key = "sky-abc12-123456" + invalid_key = DUMMY_INVALID_LENGTH_API_KEY self.assertFalse(validate_api_key(invalid_key, self.logger)) def test_validate_credentials_with_api_key(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef" + "api_key": DUMMY_VALID_API_KEY } validate_credentials(self.logger, credentials) @@ -129,7 +140,7 @@ def test_validate_credentials_empty_credentials(self): def test_validate_credentials_multiple_auth_methods(self): credentials = { "token": "valid_token", - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef" + "api_key": DUMMY_VALID_API_KEY } with self.assertRaises(SkyflowError) as context: validate_credentials(self.logger, credentials) @@ -152,7 +163,7 @@ def test_validate_credentials_with_empty_context(self): def test_validate_credentials_with_string_context(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "context": "user_12345" } validate_credentials(self.logger, credentials) @@ -160,14 +171,14 @@ def test_validate_credentials_with_string_context(self): def test_validate_credentials_with_dict_context(self): """A dict/JSON object context is accepted — the token engine supports it.""" credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "context": {"role": "admin", "department": "finance"} } validate_credentials(self.logger, credentials) def test_validate_credentials_with_empty_dict_context(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "context": {} } with self.assertRaises(SkyflowError) as context: @@ -176,7 +187,7 @@ def test_validate_credentials_with_empty_dict_context(self): def test_validate_credentials_with_invalid_dict_context_key(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "context": {"invalid key": "value"} } with self.assertRaises(SkyflowError) as context: @@ -196,7 +207,7 @@ def test_validate_credentials_with_scalar_context(self): for scalar_context in [123, 0, 1.5, 0.0, True, False]: with self.subTest(context=scalar_context): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "context": scalar_context } validate_credentials(self.logger, credentials) @@ -205,7 +216,7 @@ def test_validate_credentials_with_invalid_context_type(self): for invalid_context in [["user_12345"], ("user_12345",), None, object()]: with self.subTest(context=invalid_context): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "context": invalid_context } with self.assertRaises(SkyflowError) as context: @@ -215,7 +226,7 @@ def test_validate_credentials_with_invalid_context_type(self): def test_validate_credentials_with_dict_context_in_config(self): """Config-scoped messages are used when a config id is available.""" credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "context": {} } with self.assertRaises(SkyflowError) as context: @@ -231,14 +242,14 @@ def test_validate_credentials_with_dict_context_in_config(self): def test_validate_credentials_with_roles(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "roles": ["role_id_1", "role_id_2"] } validate_credentials(self.logger, credentials) def test_validate_credentials_with_invalid_roles_type(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "roles": "role_id_1" } with self.assertRaises(SkyflowError) as context: @@ -247,7 +258,7 @@ def test_validate_credentials_with_invalid_roles_type(self): def test_validate_credentials_with_empty_roles(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "roles": [] } with self.assertRaises(SkyflowError) as context: @@ -256,7 +267,7 @@ def test_validate_credentials_with_empty_roles(self): def test_validate_credentials_with_non_string_role_elements(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "roles": [None, 123, {"id": "x"}] } with self.assertRaises(SkyflowError) as context: @@ -312,7 +323,7 @@ def test_validate_vault_config_valid(self): "vault_id": "vault123", "cluster_id": "cluster123", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef" + "api_key": DUMMY_VALID_API_KEY }, "env": Env.DEV } @@ -333,7 +344,7 @@ def test_validate_update_vault_config_valid(self): "vault_id": "vault123", "cluster_id": "cluster123", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef" + "api_key": DUMMY_VALID_API_KEY }, "env": Env.DEV } @@ -344,7 +355,7 @@ def test_validate_update_vault_config_invalid_cluster_id(self): "vault_id": "vault123", "cluster_id": "", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef" + "api_key": DUMMY_VALID_API_KEY } } with self.assertRaises(SkyflowError) as context: @@ -368,7 +379,7 @@ def test_validate_connection_config_valid(self): "connection_id": "conn123", "connection_url": "https://example.com", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef" + "api_key": DUMMY_VALID_API_KEY } } self.assertTrue(validate_connection_config(self.logger, config)) @@ -377,7 +388,7 @@ def test_validate_connection_config_missing_url(self): config = { "connection_id": "conn123", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef" + "api_key": DUMMY_VALID_API_KEY } } with self.assertRaises(SkyflowError) as context: @@ -389,7 +400,7 @@ def test_validate_connection_config_empty_connection_id(self): "connection_id": "", "connection_url": "https://example.com", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef" + "api_key": DUMMY_VALID_API_KEY } } with self.assertRaises(SkyflowError) as context: @@ -413,7 +424,7 @@ def test_validate_update_connection_config_valid(self): "connection_id": "conn123", "connection_url": "https://example.com", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef" + "api_key": DUMMY_VALID_API_KEY } } self.assertTrue(validate_update_connection_config(self.logger, config)) @@ -432,7 +443,7 @@ def test_validate_update_connection_config_empty_url(self): "connection_id": "conn123", "connection_url": "", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef" + "api_key": DUMMY_VALID_API_KEY } } with self.assertRaises(SkyflowError) as context: @@ -1344,7 +1355,7 @@ def test_validate_deidentify_file_request_wait_time_float_out_of_range(self): self.assertEqual(context.exception.message, SkyflowMessages.Error.WAIT_TIME_GREATER_THEN_64.value) def test_validate_credentials_with_valid_token_uri(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "token_uri": "https://valid-url.com" } # Should not raise @@ -1352,7 +1363,7 @@ def test_validate_credentials_with_valid_token_uri(self): def test_validate_credentials_with_invalid_token_uri_type(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "token_uri": 12345 # Not a string } with self.assertRaises(SkyflowError) as context: @@ -1361,7 +1372,7 @@ def test_validate_credentials_with_invalid_token_uri_type(self): def test_validate_credentials_with_invalid_token_uri_url(self): credentials = { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "token_uri": "not_a_url" } with self.assertRaises(SkyflowError) as context: @@ -1374,7 +1385,7 @@ def test_validate_update_vault_config_with_valid_token_uri(self): "vault_id": "vault123", "cluster_id": "cluster123", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "token_uri": "https://valid-url.com" }, "env": Env.DEV @@ -1387,7 +1398,7 @@ def test_validate_update_vault_config_with_invalid_token_uri_type(self): "vault_id": "vault123", "cluster_id": "cluster123", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "token_uri": 12345 } } @@ -1400,7 +1411,7 @@ def test_validate_update_vault_config_with_invalid_token_uri_url(self): "vault_id": "vault123", "cluster_id": "cluster123", "credentials": { - "api_key": "sky-abc12-1234567890abcdef1234567890abcdef", + "api_key": DUMMY_VALID_API_KEY, "token_uri": "not_a_url" } }