-
Notifications
You must be signed in to change notification settings - Fork 12
feat(crypto): decrypt secret objects #482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Adds backward-compatible decryption of both legacy encrypted strings and new JSON‐based encrypted values (including objects and arrays).
- Extends regex and decryption logic to inspect a prefix and decode JSON when needed
- Introduces separate
ENCRYPTED_STRING_VALUE_PREFIX
andENCRYPTED_JSON_VALUE_PREFIX
constants - Updates tests to cover legacy string, JSON string, object, and array decryption
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
tests/unit/actor/test_actor_key_value_store.py | Tests expanded for legacy string and JSON (string, object, array) decryption |
src/apify/_crypto.py | decrypt_input_secrets now distinguishes prefixes and does json.loads for JSON |
src/apify/_consts.py | New constants for string vs JSON prefixes and updated regex to capture both formats |
Comments suppressed due to low confidence (1)
tests/unit/actor/test_actor_key_value_store.py:87
- The helper function
json_dumps
is not defined in this scope. Usejson.dumps(secret_string)
instead to serialize the value.
encrypted_string = public_encrypt(json_dumps(secret_string), public_key=PUBLIC_KEY)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
# Secret object/array inputs Based on the [issue](apify/apify-core#21369): > An ideal solution would be if we could encrypt objects This is proposal to enable `isSecret` boolean property for `object` and `array` fields in Input Schema. Currently this is available only for `string` fields with editors either `textfield` or `textarea`. ## Update based on the outcome of discussion in this PR: - Enable this also for `array` properties (not just `object`) - Enable "validation" properties like (`minProperties`, `maxProperties`, sub-schema in the future,..) even for secured fields - Encrypt the value to string and update the validation logic of JSON Schema (Ajv) validator to this form of string (encrypted object/array) as a value for `object`/`array` fields. - In the encrypted string capture the hash of the field schema (without unimportant fields like title, description, etc.) so we know that the stored encrypted value might no longer match the Actor's input schema. Approach suggested by @jancurn in the discussion below. The actual implementation stringify the object value and encrypts the string to final value in form of: ``` "ENCRYPTED_VALUE:FIELD_SCHEMA_HASH:ENCRYPTED_PASSWORD:ENCRYPTED_VALUE" // for strings "ENCRYPTED_JSON_VALUE:FIELD_SCHEMA_HASH:ENCRYPTED_PASSWORD:ENCRYPTED_VALUE" // for objects/arrays ``` Where the second group (`FIELD_SCHEMA_HASH`) is optional so all existing stored encrypted values are still matching and are backwards compatible. ----- ### Original description (❗outdated): >The `object` fields with `isSecret: true` won't be able to specify some properties that "normal" `object` fields can do, such as: `default`, `prefill`, `patternKey`, `patternValue`, `minProperties`, `maxProperties`. Editor can be only `json` or `hidden`. This restriction is basically the same as with the secret `string` property. > >In addition to change in the Input Schema's JSON schema it's also needed to change the encryption/decryption logic. If input is `string`, there is no change and the encrypted value is stored in `ENCRYPTED_VALUE:base64:base64` form. In case of `object` input, we need to keep the type of the encrypted value to be still `object` because of validation of input in other stages. > >This propose to store encrypted objects as object with structure: >``` >{ > "secret": "encrypted-stringified-json-of-original-object" >} >``` >where the `secret` key, contains same string value as normal encrypted string property. > >When decrypting an encrypted value the logic is exactly the same as with string. We would check if the object has `secret` field and if the value is string that match the encrypted string regex. > >- API, Console and Javascript SDK uses the `@apify/input_secrets` for encryption/decryption (it's part of this PR) >- Python SDK uses `apify._crypto` to decrypt secrets here is draft PR (I didn't test is yet), just to showcase what change >would be needed there: apify/apify-sdk-python#482 >- The last required change would be in console to handle secret inputs via input UI. Also draft, but this is tested and >works well: apify/apify-core#21454 > >I didn't find any other place where would this change causing issues.
Add support for
isSecret
objects and arrays in input schema and the new form of encrypted value:More context here apify/apify-shared-js#515