You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Read Dapier-managed Mailchimp credential from DynamoDB
Status: pending
Tags: enhancement, backend, infra, data, P1
Depends on: Dapier CredentialsTable deployment/export and a populated mailchimp record (external repository)
Blocks: None
Scope
Replace only the mailing-list export service's Mailchimp Secrets Manager lookup with a consistent GetItem from the dedicated DynamoDB credentials table owned and populated by Dapier. DynamoDB's normal server-side encryption at rest is the protection mechanism: DataOps does not perform client-side encryption/decryption and does not call KMS or another credential service for this value.
The cross-repository contract is:
DataOps receives the Dapier credentials table name and ARN as deployment parameters; it does not create, migrate, scan, or write the table.
The table partition key is credential_id (String).
The Mailchimp item has credential_id: "mailchimp", provider: "mailchimp", value as a map containing apiKey and server, and non-secret updated_at metadata as an ISO timestamp. No DataOps config, CloudFormation parameter, environment variable, log, job, artifact, task, or API response contains value or apiKey.
DATAOPS_MAILING_EXPORTS_CONFIG references credentialId: "mailchimp" instead of secretName for each Mailchimp export configuration.
DataOps uses GetItem with ConsistentRead: true and the configured credential ID. It accepts only a matching Mailchimp record with a non-empty string value.apiKey; value.server, when present, must remain subject to the provider's existing validation.
Keep the existing operator-visible authorization behavior. Missing, unreadable, wrong-provider, or malformed credential records must produce the existing sanitized authorization failure and fix-authorization action, without exposing DynamoDB errors, table identifiers, item contents, API keys, or Mailchimp responses.
Update the SAM/CloudFormation contract, mailing export documentation, focused backend tests, and infrastructure tests. Remove the mailing-export-specific MailchimpSecretArn parameter/condition and Secrets Manager IAM grant after the DynamoDB path is active; do not change Secrets Manager use by unrelated DataOps features.
Acceptance Criteria
Mailing export configuration requires a non-empty credentialId and no longer accepts or exposes secretName; public configuration responses continue to omit credential identifiers.
The production credential loader performs exactly one consistent DynamoDB GetItem against the configured Dapier table and requested credentialId, with no Scan, Query, BatchGet, write, KMS, or Secrets Manager call.
A valid mailchimp item supplies value.apiKey and optional value.server to the existing provider registry and the export continues through the current request/poll/download flow.
Missing table configuration, missing item, key/provider mismatch, missing or non-string API key, malformed value map, and DynamoDB read failure all persist a sanitized authorization failure with nextAction: "fix-authorization".
Credential values are absent from logs, exceptions returned to callers, mailing-export jobs, artifacts, task links, API responses, and CloudFormation/environment configuration. Automated tests use obvious placeholders rather than a real credential.
DataOps infrastructure accepts the Dapier credential table name and ARN, passes only the table name to the backend runtime, and grants only dynamodb:GetItem on that exact table ARN, constrained with dynamodb:LeadingKeys to mailchimp. It grants no Scan/Query/BatchGet/write access to the credential table.
The mailing-export-specific MailchimpSecretArn, HasMailchimpSecret, and conditional secretsmanager:GetSecretValue resource are removed without altering unrelated DataOps secret permissions.
DataOps documentation describes the DynamoDB contract, transparent at-rest encryption, write-only ownership by Dapier, rotation by replacing the same item, safe failure behavior, and deployment/rollback order. It must not claim that DynamoDB prevents an authorized GetItem caller from receiving plaintext.
Existing mailing export idempotency, provider polling, private ZIP storage, artifact/task handling, daily limit behavior, and authenticated API behavior remain unchanged.
[HUMAN] In the target AWS account, after Dapier has populated the item, an authorized operator triggers one Mailchimp export and confirms it reaches requested/pending/completed rather than credential authorization failure; no credential value is inspected or copied as evidence.
[HUMAN] After the DataOps deployment, IAM policy inspection confirms the runtime role has only GetItem for the dedicated Dapier credential table and no longer has access to the legacy Mailchimp secret.
Test Scenarios
Scenario: Valid Dapier credential
Given: A configured Mailchimp export and a credential loader returning the contracted mailchimp item with placeholder values
When: The export starts
Then: DataOps constructs the Mailchimp provider and preserves the existing durable export workflow without persisting or returning the credential
Scenario: Missing or malformed credential
Given: The table setting is absent, the item is absent, the provider does not match, or value.apiKey is absent/non-string
When: The scheduled or manual export runs
Then: The job is failed with category authorization, a sanitized operator message, and fix-authorization, with no sensitive item data in logs or responses
Scenario: DynamoDB denies the read
Given: GetItem raises an access, throttling, or service error that may include internal details
When: The export runs
Then: The job records the same sanitized authorization failure and neither the original exception nor item/table details cross the service boundary
Scenario: Public API remains credential-free
Given: A configuration contains credentialId: "mailchimp" and runs exist
When: An authenticated operator requests GET /api/mailing-exports
Then: The response contains operator-facing configuration and safe run state but no credential ID, credential record, API key, or server derived from the credential
Scenario: Least-privilege infrastructure
Given: The SAM template is rendered with the Dapier table name and ARN
When: Infrastructure tests inspect backend environment and IAM statements
Then: The runtime receives the table name, can only call GetItem on the exact ARN for leading key mailchimp, and has no mailing-export Mailchimp Secrets Manager permission
Required Verification
npm --prefix backend test
npm --prefix backend run typecheck
npm --prefix backend run build
uv run --with pytest python -m pytest tests/infra
make sam-validate
make sam-build
No Playwright screenshot is required because this issue changes no UI; existing route tests must prove the API remains sanitized.
Deployment Sequence
Dapier deploys the dedicated credential table, write-only admin API/UI behavior, stable item contract above, and output/documentation for the table name and ARN.
[HUMAN] An operator saves/re-saves the real Mailchimp API key in Dapier so the mailchimp item exists before the reader switches. Do not copy the value through DataOps deployment parameters or logs.
Deploy DataOps with the Dapier table name/ARN parameters, the credentialId: "mailchimp" mailing config, exact-key GetItem IAM permission, and removal of its legacy Mailchimp secret permission.
Run the human smoke check. On failure, roll DataOps back to its previous stack version while leaving the Dapier table/item intact; do not paste the credential into rollback commands.
After successful verification, Dapier may remove the obsolete Secrets Manager copy under its own issue/change. DataOps must not delete or mutate it.
Out of Scope
Creating or writing the credential table from DataOps.
Dapier UI/API implementation, credential migration, or deletion of Dapier/Secrets Manager resources.
Client-side/application-layer encryption, direct KMS calls, SSM Parameter Store, Secrets Manager fallback, automatic rotation, or secret history/version UI.
Moving DataOps admin/session, Typefully, GitHub, bookkeeping, email intake, or any other credentials to DynamoDB.
Reading arbitrary credential IDs or providers from the Dapier table.
Dependencies
Deployment dependency: Dapier defines and owns the dedicated CredentialsTable and exact item contract above. Dapier must deploy/export the table and an operator must populate credential_id: "mailchimp" before the DataOps reader switches; this sequencing requirement does not block DataOps implementation and automated testing.
The Dapier stack must expose a stable table name and ARN for DataOps deployment. DataOps should consume parameters rather than hardcode an AWS account ID or physical table name.
The dedicated table deliberately stores credential values as ordinary DynamoDB attributes protected by DynamoDB's transparent encryption at rest. Any principal with authorized GetItem access receives plaintext, so IAM isolation and application-level redaction are mandatory privacy boundaries.
Read Dapier-managed Mailchimp credential from DynamoDB
Status: pending
Tags:
enhancement,backend,infra,data,P1Depends on: Dapier
CredentialsTabledeployment/export and a populatedmailchimprecord (external repository)Blocks: None
Scope
Replace only the mailing-list export service's Mailchimp Secrets Manager lookup with a consistent
GetItemfrom the dedicated DynamoDB credentials table owned and populated by Dapier. DynamoDB's normal server-side encryption at rest is the protection mechanism: DataOps does not perform client-side encryption/decryption and does not call KMS or another credential service for this value.The cross-repository contract is:
credential_id(String).credential_id: "mailchimp",provider: "mailchimp",valueas a map containingapiKeyandserver, and non-secretupdated_atmetadata as an ISO timestamp. No DataOps config, CloudFormation parameter, environment variable, log, job, artifact, task, or API response containsvalueorapiKey.DATAOPS_MAILING_EXPORTS_CONFIGreferencescredentialId: "mailchimp"instead ofsecretNamefor each Mailchimp export configuration.GetItemwithConsistentRead: trueand the configured credential ID. It accepts only a matching Mailchimp record with a non-empty stringvalue.apiKey;value.server, when present, must remain subject to the provider's existing validation.Keep the existing operator-visible authorization behavior. Missing, unreadable, wrong-provider, or malformed credential records must produce the existing sanitized
authorizationfailure andfix-authorizationaction, without exposing DynamoDB errors, table identifiers, item contents, API keys, or Mailchimp responses.Update the SAM/CloudFormation contract, mailing export documentation, focused backend tests, and infrastructure tests. Remove the mailing-export-specific
MailchimpSecretArnparameter/condition and Secrets Manager IAM grant after the DynamoDB path is active; do not change Secrets Manager use by unrelated DataOps features.Acceptance Criteria
credentialIdand no longer accepts or exposessecretName; public configuration responses continue to omit credential identifiers.GetItemagainst the configured Dapier table and requestedcredentialId, with no Scan, Query, BatchGet, write, KMS, or Secrets Manager call.mailchimpitem suppliesvalue.apiKeyand optionalvalue.serverto the existing provider registry and the export continues through the current request/poll/download flow.authorizationfailure withnextAction: "fix-authorization".dynamodb:GetItemon that exact table ARN, constrained withdynamodb:LeadingKeystomailchimp. It grants no Scan/Query/BatchGet/write access to the credential table.MailchimpSecretArn,HasMailchimpSecret, and conditionalsecretsmanager:GetSecretValueresource are removed without altering unrelated DataOps secret permissions.GetItemcaller from receiving plaintext.[HUMAN]In the target AWS account, after Dapier has populated the item, an authorized operator triggers one Mailchimp export and confirms it reaches requested/pending/completed rather than credential authorization failure; no credential value is inspected or copied as evidence.[HUMAN]After the DataOps deployment, IAM policy inspection confirms the runtime role has onlyGetItemfor the dedicated Dapier credential table and no longer has access to the legacy Mailchimp secret.Test Scenarios
Scenario: Valid Dapier credential
Given: A configured Mailchimp export and a credential loader returning the contracted
mailchimpitem with placeholder valuesWhen: The export starts
Then: DataOps constructs the Mailchimp provider and preserves the existing durable export workflow without persisting or returning the credential
Scenario: Missing or malformed credential
Given: The table setting is absent, the item is absent, the provider does not match, or
value.apiKeyis absent/non-stringWhen: The scheduled or manual export runs
Then: The job is failed with category
authorization, a sanitized operator message, andfix-authorization, with no sensitive item data in logs or responsesScenario: DynamoDB denies the read
Given:
GetItemraises an access, throttling, or service error that may include internal detailsWhen: The export runs
Then: The job records the same sanitized authorization failure and neither the original exception nor item/table details cross the service boundary
Scenario: Public API remains credential-free
Given: A configuration contains
credentialId: "mailchimp"and runs existWhen: An authenticated operator requests
GET /api/mailing-exportsThen: The response contains operator-facing configuration and safe run state but no credential ID, credential record, API key, or server derived from the credential
Scenario: Least-privilege infrastructure
Given: The SAM template is rendered with the Dapier table name and ARN
When: Infrastructure tests inspect backend environment and IAM statements
Then: The runtime receives the table name, can only call
GetItemon the exact ARN for leading keymailchimp, and has no mailing-export Mailchimp Secrets Manager permissionRequired Verification
npm --prefix backend testnpm --prefix backend run typechecknpm --prefix backend run builduv run --with pytest python -m pytest tests/inframake sam-validatemake sam-buildDeployment Sequence
[HUMAN]An operator saves/re-saves the real Mailchimp API key in Dapier so themailchimpitem exists before the reader switches. Do not copy the value through DataOps deployment parameters or logs.credentialId: "mailchimp"mailing config, exact-keyGetItemIAM permission, and removal of its legacy Mailchimp secret permission.Out of Scope
Dependencies
CredentialsTableand exact item contract above. Dapier must deploy/export the table and an operator must populatecredential_id: "mailchimp"before the DataOps reader switches; this sequencing requirement does not block DataOps implementation and automated testing.GetItemaccess receives plaintext, so IAM isolation and application-level redaction are mandatory privacy boundaries.