Skip to content

Run CI/CD flow

Feature under active development

CI/CD version management is actively evolving. This documentation is continuously updated as the feature matures. Always verify with the latest API reference or release notes before implementing in production.

This page walks you through the practical steps of using Mosaic’s Version Management APIs to move configurations across tenants. It covers the full lifecycle: export, review, validate, and import — including caveats such as alias handling, concurrency, and audit logging.

If you're looking for general guidance, see Development lifecycle.

Phase 1: Export

Mosaic supports two export types.

  • A partial export (recommended) promotes specific entities.
  • A full export moves the entire tenant configuration.

To learn more about their differences, see Cross-tenant version management (CI/CD).

Both exports include aliases for environment variables, keys, credentials, and certificates. Sensitive values are never included. A manifest.yaml file is also included, with details about the database versions of the Journey module entities, and Identity Management data. These details are useful during validation (see Phase 3: Validate).

To perform an export, call Version Management against the source tenant and provide a valid access token for that tenant (issued using management app credentials).

Curate token structure

When generating an admin access token for Version Management APIs, do not include the resource parameter. Version Management requires a non-resource-scoped token.

Environment URLs

Align the URL to the appropriate endpoint for your use case:

  • https://version-management.sbx.transmitsecurity.io - Sandbox environment
  • https://version-management.transmitsecurity.io - US production environment
  • https://version-management.ca.transmitsecurity.io - CA production environment
  • https://version-management.eu.transmitsecurity.io - EU production environment
  • https://version-management.au.transmitsecurity.io - AU production environment
  • https://version-management.gasne1-ts01.transmitsecurity.io - JP production environment

The response is a binary ZIP payload. When using curl, redirect the output to a file (for example, with --output export.zip). To inspect or version the configuration, extract the ZIP contents before reviewing or committing them to Git. The same structure must be preserved if you later re-zip the bundle for import.

To promote specific items instead of the whole tenant, call the partial export API — a POST with a body describing what to include. For each of the four supported entity types (journeys, subJourneys, externalConnections, typedLists), set a mode:

  • sync – exports every current item of that type. On import, the target is mirrored: items that aren't in the package are deleted.
  • selective – exports only the IDs listed in ids (1–25 per type). On import, those items are added or updated, and other items of that type are left intact.
  • Omitting a type entirely leaves such objects untouched in the target tenant.
curl -X 'POST' \
  'https://version-management.transmitsecurity.io/version/export/<SOURCE_TENANT_ID>' \
  -H 'Authorization: Bearer <MANAGEMENT_APP_ACCESS_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "entities": {
      "journeys": { "mode": "selective", "ids": ["<JOURNEY_ID>"] },
      "externalConnections": { "mode": "sync" }
    }
  }' \
  --output export.zip

This example promotes one journey and mirrors external connections. Sub-journeys and typed lists are omitted, so importing this package leaves them untouched in the target tenant.

Where the selection is recorded

The export records the mode used for each type, and the import reads it back to decide how to apply the package: a manifest.yaml in each entity folder (journeys/, sub-journeys/, external-connections/, typed-lists/), alongside the module-level manifest.yaml.

Requested IDs that don't exist in the source tenant are reported there as notFound; the export itself still succeeds.

Don't drop or edit these files — a package without them is treated as a full export, and every entity type is synced.

Scope of a partial export

The selection applies only to the four entity types listed above. The rest of the tenant configuration (identity management data, such as clients, user schema, and SSO configuration) is still exported—and imported—in full.

Phase 2: Review data

After generating an export, store the package in a version control system such as Git. Use pull requests and protected branches to review changes before promotion to the next environment. Version control provides a clear history of configuration changes and helps identify regressions. Be sure to keep dependencies intact (for example, journeys and their external connections) to avoid broken references during import.

Use GitHub or another version control system to manage your exports. Keep bundles private and never store secret values in Git.

Managing ZIP exports in Git

When storing exports in Git, extract the ZIP file before committing so that YAML changes can be reviewed and diffed easily. Before importing, re-zip the folder structure exactly as exported (including manifest.yaml and all subfolders) to maintain compatibility with the import API.

Phase 3: Validate

Before applying a configuration, use the version validation API in the target tenant with the exported data.

curl -X 'POST' \
  'https://version-management.transmitsecurity.io/version/validate/<TARGET_TENANT_ID>?format=zip' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer <MANAGEMENT_APP_ACCESS_TOKEN>' \
  -H 'Content-Type: application/zip' \
  --data-binary '@export.zip'
Environment URLs

Align the URL to the appropriate endpoint for your use case:

  • https://version-management.sbx.transmitsecurity.io - Sandbox environment
  • https://version-management.transmitsecurity.io - US production environment
  • https://version-management.ca.transmitsecurity.io - CA production environment
  • https://version-management.eu.transmitsecurity.io - EU production environment
  • https://version-management.au.transmitsecurity.io - AU production environment
  • https://version-management.gasne1-ts01.transmitsecurity.io - JP production environment
Note

When sending ZIP files with curl, use --data-binary to ensure the payload is transmitted intact. Send the header exactly as Content-Type: application/zip. Variants such as application/octet-stream, application/x-zip-compressed, or an appended charset parameter aren't recognized as a ZIP payload.

Validation checks that:

  • all required aliases (environment variables, keys, certificates, credentials) exist and have values,
  • the exported configuration is structurally valid,
  • and it is compatible with the target tenant’s version.

For a partial export, validation additionally checks that every entity referenced by the package (for example, an external connection used by an exported journey) is either included in the package or already present in the target tenant. Full exports are self-contained, so this check doesn't apply to them.

If references are missing, the response returns status: failure with the message Validation completed with missing dependencies, and details contains a MISSING_DEPENDENCIES entry naming each missing entity and where it's used:

{
  "status": "failure",
  "message": "Validation completed with missing dependencies",
  "details": [
    {
      "type": "MISSING_DEPENDENCIES",
      "message": "One or more depend on entities not found in this package or in the target tenant",
      "details": [
        "Missing provider \"<CONNECTION_ID>\" (used in journey \"<JOURNEY_ID>\" - \"My journey\")"
      ]
    }
  ]
}

Each line names the missing entity and the item that references it. External connections appear as provider in these messages, and sub-journeys as sub-journey.

Resolve the findings before importing: add the missing entities to the selection, or make sure they already exist in the target tenant. An import of a package with missing dependencies is rejected with 400 Bad Request.

Note that this phase does not run the full import logic — it only validates prerequisites and structure. This means validation may pass even if the subsequent import encounters issues.

Review the validation report carefully and fix any problems (e.g., missing variables or version mismatches). Repeat validation until the report is clean before proceeding with the import.

Phase 4: Import

Once validation passes, run the import API in the target tenant to apply the configuration. There's a single import API for both kinds of package — the package itself tells the import what to apply:

  • Full export – the import replaces the tenant’s configuration with the content of the file.
  • Partial export – the import applies each entity type according to the mode recorded for it at export time: sync mirrors the type (items missing from the package are deleted), selective adds or updates only the exported items, and a type that wasn't exported is left untouched. Identity management data in the package is still applied in full.
ZIP structure required

When importing, the file must be a ZIP archive with the same structure as the original export (including all subfolders and manifest.yaml). Incorrect structure or missing files may cause the import to fail.

Optional: rollback on failure — You can pass the query parameter failureRollBack=true to request that, if the import fails or only partially completes (e.g. one module import succeeds but another fails), the system automatically reverts the target tenant to its state before the import. The response may include a rollbackResult object with the outcome (e.g. success or failure and a message).

curl -X 'POST' \
  'https://version-management.transmitsecurity.io/version/import/<TARGET_TENANT_ID>?format=zip&failureRollBack=true' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer <MANAGEMENT_APP_ACCESS_TOKEN>' \
  -H 'Content-Type: application/zip' \
  --data-binary '@export.zip'
Environment URLs

Align the URL to the appropriate endpoint for your use case:

  • https://version-management.sbx.transmitsecurity.io - Sandbox environment
  • https://version-management.transmitsecurity.io - US production environment
  • https://version-management.ca.transmitsecurity.io - CA production environment
  • https://version-management.eu.transmitsecurity.io - EU production environment
  • https://version-management.au.transmitsecurity.io - AU production environment
  • https://version-management.gasne1-ts01.transmitsecurity.io - JP production environment
Note

When sending ZIP files with curl, use --data-binary to ensure the payload is transmitted intact. Send the header exactly as Content-Type: application/zip. Variants such as application/octet-stream, application/x-zip-compressed, or an appended charset parameter aren't recognized as a ZIP payload.

Run imports serially and schedule them during a maintenance window if the changes are significant to reduce the risk of conflicts.

Concurrency and locking

Mosaic does not currently provide a built-in locking mechanism. Avoid parallel imports for the same tenant and handle locking in your CI/CD pipeline until a service-level lock is introduced in future releases. If you call import while another import is in progress for that tenant, the API returns 409 Conflict with a message that an import is already in progress; retry after the current import completes.

In addition to the standard import, the Version Management Service provides a force import API.

Force import: risk and caveats

Force import should be a last resort. It skips alias validation and, for partial packages, the missing-dependency check. Database version compatibility and conversion checks still run, and the bundle’s structural integrity is enforced. If database versions are incompatible, force import will fail.

Use cases are rare, for example:

  • Recovering from a failed import where alias validation blocks a retry.
  • Aligning environments when you intentionally do not provision all aliases in the target tenant (accepting the risks).

Risks include:

  • Missing or unresolved aliases will not be detected and can cause runtime errors in journeys.
  • The missing-dependency check is skipped as well, so a partial package can be imported with references that resolve to nothing in the target tenant.
  • The tenant configuration is overwritten (for a partial package, within the scope recorded in it); use failureRollBack=true if you want the system to revert the tenant to its state before the import when the import fails or only partially completes.

Recommendation: Always run version validation API and import API first. Use force import only if you fully accept the risks, and ideally under guidance from Transmit Security support.

After a successful import, run a full regression in the target tenant to verify that all journeys, configurations, and integrations behave as expected.

Audit Logging

All import and export operations are recorded in the Admin User Activity Log for traceability and troubleshooting. Logged details include:

  • Action type (export, import, validation) and related metadata
  • Timestamp

Sensitive data such as tokens or secrets are never stored in plain text; they are redacted or fingerprinted in logs.