STRATCONN-6355 - [S3] - SHA256 support#3802
Conversation
There was a problem hiding this comment.
Pull request overview
Adds configurable SHA256 hashing for selected output columns in the S3 → Sync to S3 action, so users can hash specific column values before the file is written and uploaded to S3.
Changes:
- Introduces a new
columns_to_hashaction field (array of{ column_name }) to configure which columns should be hashed. - Updates the S3 file generation path to hash configured columns using SHA256 before CSV escaping/quoting.
- Extends the generated
Payloadtype to includecolumns_to_hash.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/destination-actions/src/destinations/s3/syncToS3/generated-types.ts | Adds columns_to_hash to the action payload type. |
| packages/destination-actions/src/destinations/s3/syncToS3/functions.ts | Computes configured columns-to-hash and hashes matching column values during file generation. |
| packages/destination-actions/src/destinations/s3/syncToS3/fields.ts | Adds UI/config field definition for columns_to_hash. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (5)
packages/destination-actions/src/destinations/s3/syncToS3/functions.ts:36
columns_to_hashis read only frompayloads[0], so in batch mode any per-event differences will be silently ignored. Consider validating that all payloads have the samecolumns_to_hashconfiguration (or moving this to a batch-level argument) and throw aPayloadValidationErrorif they differ to avoid inconsistent hashing within a batch.
This issue also appears in the following locations of the same file:
- line 27
- line 38
- line 75
const headerNames = new Set(headers.map((h) => h.originalName))
const columnsToHash = validateColumnsToHash(payloads[0]?.columns_to_hash ?? [], headerNames)
const fileContent = generateFile(payloads, headers, delimiter, actionColName, batchColName, columnsToHash)
const s3Client = new Client(settings.s3_aws_region, settings.iam_role_arn, settings.iam_external_id)
await s3Client.uploadS3(
settings,
fileContent,
packages/destination-actions/src/destinations/s3/syncToS3/functions.ts:77
hash_algorithmis passed directly intocrypto.createHash(). If a caller provides an unsupported/typo’d algorithm (or different casing), this will throw a low-context runtime error. Please validate against the supported set (currently onlysha256) and rethrow as aPayloadValidationErrorwith an actionable message (and/or normalize casing).
const isLastRow = index === payloads.length - 1
const row = headers.map((header): string => {
if (header.originalName === actionColName) {
packages/destination-actions/src/destinations/s3/syncToS3/functions.ts:36
- Duplicate
column_nameentries incolumns_to_hashare silently overwritten when building theMap, which can mask configuration mistakes. Consider detecting duplicates and throwing aPayloadValidationErrorlisting the repeated column names.
const headerNames = new Set(headers.map((h) => h.originalName))
const columnsToHash = validateColumnsToHash(payloads[0]?.columns_to_hash ?? [], headerNames)
const fileContent = generateFile(payloads, headers, delimiter, actionColName, batchColName, columnsToHash)
const s3Client = new Client(settings.s3_aws_region, settings.iam_role_arn, settings.iam_external_id)
await s3Client.uploadS3(
settings,
fileContent,
packages/destination-actions/src/destinations/s3/syncToS3/functions.ts:46
- The new
columns_to_hashbehavior (hashing output, invalid column validation, invalid algorithm handling) is not covered by unit tests. Since this destination already has tests forgenerateFile, please add test cases that assert hashed values are emitted for configured columns and that invalid configurations fail with the expectedPayloadValidationErrormessages.
return ''
packages/destination-actions/src/destinations/s3/syncToS3/functions.ts:43
- The validation error message says the columns “do not exist”, but the check is against the generated output headers; a column could exist in the event payload but not be included in the output file. Consider clarifying the message to something like “not included in the output columns” (and optionally include the list of valid output column names) to make it easier to debug misconfigurations.
payloads[0]?.s3_aws_folder_name ?? '',
payloads[0]?.file_extension,
signal
)
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (3)
packages/destination-actions/src/destinations/s3/syncToS3/functions.ts:32
columns_to_hashis user-configurable (fields.ts) but is silently ignored unless theactions-s3-hashingfeature flag is enabled. That can lead to hard-to-diagnose misconfigurations. Consider either (a) throwing a PayloadValidationError whencolumns_to_hashis non-empty but the feature flag is off, or (b) hiding/gating the field itself until the flag is enabled.
const columnsToHash =
features && features[S3_HASHING_FEATURE_FLAG]
? validateColumnsToHash(payloads[0]?.columns_to_hash ?? [], new Set(headers.map((h) => h.originalName)))
: new Map<string, HashAlgorithm>()
packages/destination-actions/src/destinations/s3/syncToS3/functions.ts:121
validateColumnsToHashdoesn’t normalize user-provided strings (e.g. whitespace). As written, values like" email "or"sha256 "will fail validation even though they’re semantically correct. Trimming (and possibly lowercasing the algorithm) before validation would improve robustness and error quality.
for (const entry of entries) {
const columnName = String(entry.column_name ?? '')
const hashAlgorithm = String(entry.hash_algorithm ?? '')
packages/destination-actions/src/destinations/s3/syncToS3/tests/index.test.ts:171
- These assertions split the CSV row on
,, but the generated row contains quoted JSON with embedded commas (e.g. thepropertiescolumn). This parsing is not CSV-safe and could produce incorrect column indexing as soon as a hashed column appears after a comma-containing field. Consider asserting against the full expected output string (as the earlier test does) or using a CSV-aware parser for the row.
const rows = result.toString().split('\n')
const headerRow = rows[0].split(',')
const dataRow = rows[1].split(',')
Block the send with a PayloadValidationError when columns_to_hash is configured but the actions-s3-hashing feature flag is off, so unhashed PII is never written to S3. Adds send-level tests covering flag on/off. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Whitespace-only values now correctly fail the required checks, and leading/trailing spaces are stripped before matching against valid column names. Addresses Copilot review comment on PR #3802. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Whitespace-only values now correctly fail the required checks, and leading/trailing spaces are stripped before matching against valid column names. Addresses Copilot review comment on PR #3802. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds a columns_to_hash field to the S3 destination that allows customers to specify which columns should be hashed before being written to the output file
Supports configurable hash algorithms per column (currently SHA256, extensible to others)
Includes validation that rejects missing fields, unsupported algorithms, and column names that don't match the configured columns
Gated behind the actions-s3-hashing feature flag — when the flag is off, hashing configuration is ignored
Uses the shared processHashing utility for consistent hashing behavior (including pre-hash detection)
Testing
Staging test to be completed. TODO
Unit tests added:
E2E tests added
Verified that hashed columns feature working as expected.
Security Review
Please ensure sensitive data is properly protected in your integration.
type: 'password'New Destination Checklist
verioning-info.tsfile. example