Skip to content

Read Dapier-managed Mailchimp credential from DynamoDB #120

Description

@alexeygrigorev

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

  1. 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.
  2. [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.
  3. 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.
  4. 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.
  5. 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.
  • Changing Mailchimp export scope, scheduling, storage, artifact visibility, task linkage, or portal UI.
  • 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1ImportantbackendBackend/APIdataData model, migration, storageenhancementNew or improved functionalityhumanCode done or issue blocked on human verificationinfraDeployment and infrastructure

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions