Skip to content

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

Merged
merged 4 commits into from
Jul 4, 2025
Merged

Conversation

MFori
Copy link
Member

@MFori MFori commented Jun 5, 2025

Add support for isSecret objects and arrays in input schema and the new form of encrypted value:

ENCRYPTED_JSON_VALUE:{FIELD_SCHEMA_HASH}:{ENCRYPTED_PASSWORD}:{ENCRYPTED_VALUE}

More context here apify/apify-shared-js#515

@MFori MFori self-assigned this Jun 5, 2025
@MFori MFori added the t-console Issues with this label are in the ownership of the console team. label Jun 5, 2025
@github-actions github-actions bot added this to the 116th sprint - Console team milestone Jun 5, 2025
@github-actions github-actions bot added the tested Temporary label used only programatically for some analytics. label Jul 2, 2025
@MFori MFori requested a review from Copilot July 2, 2025 14:12
Copy link

@Copilot Copilot AI left a 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 and ENCRYPTED_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. Use json.dumps(secret_string) instead to serialize the value.
    encrypted_string = public_encrypt(json_dumps(secret_string), public_key=PUBLIC_KEY)

@MFori MFori requested review from vdusek and Pijukatel July 2, 2025 14:15
@MFori MFori marked this pull request as ready for review July 2, 2025 14:16
Copy link
Contributor

@vdusek vdusek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@MFori MFori merged commit ce9daf7 into master Jul 4, 2025
3 checks passed
@MFori MFori deleted the feat/decrypt-secret-objects branch July 4, 2025 15:53
MFori added a commit to apify/apify-shared-js that referenced this pull request Jul 4, 2025
# 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
t-console Issues with this label are in the ownership of the console team. tested Temporary label used only programatically for some analytics.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants